This commit is contained in:
isaac hershenson
2024-06-18 14:45:06 -07:00
parent 004be5a644
commit ec8fca977e
17 changed files with 202 additions and 125 deletions
@@ -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\"]"
]
},
{
+11 -5
View File
@@ -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",
+16 -4
View File
@@ -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)"
]
},
+22 -16
View File
@@ -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\")"
+7 -3
View File
@@ -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"
]