reasoning display

This commit is contained in:
Madhu 2025-01-28 23:40:47 +05:30
parent b87c6539cb
commit 2407a8ab64
2 changed files with 21 additions and 188 deletions

View file

@ -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:

View file

@ -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)