mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-30 11:49:38 +02:00
@@ -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,9 +138,7 @@
|
||||
"source": [
|
||||
"# Let's kick off a run\n",
|
||||
"input = {\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in sf\"}]}\n",
|
||||
"run = await client.runs.create(\n",
|
||||
" thread[\"thread_id\"], assistant[\"assistant_id\"], input=input\n",
|
||||
")"
|
||||
"run = await client.runs.create(thread['thread_id'], assistant[\"assistant_id\"], input=input)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -168,7 +166,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'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -451,7 +449,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'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -479,7 +477,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'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -490,7 +488,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'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -591,7 +589,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,12 +93,10 @@
|
||||
],
|
||||
"source": [
|
||||
"# We can now call `.get_schemas` to get schemas associated with this graph\n",
|
||||
"schemas = await client.assistants.get_schemas(\n",
|
||||
" assistant_id=base_assistant[\"assistant_id\"]\n",
|
||||
")\n",
|
||||
"schemas = await client.assistants.get_schemas(assistant_id=base_assistant[\"assistant_id\"])\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']"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -108,9 +106,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assistant = await client.assistants.create(\n",
|
||||
" graph_id=\"agent\", config={\"configurable\": {\"model_name\": \"openai\"}}\n",
|
||||
")"
|
||||
"assistant = await client.assistants.create(graph_id=\"agent\", config={\"configurable\": {\"model_name\": \"openai\"}})"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -167,9 +163,7 @@
|
||||
"source": [
|
||||
"thread = await client.threads.create()\n",
|
||||
"input = {\"messages\": [{\"role\": \"user\", \"content\": \"who made you?\"}]}\n",
|
||||
"async for event in client.runs.stream(\n",
|
||||
" thread[\"thread_id\"], assistant[\"assistant_id\"], input=input\n",
|
||||
"):\n",
|
||||
"async for event in client.runs.stream(thread['thread_id'], assistant['assistant_id'], input=input):\n",
|
||||
" print(event)"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import httpx\n",
|
||||
"from langgraph_sdk import get_client\n",
|
||||
"from langchain_core.messages import convert_to_messages\n",
|
||||
"from langgraph_sdk import get_client"
|
||||
"import httpx"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -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,8 +222,7 @@
|
||||
"source": [
|
||||
"# the first run will be interrupted\n",
|
||||
"interrupted_run = await client.runs.create(\n",
|
||||
" thread[\"thread_id\"],\n",
|
||||
" assistant[\"assistant_id\"],\n",
|
||||
" thread[\"thread_id\"], assistant[\"assistant_id\"],\n",
|
||||
" input={\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in sf?\"}]},\n",
|
||||
")\n",
|
||||
"await asyncio.sleep(2)\n",
|
||||
@@ -378,8 +377,7 @@
|
||||
"source": [
|
||||
"# the first run will be interrupted\n",
|
||||
"rolled_back_run = await client.runs.create(\n",
|
||||
" thread[\"thread_id\"],\n",
|
||||
" assistant[\"assistant_id\"],\n",
|
||||
" thread[\"thread_id\"], assistant[\"assistant_id\"],\n",
|
||||
" input={\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in sf?\"}]},\n",
|
||||
")\n",
|
||||
"await asyncio.sleep(2)\n",
|
||||
@@ -481,7 +479,7 @@
|
||||
"source": [
|
||||
"try:\n",
|
||||
" await client.runs.get(thread[\"thread_id\"], rolled_back_run[\"run_id\"])\n",
|
||||
"except httpx.HTTPStatusError as _:\n",
|
||||
"except httpx.HTTPStatusError as e:\n",
|
||||
" print(\"Original run was correctly deleted\")"
|
||||
]
|
||||
},
|
||||
@@ -514,7 +512,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,11 +188,7 @@
|
||||
"source": [
|
||||
"input = {\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in sf\"}]}\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",
|
||||
" thread['thread_id'], assistant['assistant_id'], input=input, stream_mode=\"updates\", interrupt_before=['action']\n",
|
||||
"):\n",
|
||||
" print(f\"Receiving new event of type: {chunk.event}...\")\n",
|
||||
" print(chunk.data)\n",
|
||||
@@ -243,11 +239,7 @@
|
||||
"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",
|
||||
" thread['thread_id'], assistant['assistant_id'], input=input, stream_mode=\"updates\", interrupt_before=['action']\n",
|
||||
"):\n",
|
||||
" print(f\"Receiving new event of type: {chunk.event}...\")\n",
|
||||
" print(chunk.data)\n",
|
||||
@@ -297,11 +289,7 @@
|
||||
"source": [
|
||||
"input = {\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in la?\"}]}\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",
|
||||
" thread['thread_id'], assistant['assistant_id'], input=input, stream_mode=\"updates\", interrupt_before=['action']\n",
|
||||
"):\n",
|
||||
" print(f\"Receiving new event of type: {chunk.event}...\")\n",
|
||||
" print(chunk.data)\n",
|
||||
@@ -323,7 +311,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"thread_state = await client.threads.get_state(thread[\"thread_id\"])"
|
||||
"thread_state = await client.threads.get_state(thread['thread_id'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -341,7 +329,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"last_message = thread_state[\"values\"][\"messages\"][-1]"
|
||||
"last_message = thread_state['values']['messages'][-1]"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -365,7 +353,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"last_message[\"content\"]"
|
||||
"last_message['content']"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -383,14 +371,12 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"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['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['content'] = [{\n",
|
||||
"# 'id': last_message['content'][0]['id'],\n",
|
||||
"# 'name': 'tavily_search_results_json',\n",
|
||||
@@ -427,9 +413,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"await client.threads.update_state(\n",
|
||||
" thread[\"thread_id\"], values={\"messages\": [last_message]}\n",
|
||||
")"
|
||||
"await client.threads.update_state(thread['thread_id'], values={\"messages\": [last_message]})"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -460,8 +444,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']"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -508,11 +492,7 @@
|
||||
"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",
|
||||
" thread['thread_id'], assistant['assistant_id'], input=input, stream_mode=\"updates\", interrupt_before=['action']\n",
|
||||
"):\n",
|
||||
" print(f\"Receiving new event of type: {chunk.event}...\")\n",
|
||||
" print(chunk.data)\n",
|
||||
@@ -537,7 +517,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)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -591,7 +571,7 @@
|
||||
],
|
||||
"source": [
|
||||
"rewind_state = thread_history[3]\n",
|
||||
"rewind_state[\"values\"][\"messages\"][-1][\"tool_calls\"]"
|
||||
"rewind_state['values']['messages'][-1]['tool_calls']"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -613,7 +593,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"rewind_state[\"config\"]"
|
||||
"rewind_state['config']"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -660,12 +640,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,13 +23,11 @@
|
||||
"\n",
|
||||
"client = get_client()\n",
|
||||
"\n",
|
||||
"openai_assistant = await client.assistants.create(\n",
|
||||
" graph_id=\"agent\", config={\"configurable\": {\"model_name\": \"openai\"}}\n",
|
||||
")\n",
|
||||
"openai_assistant = await client.assistants.create(graph_id=\"agent\", config={\"configurable\": {\"model_name\": \"openai\"}})\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]"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -119,12 +117,7 @@
|
||||
"source": [
|
||||
"thread = await client.threads.create()\n",
|
||||
"input = {\"messages\": [{\"role\": \"user\", \"content\": \"who made you?\"}]}\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",
|
||||
"async for event in client.runs.stream(thread['thread_id'], openai_assistant['assistant_id'], input=input, stream_mode='updates'):\n",
|
||||
" print(event)"
|
||||
]
|
||||
},
|
||||
@@ -154,12 +147,7 @@
|
||||
],
|
||||
"source": [
|
||||
"input = {\"messages\": [{\"role\": \"user\", \"content\": \"and you?\"}]}\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",
|
||||
"async for event in client.runs.stream(thread['thread_id'], default_assistant['assistant_id'], input=input, stream_mode='updates'):\n",
|
||||
" print(event)"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -63,9 +63,7 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assistant = await client.assistants.create(\n",
|
||||
" graph_id=\"agent\", config={\"configurable\": {\"model_name\": \"openai\"}}\n",
|
||||
")"
|
||||
"assistant = await client.assistants.create(graph_id=\"agent\", config={\"configurable\": {\"model_name\": \"openai\"}})"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -137,7 +135,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"runs = await client.runs.list(thread[\"thread_id\"])\n",
|
||||
"runs = await client.runs.list(thread['thread_id'])\n",
|
||||
"runs"
|
||||
]
|
||||
},
|
||||
@@ -150,14 +148,11 @@
|
||||
"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(\n",
|
||||
" f\"Tool Call ID: {call['id']}, Function: {call['name']}, Arguments: {call['args']}\"\n",
|
||||
" )\n",
|
||||
" formatted_calls.append(f\"Tool Call ID: {call['id']}, Function: {call['name']}, Arguments: {call['args']}\")\n",
|
||||
" return \"\\n\".join(formatted_calls)\n",
|
||||
" return \"No tool calls\""
|
||||
]
|
||||
@@ -1351,36 +1346,35 @@
|
||||
"source": [
|
||||
"input = {\"messages\": [{\"role\": \"user\", \"content\": \"whats the weather in sf\"}]}\n",
|
||||
"\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",
|
||||
"async for event in client.runs.stream(thread['thread_id'], assistant['assistant_id'], input=input, stream_mode='messages'):\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)"
|
||||
" print(\"-\" * 50)\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"
|
||||
]
|
||||
},
|
||||
@@ -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,12 +180,7 @@
|
||||
],
|
||||
"source": [
|
||||
"input = {\"messages\": [{\"role\": \"human\", \"content\": \"whats the weather in la\"}]}\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",
|
||||
"async for chunk in client.runs.stream(thread['thread_id'], assistant['assistant_id'], input=input, stream_mode=\"updates\", ):\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,9 +139,7 @@
|
||||
"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(\n",
|
||||
" thread[\"thread_id\"], assistant[\"assistant_id\"], input=input\n",
|
||||
"):\n",
|
||||
"async for chunk in client.runs.stream(thread['thread_id'], assistant['assistant_id'], input=input):\n",
|
||||
" print(f\"Receiving new event of type: {chunk.event}...\")\n",
|
||||
" print(chunk.data)\n",
|
||||
" print(\"\\n\\n\")"
|
||||
@@ -165,9 +163,7 @@
|
||||
"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(\n",
|
||||
" thread[\"thread_id\"], assistant[\"assistant_id\"], input=input\n",
|
||||
"):\n",
|
||||
"async for chunk in client.runs.stream(thread['thread_id'], assistant['assistant_id'], input=input):\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\"][\"query\"] = (\n",
|
||||
" \"weather in San Francisco, Accuweather\"\n",
|
||||
")"
|
||||
"current_values.values[\"messages\"][-1].tool_calls[0][\"args\"][\n",
|
||||
" \"query\"\n",
|
||||
"] = \"weather in San Francisco, Accuweather\""
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -729,9 +729,9 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"current_values.values[\"messages\"][-1].tool_calls[0][\"args\"][\"query\"] = (\n",
|
||||
" \"weather in San Francisco today\"\n",
|
||||
")"
|
||||
"current_values.values[\"messages\"][-1].tool_calls[0][\"args\"][\n",
|
||||
" \"query\"\n",
|
||||
"] = \"weather in San Francisco today\""
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -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,7 +214,6 @@
|
||||
" [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",
|
||||
@@ -342,7 +341,6 @@
|
||||
" 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;\"))"
|
||||
]
|
||||
},
|
||||
@@ -395,12 +393,8 @@
|
||||
"\n",
|
||||
"You will call the appropriate tool to execute the query after running this check.\"\"\"\n",
|
||||
"\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",
|
||||
"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",
|
||||
"\n",
|
||||
"query_check.invoke({\"messages\": [(\"user\", \"SELET * FROM Artist LIMIT 10;\")]})"
|
||||
]
|
||||
@@ -446,11 +440,9 @@
|
||||
"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",
|
||||
@@ -460,7 +452,8 @@
|
||||
" tool_calls=[\n",
|
||||
" {\n",
|
||||
" \"name\": \"sql_db_list_tables\",\n",
|
||||
" \"args\": {},\n",
|
||||
" \"args\": {\n",
|
||||
" },\n",
|
||||
" \"id\": \"tool_abcd123\",\n",
|
||||
" }\n",
|
||||
" ],\n",
|
||||
@@ -468,41 +461,31 @@
|
||||
" ]\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 {\"messages\": [query_check.invoke({\"messages\": [state[\"messages\"][-1]]})]}\n",
|
||||
"\n",
|
||||
" return {\n",
|
||||
" \"messages\": [\n",
|
||||
" query_check.invoke({\"messages\": [state[\"messages\"][-1]]})\n",
|
||||
" ]\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(\n",
|
||||
" \"list_tables_tool\", create_tool_node_with_fallback([list_tables_tool])\n",
|
||||
")\n",
|
||||
"workflow.add_node(\"list_tables_tool\", create_tool_node_with_fallback([list_tables_tool]))\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(\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",
|
||||
"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",
|
||||
"\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",
|
||||
@@ -526,17 +509,11 @@
|
||||
"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(\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",
|
||||
"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",
|
||||
"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",
|
||||
@@ -552,7 +529,6 @@
|
||||
" 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",
|
||||
@@ -561,7 +537,6 @@
|
||||
"# 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",
|
||||
@@ -574,7 +549,6 @@
|
||||
" 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",
|
||||
@@ -675,9 +649,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for event in app.stream(\n",
|
||||
" {\"messages\": [(\"user\", \"Which sales agent made the most in sales in 2009?\")]}\n",
|
||||
"):\n",
|
||||
"for event in app.stream({\"messages\": [(\"user\", \"Which sales agent made the most in sales in 2009?\")]}):\n",
|
||||
" print(event)"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -125,10 +125,12 @@ 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,7 +63,8 @@ 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,5 +1,4 @@
|
||||
"""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,7 +126,8 @@ class Channel:
|
||||
*,
|
||||
key: Optional[str] = None,
|
||||
tags: Optional[list[str]] = None,
|
||||
) -> PregelNode: ...
|
||||
) -> PregelNode:
|
||||
...
|
||||
|
||||
@overload
|
||||
@classmethod
|
||||
@@ -136,7 +137,8 @@ class Channel:
|
||||
*,
|
||||
key: None = None,
|
||||
tags: Optional[list[str]] = None,
|
||||
) -> PregelNode: ...
|
||||
) -> PregelNode:
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def subscribe_to(
|
||||
@@ -1607,7 +1609,8 @@ def _prepare_next_tasks(
|
||||
step: int,
|
||||
for_execution: Literal[False],
|
||||
manager: Literal[None] = None,
|
||||
) -> tuple[Checkpoint, list[PregelTaskDescription]]: ...
|
||||
) -> tuple[Checkpoint, list[PregelTaskDescription]]:
|
||||
...
|
||||
|
||||
|
||||
@overload
|
||||
@@ -1620,7 +1623,8 @@ 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,6 +10,8 @@ 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