Spaces:
Runtime error
Runtime error
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
|