reasoning display
This commit is contained in:
parent
b87c6539cb
commit
2407a8ab64
2 changed files with 21 additions and 188 deletions
|
|
@ -5,10 +5,6 @@ import streamlit as st
|
|||
from openai import OpenAI
|
||||
import anthropic
|
||||
from dotenv import load_dotenv
|
||||
from rich import print as rprint
|
||||
from rich.panel import Panel
|
||||
from prompt_toolkit import PromptSession
|
||||
from prompt_toolkit.styles import Style
|
||||
|
||||
# Model Constants
|
||||
DEEPSEEK_MODEL: str = "deepseek-reasoner"
|
||||
|
|
@ -36,49 +32,33 @@ class ModelChain:
|
|||
def get_model_display_name(self):
|
||||
return self.current_model
|
||||
|
||||
def get_deepseek_reasoning(self, user_input: str) -> str:
|
||||
def get_deepseek_reasoning(self, user_input: str) -> str:
|
||||
start_time = time.time()
|
||||
self.deepseek_messages.append({"role": "user", "content": user_input})
|
||||
|
||||
response = self.deepseek_client.chat.completions.create(
|
||||
model=DEEPSEEK_MODEL,
|
||||
max_tokens=1,
|
||||
messages=self.deepseek_messages,
|
||||
stream=True
|
||||
)
|
||||
|
||||
reasoning_content = ""
|
||||
final_content = ""
|
||||
|
||||
# Create expander for reasoning
|
||||
with st.expander("💭 Reasoning Process", expanded=True):
|
||||
reasoning_placeholder = st.empty()
|
||||
try:
|
||||
response = self.deepseek_client.chat.completions.create(
|
||||
max_tokens=1, # Keep max_tokens=1 to only get reasoning
|
||||
model=DEEPSEEK_MODEL,
|
||||
messages=self.deepseek_messages
|
||||
)
|
||||
|
||||
for chunk in response:
|
||||
if chunk.choices[0].delta.reasoning_content:
|
||||
reasoning_piece = chunk.choices[0].delta.reasoning_content
|
||||
reasoning_content += reasoning_piece
|
||||
reasoning_placeholder.markdown(reasoning_content)
|
||||
elif chunk.choices[0].delta.content:
|
||||
final_content += chunk.choices[0].delta.content
|
||||
reasoning_content = response.choices[0].message.reasoning_content
|
||||
|
||||
# Create expander for reasoning
|
||||
with st.expander("💭 Reasoning Process", expanded=True):
|
||||
st.markdown(reasoning_content)
|
||||
elapsed_time = time.time() - start_time
|
||||
time_str = f"{elapsed_time/60:.1f} minutes" if elapsed_time >= 60 else f"{elapsed_time:.1f} seconds"
|
||||
st.caption(f"⏱️ Thought for {time_str}")
|
||||
|
||||
elapsed_time = time.time() - start_time
|
||||
time_str = f"{elapsed_time/60:.1f} minutes" if elapsed_time >= 60 else f"{elapsed_time:.1f} seconds"
|
||||
st.caption(f"⏱️ Thought for {time_str}")
|
||||
return reasoning_content
|
||||
|
||||
return reasoning_content
|
||||
except Exception as e:
|
||||
st.error(f"Error getting DeepSeek reasoning: {str(e)}")
|
||||
return "Error occurred while getting reasoning"
|
||||
|
||||
def get_claude_response(self, user_input: str, reasoning: str) -> str:
|
||||
"""
|
||||
Get response from Claude model.
|
||||
|
||||
Args:
|
||||
user_input: User's input text
|
||||
reasoning: Reasoning from DeepSeek
|
||||
|
||||
Returns:
|
||||
str: Claude's response
|
||||
"""
|
||||
user_message = {
|
||||
"role": "user",
|
||||
"content": [{"type": "text", "text": user_input}]
|
||||
|
|
@ -106,16 +86,16 @@ class ModelChain:
|
|||
full_response += text
|
||||
response_placeholder.markdown(full_response)
|
||||
|
||||
# Store the messages in Claude's history only
|
||||
self.claude_messages.extend([user_message, {
|
||||
"role": "assistant",
|
||||
"content": [{"type": "text", "text": full_response}]
|
||||
}])
|
||||
self.deepseek_messages.append({"role": "assistant", "content": full_response})
|
||||
|
||||
return full_response
|
||||
|
||||
except Exception as e:
|
||||
st.error(f"Error in response: {str(e)}")
|
||||
st.error(f"Error in Claude response: {str(e)}")
|
||||
return "Error occurred while getting response"
|
||||
|
||||
def main() -> None:
|
||||
|
|
|
|||
|
|
@ -1,147 +0,0 @@
|
|||
|
||||
import os
|
||||
from typing import List
|
||||
import fire
|
||||
|
||||
from langroid.pydantic_v1 import BaseModel, Field
|
||||
import langroid as lr
|
||||
from langroid.utils.configuration import settings
|
||||
from langroid.agent.tool_message import ToolMessage
|
||||
from langroid.agent.tools.orchestration import FinalResultTool
|
||||
import langroid.language_models as lm
|
||||
from rich.prompt import Prompt
|
||||
from langroid.agent.chat_document import ChatDocument
|
||||
|
||||
# for best results:
|
||||
DEFAULT_LLM = lm.OpenAIChatModel.GPT4o
|
||||
|
||||
os.environ["TOKENIZERS_PARALLELISM"] = "false"
|
||||
|
||||
# (1) Define the desired structure via Pydantic.
|
||||
# Here we define a nested structure for City information.
|
||||
# The "Field" annotations are optional, and are included in the system message
|
||||
# if provided, and help with generation accuracy.
|
||||
|
||||
|
||||
class CityData(BaseModel):
|
||||
population: int = Field(..., description="population of city")
|
||||
country: str = Field(..., description="country of city")
|
||||
|
||||
|
||||
class City(BaseModel):
|
||||
name: str = Field(..., description="name of city")
|
||||
details: CityData = Field(..., description="details of city")
|
||||
|
||||
|
||||
# (2) Define the Tool class for the LLM to use, to produce the above structure.
|
||||
class CityTool(lr.agent.ToolMessage):
|
||||
"""Present information about a city"""
|
||||
|
||||
request: str = "city_tool"
|
||||
purpose: str = """
|
||||
To present <city_info> AFTER user gives a city name,
|
||||
with all fields of the appropriate type filled out;
|
||||
"""
|
||||
city_info: City = Field(..., description="information about a city")
|
||||
|
||||
def handle(self) -> FinalResultTool:
|
||||
"""Handle LLM's structured output if it matches City structure"""
|
||||
print("SUCCESS! Got Valid City Info")
|
||||
return FinalResultTool(answer=self.city_info)
|
||||
|
||||
@staticmethod
|
||||
def handle_message_fallback(
|
||||
agent: lr.ChatAgent, msg: str | ChatDocument
|
||||
) -> str | None:
|
||||
"""
|
||||
We end up here when there was no recognized tool msg from the LLM;
|
||||
In this case use the AgentDoneTool with content set to
|
||||
the original message content.
|
||||
"""
|
||||
if isinstance(msg, ChatDocument) and msg.metadata.sender == lr.Entity.LLM:
|
||||
return f"""
|
||||
You forgot to use the TOOL/Function `{CityTool.name()}`.
|
||||
Please use this tool to present the city info.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def examples(cls) -> List["ToolMessage"]:
|
||||
# Used to provide few-shot examples in the system prompt
|
||||
return [
|
||||
cls(
|
||||
city_info=City(
|
||||
name="San Francisco",
|
||||
details=CityData(
|
||||
population=800_000,
|
||||
country="USA",
|
||||
),
|
||||
)
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def app(
|
||||
m: str = DEFAULT_LLM, # model
|
||||
d: bool = False, # pass -d to enable debug mode (see prompts etc)
|
||||
nc: bool = False, # pass -nc to disable cache-retrieval (i.e. get fresh answers)
|
||||
):
|
||||
settings.debug = d
|
||||
settings.cache = not nc
|
||||
# create LLM config
|
||||
llm_cfg = lm.OpenAIGPTConfig(
|
||||
chat_model=m or DEFAULT_LLM,
|
||||
chat_context_length=32000, # set this based on model
|
||||
max_output_tokens=1000,
|
||||
temperature=0.2,
|
||||
stream=True,
|
||||
timeout=45,
|
||||
)
|
||||
|
||||
# Recommended: First test if basic chat works with this llm setup as below:
|
||||
# Once this works, then you can try the rest of the example.
|
||||
#
|
||||
# agent = lr.ChatAgent(
|
||||
# lr.ChatAgentConfig(
|
||||
# llm=llm_cfg,
|
||||
# )
|
||||
# )
|
||||
#
|
||||
# agent.llm_response("What is 3 + 4?")
|
||||
#
|
||||
# task = lr.Task(agent)
|
||||
# verify you can interact with this in a chat loop on cmd line:
|
||||
# task.run("Concisely answer some questions")
|
||||
|
||||
# Define a ChatAgentConfig and ChatAgent
|
||||
|
||||
config = lr.ChatAgentConfig(
|
||||
llm=llm_cfg,
|
||||
system_message=f"""
|
||||
You will receive a city name,
|
||||
and you must use the TOOL/FUNCTION `{CityTool.name()}` to generate/present
|
||||
information about the city.
|
||||
""",
|
||||
)
|
||||
|
||||
agent = lr.ChatAgent(config)
|
||||
|
||||
# (4) Enable the Tool for this agent --> this auto-inserts JSON instructions
|
||||
# and few-shot examples (specified in the tool defn above) into the system message
|
||||
agent.enable_message(CityTool)
|
||||
|
||||
# (5) Create task specialized to return City object
|
||||
task: City | None = lr.Task(agent, interactive=False)[City]
|
||||
|
||||
while True:
|
||||
city = Prompt.ask("Enter a city name")
|
||||
if city in ["q", "x"]:
|
||||
break
|
||||
result: City | None = task.run(city)
|
||||
if result:
|
||||
print(f"City Info: {result}")
|
||||
else:
|
||||
print("No valid city info found.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
fire.Fire(app)
|
||||
Loading…
Reference in a new issue