mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-17 21:25:46 +02:00
fmt
This commit is contained in:
@@ -125,7 +125,7 @@
|
||||
],
|
||||
"source": [
|
||||
"# If we list runs on this thread, we can see it is empty\n",
|
||||
"runs = await client.runs.list(thread['thread_id'])\n",
|
||||
"runs = await client.runs.list(thread[\"thread_id\"])\n",
|
||||
"runs"
|
||||
]
|
||||
},
|
||||
@@ -138,7 +138,9 @@
|
||||
"source": [
|
||||
"# Let's kick off a run\n",
|
||||
"input = {\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in sf\"}]}\n",
|
||||
"run = await client.runs.create(thread['thread_id'], assistant[\"assistant_id\"], input=input)\n"
|
||||
"run = await client.runs.create(\n",
|
||||
" thread[\"thread_id\"], assistant[\"assistant_id\"], input=input\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -166,7 +168,7 @@
|
||||
],
|
||||
"source": [
|
||||
"# The first time we poll it, we can see `status=pending`\n",
|
||||
"await client.runs.get(thread['thread_id'], run['run_id'])"
|
||||
"await client.runs.get(thread[\"thread_id\"], run[\"run_id\"])"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -449,7 +451,7 @@
|
||||
],
|
||||
"source": [
|
||||
"# We can list events for the run\n",
|
||||
"await client.runs.list_events(thread['thread_id'], run['run_id'])"
|
||||
"await client.runs.list_events(thread[\"thread_id\"], run[\"run_id\"])"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -477,7 +479,7 @@
|
||||
],
|
||||
"source": [
|
||||
"# Eventually, it should finish and we should see `status=success`\n",
|
||||
"await client.runs.get(thread['thread_id'], run['run_id'])"
|
||||
"await client.runs.get(thread[\"thread_id\"], run[\"run_id\"])"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -488,7 +490,7 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# We can get the final results\n",
|
||||
"results = await client.runs.list_events(thread['thread_id'], run['run_id'])"
|
||||
"results = await client.runs.list_events(thread[\"thread_id\"], run[\"run_id\"])"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -589,7 +591,7 @@
|
||||
],
|
||||
"source": [
|
||||
"# We can get the content of the final message\n",
|
||||
"final_result['data']['output']['messages'][-1]['content']"
|
||||
"final_result[\"data\"][\"output\"][\"messages\"][-1][\"content\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"# We can do this by getting the default assistant\n",
|
||||
"# There should always be a default assistant with no configuration\n",
|
||||
"assistants = await client.assistants.search()\n",
|
||||
"assistants = [a for a in assistants if not a['config']]\n",
|
||||
"assistants = [a for a in assistants if not a[\"config\"]]\n",
|
||||
"base_assistant = assistants[0]"
|
||||
]
|
||||
},
|
||||
@@ -93,10 +93,12 @@
|
||||
],
|
||||
"source": [
|
||||
"# We can now call `.get_schemas` to get schemas associated with this graph\n",
|
||||
"schemas = await client.assistants.get_schemas(assistant_id=base_assistant[\"assistant_id\"])\n",
|
||||
"schemas = await client.assistants.get_schemas(\n",
|
||||
" assistant_id=base_assistant[\"assistant_id\"]\n",
|
||||
")\n",
|
||||
"# There are multiple types of schemas\n",
|
||||
"# We can get the `config_schema` to look at the the configurable parameters\n",
|
||||
"schemas['config_schema']['definitions']['Configurable']['properties']"
|
||||
"schemas[\"config_schema\"][\"definitions\"][\"Configurable\"][\"properties\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -106,7 +108,9 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assistant = await client.assistants.create(graph_id=\"agent\", config={\"configurable\": {\"model_name\": \"openai\"}})"
|
||||
"assistant = await client.assistants.create(\n",
|
||||
" graph_id=\"agent\", config={\"configurable\": {\"model_name\": \"openai\"}}\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -163,7 +167,9 @@
|
||||
"source": [
|
||||
"thread = await client.threads.create()\n",
|
||||
"input = {\"messages\": [{\"role\": \"user\", \"content\": \"who made you?\"}]}\n",
|
||||
"async for event in client.runs.stream(thread['thread_id'], assistant['assistant_id'], input=input):\n",
|
||||
"async for event in client.runs.stream(\n",
|
||||
" thread[\"thread_id\"], assistant[\"assistant_id\"], input=input\n",
|
||||
"):\n",
|
||||
" print(event)"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langgraph_sdk import get_client\n",
|
||||
"import httpx\n",
|
||||
"from langchain_core.messages import convert_to_messages\n",
|
||||
"import httpx"
|
||||
"from langgraph_sdk import get_client"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -77,7 +77,7 @@
|
||||
"run = await client.runs.create(\n",
|
||||
" thread[\"thread_id\"],\n",
|
||||
" assistant[\"assistant_id\"],\n",
|
||||
" input={\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in sf?\"}]}\n",
|
||||
" input={\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in sf?\"}]},\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
@@ -222,7 +222,8 @@
|
||||
"source": [
|
||||
"# the first run will be interrupted\n",
|
||||
"interrupted_run = await client.runs.create(\n",
|
||||
" thread[\"thread_id\"], assistant[\"assistant_id\"],\n",
|
||||
" thread[\"thread_id\"],\n",
|
||||
" assistant[\"assistant_id\"],\n",
|
||||
" input={\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in sf?\"}]},\n",
|
||||
")\n",
|
||||
"await asyncio.sleep(2)\n",
|
||||
@@ -377,7 +378,8 @@
|
||||
"source": [
|
||||
"# the first run will be interrupted\n",
|
||||
"rolled_back_run = await client.runs.create(\n",
|
||||
" thread[\"thread_id\"], assistant[\"assistant_id\"],\n",
|
||||
" thread[\"thread_id\"],\n",
|
||||
" assistant[\"assistant_id\"],\n",
|
||||
" input={\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in sf?\"}]},\n",
|
||||
")\n",
|
||||
"await asyncio.sleep(2)\n",
|
||||
@@ -479,7 +481,7 @@
|
||||
"source": [
|
||||
"try:\n",
|
||||
" await client.runs.get(thread[\"thread_id\"], rolled_back_run[\"run_id\"])\n",
|
||||
"except httpx.HTTPStatusError as e:\n",
|
||||
"except httpx.HTTPStatusError as _:\n",
|
||||
" print(\"Original run was correctly deleted\")"
|
||||
]
|
||||
},
|
||||
@@ -512,7 +514,7 @@
|
||||
"first_run = await client.runs.create(\n",
|
||||
" thread[\"thread_id\"],\n",
|
||||
" assistant[\"assistant_id\"],\n",
|
||||
" input={\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in sf?\"}]}\n",
|
||||
" input={\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in sf?\"}]},\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
"source": [
|
||||
"# There should always be a default assistant with no configuration\n",
|
||||
"assistants = await client.assistants.search()\n",
|
||||
"assistants = [a for a in assistants if not a['config']]\n",
|
||||
"assistants = [a for a in assistants if not a[\"config\"]]\n",
|
||||
"assistants"
|
||||
]
|
||||
},
|
||||
@@ -142,7 +142,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"runs = await client.runs.list(thread['thread_id'])\n",
|
||||
"runs = await client.runs.list(thread[\"thread_id\"])\n",
|
||||
"runs"
|
||||
]
|
||||
},
|
||||
@@ -188,7 +188,11 @@
|
||||
"source": [
|
||||
"input = {\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in sf\"}]}\n",
|
||||
"async for chunk in client.runs.stream(\n",
|
||||
" thread['thread_id'], assistant['assistant_id'], input=input, stream_mode=\"updates\", interrupt_before=['action']\n",
|
||||
" thread[\"thread_id\"],\n",
|
||||
" assistant[\"assistant_id\"],\n",
|
||||
" input=input,\n",
|
||||
" stream_mode=\"updates\",\n",
|
||||
" interrupt_before=[\"action\"],\n",
|
||||
"):\n",
|
||||
" print(f\"Receiving new event of type: {chunk.event}...\")\n",
|
||||
" print(chunk.data)\n",
|
||||
@@ -239,7 +243,11 @@
|
||||
"source": [
|
||||
"input = None\n",
|
||||
"async for chunk in client.runs.stream(\n",
|
||||
" thread['thread_id'], assistant['assistant_id'], input=input, stream_mode=\"updates\", interrupt_before=['action']\n",
|
||||
" thread[\"thread_id\"],\n",
|
||||
" assistant[\"assistant_id\"],\n",
|
||||
" input=input,\n",
|
||||
" stream_mode=\"updates\",\n",
|
||||
" interrupt_before=[\"action\"],\n",
|
||||
"):\n",
|
||||
" print(f\"Receiving new event of type: {chunk.event}...\")\n",
|
||||
" print(chunk.data)\n",
|
||||
@@ -289,7 +297,11 @@
|
||||
"source": [
|
||||
"input = {\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in la?\"}]}\n",
|
||||
"async for chunk in client.runs.stream(\n",
|
||||
" thread['thread_id'], assistant['assistant_id'], input=input, stream_mode=\"updates\", interrupt_before=['action']\n",
|
||||
" thread[\"thread_id\"],\n",
|
||||
" assistant[\"assistant_id\"],\n",
|
||||
" input=input,\n",
|
||||
" stream_mode=\"updates\",\n",
|
||||
" interrupt_before=[\"action\"],\n",
|
||||
"):\n",
|
||||
" print(f\"Receiving new event of type: {chunk.event}...\")\n",
|
||||
" print(chunk.data)\n",
|
||||
@@ -311,7 +323,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"thread_state = await client.threads.get_state(thread['thread_id'])"
|
||||
"thread_state = await client.threads.get_state(thread[\"thread_id\"])"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -329,7 +341,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"last_message = thread_state['values']['messages'][-1]"
|
||||
"last_message = thread_state[\"values\"][\"messages\"][-1]"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -353,7 +365,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"last_message['content']"
|
||||
"last_message[\"content\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -371,12 +383,14 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"last_message['tool_calls'] = [{\n",
|
||||
" 'id': last_message['tool_calls'][0]['id'],\n",
|
||||
" 'name': 'tavily_search_results_json',\n",
|
||||
" # We change the query to say temperature\n",
|
||||
" 'args': {'query': 'weather in Louisiana'}\n",
|
||||
"}]\n",
|
||||
"last_message[\"tool_calls\"] = [\n",
|
||||
" {\n",
|
||||
" \"id\": last_message[\"tool_calls\"][0][\"id\"],\n",
|
||||
" \"name\": \"tavily_search_results_json\",\n",
|
||||
" # We change the query to say temperature\n",
|
||||
" \"args\": {\"query\": \"weather in Louisiana\"},\n",
|
||||
" }\n",
|
||||
"]\n",
|
||||
"# last_message['content'] = [{\n",
|
||||
"# 'id': last_message['content'][0]['id'],\n",
|
||||
"# 'name': 'tavily_search_results_json',\n",
|
||||
@@ -413,7 +427,9 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"await client.threads.update_state(thread['thread_id'], values={\"messages\": [last_message]})"
|
||||
"await client.threads.update_state(\n",
|
||||
" thread[\"thread_id\"], values={\"messages\": [last_message]}\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -444,8 +460,8 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"thread_state = await client.threads.get_state(thread['thread_id'])\n",
|
||||
"thread_state['values']['messages'][-1]['tool_calls']"
|
||||
"thread_state = await client.threads.get_state(thread[\"thread_id\"])\n",
|
||||
"thread_state[\"values\"][\"messages\"][-1][\"tool_calls\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -492,7 +508,11 @@
|
||||
"source": [
|
||||
"input = None\n",
|
||||
"async for chunk in client.runs.stream(\n",
|
||||
" thread['thread_id'], assistant['assistant_id'], input=input, stream_mode=\"updates\", interrupt_before=['action']\n",
|
||||
" thread[\"thread_id\"],\n",
|
||||
" assistant[\"assistant_id\"],\n",
|
||||
" input=input,\n",
|
||||
" stream_mode=\"updates\",\n",
|
||||
" interrupt_before=[\"action\"],\n",
|
||||
"):\n",
|
||||
" print(f\"Receiving new event of type: {chunk.event}...\")\n",
|
||||
" print(chunk.data)\n",
|
||||
@@ -517,7 +537,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"thread_history = await client.threads.get_history(thread['thread_id'], limit=100)"
|
||||
"thread_history = await client.threads.get_history(thread[\"thread_id\"], limit=100)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -571,7 +591,7 @@
|
||||
],
|
||||
"source": [
|
||||
"rewind_state = thread_history[3]\n",
|
||||
"rewind_state['values']['messages'][-1]['tool_calls']"
|
||||
"rewind_state[\"values\"][\"messages\"][-1][\"tool_calls\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -593,7 +613,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"rewind_state['config']"
|
||||
"rewind_state[\"config\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -640,12 +660,12 @@
|
||||
"source": [
|
||||
"input = None\n",
|
||||
"async for chunk in client.runs.stream(\n",
|
||||
" thread['thread_id'], \n",
|
||||
" assistant['assistant_id'], \n",
|
||||
" input=input, \n",
|
||||
" stream_mode=\"updates\", \n",
|
||||
" interrupt_before=['action'],\n",
|
||||
" config=rewind_state['config']\n",
|
||||
" thread[\"thread_id\"],\n",
|
||||
" assistant[\"assistant_id\"],\n",
|
||||
" input=input,\n",
|
||||
" stream_mode=\"updates\",\n",
|
||||
" interrupt_before=[\"action\"],\n",
|
||||
" config=rewind_state[\"config\"],\n",
|
||||
"):\n",
|
||||
" print(f\"Receiving new event of type: {chunk.event}...\")\n",
|
||||
" print(chunk.data)\n",
|
||||
|
||||
@@ -23,11 +23,13 @@
|
||||
"\n",
|
||||
"client = get_client()\n",
|
||||
"\n",
|
||||
"openai_assistant = await client.assistants.create(graph_id=\"agent\", config={\"configurable\": {\"model_name\": \"openai\"}})\n",
|
||||
"openai_assistant = await client.assistants.create(\n",
|
||||
" graph_id=\"agent\", config={\"configurable\": {\"model_name\": \"openai\"}}\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"# There should always be a default assistant with no configuration\n",
|
||||
"assistants = await client.assistants.search()\n",
|
||||
"default_assistant = [a for a in assistants if not a['config']][0]"
|
||||
"default_assistant = [a for a in assistants if not a[\"config\"]][0]"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -117,7 +119,12 @@
|
||||
"source": [
|
||||
"thread = await client.threads.create()\n",
|
||||
"input = {\"messages\": [{\"role\": \"user\", \"content\": \"who made you?\"}]}\n",
|
||||
"async for event in client.runs.stream(thread['thread_id'], openai_assistant['assistant_id'], input=input, stream_mode='updates'):\n",
|
||||
"async for event in client.runs.stream(\n",
|
||||
" thread[\"thread_id\"],\n",
|
||||
" openai_assistant[\"assistant_id\"],\n",
|
||||
" input=input,\n",
|
||||
" stream_mode=\"updates\",\n",
|
||||
"):\n",
|
||||
" print(event)"
|
||||
]
|
||||
},
|
||||
@@ -147,7 +154,12 @@
|
||||
],
|
||||
"source": [
|
||||
"input = {\"messages\": [{\"role\": \"user\", \"content\": \"and you?\"}]}\n",
|
||||
"async for event in client.runs.stream(thread['thread_id'], default_assistant['assistant_id'], input=input, stream_mode='updates'):\n",
|
||||
"async for event in client.runs.stream(\n",
|
||||
" thread[\"thread_id\"],\n",
|
||||
" default_assistant[\"assistant_id\"],\n",
|
||||
" input=input,\n",
|
||||
" stream_mode=\"updates\",\n",
|
||||
"):\n",
|
||||
" print(event)"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -63,7 +63,9 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assistant = await client.assistants.create(graph_id=\"agent\", config={\"configurable\": {\"model_name\": \"openai\"}})"
|
||||
"assistant = await client.assistants.create(\n",
|
||||
" graph_id=\"agent\", config={\"configurable\": {\"model_name\": \"openai\"}}\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -135,7 +137,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"runs = await client.runs.list(thread['thread_id'])\n",
|
||||
"runs = await client.runs.list(thread[\"thread_id\"])\n",
|
||||
"runs"
|
||||
]
|
||||
},
|
||||
@@ -148,11 +150,14 @@
|
||||
"source": [
|
||||
"# Helper function for formatting messages\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def format_tool_calls(tool_calls):\n",
|
||||
" if tool_calls:\n",
|
||||
" formatted_calls = []\n",
|
||||
" for call in tool_calls:\n",
|
||||
" formatted_calls.append(f\"Tool Call ID: {call['id']}, Function: {call['name']}, Arguments: {call['args']}\")\n",
|
||||
" formatted_calls.append(\n",
|
||||
" f\"Tool Call ID: {call['id']}, Function: {call['name']}, Arguments: {call['args']}\"\n",
|
||||
" )\n",
|
||||
" return \"\\n\".join(formatted_calls)\n",
|
||||
" return \"No tool calls\""
|
||||
]
|
||||
@@ -1346,35 +1351,36 @@
|
||||
"source": [
|
||||
"input = {\"messages\": [{\"role\": \"user\", \"content\": \"whats the weather in sf\"}]}\n",
|
||||
"\n",
|
||||
"async for event in client.runs.stream(thread['thread_id'], assistant['assistant_id'], input=input, stream_mode='messages'):\n",
|
||||
" if event.event == 'metadata':\n",
|
||||
"async for event in client.runs.stream(\n",
|
||||
" thread[\"thread_id\"], assistant[\"assistant_id\"], input=input, stream_mode=\"messages\"\n",
|
||||
"):\n",
|
||||
" if event.event == \"metadata\":\n",
|
||||
" print(f\"Metadata: Run ID - {event.data['run_id']}\")\n",
|
||||
" elif event.event == 'data':\n",
|
||||
" elif event.event == \"data\":\n",
|
||||
" for data_item in event.data:\n",
|
||||
" if 'role' in data_item and data_item['role'] == 'user':\n",
|
||||
" if \"role\" in data_item and data_item[\"role\"] == \"user\":\n",
|
||||
" print(f\"Human: {data_item['content']}\")\n",
|
||||
" else:\n",
|
||||
" tool_calls = data_item.get('tool_calls', [])\n",
|
||||
" invalid_tool_calls = data_item.get('invalid_tool_calls', [])\n",
|
||||
" content = data_item.get('content', \"\")\n",
|
||||
" response_metadata = data_item.get('response_metadata', {})\n",
|
||||
" tool_calls = data_item.get(\"tool_calls\", [])\n",
|
||||
" invalid_tool_calls = data_item.get(\"invalid_tool_calls\", [])\n",
|
||||
" content = data_item.get(\"content\", \"\")\n",
|
||||
" response_metadata = data_item.get(\"response_metadata\", {})\n",
|
||||
"\n",
|
||||
" if content:\n",
|
||||
" print(f\"AI: {content}\")\n",
|
||||
" \n",
|
||||
"\n",
|
||||
" if tool_calls:\n",
|
||||
" print(\"Tool Calls:\")\n",
|
||||
" print(format_tool_calls(tool_calls))\n",
|
||||
" \n",
|
||||
"\n",
|
||||
" if invalid_tool_calls:\n",
|
||||
" print(\"Invalid Tool Calls:\")\n",
|
||||
" print(format_tool_calls(invalid_tool_calls))\n",
|
||||
"\n",
|
||||
" if response_metadata:\n",
|
||||
" finish_reason = response_metadata.get('finish_reason', 'N/A')\n",
|
||||
" finish_reason = response_metadata.get(\"finish_reason\", \"N/A\")\n",
|
||||
" print(f\"Response Metadata: Finish Reason - {finish_reason}\")\n",
|
||||
" print(\"-\" * 50)\n",
|
||||
" "
|
||||
" print(\"-\" * 50)"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
"source": [
|
||||
"# There should always be a default assistant with no configuration\n",
|
||||
"assistants = await client.assistants.search()\n",
|
||||
"assistants = [a for a in assistants if not a['config']]\n",
|
||||
"assistants = [a for a in assistants if not a[\"config\"]]\n",
|
||||
"assistants"
|
||||
]
|
||||
},
|
||||
@@ -136,7 +136,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"runs = await client.runs.list(thread['thread_id'])\n",
|
||||
"runs = await client.runs.list(thread[\"thread_id\"])\n",
|
||||
"runs"
|
||||
]
|
||||
},
|
||||
@@ -180,7 +180,12 @@
|
||||
],
|
||||
"source": [
|
||||
"input = {\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in la\"}]}\n",
|
||||
"async for chunk in client.runs.stream(thread['thread_id'], assistant['assistant_id'], input=input, stream_mode=\"updates\", ):\n",
|
||||
"async for chunk in client.runs.stream(\n",
|
||||
" thread[\"thread_id\"],\n",
|
||||
" assistant[\"assistant_id\"],\n",
|
||||
" input=input,\n",
|
||||
" stream_mode=\"updates\",\n",
|
||||
"):\n",
|
||||
" print(f\"Receiving new event of type: {chunk.event}...\")\n",
|
||||
" print(chunk.data)\n",
|
||||
" print(\"\\n\\n\")"
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
"source": [
|
||||
"# There should always be a default assistant with no configuration\n",
|
||||
"assistants = await client.assistants.search()\n",
|
||||
"assistants = [a for a in assistants if not a['config']]\n",
|
||||
"assistants = [a for a in assistants if not a[\"config\"]]\n",
|
||||
"assistants"
|
||||
]
|
||||
},
|
||||
@@ -139,7 +139,9 @@
|
||||
"source": [
|
||||
"input = {\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in la\"}]}\n",
|
||||
"thread = await client.threads.create()\n",
|
||||
"async for chunk in client.runs.stream(thread['thread_id'], assistant['assistant_id'], input=input):\n",
|
||||
"async for chunk in client.runs.stream(\n",
|
||||
" thread[\"thread_id\"], assistant[\"assistant_id\"], input=input\n",
|
||||
"):\n",
|
||||
" print(f\"Receiving new event of type: {chunk.event}...\")\n",
|
||||
" print(chunk.data)\n",
|
||||
" print(\"\\n\\n\")"
|
||||
@@ -163,7 +165,9 @@
|
||||
"input = {\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in la\"}]}\n",
|
||||
"thread = await client.threads.create()\n",
|
||||
"final_answer = None\n",
|
||||
"async for chunk in client.runs.stream(thread['thread_id'], assistant['assistant_id'], input=input):\n",
|
||||
"async for chunk in client.runs.stream(\n",
|
||||
" thread[\"thread_id\"], assistant[\"assistant_id\"], input=input\n",
|
||||
"):\n",
|
||||
" if chunk.event == \"values\":\n",
|
||||
" final_answer = chunk.data"
|
||||
]
|
||||
|
||||
@@ -475,9 +475,9 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"current_values.values[\"messages\"][-1].tool_calls[0][\"args\"][\n",
|
||||
" \"query\"\n",
|
||||
"] = \"weather in San Francisco, Accuweather\""
|
||||
"current_values.values[\"messages\"][-1].tool_calls[0][\"args\"][\"query\"] = (\n",
|
||||
" \"weather in San Francisco, Accuweather\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -729,9 +729,9 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"current_values.values[\"messages\"][-1].tool_calls[0][\"args\"][\n",
|
||||
" \"query\"\n",
|
||||
"] = \"weather in San Francisco today\""
|
||||
"current_values.values[\"messages\"][-1].tool_calls[0][\"args\"][\"query\"] = (\n",
|
||||
" \"weather in San Francisco today\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -43,11 +43,11 @@
|
||||
"execution_count": 1,
|
||||
"id": "6c05a600f1afb5b6",
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-06-12T21:24:00.532147Z",
|
||||
"start_time": "2024-06-12T21:24:00.526043Z"
|
||||
}
|
||||
},
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -78,11 +78,11 @@
|
||||
"execution_count": 2,
|
||||
"id": "64b0bf1b14c2e902",
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-06-12T21:24:09.918436Z",
|
||||
"start_time": "2024-06-12T21:24:09.608563Z"
|
||||
}
|
||||
},
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
@@ -125,11 +125,11 @@
|
||||
"execution_count": 3,
|
||||
"id": "a60191bd3489f278",
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-06-12T21:24:14.663745Z",
|
||||
"start_time": "2024-06-12T21:24:13.527958Z"
|
||||
}
|
||||
},
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -142,11 +142,11 @@
|
||||
"execution_count": 4,
|
||||
"id": "1f1e1f4f86ed54",
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-06-12T21:24:15.891582Z",
|
||||
"start_time": "2024-06-12T21:24:15.289782Z"
|
||||
}
|
||||
},
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
@@ -192,11 +192,11 @@
|
||||
"execution_count": 5,
|
||||
"id": "deae8460e4cf72b1",
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2024-06-12T21:24:17.557848Z",
|
||||
"start_time": "2024-06-12T21:24:17.508550Z"
|
||||
}
|
||||
},
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -214,6 +214,7 @@
|
||||
" [RunnableLambda(handle_tool_error)], exception_key=\"error\"\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def handle_tool_error(state) -> dict:\n",
|
||||
" error = state.get(\"error\")\n",
|
||||
" tool_calls = state[\"messages\"][-1].tool_calls\n",
|
||||
@@ -341,6 +342,7 @@
|
||||
" return \"Error: Query failed. Please rewrite your query and try again.\"\n",
|
||||
" return result\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"print(db_query_tool.invoke(\"SELECT * FROM Artist LIMIT 10;\"))"
|
||||
]
|
||||
},
|
||||
@@ -393,8 +395,12 @@
|
||||
"\n",
|
||||
"You will call the appropriate tool to execute the query after running this check.\"\"\"\n",
|
||||
"\n",
|
||||
"query_check_prompt = ChatPromptTemplate.from_messages([(\"system\", query_check_system),(\"placeholder\", \"{messages}\")])\n",
|
||||
"query_check = query_check_prompt | ChatOpenAI(model=\"gpt-4o\", temperature=0).bind_tools([db_query_tool], tool_choice=\"required\")\n",
|
||||
"query_check_prompt = ChatPromptTemplate.from_messages(\n",
|
||||
" [(\"system\", query_check_system), (\"placeholder\", \"{messages}\")]\n",
|
||||
")\n",
|
||||
"query_check = query_check_prompt | ChatOpenAI(model=\"gpt-4o\", temperature=0).bind_tools(\n",
|
||||
" [db_query_tool], tool_choice=\"required\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"query_check.invoke({\"messages\": [(\"user\", \"SELET * FROM Artist LIMIT 10;\")]})"
|
||||
]
|
||||
@@ -440,9 +446,11 @@
|
||||
"class State(TypedDict):\n",
|
||||
" messages: Annotated[list[AnyMessage], add_messages]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Define a new graph\n",
|
||||
"workflow = StateGraph(State)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Add a node for the first tool call\n",
|
||||
"def first_tool_call(state: State) -> dict[str, list[AIMessage]]:\n",
|
||||
" return {\n",
|
||||
@@ -452,8 +460,7 @@
|
||||
" tool_calls=[\n",
|
||||
" {\n",
|
||||
" \"name\": \"sql_db_list_tables\",\n",
|
||||
" \"args\": {\n",
|
||||
" },\n",
|
||||
" \"args\": {},\n",
|
||||
" \"id\": \"tool_abcd123\",\n",
|
||||
" }\n",
|
||||
" ],\n",
|
||||
@@ -461,31 +468,41 @@
|
||||
" ]\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def model_check_query(state: State) -> dict[str, list[AIMessage]]:\n",
|
||||
" \"\"\"\n",
|
||||
" Use this tool to double-check if your query is correct before executing it.\n",
|
||||
" \"\"\"\n",
|
||||
" return {\n",
|
||||
" \"messages\": [\n",
|
||||
" query_check.invoke({\"messages\": [state[\"messages\"][-1]]})\n",
|
||||
" ]\n",
|
||||
" }\n",
|
||||
" return {\"messages\": [query_check.invoke({\"messages\": [state[\"messages\"][-1]]})]}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"workflow.add_node(\"first_tool_call\", first_tool_call)\n",
|
||||
"\n",
|
||||
"# Add nodes for the first two tools\n",
|
||||
"workflow.add_node(\"list_tables_tool\", create_tool_node_with_fallback([list_tables_tool]))\n",
|
||||
"workflow.add_node(\n",
|
||||
" \"list_tables_tool\", create_tool_node_with_fallback([list_tables_tool])\n",
|
||||
")\n",
|
||||
"workflow.add_node(\"get_schema_tool\", create_tool_node_with_fallback([get_schema_tool]))\n",
|
||||
"\n",
|
||||
"# Add a node for a model to choose the relevant tables based on the question and available tables\n",
|
||||
"model_get_schema = ChatOpenAI(model=\"gpt-4o\", temperature=0).bind_tools([get_schema_tool])\n",
|
||||
"workflow.add_node(\"model_get_schema\", lambda state: {\"messages\": [model_get_schema.invoke(state[\"messages\"])],})\n",
|
||||
"model_get_schema = ChatOpenAI(model=\"gpt-4o\", temperature=0).bind_tools(\n",
|
||||
" [get_schema_tool]\n",
|
||||
")\n",
|
||||
"workflow.add_node(\n",
|
||||
" \"model_get_schema\",\n",
|
||||
" lambda state: {\n",
|
||||
" \"messages\": [model_get_schema.invoke(state[\"messages\"])],\n",
|
||||
" },\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Describe a tool to represent the end state\n",
|
||||
"class SubmitFinalAnswer(BaseModel):\n",
|
||||
" \"\"\"Submit the final answer to the user based on the query results.\"\"\"\n",
|
||||
"\n",
|
||||
" final_answer: str = Field(..., description=\"The final answer to the user\")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Add a node for a model to generate a query based on the question and schema\n",
|
||||
"query_gen_system = \"\"\"You are a SQL expert with a strong attention to detail.\n",
|
||||
"\n",
|
||||
@@ -509,11 +526,17 @@
|
||||
"If you have enough information to answer the input question, simply invoke the appropriate tool to submit the final answer to the user.\n",
|
||||
"\n",
|
||||
"DO NOT make any DML statements (INSERT, UPDATE, DELETE, DROP etc.) to the database.\"\"\"\n",
|
||||
"query_gen_prompt = ChatPromptTemplate.from_messages([(\"system\", query_gen_system),(\"placeholder\", \"{messages}\")])\n",
|
||||
"query_gen = query_gen_prompt | ChatOpenAI(model=\"gpt-4o\", temperature=0).bind_tools([SubmitFinalAnswer])\n",
|
||||
"query_gen_prompt = ChatPromptTemplate.from_messages(\n",
|
||||
" [(\"system\", query_gen_system), (\"placeholder\", \"{messages}\")]\n",
|
||||
")\n",
|
||||
"query_gen = query_gen_prompt | ChatOpenAI(model=\"gpt-4o\", temperature=0).bind_tools(\n",
|
||||
" [SubmitFinalAnswer]\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def query_gen_node(state: State):\n",
|
||||
" message = query_gen.invoke(state)\n",
|
||||
" \n",
|
||||
"\n",
|
||||
" # Sometimes, the LLM will hallucinate and call the wrong tool. We need to catch this and return an error message.\n",
|
||||
" tool_messages = []\n",
|
||||
" if message.tool_calls:\n",
|
||||
@@ -529,6 +552,7 @@
|
||||
" tool_messages = []\n",
|
||||
" return {\"messages\": [message] + tool_messages}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"workflow.add_node(\"query_gen\", query_gen_node)\n",
|
||||
"\n",
|
||||
"# Add a node for the model to check the query before executing it\n",
|
||||
@@ -537,6 +561,7 @@
|
||||
"# Add node for executing the query\n",
|
||||
"workflow.add_node(\"execute_query\", create_tool_node_with_fallback([db_query_tool]))\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Define a conditional edge to decide whether to continue or end the workflow\n",
|
||||
"def should_continue(state: State) -> Literal[END, \"correct_query\", \"query_gen\"]:\n",
|
||||
" messages = state[\"messages\"]\n",
|
||||
@@ -549,6 +574,7 @@
|
||||
" else:\n",
|
||||
" return \"correct_query\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Specify the edges between the nodes\n",
|
||||
"workflow.set_entry_point(\"first_tool_call\")\n",
|
||||
"workflow.add_edge(\"first_tool_call\", \"list_tables_tool\")\n",
|
||||
@@ -649,7 +675,9 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for event in app.stream({\"messages\": [(\"user\", \"Which sales agent made the most in sales in 2009?\")]}):\n",
|
||||
"for event in app.stream(\n",
|
||||
" {\"messages\": [(\"user\", \"Which sales agent made the most in sales in 2009?\")]}\n",
|
||||
"):\n",
|
||||
" print(event)"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -125,12 +125,10 @@ class Graph:
|
||||
return self.edges
|
||||
|
||||
@overload
|
||||
def add_node(self, node: RunnableLike) -> None:
|
||||
...
|
||||
def add_node(self, node: RunnableLike) -> None: ...
|
||||
|
||||
@overload
|
||||
def add_node(self, node: str, action: RunnableLike) -> None:
|
||||
...
|
||||
def add_node(self, node: str, action: RunnableLike) -> None: ...
|
||||
|
||||
def add_node(
|
||||
self, node: Union[str, RunnableLike], action: Optional[RunnableLike] = None
|
||||
|
||||
@@ -63,8 +63,7 @@ class ManagedValue(ABC, Generic[V]):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def __call__(self, step: int, task: PregelTaskDescription) -> V:
|
||||
...
|
||||
def __call__(self, step: int, task: PregelTaskDescription) -> V: ...
|
||||
|
||||
|
||||
class ConfiguredManagedValue(NamedTuple):
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""langgraph.prebuilt exposes a higher-level API for creating and executing agents and tools."""
|
||||
|
||||
from langgraph.prebuilt import chat_agent_executor
|
||||
from langgraph.prebuilt.agent_executor import create_agent_executor
|
||||
from langgraph.prebuilt.chat_agent_executor import create_react_agent
|
||||
|
||||
@@ -126,8 +126,7 @@ class Channel:
|
||||
*,
|
||||
key: Optional[str] = None,
|
||||
tags: Optional[list[str]] = None,
|
||||
) -> PregelNode:
|
||||
...
|
||||
) -> PregelNode: ...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
@@ -137,8 +136,7 @@ class Channel:
|
||||
*,
|
||||
key: None = None,
|
||||
tags: Optional[list[str]] = None,
|
||||
) -> PregelNode:
|
||||
...
|
||||
) -> PregelNode: ...
|
||||
|
||||
@classmethod
|
||||
def subscribe_to(
|
||||
@@ -1609,8 +1607,7 @@ def _prepare_next_tasks(
|
||||
step: int,
|
||||
for_execution: Literal[False],
|
||||
manager: Literal[None] = None,
|
||||
) -> tuple[Checkpoint, list[PregelTaskDescription]]:
|
||||
...
|
||||
) -> tuple[Checkpoint, list[PregelTaskDescription]]: ...
|
||||
|
||||
|
||||
@overload
|
||||
@@ -1623,8 +1620,7 @@ def _prepare_next_tasks(
|
||||
step: int,
|
||||
for_execution: Literal[True],
|
||||
manager: Union[ParentRunManager, AsyncParentRunManager],
|
||||
) -> tuple[Checkpoint, list[PregelExecutableTask]]:
|
||||
...
|
||||
) -> tuple[Checkpoint, list[PregelExecutableTask]]: ...
|
||||
|
||||
|
||||
def _prepare_next_tasks(
|
||||
|
||||
@@ -51,9 +51,9 @@ class RetryPolicy(NamedTuple):
|
||||
"""Maximum number of attempts to make before giving up, including the first."""
|
||||
jitter: bool = True
|
||||
"""Whether to add random jitter to the interval between retries."""
|
||||
retry_on: Union[
|
||||
tuple[Exception, ...], Callable[[Exception], bool]
|
||||
] = default_retry_on
|
||||
retry_on: Union[tuple[Exception, ...], Callable[[Exception], bool]] = (
|
||||
default_retry_on
|
||||
)
|
||||
"""List of exceptions that should trigger a retry, or a callable that returns True for exceptions that should trigger a retry."""
|
||||
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@ class SerializerProtocol(Protocol):
|
||||
Valid implementations include the `pickle`, `json` and `orjson` modules.
|
||||
"""
|
||||
|
||||
def dumps(self, obj: Any) -> bytes:
|
||||
...
|
||||
def dumps(self, obj: Any) -> bytes: ...
|
||||
|
||||
def loads(self, data: bytes) -> Any:
|
||||
...
|
||||
def loads(self, data: bytes) -> Any: ...
|
||||
|
||||
Reference in New Issue
Block a user