|
| 1 | +import os |
1 | 2 | import json |
2 | 3 | import asyncio |
3 | 4 |
|
4 | 5 | from typing import List |
5 | 6 | from langchain import hub |
6 | 7 | from pydantic import BaseModel, Field |
| 8 | +from langchain_ollama import ChatOllama |
7 | 9 | from langchain_openai import ChatOpenAI |
8 | | -from langgraph.prebuilt import create_react_agent |
| 10 | +from langchain.agents import create_react_agent |
9 | 11 | from langchain_core.prompts import ChatPromptTemplate |
10 | 12 | from langchain.callbacks.base import BaseCallbackHandler |
11 | 13 | from langchain_core.callbacks import StdOutCallbackHandler |
12 | 14 | from langchain_core.runnables.history import RunnableWithMessageHistory |
13 | | -from langchain.agents import AgentExecutor, create_openai_functions_agent |
| 15 | +from langchain.agents import (AgentExecutor, |
| 16 | + create_openai_functions_agent, |
| 17 | + create_tool_calling_agent) |
| 18 | + |
| 19 | +from src.agent.tools.shared_tools import init_llm |
14 | 20 |
|
15 | 21 |
|
16 | 22 | class PlanStep(BaseModel): |
@@ -127,20 +133,28 @@ def __init__(self, tools, memory=None, streaming: bool = True): |
127 | 133 | # Set up the streaming callback if streaming is enabled. |
128 | 134 | if streaming: |
129 | 135 | self.streaming_handler = StreamingCallbackHandler() |
130 | | - self.llm = ChatOpenAI( |
131 | | - model="gpt-4o-mini", |
132 | | - streaming=True, |
133 | | - callbacks=[self.streaming_handler] |
134 | | - ) |
| 136 | + |
| 137 | + self.llm = init_llm(service=os.environ["LLM_SERVICE"], |
| 138 | + model_name=os.environ["LLM_MODEL"], |
| 139 | + api_key=os.environ["LLM_API_KEY"], |
| 140 | + stream=streaming, |
| 141 | + callbacks=[self.streaming_handler]) |
| 142 | + |
| 143 | + if isinstance(self.llm, ChatOpenAI): |
| 144 | + self.prompt = hub.pull("pattern-agent/pattern-agent") |
| 145 | + |
| 146 | + self.agent = create_openai_functions_agent( |
| 147 | + self.llm, self.tools, self.prompt) |
| 148 | + elif isinstance(self.llm, ChatOllama): |
| 149 | + self.prompt = hub.pull("hwchase17/react") |
| 150 | + |
| 151 | + self.agent = create_react_agent( |
| 152 | + llm=self.llm, tools=self.tools, prompt=self.prompt) |
135 | 153 | else: |
136 | | - self.llm = ChatOpenAI(model="gpt-4o-mini") |
| 154 | + self.prompt = hub.pull("pattern-agent/pattern-agent") |
137 | 155 |
|
138 | | - self.prompt = hub.pull("pattern-agent/pattern-agent") |
139 | | - self.agent = create_openai_functions_agent( |
140 | | - self.llm, |
141 | | - self.tools, |
142 | | - self.prompt |
143 | | - ) |
| 156 | + self.agent = create_tool_calling_agent( |
| 157 | + llm=self.llm, tools=self.tools, prompt=self.prompt) |
144 | 158 |
|
145 | 159 | if streaming: |
146 | 160 | self.agent_executor = AgentExecutor( |
@@ -168,7 +182,19 @@ def __init__(self, tools, memory=None, streaming: bool = True): |
168 | 182 |
|
169 | 183 | async def stream(self, message: str): |
170 | 184 | """ |
171 | | - Asynchronously stream the agent’s response token-by-token. |
| 185 | + Args: |
| 186 | + message (str): The input message to be processed by the agent. |
| 187 | +
|
| 188 | + Yields: |
| 189 | + str: Tokens of the agent's response as they become available. |
| 190 | +
|
| 191 | + Raises: |
| 192 | + asyncio.TimeoutError: If waiting for a token from the queue times out. |
| 193 | +
|
| 194 | + Notes: |
| 195 | + - If memory is enabled, the agent's response is invoked synchronously using `run_in_executor`. |
| 196 | + - If memory is not enabled, the agent's response is invoked asynchronously using `arun`. |
| 197 | + - The method clears any leftover tokens in the queue before starting to stream the response. |
172 | 198 | """ |
173 | 199 | # Clear any leftover tokens. |
174 | 200 | while not self.streaming_handler.queue.empty(): |
@@ -200,6 +226,18 @@ async def stream(self, message: str): |
200 | 226 | result = await task |
201 | 227 |
|
202 | 228 | def ask(self, message: str): |
| 229 | + """ |
| 230 | + Sends a message to the agent and returns the response. |
| 231 | +
|
| 232 | + Args: |
| 233 | + message (str): The message to send to the agent. |
| 234 | +
|
| 235 | + Returns: |
| 236 | + The response from the agent. |
| 237 | +
|
| 238 | + If the agent has memory, it uses the agent with chat history to invoke the response. |
| 239 | + Otherwise, it uses the agent executor to invoke the response. |
| 240 | + """ |
203 | 241 | if self.memory: |
204 | 242 | return self.agent_with_chat_history.invoke( |
205 | 243 | input={"input": message}, |
|
0 commit comments