Spaces:
Runtime error
Runtime error
DylanonWic
commited on
Upload 17 files
Browse files- chatbot_multiagent.ipynb +74 -91
- chatbot_multiagent.py +27 -29
- prompt.py +3 -3
- tools.py +2 -2
chatbot_multiagent.ipynb
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
"cells": [
|
3 |
{
|
4 |
"cell_type": "code",
|
5 |
-
"execution_count":
|
6 |
"metadata": {},
|
7 |
"outputs": [],
|
8 |
"source": [
|
@@ -15,20 +15,21 @@
|
|
15 |
},
|
16 |
{
|
17 |
"cell_type": "code",
|
18 |
-
"execution_count":
|
19 |
"metadata": {},
|
20 |
-
"outputs": [
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
|
|
32 |
"source": [
|
33 |
"from langchain_core.messages import HumanMessage\n",
|
34 |
"import operator\n",
|
@@ -36,6 +37,7 @@
|
|
36 |
"\n",
|
37 |
"# for llm model\n",
|
38 |
"from langchain_openai import ChatOpenAI\n",
|
|
|
39 |
"from langchain.agents.format_scratchpad import format_to_openai_function_messages\n",
|
40 |
"from tools import find_place_from_text, nearby_search\n",
|
41 |
"from typing import Dict, List, Tuple, Annotated, Sequence, TypedDict\n",
|
@@ -43,7 +45,6 @@
|
|
43 |
" AgentExecutor,\n",
|
44 |
")\n",
|
45 |
"from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser\n",
|
46 |
-
"from langchain_community.chat_models import ChatOpenAI\n",
|
47 |
"from langchain_community.tools.convert_to_openai import format_tool_to_openai_function\n",
|
48 |
"from langchain_core.messages import (\n",
|
49 |
" AIMessage, \n",
|
@@ -67,6 +68,8 @@
|
|
67 |
"def format_docs(docs):\n",
|
68 |
" return \"\\n\\n\".join(doc.page_content for doc in docs)\n",
|
69 |
"\n",
|
|
|
|
|
70 |
"# Specify the pattern\n",
|
71 |
"file_pattern = \"document/*.csv\"\n",
|
72 |
"file_paths = tuple(glob.glob(file_pattern))\n",
|
@@ -88,8 +91,8 @@
|
|
88 |
"# Retrieve and generate using the relevant snippets of the blog.\n",
|
89 |
"retriever = vectorstore.as_retriever()\n",
|
90 |
"\n",
|
91 |
-
"## tools and LLM\n",
|
92 |
"\n",
|
|
|
93 |
"retriever_tool = Tool(\n",
|
94 |
" name=\"population, community and household expenditures data\",\n",
|
95 |
" func=retriever.get_relevant_documents,\n",
|
@@ -97,7 +100,8 @@
|
|
97 |
")\n",
|
98 |
"\n",
|
99 |
"# Bind the tools to the model\n",
|
100 |
-
"tools = [retriever_tool, find_place_from_text, nearby_search] # Include both tools if needed\n",
|
|
|
101 |
"\n",
|
102 |
"llm = ChatOpenAI(model=\"gpt-4o-mini\", temperature=0.0)\n",
|
103 |
"\n",
|
@@ -123,7 +127,7 @@
|
|
123 |
" prompt = prompt.partial(tool_names=\", \".join([tool.name for tool in tools]))\n",
|
124 |
" llm_with_tools = llm.bind(functions=[format_tool_to_openai_function(t) for t in tools])\n",
|
125 |
" # return prompt | llm.bind_tools(tools)\n",
|
126 |
-
" agent = prompt |
|
127 |
" return agent\n",
|
128 |
"\n",
|
129 |
"\n",
|
@@ -225,8 +229,12 @@
|
|
225 |
" # the tool calling node does not, meaning\n",
|
226 |
" # this edge will route back to the original agent\n",
|
227 |
" # who invoked the tool\n",
|
228 |
-
" lambda x: \"
|
229 |
-
" {\
|
|
|
|
|
|
|
|
|
230 |
")\n",
|
231 |
"workflow.add_edge(START, \"analyst\")\n",
|
232 |
"graph = workflow.compile()"
|
@@ -234,7 +242,7 @@
|
|
234 |
},
|
235 |
{
|
236 |
"cell_type": "code",
|
237 |
-
"execution_count":
|
238 |
"metadata": {},
|
239 |
"outputs": [],
|
240 |
"source": [
|
@@ -249,83 +257,57 @@
|
|
249 |
},
|
250 |
{
|
251 |
"cell_type": "code",
|
252 |
-
"execution_count":
|
253 |
"metadata": {},
|
254 |
"outputs": [
|
255 |
{
|
256 |
"name": "stdout",
|
257 |
"output_type": "stream",
|
258 |
"text": [
|
259 |
-
"
|
260 |
-
"
|
261 |
-
"\n",
|
262 |
-
"
|
263 |
-
"\n"
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
"\
|
272 |
-
"
|
273 |
-
"\n",
|
274 |
-
"
|
275 |
-
"
|
276 |
-
"
|
277 |
-
"\n",
|
278 |
-
"
|
279 |
-
"
|
280 |
-
"
|
281 |
-
"\n",
|
282 |
-
"
|
283 |
-
"
|
284 |
-
"
|
285 |
-
"\n",
|
286 |
-
"
|
287 |
-
"
|
288 |
-
"
|
289 |
-
"\n",
|
290 |
-
"
|
291 |
-
"\n",
|
292 |
-
"
|
293 |
-
"2. **List of Competitors Nearby**:\n",
|
294 |
-
"
|
295 |
-
"
|
296 |
-
"
|
297 |
-
"
|
298 |
-
" - **Coffee Shop B**\n",
|
299 |
-
" - Address: 456 Maboonkrong Rd, Bangkok\n",
|
300 |
-
" - Opening Hours: 7 AM - 9 PM\n",
|
301 |
-
" - Rating: 4.0\n",
|
302 |
-
" - **Coffee Shop C**\n",
|
303 |
-
" - Address: 789 Maboonkrong Rd, Bangkok\n",
|
304 |
-
" - Opening Hours: 9 AM - 11 PM\n",
|
305 |
-
" - Rating: 4.2\n",
|
306 |
-
" - **Coffee Shop D**\n",
|
307 |
-
" - Address: 321 Maboonkrong Rd, Bangkok\n",
|
308 |
-
" - Opening Hours: 8 AM - 8 PM\n",
|
309 |
-
" - Rating: 4.3\n",
|
310 |
-
" - **Coffee Shop E**\n",
|
311 |
-
" - Address: 654 Maboonkrong Rd, Bangkok\n",
|
312 |
-
" - Opening Hours: 10 AM - 10 PM\n",
|
313 |
-
" - Rating: 4.1\n",
|
314 |
-
"\n",
|
315 |
-
"3. **Products Sold by Competitors**: Coffee, pastries, sandwiches, and snacks.\n",
|
316 |
-
"4. **Number of Population Nearby**: Approximately 50,000\n",
|
317 |
-
"5. **Community Type**: Urban\n",
|
318 |
-
"6. **Household Expenditures**: Average household expenditure on food and beverages is around $300 per month.\n",
|
319 |
-
"7. **Population Data**: The population density in the area is high, with a mix of residents and tourists.\n",
|
320 |
-
"\n",
|
321 |
-
"This data should provide a comprehensive overview for analyzing the potential of opening a coffee shop near Maboonkrong. \n",
|
322 |
-
"\n",
|
323 |
-
"FINAL ANSWER\n"
|
324 |
]
|
325 |
}
|
326 |
],
|
327 |
"source": [
|
328 |
-
"question = \"
|
329 |
"\n",
|
330 |
"graph = workflow.compile()\n",
|
331 |
"\n",
|
@@ -341,13 +323,14 @@
|
|
341 |
" {\"recursion_limit\": 20},\n",
|
342 |
")\n",
|
343 |
"for s in events:\n",
|
344 |
-
"
|
345 |
-
" a[
|
|
|
346 |
]
|
347 |
},
|
348 |
{
|
349 |
"cell_type": "code",
|
350 |
-
"execution_count":
|
351 |
"metadata": {},
|
352 |
"outputs": [],
|
353 |
"source": [
|
|
|
2 |
"cells": [
|
3 |
{
|
4 |
"cell_type": "code",
|
5 |
+
"execution_count": 7,
|
6 |
"metadata": {},
|
7 |
"outputs": [],
|
8 |
"source": [
|
|
|
15 |
},
|
16 |
{
|
17 |
"cell_type": "code",
|
18 |
+
"execution_count": 8,
|
19 |
"metadata": {},
|
20 |
+
"outputs": [],
|
21 |
+
"source": [
|
22 |
+
"from langchain.globals import set_debug, set_verbose\n",
|
23 |
+
"\n",
|
24 |
+
"set_verbose(True)\n",
|
25 |
+
"set_debug(False)"
|
26 |
+
]
|
27 |
+
},
|
28 |
+
{
|
29 |
+
"cell_type": "code",
|
30 |
+
"execution_count": 9,
|
31 |
+
"metadata": {},
|
32 |
+
"outputs": [],
|
33 |
"source": [
|
34 |
"from langchain_core.messages import HumanMessage\n",
|
35 |
"import operator\n",
|
|
|
37 |
"\n",
|
38 |
"# for llm model\n",
|
39 |
"from langchain_openai import ChatOpenAI\n",
|
40 |
+
"# from langchain_community.chat_models import ChatOpenAI\n",
|
41 |
"from langchain.agents.format_scratchpad import format_to_openai_function_messages\n",
|
42 |
"from tools import find_place_from_text, nearby_search\n",
|
43 |
"from typing import Dict, List, Tuple, Annotated, Sequence, TypedDict\n",
|
|
|
45 |
" AgentExecutor,\n",
|
46 |
")\n",
|
47 |
"from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser\n",
|
|
|
48 |
"from langchain_community.tools.convert_to_openai import format_tool_to_openai_function\n",
|
49 |
"from langchain_core.messages import (\n",
|
50 |
" AIMessage, \n",
|
|
|
68 |
"def format_docs(docs):\n",
|
69 |
" return \"\\n\\n\".join(doc.page_content for doc in docs)\n",
|
70 |
"\n",
|
71 |
+
"\n",
|
72 |
+
"## Document csv\n",
|
73 |
"# Specify the pattern\n",
|
74 |
"file_pattern = \"document/*.csv\"\n",
|
75 |
"file_paths = tuple(glob.glob(file_pattern))\n",
|
|
|
91 |
"# Retrieve and generate using the relevant snippets of the blog.\n",
|
92 |
"retriever = vectorstore.as_retriever()\n",
|
93 |
"\n",
|
|
|
94 |
"\n",
|
95 |
+
"## tools and LLM\n",
|
96 |
"retriever_tool = Tool(\n",
|
97 |
" name=\"population, community and household expenditures data\",\n",
|
98 |
" func=retriever.get_relevant_documents,\n",
|
|
|
100 |
")\n",
|
101 |
"\n",
|
102 |
"# Bind the tools to the model\n",
|
103 |
+
"# tools = [retriever_tool, find_place_from_text, nearby_search] # Include both tools if needed\n",
|
104 |
+
"tools = [find_place_from_text, nearby_search]\n",
|
105 |
"\n",
|
106 |
"llm = ChatOpenAI(model=\"gpt-4o-mini\", temperature=0.0)\n",
|
107 |
"\n",
|
|
|
127 |
" prompt = prompt.partial(tool_names=\", \".join([tool.name for tool in tools]))\n",
|
128 |
" llm_with_tools = llm.bind(functions=[format_tool_to_openai_function(t) for t in tools])\n",
|
129 |
" # return prompt | llm.bind_tools(tools)\n",
|
130 |
+
" agent = prompt | llm_with_tools\n",
|
131 |
" return agent\n",
|
132 |
"\n",
|
133 |
"\n",
|
|
|
229 |
" # the tool calling node does not, meaning\n",
|
230 |
" # this edge will route back to the original agent\n",
|
231 |
" # who invoked the tool\n",
|
232 |
+
" lambda x: x[\"sender\"],\n",
|
233 |
+
" {\n",
|
234 |
+
" \"data collector\":\"data collector\",\n",
|
235 |
+
" \"analyst\":\"analyst\",\n",
|
236 |
+
" \"reporter\":\"reporter\",\n",
|
237 |
+
" },\n",
|
238 |
")\n",
|
239 |
"workflow.add_edge(START, \"analyst\")\n",
|
240 |
"graph = workflow.compile()"
|
|
|
242 |
},
|
243 |
{
|
244 |
"cell_type": "code",
|
245 |
+
"execution_count": 10,
|
246 |
"metadata": {},
|
247 |
"outputs": [],
|
248 |
"source": [
|
|
|
257 |
},
|
258 |
{
|
259 |
"cell_type": "code",
|
260 |
+
"execution_count": 11,
|
261 |
"metadata": {},
|
262 |
"outputs": [
|
263 |
{
|
264 |
"name": "stdout",
|
265 |
"output_type": "stream",
|
266 |
"text": [
|
267 |
+
"*********name: analyst\n",
|
268 |
+
"{'analyst': {'messages': [AIMessage(content=\"To assist with the feasibility analysis for a bookstore near New York, I will extract the relevant information:\\n\\n- **Location**: New York\\n- **Keyword**: Bookstore\\n\\nI will now instruct the Data Collector to gather relevant data based on this input. \\n\\nLet's proceed with the data collection.\", additional_kwargs={'function_call': {'arguments': '{\"input_dict\":{\"keyword\":\"bookstore\",\"location_name\":\"New York\",\"radius\":5000,\"place_type\":\"bookstore\"}}', 'name': 'nearby_search'}, 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 98, 'prompt_tokens': 335, 'total_tokens': 433}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'function_call', 'logprobs': None}, name='analyst', id='run-f7896776-cbec-4359-93ca-71d0f7fedeb7-0', usage_metadata={'input_tokens': 335, 'output_tokens': 98, 'total_tokens': 433})], 'sender': 'analyst'}}\n",
|
269 |
+
"*********name: data collector\n",
|
270 |
+
"{'data collector': {'messages': [AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"location\":\"New York\"}', 'name': 'find_place_from_text'}, 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 17, 'prompt_tokens': 592, 'total_tokens': 609}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_48196bc67a', 'finish_reason': 'function_call', 'logprobs': None}, name='data collector', id='run-28ebbebf-faad-44a5-b972-29b6f8bc3455-0', usage_metadata={'input_tokens': 592, 'output_tokens': 17, 'total_tokens': 609})], 'sender': 'data collector'}}\n",
|
271 |
+
"*********name: reporter\n"
|
272 |
+
]
|
273 |
+
},
|
274 |
+
{
|
275 |
+
"ename": "BadRequestError",
|
276 |
+
"evalue": "Error code: 400 - {'error': {'message': \"Invalid 'messages[3].name': string does not match pattern. Expected a string that matches the pattern '^[a-zA-Z0-9_-]+$'.\", 'type': 'invalid_request_error', 'param': 'messages[3].name', 'code': 'invalid_value'}}",
|
277 |
+
"output_type": "error",
|
278 |
+
"traceback": [
|
279 |
+
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
280 |
+
"\u001b[0;31mBadRequestError\u001b[0m Traceback (most recent call last)",
|
281 |
+
"Cell \u001b[0;32mIn[11], line 16\u001b[0m\n\u001b[1;32m 3\u001b[0m graph \u001b[38;5;241m=\u001b[39m workflow\u001b[38;5;241m.\u001b[39mcompile()\n\u001b[1;32m 5\u001b[0m events \u001b[38;5;241m=\u001b[39m graph\u001b[38;5;241m.\u001b[39mstream(\n\u001b[1;32m 6\u001b[0m {\n\u001b[1;32m 7\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmessages\u001b[39m\u001b[38;5;124m\"\u001b[39m: [\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 14\u001b[0m {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrecursion_limit\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;241m20\u001b[39m},\n\u001b[1;32m 15\u001b[0m )\n\u001b[0;32m---> 16\u001b[0m \u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43ms\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mevents\u001b[49m\u001b[43m:\u001b[49m\n\u001b[1;32m 17\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mprint\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43ms\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 18\u001b[0m \u001b[38;5;66;03m# a = list(s.items())[0]\u001b[39;00m\n\u001b[1;32m 19\u001b[0m \u001b[38;5;66;03m# a[1]['messages'][0].pretty_print()\u001b[39;00m\n",
|
282 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/langgraph/pregel/__init__.py:1018\u001b[0m, in \u001b[0;36mPregel.stream\u001b[0;34m(self, input, config, stream_mode, output_keys, interrupt_before, interrupt_after, debug)\u001b[0m\n\u001b[1;32m 1015\u001b[0m \u001b[38;5;28;01mdel\u001b[39;00m fut, task\n\u001b[1;32m 1017\u001b[0m \u001b[38;5;66;03m# panic on failure or timeout\u001b[39;00m\n\u001b[0;32m-> 1018\u001b[0m \u001b[43m_panic_or_proceed\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdone\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minflight\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mloop\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstep\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1019\u001b[0m \u001b[38;5;66;03m# don't keep futures around in memory longer than needed\u001b[39;00m\n\u001b[1;32m 1020\u001b[0m \u001b[38;5;28;01mdel\u001b[39;00m done, inflight, futures\n",
|
283 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/langgraph/pregel/__init__.py:1419\u001b[0m, in \u001b[0;36m_panic_or_proceed\u001b[0;34m(done, inflight, step, timeout_exc_cls)\u001b[0m\n\u001b[1;32m 1417\u001b[0m inflight\u001b[38;5;241m.\u001b[39mpop()\u001b[38;5;241m.\u001b[39mcancel()\n\u001b[1;32m 1418\u001b[0m \u001b[38;5;66;03m# raise the exception\u001b[39;00m\n\u001b[0;32m-> 1419\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m exc\n\u001b[1;32m 1421\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m inflight:\n\u001b[1;32m 1422\u001b[0m \u001b[38;5;66;03m# if we got here means we timed out\u001b[39;00m\n\u001b[1;32m 1423\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m inflight:\n\u001b[1;32m 1424\u001b[0m \u001b[38;5;66;03m# cancel all pending tasks\u001b[39;00m\n",
|
284 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/langgraph/pregel/executor.py:60\u001b[0m, in \u001b[0;36mBackgroundExecutor.done\u001b[0;34m(self, task)\u001b[0m\n\u001b[1;32m 58\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mdone\u001b[39m(\u001b[38;5;28mself\u001b[39m, task: concurrent\u001b[38;5;241m.\u001b[39mfutures\u001b[38;5;241m.\u001b[39mFuture) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 59\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 60\u001b[0m \u001b[43mtask\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mresult\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 61\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m GraphInterrupt:\n\u001b[1;32m 62\u001b[0m \u001b[38;5;66;03m# This exception is an interruption signal, not an error\u001b[39;00m\n\u001b[1;32m 63\u001b[0m \u001b[38;5;66;03m# so we don't want to re-raise it on exit\u001b[39;00m\n\u001b[1;32m 64\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtasks\u001b[38;5;241m.\u001b[39mpop(task)\n",
|
285 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/concurrent/futures/_base.py:449\u001b[0m, in \u001b[0;36mFuture.result\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m 447\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m CancelledError()\n\u001b[1;32m 448\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_state \u001b[38;5;241m==\u001b[39m FINISHED:\n\u001b[0;32m--> 449\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__get_result\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 451\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_condition\u001b[38;5;241m.\u001b[39mwait(timeout)\n\u001b[1;32m 453\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_state \u001b[38;5;129;01min\u001b[39;00m [CANCELLED, CANCELLED_AND_NOTIFIED]:\n",
|
286 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/concurrent/futures/_base.py:401\u001b[0m, in \u001b[0;36mFuture.__get_result\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 399\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_exception:\n\u001b[1;32m 400\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 401\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_exception\n\u001b[1;32m 402\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[1;32m 403\u001b[0m \u001b[38;5;66;03m# Break a reference cycle with the exception in self._exception\u001b[39;00m\n\u001b[1;32m 404\u001b[0m \u001b[38;5;28mself\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n",
|
287 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/concurrent/futures/thread.py:58\u001b[0m, in \u001b[0;36m_WorkItem.run\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 55\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[1;32m 57\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 58\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfn\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 59\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m exc:\n\u001b[1;32m 60\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfuture\u001b[38;5;241m.\u001b[39mset_exception(exc)\n",
|
288 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/langgraph/pregel/retry.py:25\u001b[0m, in \u001b[0;36mrun_with_retry\u001b[0;34m(task, retry_policy)\u001b[0m\n\u001b[1;32m 23\u001b[0m task\u001b[38;5;241m.\u001b[39mwrites\u001b[38;5;241m.\u001b[39mclear()\n\u001b[1;32m 24\u001b[0m \u001b[38;5;66;03m# run the task\u001b[39;00m\n\u001b[0;32m---> 25\u001b[0m \u001b[43mtask\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mproc\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtask\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minput\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtask\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mconfig\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 26\u001b[0m \u001b[38;5;66;03m# if successful, end\u001b[39;00m\n\u001b[1;32m 27\u001b[0m \u001b[38;5;28;01mbreak\u001b[39;00m\n",
|
289 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/langchain_core/runnables/base.py:2876\u001b[0m, in \u001b[0;36mRunnableSequence.invoke\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m 2874\u001b[0m context\u001b[38;5;241m.\u001b[39mrun(_set_config_context, config)\n\u001b[1;32m 2875\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m i \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[0;32m-> 2876\u001b[0m \u001b[38;5;28minput\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[43mcontext\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstep\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minvoke\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2877\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 2878\u001b[0m \u001b[38;5;28minput\u001b[39m \u001b[38;5;241m=\u001b[39m context\u001b[38;5;241m.\u001b[39mrun(step\u001b[38;5;241m.\u001b[39minvoke, \u001b[38;5;28minput\u001b[39m, config)\n",
|
290 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/langgraph/utils.py:102\u001b[0m, in \u001b[0;36mRunnableCallable.invoke\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m accepts_config(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfunc):\n\u001b[1;32m 101\u001b[0m kwargs[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mconfig\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m config\n\u001b[0;32m--> 102\u001b[0m ret \u001b[38;5;241m=\u001b[39m \u001b[43mcontext\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfunc\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 103\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(ret, Runnable) \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mrecurse:\n\u001b[1;32m 104\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m ret\u001b[38;5;241m.\u001b[39minvoke(\u001b[38;5;28minput\u001b[39m, config)\n",
|
291 |
+
"Cell \u001b[0;32mIn[9], line 112\u001b[0m, in \u001b[0;36magent_node\u001b[0;34m(state, agent, name)\u001b[0m\n\u001b[1;32m 110\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21magent_node\u001b[39m(state, agent, name):\n\u001b[1;32m 111\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m*********name: \u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m+\u001b[39m name)\n\u001b[0;32m--> 112\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43magent\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstate\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 113\u001b[0m \u001b[38;5;66;03m# We convert the agent output into a format that is suitable to append to the global state\u001b[39;00m\n\u001b[1;32m 114\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(result, ToolMessage):\n",
|
292 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/langchain_core/runnables/base.py:2878\u001b[0m, in \u001b[0;36mRunnableSequence.invoke\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m 2876\u001b[0m \u001b[38;5;28minput\u001b[39m \u001b[38;5;241m=\u001b[39m context\u001b[38;5;241m.\u001b[39mrun(step\u001b[38;5;241m.\u001b[39minvoke, \u001b[38;5;28minput\u001b[39m, config, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 2877\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m-> 2878\u001b[0m \u001b[38;5;28minput\u001b[39m \u001b[38;5;241m=\u001b[39m context\u001b[38;5;241m.\u001b[39mrun(step\u001b[38;5;241m.\u001b[39minvoke, \u001b[38;5;28minput\u001b[39m, config)\n\u001b[1;32m 2879\u001b[0m \u001b[38;5;66;03m# finish the root run\u001b[39;00m\n\u001b[1;32m 2880\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n",
|
293 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/langchain_core/runnables/base.py:5094\u001b[0m, in \u001b[0;36mRunnableBindingBase.invoke\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m 5088\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21minvoke\u001b[39m(\n\u001b[1;32m 5089\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 5090\u001b[0m \u001b[38;5;28minput\u001b[39m: Input,\n\u001b[1;32m 5091\u001b[0m config: Optional[RunnableConfig] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 5092\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Optional[Any],\n\u001b[1;32m 5093\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Output:\n\u001b[0;32m-> 5094\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbound\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 5095\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 5096\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_merge_configs\u001b[49m\u001b[43m(\u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 5097\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43m{\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 5098\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n",
|
294 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/langchain_core/language_models/chat_models.py:276\u001b[0m, in \u001b[0;36mBaseChatModel.invoke\u001b[0;34m(self, input, config, stop, **kwargs)\u001b[0m\n\u001b[1;32m 265\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21minvoke\u001b[39m(\n\u001b[1;32m 266\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 267\u001b[0m \u001b[38;5;28minput\u001b[39m: LanguageModelInput,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 271\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Any,\n\u001b[1;32m 272\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m BaseMessage:\n\u001b[1;32m 273\u001b[0m config \u001b[38;5;241m=\u001b[39m ensure_config(config)\n\u001b[1;32m 274\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m cast(\n\u001b[1;32m 275\u001b[0m ChatGeneration,\n\u001b[0;32m--> 276\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgenerate_prompt\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 277\u001b[0m \u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_convert_input\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 278\u001b[0m \u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 279\u001b[0m \u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mconfig\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mcallbacks\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 280\u001b[0m \u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mconfig\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtags\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 281\u001b[0m \u001b[43m \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mconfig\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mmetadata\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 282\u001b[0m \u001b[43m \u001b[49m\u001b[43mrun_name\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mconfig\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mrun_name\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 283\u001b[0m \u001b[43m \u001b[49m\u001b[43mrun_id\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mconfig\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpop\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mrun_id\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 284\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 285\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241m.\u001b[39mgenerations[\u001b[38;5;241m0\u001b[39m][\u001b[38;5;241m0\u001b[39m],\n\u001b[1;32m 286\u001b[0m )\u001b[38;5;241m.\u001b[39mmessage\n",
|
295 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/langchain_core/language_models/chat_models.py:776\u001b[0m, in \u001b[0;36mBaseChatModel.generate_prompt\u001b[0;34m(self, prompts, stop, callbacks, **kwargs)\u001b[0m\n\u001b[1;32m 768\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mgenerate_prompt\u001b[39m(\n\u001b[1;32m 769\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 770\u001b[0m prompts: List[PromptValue],\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 773\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Any,\n\u001b[1;32m 774\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m LLMResult:\n\u001b[1;32m 775\u001b[0m prompt_messages \u001b[38;5;241m=\u001b[39m [p\u001b[38;5;241m.\u001b[39mto_messages() \u001b[38;5;28;01mfor\u001b[39;00m p \u001b[38;5;129;01min\u001b[39;00m prompts]\n\u001b[0;32m--> 776\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgenerate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mprompt_messages\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcallbacks\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
|
296 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/langchain_core/language_models/chat_models.py:633\u001b[0m, in \u001b[0;36mBaseChatModel.generate\u001b[0;34m(self, messages, stop, callbacks, tags, metadata, run_name, run_id, **kwargs)\u001b[0m\n\u001b[1;32m 631\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m run_managers:\n\u001b[1;32m 632\u001b[0m run_managers[i]\u001b[38;5;241m.\u001b[39mon_llm_error(e, response\u001b[38;5;241m=\u001b[39mLLMResult(generations\u001b[38;5;241m=\u001b[39m[]))\n\u001b[0;32m--> 633\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m e\n\u001b[1;32m 634\u001b[0m flattened_outputs \u001b[38;5;241m=\u001b[39m [\n\u001b[1;32m 635\u001b[0m LLMResult(generations\u001b[38;5;241m=\u001b[39m[res\u001b[38;5;241m.\u001b[39mgenerations], llm_output\u001b[38;5;241m=\u001b[39mres\u001b[38;5;241m.\u001b[39mllm_output) \u001b[38;5;66;03m# type: ignore[list-item]\u001b[39;00m\n\u001b[1;32m 636\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m res \u001b[38;5;129;01min\u001b[39;00m results\n\u001b[1;32m 637\u001b[0m ]\n\u001b[1;32m 638\u001b[0m llm_output \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_combine_llm_outputs([res\u001b[38;5;241m.\u001b[39mllm_output \u001b[38;5;28;01mfor\u001b[39;00m res \u001b[38;5;129;01min\u001b[39;00m results])\n",
|
297 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/langchain_core/language_models/chat_models.py:623\u001b[0m, in \u001b[0;36mBaseChatModel.generate\u001b[0;34m(self, messages, stop, callbacks, tags, metadata, run_name, run_id, **kwargs)\u001b[0m\n\u001b[1;32m 620\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i, m \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(messages):\n\u001b[1;32m 621\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 622\u001b[0m results\u001b[38;5;241m.\u001b[39mappend(\n\u001b[0;32m--> 623\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_generate_with_cache\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 624\u001b[0m \u001b[43m \u001b[49m\u001b[43mm\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 625\u001b[0m \u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 626\u001b[0m \u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_managers\u001b[49m\u001b[43m[\u001b[49m\u001b[43mi\u001b[49m\u001b[43m]\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mrun_managers\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 627\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 628\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 629\u001b[0m )\n\u001b[1;32m 630\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 631\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m run_managers:\n",
|
298 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/langchain_core/language_models/chat_models.py:845\u001b[0m, in \u001b[0;36mBaseChatModel._generate_with_cache\u001b[0;34m(self, messages, stop, run_manager, **kwargs)\u001b[0m\n\u001b[1;32m 843\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 844\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m inspect\u001b[38;5;241m.\u001b[39msignature(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_generate)\u001b[38;5;241m.\u001b[39mparameters\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrun_manager\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n\u001b[0;32m--> 845\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_generate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 846\u001b[0m \u001b[43m \u001b[49m\u001b[43mmessages\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\n\u001b[1;32m 847\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 848\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 849\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_generate(messages, stop\u001b[38;5;241m=\u001b[39mstop, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n",
|
299 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/langchain_openai/chat_models/base.py:635\u001b[0m, in \u001b[0;36mBaseChatOpenAI._generate\u001b[0;34m(self, messages, stop, run_manager, **kwargs)\u001b[0m\n\u001b[1;32m 633\u001b[0m generation_info \u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mheaders\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;28mdict\u001b[39m(raw_response\u001b[38;5;241m.\u001b[39mheaders)}\n\u001b[1;32m 634\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m--> 635\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mclient\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcreate\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mpayload\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 636\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_create_chat_result(response, generation_info)\n",
|
300 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/openai/_utils/_utils.py:274\u001b[0m, in \u001b[0;36mrequired_args.<locals>.inner.<locals>.wrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 272\u001b[0m msg \u001b[38;5;241m=\u001b[39m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mMissing required argument: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mquote(missing[\u001b[38;5;241m0\u001b[39m])\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 273\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(msg)\n\u001b[0;32m--> 274\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n",
|
301 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/openai/resources/chat/completions.py:668\u001b[0m, in \u001b[0;36mCompletions.create\u001b[0;34m(self, messages, model, frequency_penalty, function_call, functions, logit_bias, logprobs, max_tokens, n, parallel_tool_calls, presence_penalty, response_format, seed, service_tier, stop, stream, stream_options, temperature, tool_choice, tools, top_logprobs, top_p, user, extra_headers, extra_query, extra_body, timeout)\u001b[0m\n\u001b[1;32m 633\u001b[0m \u001b[38;5;129m@required_args\u001b[39m([\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmessages\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmodel\u001b[39m\u001b[38;5;124m\"\u001b[39m], [\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmessages\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmodel\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mstream\u001b[39m\u001b[38;5;124m\"\u001b[39m])\n\u001b[1;32m 634\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcreate\u001b[39m(\n\u001b[1;32m 635\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 665\u001b[0m timeout: \u001b[38;5;28mfloat\u001b[39m \u001b[38;5;241m|\u001b[39m httpx\u001b[38;5;241m.\u001b[39mTimeout \u001b[38;5;241m|\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;241m|\u001b[39m NotGiven \u001b[38;5;241m=\u001b[39m NOT_GIVEN,\n\u001b[1;32m 666\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m ChatCompletion \u001b[38;5;241m|\u001b[39m Stream[ChatCompletionChunk]:\n\u001b[1;32m 667\u001b[0m validate_response_format(response_format)\n\u001b[0;32m--> 668\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_post\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 669\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m/chat/completions\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 670\u001b[0m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmaybe_transform\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 671\u001b[0m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\n\u001b[1;32m 672\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mmessages\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmessages\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 673\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mmodel\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 674\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mfrequency_penalty\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mfrequency_penalty\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 675\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mfunction_call\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mfunction_call\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 676\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mfunctions\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mfunctions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 677\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mlogit_bias\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mlogit_bias\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 678\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mlogprobs\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mlogprobs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 679\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mmax_tokens\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mmax_tokens\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 680\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mn\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 681\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mparallel_tool_calls\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mparallel_tool_calls\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 682\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mpresence_penalty\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mpresence_penalty\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 683\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mresponse_format\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mresponse_format\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 684\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mseed\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mseed\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 685\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mservice_tier\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mservice_tier\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 686\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mstop\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 687\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mstream\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 688\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mstream_options\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream_options\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 689\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtemperature\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtemperature\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 690\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtool_choice\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtool_choice\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 691\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtools\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtools\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 692\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtop_logprobs\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtop_logprobs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 693\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mtop_p\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtop_p\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 694\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43muser\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43muser\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 695\u001b[0m \u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 696\u001b[0m \u001b[43m \u001b[49m\u001b[43mcompletion_create_params\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mCompletionCreateParams\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 697\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 698\u001b[0m \u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmake_request_options\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 699\u001b[0m \u001b[43m \u001b[49m\u001b[43mextra_headers\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mextra_headers\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mextra_query\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mextra_query\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mextra_body\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mextra_body\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtimeout\u001b[49m\n\u001b[1;32m 700\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 701\u001b[0m \u001b[43m \u001b[49m\u001b[43mcast_to\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mChatCompletion\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 702\u001b[0m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstream\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 703\u001b[0m \u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mStream\u001b[49m\u001b[43m[\u001b[49m\u001b[43mChatCompletionChunk\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 704\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n",
|
302 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/openai/_base_client.py:1260\u001b[0m, in \u001b[0;36mSyncAPIClient.post\u001b[0;34m(self, path, cast_to, body, options, files, stream, stream_cls)\u001b[0m\n\u001b[1;32m 1246\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mpost\u001b[39m(\n\u001b[1;32m 1247\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 1248\u001b[0m path: \u001b[38;5;28mstr\u001b[39m,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 1255\u001b[0m stream_cls: \u001b[38;5;28mtype\u001b[39m[_StreamT] \u001b[38;5;241m|\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 1256\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m ResponseT \u001b[38;5;241m|\u001b[39m _StreamT:\n\u001b[1;32m 1257\u001b[0m opts \u001b[38;5;241m=\u001b[39m FinalRequestOptions\u001b[38;5;241m.\u001b[39mconstruct(\n\u001b[1;32m 1258\u001b[0m method\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mpost\u001b[39m\u001b[38;5;124m\"\u001b[39m, url\u001b[38;5;241m=\u001b[39mpath, json_data\u001b[38;5;241m=\u001b[39mbody, files\u001b[38;5;241m=\u001b[39mto_httpx_files(files), \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39moptions\n\u001b[1;32m 1259\u001b[0m )\n\u001b[0;32m-> 1260\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m cast(ResponseT, \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcast_to\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mopts\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstream_cls\u001b[49m\u001b[43m)\u001b[49m)\n",
|
303 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/openai/_base_client.py:937\u001b[0m, in \u001b[0;36mSyncAPIClient.request\u001b[0;34m(self, cast_to, options, remaining_retries, stream, stream_cls)\u001b[0m\n\u001b[1;32m 928\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mrequest\u001b[39m(\n\u001b[1;32m 929\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 930\u001b[0m cast_to: Type[ResponseT],\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 935\u001b[0m stream_cls: \u001b[38;5;28mtype\u001b[39m[_StreamT] \u001b[38;5;241m|\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 936\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m ResponseT \u001b[38;5;241m|\u001b[39m _StreamT:\n\u001b[0;32m--> 937\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 938\u001b[0m \u001b[43m \u001b[49m\u001b[43mcast_to\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcast_to\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 939\u001b[0m \u001b[43m \u001b[49m\u001b[43moptions\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43moptions\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 940\u001b[0m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 941\u001b[0m \u001b[43m \u001b[49m\u001b[43mstream_cls\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstream_cls\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 942\u001b[0m \u001b[43m \u001b[49m\u001b[43mremaining_retries\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mremaining_retries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 943\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n",
|
304 |
+
"File \u001b[0;32m/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/openai/_base_client.py:1041\u001b[0m, in \u001b[0;36mSyncAPIClient._request\u001b[0;34m(self, cast_to, options, remaining_retries, stream, stream_cls)\u001b[0m\n\u001b[1;32m 1038\u001b[0m err\u001b[38;5;241m.\u001b[39mresponse\u001b[38;5;241m.\u001b[39mread()\n\u001b[1;32m 1040\u001b[0m log\u001b[38;5;241m.\u001b[39mdebug(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mRe-raising status error\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m-> 1041\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_make_status_error_from_response(err\u001b[38;5;241m.\u001b[39mresponse) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m 1043\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_process_response(\n\u001b[1;32m 1044\u001b[0m cast_to\u001b[38;5;241m=\u001b[39mcast_to,\n\u001b[1;32m 1045\u001b[0m options\u001b[38;5;241m=\u001b[39moptions,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 1049\u001b[0m retries_taken\u001b[38;5;241m=\u001b[39moptions\u001b[38;5;241m.\u001b[39mget_max_retries(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmax_retries) \u001b[38;5;241m-\u001b[39m retries,\n\u001b[1;32m 1050\u001b[0m )\n",
|
305 |
+
"\u001b[0;31mBadRequestError\u001b[0m: Error code: 400 - {'error': {'message': \"Invalid 'messages[3].name': string does not match pattern. Expected a string that matches the pattern '^[a-zA-Z0-9_-]+$'.\", 'type': 'invalid_request_error', 'param': 'messages[3].name', 'code': 'invalid_value'}}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
306 |
]
|
307 |
}
|
308 |
],
|
309 |
"source": [
|
310 |
+
"question = \"Feasibility analysis for a bookstore near New york\"\n",
|
311 |
"\n",
|
312 |
"graph = workflow.compile()\n",
|
313 |
"\n",
|
|
|
323 |
" {\"recursion_limit\": 20},\n",
|
324 |
")\n",
|
325 |
"for s in events:\n",
|
326 |
+
" print(s)\n",
|
327 |
+
" # a = list(s.items())[0]\n",
|
328 |
+
" # a[1]['messages'][0].pretty_print()"
|
329 |
]
|
330 |
},
|
331 |
{
|
332 |
"cell_type": "code",
|
333 |
+
"execution_count": null,
|
334 |
"metadata": {},
|
335 |
"outputs": [],
|
336 |
"source": [
|
chatbot_multiagent.py
CHANGED
@@ -5,6 +5,12 @@ import utils
|
|
5 |
utils.load_env()
|
6 |
os.environ['LANGCHAIN_TRACING_V2'] = "false"
|
7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
# %%
|
9 |
from langchain_core.messages import HumanMessage
|
10 |
import operator
|
@@ -12,6 +18,7 @@ import functools
|
|
12 |
|
13 |
# for llm model
|
14 |
from langchain_openai import ChatOpenAI
|
|
|
15 |
from langchain.agents.format_scratchpad import format_to_openai_function_messages
|
16 |
from tools import find_place_from_text, nearby_search
|
17 |
from typing import Dict, List, Tuple, Annotated, Sequence, TypedDict
|
@@ -19,7 +26,6 @@ from langchain.agents import (
|
|
19 |
AgentExecutor,
|
20 |
)
|
21 |
from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser
|
22 |
-
from langchain_community.chat_models import ChatOpenAI
|
23 |
from langchain_community.tools.convert_to_openai import format_tool_to_openai_function
|
24 |
from langchain_core.messages import (
|
25 |
AIMessage,
|
@@ -43,6 +49,8 @@ from langchain.tools import Tool
|
|
43 |
def format_docs(docs):
|
44 |
return "\n\n".join(doc.page_content for doc in docs)
|
45 |
|
|
|
|
|
46 |
# Specify the pattern
|
47 |
file_pattern = "document/*.csv"
|
48 |
file_paths = tuple(glob.glob(file_pattern))
|
@@ -64,8 +72,8 @@ vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings
|
|
64 |
# Retrieve and generate using the relevant snippets of the blog.
|
65 |
retriever = vectorstore.as_retriever()
|
66 |
|
67 |
-
## tools and LLM
|
68 |
|
|
|
69 |
retriever_tool = Tool(
|
70 |
name="population, community and household expenditures data",
|
71 |
func=retriever.get_relevant_documents,
|
@@ -73,7 +81,8 @@ retriever_tool = Tool(
|
|
73 |
)
|
74 |
|
75 |
# Bind the tools to the model
|
76 |
-
tools = [retriever_tool, find_place_from_text, nearby_search] # Include both tools if needed
|
|
|
77 |
|
78 |
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.0)
|
79 |
|
@@ -99,7 +108,7 @@ def create_agent(llm, tools, system_message: str):
|
|
99 |
prompt = prompt.partial(tool_names=", ".join([tool.name for tool in tools]))
|
100 |
llm_with_tools = llm.bind(functions=[format_tool_to_openai_function(t) for t in tools])
|
101 |
# return prompt | llm.bind_tools(tools)
|
102 |
-
agent = prompt |
|
103 |
return agent
|
104 |
|
105 |
|
@@ -201,8 +210,12 @@ workflow.add_conditional_edges(
|
|
201 |
# the tool calling node does not, meaning
|
202 |
# this edge will route back to the original agent
|
203 |
# who invoked the tool
|
204 |
-
lambda x: "
|
205 |
-
{
|
|
|
|
|
|
|
|
|
206 |
)
|
207 |
workflow.add_edge(START, "analyst")
|
208 |
graph = workflow.compile()
|
@@ -217,24 +230,7 @@ graph = workflow.compile()
|
|
217 |
# pass
|
218 |
|
219 |
# %%
|
220 |
-
# question = "วิเคราะห์ร้านอาหารแถวลุมพินี เซ็นเตอร์ ลาดพร้าว"
|
221 |
|
222 |
-
# graph = workflow.compile()
|
223 |
-
|
224 |
-
# events = graph.stream(
|
225 |
-
# {
|
226 |
-
# "messages": [
|
227 |
-
# HumanMessage(
|
228 |
-
# question
|
229 |
-
# )
|
230 |
-
# ],
|
231 |
-
# },
|
232 |
-
# # Maximum number of steps to take in the graph
|
233 |
-
# {"recursion_limit": 20},
|
234 |
-
# )
|
235 |
-
# for s in events:
|
236 |
-
# a = list(s.items())[0]
|
237 |
-
# a[1]['messages'][0].pretty_print()
|
238 |
|
239 |
# %%
|
240 |
def submitUserMessage(user_input: str) -> str:
|
@@ -244,17 +240,19 @@ def submitUserMessage(user_input: str) -> str:
|
|
244 |
{
|
245 |
"messages": [
|
246 |
HumanMessage(
|
247 |
-
|
248 |
)
|
249 |
],
|
250 |
},
|
251 |
# Maximum number of steps to take in the graph
|
252 |
-
{"recursion_limit":
|
253 |
)
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
response =
|
|
|
|
|
258 |
|
259 |
return response
|
260 |
|
|
|
5 |
utils.load_env()
|
6 |
os.environ['LANGCHAIN_TRACING_V2'] = "false"
|
7 |
|
8 |
+
# %%
|
9 |
+
from langchain.globals import set_debug, set_verbose
|
10 |
+
|
11 |
+
set_verbose(True)
|
12 |
+
set_debug(False)
|
13 |
+
|
14 |
# %%
|
15 |
from langchain_core.messages import HumanMessage
|
16 |
import operator
|
|
|
18 |
|
19 |
# for llm model
|
20 |
from langchain_openai import ChatOpenAI
|
21 |
+
# from langchain_community.chat_models import ChatOpenAI
|
22 |
from langchain.agents.format_scratchpad import format_to_openai_function_messages
|
23 |
from tools import find_place_from_text, nearby_search
|
24 |
from typing import Dict, List, Tuple, Annotated, Sequence, TypedDict
|
|
|
26 |
AgentExecutor,
|
27 |
)
|
28 |
from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser
|
|
|
29 |
from langchain_community.tools.convert_to_openai import format_tool_to_openai_function
|
30 |
from langchain_core.messages import (
|
31 |
AIMessage,
|
|
|
49 |
def format_docs(docs):
|
50 |
return "\n\n".join(doc.page_content for doc in docs)
|
51 |
|
52 |
+
|
53 |
+
## Document csv
|
54 |
# Specify the pattern
|
55 |
file_pattern = "document/*.csv"
|
56 |
file_paths = tuple(glob.glob(file_pattern))
|
|
|
72 |
# Retrieve and generate using the relevant snippets of the blog.
|
73 |
retriever = vectorstore.as_retriever()
|
74 |
|
|
|
75 |
|
76 |
+
## tools and LLM
|
77 |
retriever_tool = Tool(
|
78 |
name="population, community and household expenditures data",
|
79 |
func=retriever.get_relevant_documents,
|
|
|
81 |
)
|
82 |
|
83 |
# Bind the tools to the model
|
84 |
+
# tools = [retriever_tool, find_place_from_text, nearby_search] # Include both tools if needed
|
85 |
+
tools = [find_place_from_text, nearby_search]
|
86 |
|
87 |
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.0)
|
88 |
|
|
|
108 |
prompt = prompt.partial(tool_names=", ".join([tool.name for tool in tools]))
|
109 |
llm_with_tools = llm.bind(functions=[format_tool_to_openai_function(t) for t in tools])
|
110 |
# return prompt | llm.bind_tools(tools)
|
111 |
+
agent = prompt | llm_with_tools
|
112 |
return agent
|
113 |
|
114 |
|
|
|
210 |
# the tool calling node does not, meaning
|
211 |
# this edge will route back to the original agent
|
212 |
# who invoked the tool
|
213 |
+
lambda x: x["sender"],
|
214 |
+
{
|
215 |
+
"data collector":"data collector",
|
216 |
+
"analyst":"analyst",
|
217 |
+
"reporter":"reporter",
|
218 |
+
},
|
219 |
)
|
220 |
workflow.add_edge(START, "analyst")
|
221 |
graph = workflow.compile()
|
|
|
230 |
# pass
|
231 |
|
232 |
# %%
|
|
|
233 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
234 |
|
235 |
# %%
|
236 |
def submitUserMessage(user_input: str) -> str:
|
|
|
240 |
{
|
241 |
"messages": [
|
242 |
HumanMessage(
|
243 |
+
question
|
244 |
)
|
245 |
],
|
246 |
},
|
247 |
# Maximum number of steps to take in the graph
|
248 |
+
{"recursion_limit": 20},
|
249 |
)
|
250 |
+
|
251 |
+
events = [e for e in events]
|
252 |
+
|
253 |
+
response = list(events[-1].values())[0]["messages"][0]
|
254 |
+
response = response.content
|
255 |
+
response = response.replace("FINAL ANSWER: ", "")
|
256 |
|
257 |
return response
|
258 |
|
prompt.py
CHANGED
@@ -3,6 +3,7 @@ agent_meta = [
|
|
3 |
"name": "analyst",
|
4 |
"prompt": """
|
5 |
You are the Analyst responsible for extracting key information from the user and guiding the data collection process. When the user asks about analyzing a location for a business opportunity, you will:
|
|
|
6 |
- Extract the location the user wants to analyze and the keyword representing the type of place (e.g., “shop,” “coffee shop,” which represents the competitor).
|
7 |
- Communicate this information clearly to the Data Collector, instructing them to gather relevant data based on the user’s input.
|
8 |
"""
|
@@ -22,7 +23,7 @@ agent_meta = [
|
|
22 |
- Population data.
|
23 |
- The tools at your disposal include:
|
24 |
1. Population, Community, and Household Expenditures Data: Contains community type by district, household expenditures by province, and population data by district.
|
25 |
-
2. find_place_from_text: Provides address (district, province),
|
26 |
3. nearby_search: Provides a list of competitors nearby according to the keyword, including address, location, name, opening hours, rating, and plus code.
|
27 |
- After collecting the data, send it to the Reporter. Ensure that all communications and data are handled in English.
|
28 |
"""
|
@@ -31,12 +32,11 @@ agent_meta = [
|
|
31 |
"name": "reporter",
|
32 |
"prompt": """
|
33 |
You are the Reporter responsible for feasibility analysis . You role is to compiling the data into a clear and informative report for the user. When you receive the data from the Data Collector, you will:
|
34 |
-
|
35 |
- Organize and analyze the data to generate insights about the competitive landscape and market opportunities at the specified location.
|
36 |
- Ensure that your report includes both numerical data (such as the number of competitors, population figures, and household expenditures) and analytical insights (such as market opportunities and recommendations).
|
37 |
- If the Data Collector is unable to find certain data(or not povide data anymore), you will still provide a final answer based on the available information.
|
38 |
- Create a well-structured report that provides the user with actionable recommendations based on the analysis.
|
39 |
-
- Ensure the report is clear, concise, and delivered in Thai language if it is the final answer.
|
40 |
- Don't forget to give Descriptive anlytical summary at last.
|
41 |
"""
|
42 |
}
|
|
|
3 |
"name": "analyst",
|
4 |
"prompt": """
|
5 |
You are the Analyst responsible for extracting key information from the user and guiding the data collection process. When the user asks about analyzing a location for a business opportunity, you will:
|
6 |
+
Ensure that all communications and data are handled in English
|
7 |
- Extract the location the user wants to analyze and the keyword representing the type of place (e.g., “shop,” “coffee shop,” which represents the competitor).
|
8 |
- Communicate this information clearly to the Data Collector, instructing them to gather relevant data based on the user’s input.
|
9 |
"""
|
|
|
23 |
- Population data.
|
24 |
- The tools at your disposal include:
|
25 |
1. Population, Community, and Household Expenditures Data: Contains community type by district, household expenditures by province, and population data by district.
|
26 |
+
2. find_place_from_text: Provides address (district, province), and name of the place.
|
27 |
3. nearby_search: Provides a list of competitors nearby according to the keyword, including address, location, name, opening hours, rating, and plus code.
|
28 |
- After collecting the data, send it to the Reporter. Ensure that all communications and data are handled in English.
|
29 |
"""
|
|
|
32 |
"name": "reporter",
|
33 |
"prompt": """
|
34 |
You are the Reporter responsible for feasibility analysis . You role is to compiling the data into a clear and informative report for the user. When you receive the data from the Data Collector, you will:
|
35 |
+
Ensure that all communications and data are handled in English
|
36 |
- Organize and analyze the data to generate insights about the competitive landscape and market opportunities at the specified location.
|
37 |
- Ensure that your report includes both numerical data (such as the number of competitors, population figures, and household expenditures) and analytical insights (such as market opportunities and recommendations).
|
38 |
- If the Data Collector is unable to find certain data(or not povide data anymore), you will still provide a final answer based on the available information.
|
39 |
- Create a well-structured report that provides the user with actionable recommendations based on the analysis.
|
|
|
40 |
- Don't forget to give Descriptive anlytical summary at last.
|
41 |
"""
|
42 |
}
|
tools.py
CHANGED
@@ -17,7 +17,7 @@ def find_place_from_text(location:str):
|
|
17 |
return f"""
|
18 |
address: {r['formatted_address']}\n
|
19 |
location: {r['geometry']['location']}\n
|
20 |
-
|
21 |
"""
|
22 |
|
23 |
# def nearby_search(keyword:str, location:str, radius=2000, place_type=None):
|
@@ -64,7 +64,7 @@ def nearby_search(input_dict: NearbySearchInput):
|
|
64 |
strout += f"""
|
65 |
address: {address}\n
|
66 |
location: {location_info}\n
|
67 |
-
|
68 |
opening hours: {opening_hours}\n
|
69 |
rating: {rating}\n
|
70 |
plus code: {plus_code}\n\n
|
|
|
17 |
return f"""
|
18 |
address: {r['formatted_address']}\n
|
19 |
location: {r['geometry']['location']}\n
|
20 |
+
location_name: {r['name']}\n
|
21 |
"""
|
22 |
|
23 |
# def nearby_search(keyword:str, location:str, radius=2000, place_type=None):
|
|
|
64 |
strout += f"""
|
65 |
address: {address}\n
|
66 |
location: {location_info}\n
|
67 |
+
lacation_name: {name}\n
|
68 |
opening hours: {opening_hours}\n
|
69 |
rating: {rating}\n
|
70 |
plus code: {plus_code}\n\n
|