diff --git a/langchain-crash-course/5_agents_tools/agent_react_chat.py b/langchain-crash-course/5_agents_tools/agent_react_chat.py index 81a2b2d..e4c403a 100644 --- a/langchain-crash-course/5_agents_tools/agent_react_chat.py +++ b/langchain-crash-course/5_agents_tools/agent_react_chat.py @@ -15,14 +15,18 @@ # Import langchain modules from langchain import hub -from langchain.agents import AgentExecutor, create_react_agent -from langchain_core.prompts import PromptTemplate +from langchain.agents import AgentExecutor, create_structured_chat_agent +from langchain_core.chat_history import ( + BaseChatMessageHistory, + InMemoryChatMessageHistory, +) from langchain_core.runnables import Runnable +from langchain_core.runnables.history import RunnableWithMessageHistory from langchain_core.tools import Tool from langchain_ollama import ChatOllama from langchain_openai import ChatOpenAI -# Import custom logger +# Import custom modules from utils.logger import RAGLogger from wikipedia import summary @@ -40,7 +44,7 @@ if not openai_configured and not ollama_configured: raise ValueError( "Neither OpenAI (OPENAI_API_KEY, OPENAI_LLM) nor Ollama (OLLAMA_LLM) is configured. " - "Please check your .env file." + "Please check your .env file. Note: Ollama llm model should be locally installed." ) sys.exit(1) @@ -62,15 +66,15 @@ def get_current_time(*args: Any, **kwargs: Any) -> str: """Get current time.""" current_time: str = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - logger.info(msg=f"Got current time: {current_time}") + logger.info(msg=f"Getting current time: {current_time}") return current_time -async def get_wikipedia_summary(query: str) -> str: - """""" +def get_wikipedia_summary(query: str) -> str: + """Get a summary from Wikipedia.""" try: - summary_result: str = await summary(title=query, sentences=3) - logger.info(msg=f"Wikipedia summary: {summary_result[:100]}") + summary_result: str = summary(title=query, sentences=3) + logger.info(msg=f"Getting Wikipedia summary: {summary_result[:100]}.....") return summary_result except Exception as e: logger.error(msg=f"Error getting Wikipedia summary: {e}") @@ -80,7 +84,7 @@ async def get_wikipedia_summary(query: str) -> str: # Set tools list to Agent tools: list = [ Tool( - name="Time", + name="Current Time", func=get_current_time, description="Useful for when you need to know the current time.", ), @@ -92,34 +96,46 @@ async def get_wikipedia_summary(query: str) -> str: ] # Pull the prompt template from the hub -# ReAct = Reason and Action -# https://smith.langchain.com/hub/hwchase17/react +# https://smith.langchain.com/hub/hwchase17/structured-chat-agent prompt_template: Any = hub.pull(owner_repo_commit="hwchase17/structured-chat-agent") +# Set up chat history +store: dict[str, BaseChatMessageHistory] = {} + -prompt: PromptTemplate = PromptTemplate.from_template(template=prompt_template) +def get_session_history(session_id: str) -> BaseChatMessageHistory: + """Get chat history for a session.""" + if session_id not in store: + store[session_id] = InMemoryChatMessageHistory() + return store[session_id] -# Create an agent -agent: Runnable[Any, Any] = create_react_agent( - tools=tools, llm=llm, prompt=prompt, stop_sequence=True + +# Create structured chat agent +agent: Runnable[Any, Any] = create_structured_chat_agent( + tools=tools, llm=llm, prompt=prompt_template ) # Create agent executor -agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True) +agent_executor: AgentExecutor = AgentExecutor( + agent=agent, tools=tools, verbose=True, handle_parsing_errors=True +) + +# Add chat history to agent executor +agent_with_chat_history: RunnableWithMessageHistory = RunnableWithMessageHistory( + runnable=agent_executor, + get_session_history=get_session_history, + input_messages_key="input", + history_messages_key="chat_history", +) -# Run agent executor +# Run agent executor with chat history async def main() -> None: - """ - Main function to run the agent executor. - - This function continuously prompts the user for a query, runs the agent - executor, and displays the response. The loop can be exited by typing - 'exit', or by sending a KeyboardInterrupt (Ctrl+C) or EOFError (Ctrl+D). - """ - logger.info(msg="Start Agent Tools Basic Application...") + logger.info(msg="Start Agent React Chat Application...") print("Type 'exit' to end the conversation.") + session_id: str = "chat_session" + while True: try: # User Query @@ -133,9 +149,11 @@ async def main() -> None: print("Exiting...") break - # Run agent executor - response: Any = await agent_executor.ainvoke(input={"input": query}) - logger.info(msg="Agent response generated successfully") + # Run agent executor with chat history + response: Any = await agent_with_chat_history.ainvoke( + input={"input": query}, + config={"configurable": {"session_id": session_id}}, + ) print(f"Agent: {response['output']}") except (KeyboardInterrupt, EOFError): @@ -144,9 +162,9 @@ async def main() -> None: break except Exception as e: - logger.error(f"Unexpected error: {e}") + logger.error(msg=f"Unexpected error: {e}") # Main entry point if __name__ == "__main__": - asyncio.run(main()) + asyncio.run(main=main()) diff --git a/langchain-crash-course/5_agents_tools/logs/agent_tools.log b/langchain-crash-course/5_agents_tools/logs/agent_tools.log index b4f123f..32a5787 100644 --- a/langchain-crash-course/5_agents_tools/logs/agent_tools.log +++ b/langchain-crash-course/5_agents_tools/logs/agent_tools.log @@ -1,6 +1,8 @@ 2025-08-31 22:51:29,350 - 5_agents_tools - INFO - Start Agent Tools Basic Application... 2025-08-31 22:52:03,279 - 5_agents_tools - INFO - Agent response generated successfully 2025-08-31 22:52:11,062 - 5_agents_tools - INFO - User exited conversation -2025-09-04 15:29:45,097 - 5_agents_tools - INFO - Start Agent Tools Basic Application... -2025-09-04 15:30:06,091 - 5_agents_tools - INFO - Agent response generated successfully -2025-09-04 15:30:19,119 - 5_agents_tools - INFO - User exited conversation +2025-09-04 21:00:41,977 - 5_agents_tools - INFO - Start Agent React Chat Application... +2025-09-04 21:01:15,876 - 5_agents_tools - INFO - Getting current time: 2025-09-04 21:01:15 +2025-09-04 21:01:56,097 - 5_agents_tools - ERROR - Error getting Wikipedia summary: Page id "michael jacks" does not match any pages. Try another id! +2025-09-04 21:02:05,819 - 5_agents_tools - INFO - Getting Wikipedia summary: Michael Joseph Jackson (August 29, 1958 – June 25, 2009) was an American singer, songwriter, dancer,..... +2025-09-04 21:30:59,868 - 5_agents_tools - INFO - User exited conversation