diff --git a/docs/docs/cloud/deployment/img/api_page.png b/docs/docs/cloud/deployment/img/api_page.png deleted file mode 100644 index 589f565d2..000000000 Binary files a/docs/docs/cloud/deployment/img/api_page.png and /dev/null differ diff --git a/docs/docs/cloud/deployment/img/cloud_deployment.png b/docs/docs/cloud/deployment/img/cloud_deployment.png new file mode 100644 index 000000000..677297238 Binary files /dev/null and b/docs/docs/cloud/deployment/img/cloud_deployment.png differ diff --git a/docs/docs/cloud/deployment/img/deploy_filled_out.png b/docs/docs/cloud/deployment/img/deploy_filled_out.png deleted file mode 100644 index 4c42ee134..000000000 Binary files a/docs/docs/cloud/deployment/img/deploy_filled_out.png and /dev/null differ diff --git a/docs/docs/cloud/deployment/img/deployed_page.png b/docs/docs/cloud/deployment/img/deployed_page.png index ccae96a1d..e33c6492f 100644 Binary files a/docs/docs/cloud/deployment/img/deployed_page.png and b/docs/docs/cloud/deployment/img/deployed_page.png differ diff --git a/docs/docs/cloud/deployment/img/deployment_page.png b/docs/docs/cloud/deployment/img/deployment_page.png index 606436ac8..165d3c34a 100644 Binary files a/docs/docs/cloud/deployment/img/deployment_page.png and b/docs/docs/cloud/deployment/img/deployment_page.png differ diff --git a/docs/docs/cloud/deployment/img/graph_run.png b/docs/docs/cloud/deployment/img/graph_run.png index 372ab22b1..03d3f9ac2 100644 Binary files a/docs/docs/cloud/deployment/img/graph_run.png and b/docs/docs/cloud/deployment/img/graph_run.png differ diff --git a/docs/docs/cloud/deployment/img/graph_visualization.png b/docs/docs/cloud/deployment/img/graph_visualization.png deleted file mode 100644 index 53d99b74d..000000000 Binary files a/docs/docs/cloud/deployment/img/graph_visualization.png and /dev/null differ diff --git a/docs/docs/cloud/deployment/img/quick_start_studio.png b/docs/docs/cloud/deployment/img/quick_start_studio.png new file mode 100644 index 000000000..54160b400 Binary files /dev/null and b/docs/docs/cloud/deployment/img/quick_start_studio.png differ diff --git a/docs/docs/cloud/deployment/test_locally.md b/docs/docs/cloud/deployment/test_locally.md index eec829bfa..3277f8314 100644 --- a/docs/docs/cloud/deployment/test_locally.md +++ b/docs/docs/cloud/deployment/test_locally.md @@ -8,11 +8,17 @@ Testing locally ensures that there are no errors or conflicts with Python depend Install the proper packages: -```shell -pip install langgraph-cli -``` -Ensure you have an API key, which you can create from the LangSmith UI (Settings > API Keys). This is required to authenticate that you have LangGraph Cloud access. After you have saved the key to a safe place, place the following line in your `.env` file: +=== "pip" + ```bash + pip install -U langgraph-cli + ``` +=== "Homebrew" (macOS only) + ```bash + brew install langgraph-cli + ``` + +Ensure you have an API key, which you can create from the [LangSmith UI](https://smith.langchain.com) (Settings > API Keys). This is required to authenticate that you have LangGraph Cloud access. After you have saved the key to a safe place, place the following line in your `.env` file: ```python LANGCHAIN_API_KEY = ********* @@ -20,7 +26,7 @@ LANGCHAIN_API_KEY = ********* ## Start the API server -Once you have downloaded the CLI, you can run the following command to start the API server for local testing: +Once you have installed the CLI, you can run the following command to start the API server for local testing: ```shell langgraph up diff --git a/docs/docs/cloud/how-tos/index.md b/docs/docs/cloud/how-tos/index.md index 0cf513075..b5ef870dd 100644 --- a/docs/docs/cloud/how-tos/index.md +++ b/docs/docs/cloud/how-tos/index.md @@ -22,6 +22,7 @@ LangGraph Cloud gives you best in class observability, testing, and hosting serv Learn how to deploy your app to LangGraph Cloud in these how to guides: - [How to deploy to LangGraph cloud](../deployment/cloud.md) +- [How to interact with the deployment using RemoteGraph](../../how-tos/use-remote-graph.md) ## Streaming diff --git a/docs/docs/cloud/how-tos/stream_debug.md b/docs/docs/cloud/how-tos/stream_debug.md index 035b0ba96..0dee6a7cd 100644 --- a/docs/docs/cloud/how-tos/stream_debug.md +++ b/docs/docs/cloud/how-tos/stream_debug.md @@ -1,5 +1,8 @@ # How to stream debug events +!!! info "Prerequisites" + * [Streaming](../../concepts/streaming.md) + This guide covers how to stream debug events from your graph (`stream_mode="debug"`). Streaming debug events produces responses containing `type` and `timestamp` keys. Debug events correspond to different steps in the graph's execution, and there are three different types of steps that will get streamed back to you: - `checkpoint`: These events will get streamed anytime the graph saves its state, which occurs after every super-step. Read more about checkpoints [here](https://langchain-ai.github.io/langgraph/concepts/low_level/#checkpointer) diff --git a/docs/docs/cloud/how-tos/stream_events.md b/docs/docs/cloud/how-tos/stream_events.md index 5d3f8f796..385909376 100644 --- a/docs/docs/cloud/how-tos/stream_events.md +++ b/docs/docs/cloud/how-tos/stream_events.md @@ -1,6 +1,9 @@ # How to stream events -This guide covers how to stream events from your graph (`stream_mode="events"`). Depending on the use case and user experience of your LangGraph application, your application may process event types differently. Read more about events in this [conceptual guide](https://langchain-ai.github.io/langgraph/concepts/low_level/#astream_events-for-streaming-tokens-of-llm-calls). +!!! info "Prerequisites" + * [Streaming](../../concepts/streaming.md#streaming-llm-tokens-and-events-astream_events) + +This guide covers how to stream events from your graph (`stream_mode="events"`). Depending on the use case and user experience of your LangGraph application, your application may process event types differently. ## Setup diff --git a/docs/docs/cloud/how-tos/stream_messages.md b/docs/docs/cloud/how-tos/stream_messages.md index 653da7f71..d81d40a57 100644 --- a/docs/docs/cloud/how-tos/stream_messages.md +++ b/docs/docs/cloud/how-tos/stream_messages.md @@ -1,41 +1,9 @@ # How to stream messages from your graph -This guide covers how to stream messages from your graph. In order to use this mode, the state of the graph you are interacting with MUST have a `messages` key that is a list of messages. +!!! info "Prerequisites" + * [Streaming](../../concepts/streaming.md) -E.g., the state should look something like: - -=== "Python" - - ```python - from typing import Annotated - from typing_extensions import TypedDict - from langgraph.graph import add_messages - from langchain_core.messages import AnyMessage - - class State(TypedDict): - messages: Annotated[list[AnyMessage], add_messages] - ``` - -=== "Javascript" - - ```js - import { type BaseMessage } from "@langchain/core/messages"; - import { Annotation, messagesStateReducer } from "@langchain/langgraph"; - - export const StateAnnotation = Annotation.Root({ - messages: Annotation({ - reducer: messagesStateReducer, - default: () => [], - }), - }); - ``` - -Alternatively, you can use an instance or subclass of `from langgraph.graph import MessagesState` (`MessagesState` is equivalent to the implementation above). Or in Javascript: `import { MessagesAnnotation } from "@langchain/langgraph";`. - -With `stream_mode="messages"` two things will be streamed back: - -- It outputs messages produced by any chat model called inside (unless tagged in a special way) -- It outputs messages returned from nodes (to allow for nodes to return `ToolMessages` and the like) +This guide covers how to stream messages from your graph. With `stream_mode="messages"`, messages from any chat model invocations inside your graph nodes will be streamed back. Read more about how the `messages` streaming mode works [here](https://langchain-ai.github.io/langgraph/cloud/concepts/api/#modemessages) @@ -90,98 +58,6 @@ Output: 'values': None } -Let's also define a helper function for better formatting of the tool calls in messages (for CURL we will define a helper script called `process_stream.sh`) - -=== "Python" - - ```python - def format_tool_calls(tool_calls): - if tool_calls: - formatted_calls = [] - for call in tool_calls: - formatted_calls.append( - f"Tool Call ID: {call['id']}, Function: {call['name']}, Arguments: {call['args']}" - ) - return "\n".join(formatted_calls) - return "No tool calls" - ``` - -=== "Javascript" - - ```js - function formatToolCalls(toolCalls) { - if (toolCalls && toolCalls.length > 0) { - const formattedCalls = toolCalls.map(call => { - return `Tool Call ID: ${call.id}, Function: ${call.name}, Arguments: ${call.args}`; - }); - return formattedCalls.join("\n"); - } - return "No tool calls"; - } - ``` - -=== "CURL" - - ```bash - # process_stream.sh - - format_tool_calls() { - echo "$1" | jq -r 'map("Tool Call ID: \(.id), Function: \(.name), Arguments: \(.args)") | join("\n")' - } - - process_data_item() { - local data_item="$1" - - if echo "$data_item" | jq -e '.role == "user"' > /dev/null; then - echo "Human: $(echo "$data_item" | jq -r '.content')" - else - local tool_calls=$(echo "$data_item" | jq -r '.tool_calls // []') - local invalid_tool_calls=$(echo "$data_item" | jq -r '.invalid_tool_calls // []') - local content=$(echo "$data_item" | jq -r '.content // ""') - local response_metadata=$(echo "$data_item" | jq -r '.response_metadata // {}') - - if [ -n "$content" ] && [ "$content" != "null" ]; then - echo "AI: $content" - fi - - if [ "$tool_calls" != "[]" ]; then - echo "Tool Calls:" - format_tool_calls "$tool_calls" - fi - - if [ "$invalid_tool_calls" != "[]" ]; then - echo "Invalid Tool Calls:" - format_tool_calls "$invalid_tool_calls" - fi - - if [ "$response_metadata" != "{}" ]; then - local finish_reason=$(echo "$response_metadata" | jq -r '.finish_reason // "N/A"') - echo "Response Metadata: Finish Reason - $finish_reason" - fi - fi - } - - while IFS=': ' read -r key value; do - case "$key" in - event) - event="$value" - ;; - data) - if [ "$event" = "metadata" ]; then - run_id=$(echo "$value" | jq -r '.run_id') - echo "Metadata: Run ID - $run_id" - echo "------------------------------------------------" - elif [ "$event" = "messages/partial" ]; then - echo "$value" | jq -c '.[]' | while read -r data_item; do - process_data_item "$data_item" - done - echo "------------------------------------------------" - fi - ;; - esac - done - ``` - ## Stream graph in messages mode Now we can stream by messages, which will return complete messages (at the end of node execution) as well as tokens for any messages generated inside a node: @@ -192,41 +68,16 @@ Now we can stream by messages, which will return complete messages (at the end o input = {"messages": [{"role": "user", "content": "what's the weather in sf"}]} config = {"configurable": {"model_name": "openai"}} - async for event in client.runs.stream( + async for chunk in client.runs.stream( thread["thread_id"], assistant_id=assistant_id, input=input, config=config, stream_mode="messages", ): - if event.event == "metadata": - print(f"Metadata: Run ID - {event.data['run_id']}") - print("-" * 50) - elif event.event == "messages/partial": - for data_item in event.data: - if "role" in data_item and data_item["role"] == "user": - print(f"Human: {data_item['content']}") - else: - tool_calls = data_item.get("tool_calls", []) - invalid_tool_calls = data_item.get("invalid_tool_calls", []) - content = data_item.get("content", "") - response_metadata = data_item.get("response_metadata", {}) - - if content: - print(f"AI: {content}") - - if tool_calls: - print("Tool Calls:") - print(format_tool_calls(tool_calls)) - - if invalid_tool_calls: - print("Invalid Tool Calls:") - print(format_tool_calls(invalid_tool_calls)) - - if response_metadata: - finish_reason = response_metadata.get("finish_reason", "N/A") - print(f"Response Metadata: Finish Reason - {finish_reason}") - print("-" * 50) + print(f"Receiving new event of type: {chunk.event}...") + print(chunk.data) + print("\n\n") ``` === "Javascript" @@ -251,43 +102,10 @@ Now we can stream by messages, which will return complete messages (at the end o streamMode: "messages" } ); - - for await (const event of streamResponse) { - if (event.event === "metadata") { - console.log(`Metadata: Run ID - ${event.data.run_id}`); - console.log("-".repeat(50)); - } else if (event.event === "messages/partial") { - event.data.forEach(dataItem => { - if (dataItem.role && dataItem.role === "user") { - console.log(`Human: ${dataItem.content}`); - } else { - const toolCalls = dataItem.tool_calls || []; - const invalidToolCalls = dataItem.invalid_tool_calls || []; - const content = dataItem.content || ""; - const responseMetadata = dataItem.response_metadata || {}; - - if (content) { - console.log(`AI: ${content}`); - } - - if (toolCalls.length > 0) { - console.log("Tool Calls:"); - console.log(formatToolCalls(toolCalls)); - } - - if (invalidToolCalls.length > 0) { - console.log("Invalid Tool Calls:"); - console.log(formatToolCalls(invalidToolCalls)); - } - - if (responseMetadata) { - const finishReason = responseMetadata.finish_reason || "N/A"; - console.log(`Response Metadata: Finish Reason - ${finishReason}`); - } - } - }); - console.log("-".repeat(50)); - } + for await (const chunk of streamResponse) { + console.log(`Receiving new event of type: ${chunk.event}...`); + console.log(chunk.data); + console.log("\n\n"); } ``` @@ -295,203 +113,198 @@ Now we can stream by messages, which will return complete messages (at the end o ```bash curl --request POST \ - --url /threads//runs/stream \ - --header 'Content-Type: application/json' \ - --data "{ - \"assistant_id\": \"agent\", - \"config\":{\"configurable\":{\"model_name\":\"openai\"}}, - \"input\": {\"messages\": [{\"role\": \"human\", \"content\": \"What's the weather in sf\"}]}, - \"stream_mode\": [ - \"messages\" - ] - }" | sed 's/\r$//' | ./process_stream.sh + --url /threads//runs/stream \ + --header 'Content-Type: application/json' \ + --data "{ + \"assistant_id\": \"agent\", + \"input\": {\"messages\": [{\"role\": \"human\", \"content\": \"what's the weather in la\"}]}, + \"stream_mode\": [ + \"messages\" + ] + }" | \ + sed 's/\r$//' | \ + awk ' + /^event:/ { + if (data_content != "") { + print data_content "\n" + } + sub(/^event: /, "Receiving event of type: ", $0) + printf "%s...\n", $0 + data_content = "" + } + /^data:/ { + sub(/^data: /, "", $0) + data_content = $0 + } + END { + if (data_content != "") { + print data_content "\n" + } + } + ' ``` Output: - Metadata: Run ID - 1ef2fe5c-6a1d-6575-bc09-d7832711c17e - -------------------------------------------------- - Invalid Tool Calls: - Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: - -------------------------------------------------- - Tool Calls: - Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {} - -------------------------------------------------- - Tool Calls: - Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {} - -------------------------------------------------- - Tool Calls: - Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {'query': ''} - -------------------------------------------------- - Tool Calls: - Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {'query': 'current'} - -------------------------------------------------- - Tool Calls: - Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {'query': 'current weather'} - -------------------------------------------------- - Tool Calls: - Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {'query': 'current weather in'} - -------------------------------------------------- - Tool Calls: - Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {'query': 'current weather in San'} - -------------------------------------------------- - Tool Calls: - Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {'query': 'current weather in San Francisco'} - -------------------------------------------------- - Tool Calls: - Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {'query': 'current weather in San Francisco'} - -------------------------------------------------- - Tool Calls: - Tool Call ID: call_cg14F20jMBqWYrNgEkdWHwB3, Function: tavily_search_results_json, Arguments: {'query': 'current weather in San Francisco'} - Response Metadata: Finish Reason - tool_calls - -------------------------------------------------- - -------------------------------------------------- - AI: The - -------------------------------------------------- - AI: The current - -------------------------------------------------- - AI: The current weather - -------------------------------------------------- - AI: The current weather in - -------------------------------------------------- - AI: The current weather in San - -------------------------------------------------- - AI: The current weather in San Francisco - -------------------------------------------------- - AI: The current weather in San Francisco is - -------------------------------------------------- - AI: The current weather in San Francisco is over - -------------------------------------------------- - AI: The current weather in San Francisco is overcast - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13 - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13. - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9 - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C ( - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57 - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57. - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0 - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-s - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-south - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6 - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6. - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph ( - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11 - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11. - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 k - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81 - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km ( - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). The - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). The UV - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). The UV index - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). The UV index is - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). The UV index is - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). The UV index is 3 - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). The UV index is 3. - -------------------------------------------------- - AI: The current weather in San Francisco is overcast with a temperature of 13.9°C (57.0°F). The wind is blowing from the south-southwest at 6.9 mph (11.2 kph). The humidity is at 81%, and the visibility is 16 km (9 miles). The UV index is 3. - Response Metadata: Finish Reason - stop - -------------------------------------------------- + Receiving new event of type: metadata... + {"run_id": "1ef971e0-9a84-6154-9047-247b4ce89c4d", "attempt": 1} + + + Receiving new event of type: messages/metadata... + { + "run-700157a5-df1a-4829-9e7c-1e07a1d934f7": { + "metadata": { + "graph_id": "agent", + "langgraph_node": "agent", + ... + } + } + } + + ... + + Receiving new event of type: messages/partial... + [ + { + "tool_calls": [ + { + "name": "tavily_search_results_json", + "args": { + "query": "weather" + }, + "id": "toolu_01RJGmVJtTxccoHHixGkGqaC", + "type": "tool_call" + } + ], + } + ] + + + + Receiving new event of type: messages/partial... + [ + { + "type": "ai", + "tool_calls": [ + { + "name": "tavily_search_results_json", + "args": { + "query": "weather in " + }, + "id": "toolu_01RJGmVJtTxccoHHixGkGqaC", + "type": "tool_call" + } + ], + ... + } + ] + + ... + + Receiving new event of type: messages/partial... + [ + { + "type": "ai", + "tool_calls": [ + { + "name": "tavily_search_results_json", + "args": { + "query": "weather in san francisco" + }, + "id": "toolu_01RJGmVJtTxccoHHixGkGqaC", + "type": "tool_call" + } + ], + ... + } + ] + + + + Receiving new event of type: messages/metadata... + { + "aa162b98-433d-4e3c-b204-0d41a6694156": { + "metadata": { + "graph_id": "agent", + "langgraph_node": "action", + ... + } + } + } + + + + Receiving new event of type: messages/complete... + [ + { + "content": "[{\"url\": \"https://www.weatherapi.com/\", \"content\": \"{'location': {'name': 'San Francisco', 'region': 'California', 'country': 'United States of America', 'lat': 37.775, 'lon': -122.4183, 'tz_id': 'America/Los_Angeles', 'localtime_epoch': 1730334046, 'localtime': '2024-10-30 17:20'}, 'current': {'last_updated_epoch': 1730333700, 'last_updated': '2024-10-30 17:15', 'temp_c': 12.3, 'temp_f': 54.2, 'is_day': 1, 'condition': {'text': 'Partly Cloudy', 'icon': '//cdn.weatherapi.com/weather/64x64/day/116.png', 'code': 1003}, 'wind_mph': 9.6, 'wind_kph': 15.5, 'wind_degree': 238, 'wind_dir': 'WSW', 'pressure_mb': 1021.0, 'pressure_in': 30.15, 'precip_mm': 0.0, 'precip_in': 0.0, 'humidity': 93, 'cloud': 57, 'feelslike_c': 11.2, 'feelslike_f': 52.2, 'windchill_c': 11.2, 'windchill_f': 52.2, 'heatindex_c': 12.3, 'heatindex_f': 54.2, 'dewpoint_c': 11.2, 'dewpoint_f': 52.1, 'vis_km': 10.0, 'vis_miles': 6.0, 'uv': 0.5, 'gust_mph': 12.9, 'gust_kph': 20.8}}\"}]", + "type": "tool", + "name": "tavily_search_results_json", + "tool_call_id": "toolu_01RJGmVJtTxccoHHixGkGqaC", + } + ] + + + Receiving new event of type: messages/metadata... + { + "run-f92646d2-6b13-4648-90c7-0280766bfaf2": { + "metadata": { + "graph_id": "agent", + "langgraph_node": "agent", + ... + } + } + } + + + + Receiving new event of type: messages/partial... + [ + { + "content": [ + { + "text": "\n\nThe search", + "type": "text", + "index": 0 + } + ], + "type": "ai", + ... + } + ] + + + + Receiving new event of type: messages/partial... + [ + { + "content": [ + { + "text": "\n\nThe search results provide", + "type": "text", + "index": 0 + } + ], + "type": "ai", + ... + } + ] + + ... + + Receiving new event of type: messages/partial... + [ + { + "content": [ + { + "text": "\n\nThe search results provide the current weather conditions in San Francisco. According to the data, as of 5:20pm on October 30, 2024, the weather in San Francisco is partly cloudy with a temperature of 54\\u00b0F (12\\u00b0C). The wind is blowing from the west-southwest at around 10 mph (15 km/h). The humidity is high at 93% and visibility is 6 miles (10 km). Overall, it seems to be a cool, partly cloudy day with moderate winds in San Francisco.", + "type": "text", + "index": 0 + } + ], + "type": "ai", + ... + } + ] \ No newline at end of file diff --git a/docs/docs/cloud/how-tos/stream_multiple.md b/docs/docs/cloud/how-tos/stream_multiple.md index 303880ccc..20a05468c 100644 --- a/docs/docs/cloud/how-tos/stream_multiple.md +++ b/docs/docs/cloud/how-tos/stream_multiple.md @@ -1,5 +1,8 @@ # How to configure multiple streaming modes at the same time +!!! info "Prerequisites" + * [Streaming](../../concepts/streaming.md) + This guide covers how to configure multiple streaming modes at the same time. ## Setup @@ -175,11 +178,6 @@ Output: - Receiving new event of type: messages/complete... - [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '7da1bafa-f53c-4df8-ba63-8dd517140b9f', 'example': False}] - - - Receiving new event of type: debug... {'type': 'checkpoint', 'timestamp': '2024-06-24T21:34:06.117924+00:00', 'step': 0, 'payload': {'config': {'tags': [], 'metadata': {'created_by': 'system', 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', 'user_id': '', 'graph_id': 'agent', 'thread_id': 'bfc68029-1f7b-400f-beab-6f9032a52da4', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'callbacks': [None], 'recursion_limit': 25, 'configurable': {'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', 'user_id': '', 'graph_id': 'agent', 'thread_id': 'bfc68029-1f7b-400f-beab-6f9032a52da4', 'thread_ts': '1ef32717-bc81-68c8-8000-4e18ae7d67a5', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25'}, 'values': {'messages': [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '7da1bafa-f53c-4df8-ba63-8dd517140b9f', 'example': False}]}, 'metadata': {'source': 'loop', 'step': 0, 'writes': None}}} @@ -305,11 +303,6 @@ Output: - Receiving new event of type: messages/complete... - [{'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-2424dd6d-5cf5-4244-8d98-357640ce6e12', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}] - - - Receiving new event of type: debug... {'type': 'checkpoint', 'timestamp': '2024-06-24T21:34:06.124510+00:00', 'step': 1, 'payload': {'config': {'tags': [], 'metadata': {'created_by': 'system', 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', 'user_id': '', 'graph_id': 'agent', 'thread_id': 'bfc68029-1f7b-400f-beab-6f9032a52da4', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'callbacks': [None], 'recursion_limit': 25, 'configurable': {'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', 'user_id': '', 'graph_id': 'agent', 'thread_id': 'bfc68029-1f7b-400f-beab-6f9032a52da4', 'thread_ts': '1ef32717-bc91-6a34-8001-26353c117c25', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25'}, 'values': {'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}, 'messages': [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '7da1bafa-f53c-4df8-ba63-8dd517140b9f', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-2424dd6d-5cf5-4244-8d98-357640ce6e12', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}, 'metadata': {'source': 'loop', 'step': 1, 'writes': {'agent': {'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}, 'messages': [{'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-2424dd6d-5cf5-4244-8d98-357640ce6e12', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}}}}} @@ -469,12 +462,7 @@ Output: {'event': 'on_chain_stream', 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', 'name': 'LangGraph', 'tags': [], 'metadata': {'created_by': 'system', 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', 'user_id': '', 'graph_id': 'agent', 'thread_id': 'bfc68029-1f7b-400f-beab-6f9032a52da4', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'data': {'chunk': ['values', {'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}, 'messages': [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '7da1bafa-f53c-4df8-ba63-8dd517140b9f', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-2424dd6d-5cf5-4244-8d98-357640ce6e12', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '639ca779-403d-4915-a066-327e1f634c8b', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-0f2ef0a1-0fc7-445c-9df4-55e8bb284575', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}]}, 'parent_ids': []} - - Receiving new event of type: messages/complete... - [{'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-0f2ef0a1-0fc7-445c-9df4-55e8bb284575', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}] - - - + Receiving new event of type: debug... {'type': 'checkpoint', 'timestamp': '2024-06-24T21:34:06.134190+00:00', 'step': 3, 'payload': {'config': {'tags': [], 'metadata': {'created_by': 'system', 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', 'user_id': '', 'graph_id': 'agent', 'thread_id': 'bfc68029-1f7b-400f-beab-6f9032a52da4', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'callbacks': [None], 'recursion_limit': 25, 'configurable': {'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25', 'user_id': '', 'graph_id': 'agent', 'thread_id': 'bfc68029-1f7b-400f-beab-6f9032a52da4', 'thread_ts': '1ef32717-bca9-6418-8003-8d0d0b06845c', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca'}, 'run_id': '1ef32717-bc30-6cf2-8a26-33f63567bc25'}, 'values': {'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}, 'messages': [{'content': "What's the weather in SF?", 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': '7da1bafa-f53c-4df8-ba63-8dd517140b9f', 'example': False}, {'content': 'begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-2424dd6d-5cf5-4244-8d98-357640ce6e12', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}, {'content': 'tool_call__begin', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': None, 'id': '639ca779-403d-4915-a066-327e1f634c8b', 'tool_call_id': 'tool_call_id'}, {'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-0f2ef0a1-0fc7-445c-9df4-55e8bb284575', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}, 'metadata': {'source': 'loop', 'step': 3, 'writes': {'agent': {'some_bytes': 'c29tZV9ieXRlcw==', 'some_byte_array': 'c29tZV9ieXRlX2FycmF5', 'dict_with_bytes': {'more_bytes': 'bW9yZV9ieXRlcw=='}, 'messages': [{'content': 'end', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-0f2ef0a1-0fc7-445c-9df4-55e8bb284575', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}}}}} diff --git a/docs/docs/cloud/how-tos/stream_updates.md b/docs/docs/cloud/how-tos/stream_updates.md index 72f16d881..1c08b5e80 100644 --- a/docs/docs/cloud/how-tos/stream_updates.md +++ b/docs/docs/cloud/how-tos/stream_updates.md @@ -1,6 +1,9 @@ # How to stream state updates of your graph -This guide covers how to use `stream_mode="updates"` for your graph, which will stream the updates to the graph state that are made after each node is executed. This differs from using `stream_mode="values"`: instead of streaming the entire value of the state at each superstep, it only streams the updates from each of the nodes that made an update to the state at that superstep. Read [this conceptual guide](https://langchain-ai.github.io/langgraph/concepts/low_level/#stream-and-astream) to learn more. +!!! info "Prerequisites" + * [Streaming](../../concepts/streaming.md) + +This guide covers how to use `stream_mode="updates"` for your graph, which will stream the updates to the graph state that are made after each node is executed. This differs from using `stream_mode="values"`: instead of streaming the entire value of the state at each superstep, it only streams the updates from each of the nodes that made an update to the state at that superstep. ## Setup @@ -146,24 +149,69 @@ Now we can stream by updates, which outputs updates made to the state by each no Output: Receiving new event of type: metadata... - {'run_id': 'cfc96c16-ed9a-44bd-b5bb-c30e3c0725f0'} - - - - Receiving new event of type: data... - {'agent': {'messages': [{'content': [{'id': 'toolu_0148tMmDK51iLQfG1yaNwRHM', 'input': {'query': 'weather in los angeles'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}], 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-1a9d32b0-7007-4a36-abde-8df812a0ed94', 'example': False, 'tool_calls': [{'name': 'tavily_search_results_json', 'args': {'query': 'weather in los angeles'}, 'id': 'toolu_0148tMmDK51iLQfG1yaNwRHM'}], 'invalid_tool_calls': []}]}} - - - - Receiving new event of type: data... - {'action': {'messages': [{'content': '[{"url": "https://www.weatherapi.com/", "content": "{\'location\': {\'name\': \'Los Angeles\', \'region\': \'California\', \'country\': \'United States of America\', \'lat\': 34.05, \'lon\': -118.24, \'tz_id\': \'America/Los_Angeles\', \'localtime_epoch\': 1716062239, \'localtime\': \'2024-05-18 12:57\'}, \'current\': {\'last_updated_epoch\': 1716061500, \'last_updated\': \'2024-05-18 12:45\', \'temp_c\': 18.9, \'temp_f\': 66.0, \'is_day\': 1, \'condition\': {\'text\': \'Overcast\', \'icon\': \'//cdn.weatherapi.com/weather/64x64/day/122.png\', \'code\': 1009}, \'wind_mph\': 2.2, \'wind_kph\': 3.6, \'wind_degree\': 10, \'wind_dir\': \'N\', \'pressure_mb\': 1017.0, \'pressure_in\': 30.02, \'precip_mm\': 0.0, \'precip_in\': 0.0, \'humidity\': 65, \'cloud\': 100, \'feelslike_c\': 18.9, \'feelslike_f\': 66.0, \'vis_km\': 16.0, \'vis_miles\': 9.0, \'uv\': 6.0, \'gust_mph\': 7.5, \'gust_kph\': 12.0}}"}]', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'tavily_search_results_json', 'id': 'a36e8cd1-0e96-4417-9c15-f10a945d2b42', 'tool_call_id': 'toolu_0148tMmDK51iLQfG1yaNwRHM'}]}} - - - - Receiving new event of type: data... - {'agent': {'messages': [{'content': 'The weather in Los Angeles is currently overcast with a temperature of around 66°F (18.9°C). There are light winds from the north at around 2-3 mph. The humidity is 65% and visibility is good at 9 miles. Overall, mild spring weather conditions in LA.', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-d5c1c2f0-b12d-41ce-990b-f36570e7483d', 'example': False, 'tool_calls': [], 'invalid_tool_calls': []}]}} - - - + {"run_id": "cfc96c16-ed9a-44bd-b5bb-c30e3c0725f0"} + + + + Receiving new event of type: updates... + { + "agent": { + "messages": [ + { + "type": "ai", + "tool_calls": [ + { + "name": "tavily_search_results_json", + "args": { + "query": "weather in los angeles" + }, + "id": "toolu_0148tMmDK51iLQfG1yaNwRHM" + } + ], + ... + } + ] + } + } + + + + Receiving new event of type: updates... + { + "action": { + "messages": [ + { + "content": [ + { + "url": "https://www.weatherapi.com/", + "content": "{\"location\": {\"name\": \"Los Angeles\", \"region\": \"California\", \"country\": \"United States of America\", \"lat\": 34.05, \"lon\": -118.24, \"tz_id\": \"America/Los_Angeles\", \"localtime_epoch\": 1716062239, \"localtime\": \"2024-05-18 12:57\"}, \"current\": {\"last_updated_epoch\": 1716061500, \"last_updated\": \"2024-05-18 12:45\", \"temp_c\": 18.9, \"temp_f\": 66.0, \"is_day\": 1, \"condition\": {\"text\": \"Overcast\", \"icon\": \"//cdn.weatherapi.com/weather/64x64/day/122.png\", \"code\": 1009}, \"wind_mph\": 2.2, \"wind_kph\": 3.6, \"wind_degree\": 10, \"wind_dir\": \"N\", \"pressure_mb\": 1017.0, \"pressure_in\": 30.02, \"precip_mm\": 0.0, \"precip_in\": 0.0, \"humidity\": 65, \"cloud\": 100, \"feelslike_c\": 18.9, \"feelslike_f\": 66.0, \"vis_km\": 16.0, \"vis_miles\": 9.0, \"uv\": 6.0, \"gust_mph\": 7.5, \"gust_kph\": 12.0}}" + } + ], + "type": "tool", + "name": "tavily_search_results_json", + "tool_call_id": "toolu_0148tMmDK51iLQfG1yaNwRHM", + ... + } + ] + } + } + + + + Receiving new event of type: updates... + { + "agent": { + "messages": [ + { + "content": "The weather in Los Angeles is currently overcast with a temperature of around 66°F (18.9°C). There are light winds from the north at around 2-3 mph. The humidity is 65% and visibility is good at 9 miles. Overall, mild spring weather conditions in LA.", + "type": "ai", + ... + } + ] + } + } + + + Receiving new event of type: end... None \ No newline at end of file diff --git a/docs/docs/cloud/how-tos/stream_values.md b/docs/docs/cloud/how-tos/stream_values.md index 8dab72893..17e186027 100644 --- a/docs/docs/cloud/how-tos/stream_values.md +++ b/docs/docs/cloud/how-tos/stream_values.md @@ -1,6 +1,9 @@ # How to stream full state of your graph -This guide covers how to use `stream_mode="values"`, which streams the value of the state at each superstep. This differs from using `stream_mode="updates"`: instead of streaming just the updates to the state from each node, it streams the entire graph state at that superstep. Read [this conceptual guide](https://langchain-ai.github.io/langgraph/concepts/low_level/#stream-and-astream) to learn more. +!!! info "Prerequisites" + * [Streaming](../../concepts/streaming.md) + +This guide covers how to use `stream_mode="values"`, which streams the value of the state at each superstep. This differs from using `stream_mode="updates"`: instead of streaming just the updates to the state from each node, it streams the entire graph state at that superstep. ## Setup @@ -133,30 +136,93 @@ Now we can stream by values, which streams the full state of the graph after eac Output: Receiving new event of type: metadata... - {'run_id': 'f08791ce-0a3d-44e0-836c-ff62cd2e2786'} - - - + {"run_id": "f08791ce-0a3d-44e0-836c-ff62cd2e2786"} + + + Receiving new event of type: values... - {'messages': [{'role': 'human', 'content': 'what's the weather in la'}]} - - - + { + "messages": [ + { + "role": "human", + "content": "what's the weather in la" + } + ] + } + + + Receiving new event of type: values... - {'messages': [{'content': 'what's the weather in la', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'faa15565-8823-4aa1-87af-e21b40526fae', 'example': False}, {'content': [{'id': 'toolu_01E5mSaZWm5rWJnCqmt63v4g', 'input': {'query': 'weather in los angeles'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}], 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-3fe1db7a-6b8d-4d83-ba07-8657190ad811', 'example': False, 'tool_calls': [{'name': 'tavily_search_results_json', 'args': {'query': 'weather in los angeles'}, 'id': 'toolu_01E5mSaZWm5rWJnCqmt63v4g'}], 'invalid_tool_calls': []}]} - - - + { + "messages": [ + { + "content": "what's the weather in la", + "type": "human", + ... + }, + { + "content": "", + "type": "ai", + "tool_calls": [ + { + "name": "tavily_search_results_json", + "args": { + "query": "weather in los angeles" + }, + "id": "toolu_01E5mSaZWm5rWJnCqmt63v4g" + } + ], + ... + } + ] + } + + ... + Receiving new event of type: values... - {'messages': [{'content': 'what's the weather in la', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'faa15565-8823-4aa1-87af-e21b40526fae', 'example': False}, {'content': [{'id': 'toolu_01E5mSaZWm5rWJnCqmt63v4g', 'input': {'query': 'weather in los angeles'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}], 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-3fe1db7a-6b8d-4d83-ba07-8657190ad811', 'example': False, 'tool_calls': [{'name': 'tavily_search_results_json', 'args': {'query': 'weather in los angeles'}, 'id': 'toolu_01E5mSaZWm5rWJnCqmt63v4g'}], 'invalid_tool_calls': []}, {'content': '[{"url": "https://www.weatherapi.com/", "content": "{\'location\': {\'name\': \'Los Angeles\', \'region\': \'California\', \'country\': \'United States of America\', \'lat\': 34.05, \'lon\': -118.24, \'tz_id\': \'America/Los_Angeles\', \'localtime_epoch\': 1716310320, \'localtime\': \'2024-05-21 9:52\'}, \'current\': {\'last_updated_epoch\': 1716309900, \'last_updated\': \'2024-05-21 09:45\', \'temp_c\': 16.7, \'temp_f\': 62.1, \'is_day\': 1, \'condition\': {\'text\': \'Overcast\', \'icon\': \'//cdn.weatherapi.com/weather/64x64/day/122.png\', \'code\': 1009}, \'wind_mph\': 8.1, \'wind_kph\': 13.0, \'wind_degree\': 250, \'wind_dir\': \'WSW\', \'pressure_mb\': 1015.0, \'pressure_in\': 29.97, \'precip_mm\': 0.0, \'precip_in\': 0.0, \'humidity\': 65, \'cloud\': 100, \'feelslike_c\': 16.7, \'feelslike_f\': 62.1, \'vis_km\': 16.0, \'vis_miles\': 9.0, \'uv\': 5.0, \'gust_mph\': 12.5, \'gust_kph\': 20.2}}"}]', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'tavily_search_results_json', 'id': '0d5dab31-5ff8-4ae2-a560-bc4bcba7c9d7', 'tool_call_id': 'toolu_01E5mSaZWm5rWJnCqmt63v4g'}]} - - - - Receiving new event of type: values... - {'messages': [{'content': 'what's the weather in la', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'human', 'name': None, 'id': 'faa15565-8823-4aa1-87af-e21b40526fae', 'example': False}, {'content': [{'id': 'toolu_01E5mSaZWm5rWJnCqmt63v4g', 'input': {'query': 'weather in los angeles'}, 'name': 'tavily_search_results_json', 'type': 'tool_use'}], 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-3fe1db7a-6b8d-4d83-ba07-8657190ad811', 'example': False, 'tool_calls': [{'name': 'tavily_search_results_json', 'args': {'query': 'weather in los angeles'}, 'id': 'toolu_01E5mSaZWm5rWJnCqmt63v4g'}], 'invalid_tool_calls': []}, {'content': '[{"url": "https://www.weatherapi.com/", "content": "{\'location\': {\'name\': \'Los Angeles\', \'region\': \'California\', \'country\': \'United States of America\', \'lat\': 34.05, \'lon\': -118.24, \'tz_id\': \'America/Los_Angeles\', \'localtime_epoch\': 1716310320, \'localtime\': \'2024-05-21 9:52\'}, \'current\': {\'last_updated_epoch\': 1716309900, \'last_updated\': \'2024-05-21 09:45\', \'temp_c\': 16.7, \'temp_f\': 62.1, \'is_day\': 1, \'condition\': {\'text\': \'Overcast\', \'icon\': \'//cdn.weatherapi.com/weather/64x64/day/122.png\', \'code\': 1009}, \'wind_mph\': 8.1, \'wind_kph\': 13.0, \'wind_degree\': 250, \'wind_dir\': \'WSW\', \'pressure_mb\': 1015.0, \'pressure_in\': 29.97, \'precip_mm\': 0.0, \'precip_in\': 0.0, \'humidity\': 65, \'cloud\': 100, \'feelslike_c\': 16.7, \'feelslike_f\': 62.1, \'vis_km\': 16.0, \'vis_miles\': 9.0, \'uv\': 5.0, \'gust_mph\': 12.5, \'gust_kph\': 20.2}}"}]', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'tavily_search_results_json', 'id': '0d5dab31-5ff8-4ae2-a560-bc4bcba7c9d7', 'tool_call_id': 'toolu_01E5mSaZWm5rWJnCqmt63v4g'}, {'content': 'Based on the weather API results, the current weather in Los Angeles is overcast with a temperature of around 62°F (17°C). There are light winds from the west-southwest around 8-13 mph. The humidity is 65% and visibility is good at 9 miles. Overall, mild spring weather conditions in LA.', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-4d6d4c23-5aad-4042-b0d9-19407a9e08e3', 'example': False, 'tool_calls': [], 'invalid_tool_calls': []}]} - - - + { + "messages": [ + { + "content": "what's the weather in la", + "type": "human", + ... + }, + { + "content": "", + "type": "ai", + "tool_calls": [ + { + "name": "tavily_search_results_json", + "args": { + "query": "weather in los angeles" + }, + "id": "toolu_01E5mSaZWm5rWJnCqmt63v4g" + } + ], + ... + } + { + "content": [ + { + "url": "https://www.weatherapi.com/", + "content": "{\"location\": {\"name\": \"Los Angeles\", \"region\": \"California\", \"country\": \"United States of America\", \"lat\": 34.05, \"lon\": -118.24, \"tz_id\": \"America/Los_Angeles\", \"localtime_epoch\": 1716310320, \"localtime\": \"2024-05-21 9:52\"}, \"current\": {\"last_updated_epoch\": 1716309900, \"last_updated\": \"2024-05-21 09:45\", \"temp_c\": 16.7, \"temp_f\": 62.1, \"is_day\": 1, \"condition\": {\"text\": \"Overcast\", \"icon\": \"//cdn.weatherapi.com/weather/64x64/day/122.png\", \"code\": 1009}, \"wind_mph\": 8.1, \"wind_kph\": 13.0, \"wind_degree\": 250, \"wind_dir\": \"WSW\", \"pressure_mb\": 1015.0, \"pressure_in\": 29.97, \"precip_mm\": 0.0, \"precip_in\": 0.0, \"humidity\": 65, \"cloud\": 100, \"feelslike_c\": 16.7, \"feelslike_f\": 62.1, \"vis_km\": 16.0, \"vis_miles\": 9.0, \"uv\": 5.0, \"gust_mph\": 12.5, \"gust_kph\": 20.2}}" + } + ], + "type": "tool", + "name": "tavily_search_results_json", + "tool_call_id": "toolu_01E5mSaZWm5rWJnCqmt63v4g" + ... + }, + { + "content": "Based on the weather API results, the current weather in Los Angeles is overcast with a temperature of around 62°F (17°C). There are light winds from the west-southwest around 8-13 mph. The humidity is 65% and visibility is good at 9 miles. Overall, mild spring weather conditions in LA.", + "type": "ai", + ... + } + ] + } + + + Receiving new event of type: end... None @@ -228,40 +294,42 @@ If we want to just get the final result, we can use this endpoint and just keep Output: - {'messages': [{'content': 'what's the weather in la', - 'additional_kwargs': {}, - 'response_metadata': {}, - 'type': 'human', - 'name': None, - 'id': 'e78c2f94-d810-42fc-a399-11f6bb1b1092', - 'example': False}, - {'content': [{'id': 'toolu_01SBMoAGr4U9x3ibztm2UUom', - 'input': {'query': 'weather in los angeles'}, - 'name': 'tavily_search_results_json', - 'type': 'tool_use'}], - 'additional_kwargs': {}, - 'response_metadata': {}, - 'type': 'ai', - 'name': None, - 'id': 'run-80767ab8-09fc-40ec-9e45-657ddef5e0b1', - 'example': False, - 'tool_calls': [{'name': 'tavily_search_results_json', - 'args': {'query': 'weather in los angeles'}, - 'id': 'toolu_01SBMoAGr4U9x3ibztm2UUom'}], - 'invalid_tool_calls': []}, - {'content': '[{"url": "https://www.weatherapi.com/", "content": "{\'location\': {\'name\': \'Los Angeles\', \'region\': \'California\', \'country\': \'United States of America\', \'lat\': 34.05, \'lon\': -118.24, \'tz_id\': \'America/Los_Angeles\', \'localtime_epoch\': 1716310320, \'localtime\': \'2024-05-21 9:52\'}, \'current\': {\'last_updated_epoch\': 1716309900, \'last_updated\': \'2024-05-21 09:45\', \'temp_c\': 16.7, \'temp_f\': 62.1, \'is_day\': 1, \'condition\': {\'text\': \'Overcast\', \'icon\': \'//cdn.weatherapi.com/weather/64x64/day/122.png\', \'code\': 1009}, \'wind_mph\': 8.1, \'wind_kph\': 13.0, \'wind_degree\': 250, \'wind_dir\': \'WSW\', \'pressure_mb\': 1015.0, \'pressure_in\': 29.97, \'precip_mm\': 0.0, \'precip_in\': 0.0, \'humidity\': 65, \'cloud\': 100, \'feelslike_c\': 16.7, \'feelslike_f\': 62.1, \'vis_km\': 16.0, \'vis_miles\': 9.0, \'uv\': 5.0, \'gust_mph\': 12.5, \'gust_kph\': 20.2}}"}]', - 'additional_kwargs': {}, - 'response_metadata': {}, - 'type': 'tool', - 'name': 'tavily_search_results_json', - 'id': 'af25e94a-c119-48c3-bbd3-096e42f472ac', - 'tool_call_id': 'toolu_01SBMoAGr4U9x3ibztm2UUom'}, - {'content': 'Based on the weather API results, the current weather in Los Angeles is overcast with a temperature of around 62°F (17°C). There are light winds from the west-southwest around 8-13 mph. The humidity is 65% and visibility is good at 9 miles. Overall, mild spring weather conditions in LA.', - 'additional_kwargs': {}, - 'response_metadata': {}, - 'type': 'ai', - 'name': None, - 'id': 'run-b90f0037-e56a-4f3b-ad92-00d10d079a9e', - 'example': False, - 'tool_calls': [], - 'invalid_tool_calls': []}]} \ No newline at end of file + { + "messages": [ + { + "content": "what's the weather in la", + "type": "human", + ... + }, + { + "type": "ai", + "tool_calls": [ + { + "name": "tavily_search_results_json", + "args": { + "query": "weather in los angeles" + }, + "id": "toolu_01E5mSaZWm5rWJnCqmt63v4g" + } + ], + ... + } + { + "content": [ + { + "url": "https://www.weatherapi.com/", + "content": "{\"location\": {\"name\": \"Los Angeles\", \"region\": \"California\", \"country\": \"United States of America\", \"lat\": 34.05, \"lon\": -118.24, \"tz_id\": \"America/Los_Angeles\", \"localtime_epoch\": 1716310320, \"localtime\": \"2024-05-21 9:52\"}, \"current\": {\"last_updated_epoch\": 1716309900, \"last_updated\": \"2024-05-21 09:45\", \"temp_c\": 16.7, \"temp_f\": 62.1, \"is_day\": 1, \"condition\": {\"text\": \"Overcast\", \"icon\": \"//cdn.weatherapi.com/weather/64x64/day/122.png\", \"code\": 1009}, \"wind_mph\": 8.1, \"wind_kph\": 13.0, \"wind_degree\": 250, \"wind_dir\": \"WSW\", \"pressure_mb\": 1015.0, \"pressure_in\": 29.97, \"precip_mm\": 0.0, \"precip_in\": 0.0, \"humidity\": 65, \"cloud\": 100, \"feelslike_c\": 16.7, \"feelslike_f\": 62.1, \"vis_km\": 16.0, \"vis_miles\": 9.0, \"uv\": 5.0, \"gust_mph\": 12.5, \"gust_kph\": 20.2}}" + } + ], + "type": "tool", + "name": "tavily_search_results_json", + "tool_call_id": "toolu_01E5mSaZWm5rWJnCqmt63v4g" + ... + }, + { + "content": "Based on the weather API results, the current weather in Los Angeles is overcast with a temperature of around 62°F (17°C). There are light winds from the west-southwest around 8-13 mph. The humidity is 65% and visibility is good at 9 miles. Overall, mild spring weather conditions in LA.", + "type": "ai", + ... + } + ] + } \ No newline at end of file diff --git a/docs/docs/cloud/img/cloud_deployment.png b/docs/docs/cloud/img/cloud_deployment.png deleted file mode 100644 index 9b65bb4e6..000000000 Binary files a/docs/docs/cloud/img/cloud_deployment.png and /dev/null differ diff --git a/docs/docs/cloud/img/graph_video_poster.png b/docs/docs/cloud/img/graph_video_poster.png deleted file mode 100644 index e757082d6..000000000 Binary files a/docs/docs/cloud/img/graph_video_poster.png and /dev/null differ diff --git a/docs/docs/cloud/quick_start.md b/docs/docs/cloud/quick_start.md index 08e42ac9c..940b40e29 100644 --- a/docs/docs/cloud/quick_start.md +++ b/docs/docs/cloud/quick_start.md @@ -1,6 +1,8 @@ # Quick Start -This quick start guide will cover how to build a simple agent that can look up things on the internet. We will then deploy it to LangGraph Cloud, use the LangGraph Studio to visualize and test it out, and use the LangGraph SDK to interact with it. +In this tutorial you will build and deploy a simple chatbot agent that can look things up on the internet. You will be using [LangGraph Cloud](../concepts/langgraph_cloud.md), [LangGraph Studio](../concepts/langgraph_studio.md) to visualize and test it out, and [LangGraph SDK](./reference/sdk/python_sdk_ref.md) to interact with the deployed agent. + +If you want to learn how to build an agent like this from scratch, take a look at the [LangGraph Quick Start tutorial](../tutorials/introduction.ipynb). ## Set up requirements @@ -10,146 +12,183 @@ This tutorial will use: - Tavily for the search engine - sign up and get an API key [here](https://app.tavily.com/) - LangSmith for hosting - sign up and get an API key [here](https://smith.langchain.com/) -## Set up local files +## Create and configure your app -1. Create a new application with the following directory and files: +First, let's set create all of the necessary files for our LangGraph application. -=== "Python" +1. __Create application directory and files__ - / - |-- agent.py # code for your LangGraph agent - |-- requirements.txt # Python packages required for your graph - |-- langgraph.json # configuration file for LangGraph - |-- .env # environment files with API keys + Create a new application `my-app` with the following file structure: -=== "Javascript" - - / - |-- agent.ts # code for your LangGraph agent - |-- package.json # Javascript packages required for your graph - |-- langgraph.json # configuration file for LangGraph - |-- .env # environment files with API keys - -2. The `agent.py`/`agent.ts` file should contain code for defining your graph. The following code is a simple example, the important thing is that at some point in your file you compile your graph and assign the compiled graph to a variable (in this case the `graph` variable). This example code uses `create_react_agent`, a prebuilt agent. You can read more about it [here](../concepts/agentic_concepts.md#react-implementation). - -=== "Python" - - ```python - from langchain_anthropic import ChatAnthropic - from langchain_community.tools.tavily_search import TavilySearchResults - from langgraph.prebuilt import create_react_agent - - model = ChatAnthropic(model="claude-3-5-sonnet-20240620") - - tools = [TavilySearchResults(max_results=2)] - - graph = create_react_agent(model, tools) + ```shell + mkdir my-app ``` -=== "Javascript" + === "Python" - ```ts - import { ChatAnthropic } from "@langchain/anthropic"; - import { TavilySearchResults } from "@langchain/community/tools/tavily_search"; - import { createReactAgent } from "@langchain/langgraph/prebuilt"; + my-app/ + |-- agent.py # code for your LangGraph agent + |-- requirements.txt # Python packages required for your graph + |-- langgraph.json # configuration file for LangGraph + |-- .env # environment files with API keys - const model = new ChatAnthropic({ - model: "claude-3-5-sonnet-20240620", - }); + === "Javascript" - const tools = [ - new TavilySearchResults({ maxResults: 3, }), - ]; + my-app/ + |-- agent.ts # code for your LangGraph agent + |-- package.json # Javascript packages required for your graph + |-- langgraph.json # configuration file for LangGraph + |-- .env # environment files with API keys - export const graph = createReactAgent({ llm: model, tools }); - ``` -3. The `requirements.txt`/`package.json` file should contain any dependencies for your graph(s). In this case we only require four packages for our graph to run: +1. __Define your graph__ -=== "Python" + === "Python" + The `agent.py` file should contain code with your graph. - ```python - langgraph - langchain_anthropic - tavily-python - langchain_community - ``` + === "Javascript" + The `agent.ts` file should contain code with your graph. -=== "Javascript" + The following code example is a simple chatbot agent (similar to the one in the [previous tutorial](../tutorials/introduction.ipynb)). Specifically, it uses [create_react_agent][langgraph.prebuilt.chat_agent_executor.create_react_agent], a prebuilt [ReAct](../concepts/agentic_concepts.md#react-implementation)-style agent. - ```js - { - "name": "my-app", - "packageManager": "yarn@1.22.22", - "dependencies": { - "@langchain/community": "^0.2.31", - "@langchain/core": "^0.2.31", - "@langchain/langgraph": "0.2.0", - "@langchain/openai": "^0.2.8" + The `agent` file needs to have a variable with a [CompiledGraph][langgraph.graph.graph.CompiledGraph] (in this case the `graph` variable). + + === "Python" + + ```python + # agent.py + from langchain_anthropic import ChatAnthropic + from langchain_community.tools.tavily_search import TavilySearchResults + from langgraph.prebuilt import create_react_agent + + model = ChatAnthropic(model="claude-3-5-sonnet-20240620") + + tools = [TavilySearchResults(max_results=2)] + + # compiled graph + graph = create_react_agent(model, tools) + ``` + + === "Javascript" + + ```ts + // agent.ts + import { ChatAnthropic } from "@langchain/anthropic"; + import { TavilySearchResults } from "@langchain/community/tools/tavily_search"; + import { createReactAgent } from "@langchain/langgraph/prebuilt"; + + const model = new ChatAnthropic({ + model: "claude-3-5-sonnet-20240620", + }); + + const tools = [ + new TavilySearchResults({ maxResults: 3, }), + ]; + + // compiled graph + export const graph = createReactAgent({ llm: model, tools }); + ``` + +1. __Specify dependencies__ + + === "Python" + You should add dependencies for your graph(s) to `requirements.txt`. + + === "Javascript" + You should add dependencies for your graph(s) to `package.json`. + + In this case we only require four packages for our graph to run: + + === "Python" + + ```python + langgraph + langchain_anthropic + tavily-python + langchain_community + ``` + + === "Javascript" + + ```js + { + "name": "my-app", + "packageManager": "yarn@1.22.22", + "dependencies": { + "@langchain/community": "^0.3.11", + "@langchain/core": "^0.3.16", + "@langchain/langgraph": "0.2.18", + "@langchain/anthropic": "^0.3.7" + } + } + ``` + +1. __Create LangGraph configuration file__ + + The [`langgraph.json`][langgraph.json] file is a configuration file that describes what graph(s) you are going to deploy. In this case we only have one graph: the compiled `graph` object from `agent.py` / `agent.ts`. + + === "Python" + + ```json + { + "dependencies": ["."], + "graphs": { + "agent": "./agent.py:graph" + }, + "env": ".env" } - } - ``` + ``` -4. The [`langgraph.json`][langgraph.json] file is a configuration file that describes what graph(s) you are going to host. In this case we only have one graph to host: the compiled `graph` object from `agent.py`/`agent.ts`. + === "Javascript" -=== "Python" + ```json + { + "node_version": "20", + "dockerfile_lines": [], + "dependencies": ["."], + "graphs": { + "agent": "./src/agent.ts:graph" + }, + "env": ".env" + } + ``` - ```json - { - "dependencies": ["."], - "graphs": { - "agent": "./agent.py:graph" - }, - "env": ".env" - } - ``` + Learn more about the LangGraph CLI configuration file [here](./reference/cli.md#configuration-file). -=== "Javascript" +1. __Specify environment variables__ - ```json - { - "node_version": "20", - "dockerfile_lines": [], - "dependencies": ["."], - "graphs": { - "agent": "./src/agent.ts:graph" - }, - "env": ".env" - } - ``` + The `.env` file should have any environment variables needed to run your graph. This will only be used for local testing, so if you are not testing locally you can skip this step. -Learn more about the LangGraph CLI configuration file [here](./reference/cli.md#configuration-file). + !!! warning + The `.env` file should NOT be included with the rest of source code in your Github repository. When creating a deployment using LangGraph Cloud, you will be able to specify the environment variables manually. -5. The `.env` file should have any environment variables needed to run your graph. This will only be used for local testing, so if you are not testing locally you can skip this step. NOTE: if you do add this, you should NOT check this into git. For this graph, we need two environment variables: + For this graph, we need two environment variables: ```shell ANTHROPIC_API_KEY=... TAVILY_API_KEY=... ``` -Now that we have set everything up on our local file system, we are ready to host our graph. +!!! tip + Learn more about different application structure options [here](../how-tos/index.md#application-structure). -## Test the graph build locally +Now that we have set everything up on our local file system, we are ready to test our graph locally. -### Using LangGraph Studio Desktop (recommended) +## Test the app locally -![LangGraph Studio Desktop](./img/graph_video_poster.png) +To test the LangGraph app before deploying it using LangGraph Cloud, you can use [LangGraph Studio](../concepts/langgraph_studio.md) or start the [LangGraph server](../concepts/langgraph_server.md) locally. -Testing your graph locally is easy with LangGraph Studio Desktop. LangGraph Studio offers a new way to develop LLM applications by providing a specialized agent IDE that enables visualization, interaction, and debugging of complex agentic applications +## Using local server -With visual graphs and the ability to edit state, you can better understand agent workflows and iterate faster. LangGraph Studio integrates with [LangSmith](https://smith.langchain.com) so you can collaborate with teammates to debug failure modes. +You can also test your app by running [LangGraph server](../concepts/langgraph_server.md) locally. This is useful to make sure you have configured our [CLI configuration file][langgraph.json] correctly and can interact with your graph. -### Using the LangGraph CLI - -Before deploying to the cloud, we probably want to test the building of our graph locally. This is useful to make sure we have configured our [CLI configuration file][langgraph.json] correctly and our graph runs. - -In order to do this we can first install the LangGraph CLI +To run the server locally, you need to first install the LangGraph CLI: ```shell pip install langgraph-cli ``` -We can then test our API server locally. This requires access to LangGraph closed beta. In order to run the server locally, you will need to add your `LANGSMITH_API_KEY` to the .env file so we can validate you have access to LangGraph closed beta. +You can then test our API server locally. In order to run the server locally, you will need to add your `LANGSMITH_API_KEY` to the `.env` file. ```shell langgraph up @@ -160,10 +199,21 @@ This will start up the LangGraph API server locally. If this runs successfully, ```shell Ready! - API: http://localhost:8123 -2024-06-26 19:20:41,056:INFO:uvicorn.access 127.0.0.1:44138 - "GET /ok HTTP/1.1" 200 ``` -You can now test this out! **Note: this local server is intended SOLELY for local testing purposes and is not performant enough for production applications, so please do not use it as such.** To test it out, you can go to another terminal window and run: +First, let's verify that the server is running correctly by calling `/ok` endpoint: + +```shell +curl --request GET --url http://localhost:8123/ok +``` + +Output: + +``` +{"ok": "true"} +``` + +Now we're ready to test the app with the real inputs! ```shell curl --request POST \ @@ -175,36 +225,56 @@ curl --request POST \ "messages": [ { "role": "user", - "content": "How are you?" + "content": "What is the weather in NYC?" } ] }, - "metadata": {}, - "config": { - "configurable": {} - }, - "multitask_strategy": "reject", - "stream_mode": [ - "values" - ] + "stream_mode": "updates" }' ``` -If you get back a valid response, then all is functioning properly! +Output: -## Deploy to Cloud +``` +... -### Push your code to GitHub +data: { + "agent": { + "messages": [ + { + "content": "The search results from Tavily provide the current weather conditions in New York City, including temperature, wind speed, precipitation, humidity, and cloud cover. According to the results, as of 3:00pm on October 30th, 2024, it is overcast in NYC with a temperature of around 66°F (19°C), light winds from the southwest around 8 mph (13 km/h), and 66% humidity.\n\nSo in summary, the current weather in NYC is overcast with mild temperatures in the mid 60sF and light winds, based on the search results. Let me know if you need any other details!", + "type": "ai", + ... + } + ] + } +``` -Turn the `` directory into a GitHub repo. You can use the GitHub CLI if you like, or just create a repo manually (if unfamiliar, instructions [here](https://docs.github.com/en/migrations/importing-source-code/using-the-command-line-to-import-source-code/adding-locally-hosted-code-to-github)). +You can see that our agent responds with the up-to-date search results! -### Deploy from GitHub with LangGraph Cloud +### Using LangGraph Studio Desktop -Once you have created your github repository with a Python file containing your compiled graph as well as a `langgraph.json` file containing the configuration for hosting your graph, you can head over to LangSmith and click on the 🚀 icon on the left navbar to create a new deployment. Then click the `+ New Deployment` button. +You can also test your app locally with [LangGraph Studio](../concepts/langgraph_studio.md). LangGraph Studio offers a new way to develop LLM applications by providing a specialized agent IDE that enables visualization, interaction, and debugging of complex agentic applications. -![Langsmith Workflow](./img/cloud_deployment.png) +With visual graphs and the ability to edit state, you can better understand agent workflows and iterate faster. LangGraph Studio integrates with LangSmith allowing you to collaborate with teammates to debug failure modes. -**_If you have not deployed to LangGraph Cloud before:_** there will be a button that shows up saying Import from GitHub. You’ll need to follow that flow to connect LangGraph Cloud to GitHub. +LangGraph Studio is available as a [desktop app](https://studio.langchain.com/) for MacOS users. Once you have installed the app, you can select `my-app` directory, which will automatically start the server locally and load the graph in the UI. + +To interact with your chatbot agent in LangGraph Studio, you can add a new message in the `Input` section and press `Submit`. + +![LangGraph Studio Desktop](./deployment/img/quick_start_studio.png) + +## Deploy to LangGraph Cloud + +Once you've tested your graph locally and verified that it works as expected, you can deploy it to the LangGraph Cloud. + +First, you'll need to turn the `my-app` directory into a GitHub repo and [push it to GitHub](https://docs.github.com/en/migrations/importing-source-code/using-the-command-line-to-import-source-code/adding-locally-hosted-code-to-github). + +Once you have created your GitHub repository with a Python file containing your compiled graph as well as a `langgraph.json` with the configuration, you can head over to [LangSmith](https://smith.langchain.com/) and click on the graph icon (`LangGraph Cloud`) on the bottom of the left navbar. This will open the LangGraph deployments page. On this page, click the `+ New Deployment` button in the top right corner. + +![Langsmith Workflow](./deployment/img/cloud_deployment.png) + +**_If you have not deployed to LangGraph Cloud before:_** there will be a button that shows up saying `Import from GitHub`. You’ll need to follow that flow to connect LangGraph Cloud to GitHub. **_Once you have set up your GitHub connection:_** the new deployment page will look as follows: @@ -213,53 +283,43 @@ Once you have created your github repository with a Python file containing your To deploy your application, you should do the following: 1. Select your GitHub username or organization from the selector -2. Search for your repo to deploy in the search bar and select it -3. Choose any name -4. In the `LangGraph API config file` field, enter the path to your `langgraph.json` file (which in this case is just `langgraph.json`) -5. For Git Reference, you can select either the git branch for the code you want to deploy, or the exact commit SHA. -6. If your chain relies on environment variables, add those in. They will be propagated to the underlying server so your code can access them. In this case, we need `ANTHROPIC_API_KEY` and `TAVILY_API_KEY`. - -Putting this all together, you should have something as follows for your deployment details: - -![Deployment filled out](./deployment/img/deploy_filled_out.png) +1. Search for your repo to deploy in the search bar and select it +1. Choose a name for your deployment +1. In the `Git Branch` field, you can specify either the branch for the code you want to deploy, or the exact commit SHA. +1. In the `LangGraph API config file` field, enter the path to your `langgraph.json` file (which in this case is just `langgraph.json`) +1. If your application needs environment variables, add those in the `Environment Variables` section. They will be propagated to the underlying server so your code can access them. In this case, we will need `ANTHROPIC_API_KEY` and `TAVILY_API_KEY`. Hit `Submit` and your application will start deploying! -## Inspect Traces + Monitor Service - -### Deployments View - After your deployment is complete, your deployments page should look as follows: ![Deployed page](./deployment/img/deployed_page.png) -You can see that by default, you get access to the `Trace Count` monitoring chart and `Recent Traces` run view. These are powered by LangSmith. +## Interact with your deployment -You can click on `All Charts` to view all monitoring info for your server, or click on `See tracing project` to get more information on an individual trace. +### Using LangGraph Studio (Cloud) -### Access the Docs - -You can access the docs by clicking on the API docs link, which should send you to a page that looks like this: - -![API Docs page](./deployment/img/api_page.png) - -You won’t actually be able to test any of the API endpoints without authorizing first. To do so, grab your Langsmith API key and add it at the top where it says `API KEY (X-API-KEY)`. You should now be able to select any of the API endpoints, click `Test Request`, enter the parameters you would like to pass, and then click `Send` to view the results of the API call. - -## Interact with your deployment via LangGraph Studio - -If you click on your deployment you should see a blue button in the top right that says `LangGraph Studio`. Clicking on this button will take you to a page that looks like this: - -![Studio UI before being run](./deployment/img/graph_visualization.png) - -On this page you can test out your graph by passing in starting states and clicking `Start Run` (this should behave identically to calling `.invoke`). You will then be able to look into the execution thread for each run and explore the steps your graph is taking to produce its output. +On the deployment page for your application,, you should see a button in the top right corner that says `LangGraph Studio`. Clicking on this button will take you to the web version of LangGraph Studio. This is the same UI that you interacted with when [testing the app locally](#using-langgraph-studio-recommended), but instead of using a local LangGraph server, it uses the one from your LangGraph Cloud deployment. ![Studio UI once being run](./deployment/img/graph_run.png) -## Use with the SDK +### Using LangGraph SDK -Once you have tested that your hosted graph works as expected using LangGraph Studio, you can start using your hosted graph all over your organization by using the LangGraph SDK. Let's see how we can access our hosted graph and execute our run from a python file. +You can also interact with your deployed LangGraph application programmatically, using [LangGraph SDK](./reference/sdk/python_sdk_ref.md). -First, make sure you have the SDK installed by calling `pip install langgraph_sdk`. +First, make sure you have the SDK installed: + +=== "Python" + + ```shell + pip install langgraph_sdk + ``` + +=== "Javascript" + + ```shell + yarn add @langchain/langgraph-sdk + ``` Before using, you need to get the URL of your LangGraph deployment. You can find this in the `Deployment` view. Click the URL to copy it to the clipboard. @@ -278,8 +338,8 @@ The first thing to do when using the SDK is to setup our client, access our assi client = get_client(url=) # get default assistant - assistants = await client.assistants.search() - assistant = [a for a in assistants if not a["config"]][0] + assistants = await client.assistants.search(metadata={"created_by": "system"}) + assistant = assistants[0] # create thread thread = await client.threads.create() print(thread) @@ -292,8 +352,8 @@ The first thing to do when using the SDK is to setup our client, access our assi const client = new Client({ apiUrl: }); // get default assistant - const assistants = await client.assistants.search(); - const assistant = assistants.find(a => !a.config); + const assistants = await client.assistants.search({ metadata: {"created_by": "system"} }) + const assistant = assistants[0]; // create thread const thread = await client.threads.create(); console.log(thread) @@ -307,8 +367,9 @@ The first thing to do when using the SDK is to setup our client, access our assi --header 'Content-Type: application/json' \ --data '{ "limit": 10, - "offset": 0 - }' | jq -c 'map(select(.config == null or .config == {})) | .[0]' && \ + "offset": 0, + "metadata": {"created_by": "system"} + }' && curl --request POST \ --url /threads \ --header 'Content-Type: application/json' \ @@ -320,32 +381,35 @@ We can then execute a run on the thread: === "Python" ```python - input = {"messages":[{"role": "user", "content": "Hello! My name is Bagatur and I am 26 years old."}]} + input = { + "messages": [{"role": "user", "content": "What is the weather in NYC?"}] + } async for chunk in client.runs.stream( - thread['thread_id'], - assistant["assistant_id"], - input=input, - stream_mode="updates", - ): - if chunk.data and chunk.event != "metadata": + thread["thread_id"], + assistant["assistant_id"], + input=input, + stream_mode="updates", + ): + if chunk.data: print(chunk.data) ``` === "Javascript" ```js - const input = { "messages":[{ "role": "user", "content": "Hello! My name is Bagatur and I am 26 years old." }] }; + const input = { "messages": [{ "role": "user", "content": "What is the weather in NYC?" }] }; const streamResponse = client.runs.stream( thread["thread_id"], assistant["assistant_id"], { input, + streamMode: "updates" } ); for await (const chunk of streamResponse) { - if (chunk.data && chunk.event !== "metadata" ) { + if (chunk.data) { console.log(chunk.data); } } @@ -357,43 +421,40 @@ We can then execute a run on the thread: curl --request POST \ --url /threads//runs/stream \ --header 'Content-Type: application/json' \ - --data "{ - \"assistant_id\": , - \"input\": {\"messages\": [{\"role\": \"human\", \"content\": \"Hello! My name is Bagatur and I am 26 years old.\"}]}, - }" | sed 's/\r$//' | awk ' - /^event:/ { event = $2 } - /^data:/ { - json_data = substr($0, index($0, $2)) - - if (event != "metadata") { - print json_data - } + --data '{ + "assistant_id": , + "input": { + "messages": [ + { + "role": "user", + "content": "What is the weather in NYC?" + } + ] + }, + "stream_mode": "updates" }' ``` - Output: - {'agent': {'messages': [{'content': "Hi Bagatur! It's nice to meet you. How can I assist you today?", 'additional_kwargs': {}, 'response_metadata': {'finish_reason': 'stop', 'model_name': 'gpt-4o-2024-05-13', 'system_fingerprint': 'fp_9cb5d38cf7'}, 'type': 'ai', 'name': None, 'id': 'run-c89118b7-1b1e-42b9-a85d-c43fe99881cd', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [], 'usage_metadata': None}]}} +``` +... -## What's Next +data: { + "agent": { + "messages": [ + { + "content": "The search results from Tavily provide the current weather conditions in New York City, including temperature, wind speed, precipitation, humidity, and cloud cover. According to the results, as of 3:00pm on October 30th, 2024, it is overcast in NYC with a temperature of around 66°F (19°C), light winds from the southwest around 8 mph (13 km/h), and 66% humidity.\n\nSo in summary, the current weather in NYC is overcast with mild temperatures in the mid 60sF and light winds, based on the search results. Let me know if you need any other details!", + "type": "ai", + ... + } + ] + } +``` + +## Next steps Congratulations! If you've worked your way through this tutorial you are well on your way to becoming a LangGraph Cloud expert. Here are some other resources to check out to help you out on the path to expertise: -### LangGraph Cloud How-tos - -If you want to learn more about streaming from hosted graphs, check out the Streaming [how-to guides](how-tos/index.md#streaming). - -To learn more about double-texting and all the ways you can handle it in your application, read up on these [how-to guides](how-tos/index.md#double-texting). - -To learn about how to include different human-in-the-loop behavior in your graph, take a look at [these how-tos](how-tos/index.md#human-in-the-loop). - -### LangGraph Tutorials - -Before hosting, you have to write a graph to host. Here are some tutorials to get you more comfortable with writing LangGraph graphs and give you inspiration for the types of graphs you want to host. - -[This tutorial](../tutorials/customer-support/customer-support.ipynb) walks you through how to write a customer support bot using LangGraph. - -If you are interested in writing a SQL agent, check out [this tutorial](../tutorials/sql-agent.ipynb). - -Check out the [LangGraph tutorials](../tutorials/index.md) page to read about more exciting use cases. +* [LangGraph How-to guides](../how-tos/index.md) +* [LangGraph Tutorials](../tutorials/index.md) \ No newline at end of file diff --git a/docs/docs/cloud/reference/api/openapi.json b/docs/docs/cloud/reference/api/openapi.json index e2dbb4bdb..02dc13814 100644 --- a/docs/docs/cloud/reference/api/openapi.json +++ b/docs/docs/cloud/reference/api/openapi.json @@ -1,15 +1,43 @@ { "openapi": "3.1.0", "info": { - "title": "LangGraph", + "title": "LangGraph Platform", "version": "0.1.0" }, + "tags": [ + { + "name": "Assistants", + "description": "An assistant is a configured instance of a graph." + }, + { + "name": "Threads", + "description": "A thread contains the accumulated outputs of a group of runs." + }, + { + "name": "Thread Runs", + "description": "A run is an invocation of a graph / assistant on a thread. It updates the state of the thread." + }, + { + "name": "Stateless Runs", + "description": "A run is an invocation of a graph / assistant, with no state or memory persistence." + }, + { + "name": "Crons (Enterprise-only)", + "description": "A cron is a periodic run that recurs on a given schedule. The repeats can be isolated, or share state in a thread" + }, + { + "name": "Store", + "description": "Store is an API for managing persistent key-value store (long-term memory) that is available from any thread." + } + ], "paths": { "/assistants": { "post": { - "tags": ["assistants/create"], + "tags": [ + "Assistants" + ], "summary": "Create Assistant", - "description": "Create an assistant.", + "description": "Create an assistant.\n\nAn initial version of the assistant will be created and the assistant is set to that version. To change versions, use the `POST /assistants/{assistant_id}/latest` endpoint.", "operationId": "create_assistant_assistants_post", "requestBody": { "content": { @@ -23,7 +51,7 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -32,12 +60,22 @@ } } }, + "409": { + "description": "Conflict", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -47,9 +85,11 @@ }, "/assistants/search": { "post": { - "tags": ["assistants/manage"], + "tags": [ + "Assistants" + ], "summary": "Search Assistants", - "description": "List assistants.", + "description": "Search for assistants.\n\nThis endpoint also functions as the endpoint to list all assistants.", "operationId": "search_assistants_assistants_search_post", "requestBody": { "content": { @@ -63,7 +103,7 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -81,7 +121,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -91,7 +131,9 @@ }, "/assistants/{assistant_id}": { "get": { - "tags": ["assistants/manage"], + "tags": [ + "Assistants" + ], "summary": "Get Assistant", "description": "Get an assistant by ID.", "operationId": "get_assistant_assistants__assistant_id__get", @@ -102,7 +144,7 @@ "schema": { "type": "string", "format": "uuid", - "title": "Assistant Id", + "title": "Assistant ID", "description": "The ID of the assistant." }, "name": "assistant_id", @@ -111,7 +153,7 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -120,12 +162,12 @@ } } }, - "422": { - "description": "Validation Error", + "404": { + "description": "Not Found", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -133,9 +175,11 @@ } }, "delete": { - "tags": ["assistants/manage"], + "tags": [ + "Assistants" + ], "summary": "Delete Assistant", - "description": "Delete an assistant by ID.", + "description": "Delete an assistant by ID.\n\nAll versions of the assistant will be deleted as well.", "operationId": "delete_assistant_assistants__assistant_id__delete", "parameters": [ { @@ -144,7 +188,7 @@ "schema": { "type": "string", "format": "uuid", - "title": "Assistant Id", + "title": "Assistant ID", "description": "The ID of the assistant." }, "name": "assistant_id", @@ -153,19 +197,29 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": {} } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -173,7 +227,9 @@ } }, "patch": { - "tags": ["assistants/manage"], + "tags": [ + "Assistants" + ], "summary": "Patch Assistant", "description": "Update an assistant.", "operationId": "patch_assistant_assistants__assistant_id__patch", @@ -184,7 +240,7 @@ "schema": { "type": "string", "format": "uuid", - "title": "Assistant Id", + "title": "Assistant ID", "description": "The ID of the assistant." }, "name": "assistant_id", @@ -203,7 +259,7 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -212,12 +268,22 @@ } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -227,7 +293,9 @@ }, "/assistants/{assistant_id}/graph": { "get": { - "tags": ["assistants/manage"], + "tags": [ + "Assistants" + ], "summary": "Get Assistant Graph", "description": "Get an assistant by ID.", "operationId": "get_assistant_graph_assistants__assistant_id__graph_get", @@ -238,7 +306,7 @@ "schema": { "type": "string", "format": "uuid", - "title": "Assistant Id", + "title": "Assistant ID", "description": "The ID of the assistant." }, "name": "assistant_id", @@ -248,7 +316,14 @@ "description": "Include graph representation of subgraphs. If an integer value is provided, only subgraphs with a depth less than or equal to the value will be included.", "required": false, "schema": { - "oneOf": [{ "type": "boolean" }, { "type": "integer" }], + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "integer" + } + ], "title": "Xray", "default": false, "description": "Include graph representation of subgraphs. If an integer value is provided, only subgraphs with a depth less than or equal to the value will be included." @@ -259,7 +334,7 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -275,12 +350,22 @@ } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -290,7 +375,9 @@ }, "/assistants/{assistant_id}/subgraphs": { "get": { - "tags": ["assistants/manage"], + "tags": [ + "Assistants" + ], "summary": "Get Assistant Subgraphs", "description": "Get an assistant's subgraphs.", "operationId": "get_assistant_subgraphs_assistants__assistant_id__subgraphs_get", @@ -320,7 +407,7 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -329,12 +416,22 @@ } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -344,7 +441,9 @@ }, "/assistants/{assistant_id}/subgraphs/{namespace}": { "get": { - "tags": ["assistants/manage"], + "tags": [ + "Assistants" + ], "summary": "Get Assistant Subgraphs by Namespace", "description": "Get an assistant's subgraphs filtered by namespace.", "operationId": "get_assistant_subgraphs_assistants__assistant_id__subgraphs__namespace__get", @@ -384,7 +483,7 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -398,7 +497,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -408,7 +507,9 @@ }, "/assistants/{assistant_id}/schemas": { "get": { - "tags": ["assistants/manage"], + "tags": [ + "Assistants" + ], "summary": "Get Assistant Schemas", "description": "Get an assistant by ID.", "operationId": "get_assistant_schemas_assistants__assistant_id__schemas_get", @@ -428,7 +529,7 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -437,12 +538,22 @@ } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -452,7 +563,9 @@ }, "/assistants/{assistant_id}/versions": { "post": { - "tags": ["assistants/manage"], + "tags": [ + "Assistants" + ], "summary": "Get Assistant Versions", "description": "Get all versions of an assistant.", "operationId": "get_assistant_versions_assistants__assistant_id__versions_get", @@ -472,7 +585,7 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -490,7 +603,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -498,12 +611,14 @@ } } }, - "/assistants/{assistant_id}/change_version": { + "/assistants/{assistant_id}/latest": { "post": { - "tags": ["assistants/manage"], - "summary": "Change Assistant Version", - "description": "Change the version of an assistant.", - "operationId": "change_assistant_version__assistant_id__change_version__version_post", + "tags": [ + "Assistants" + ], + "summary": "Set Latest Assistant Version", + "description": "Set the latest version for an assistant.", + "operationId": "set_latest_assistant_version_assistants__assistant_id__versions_post", "parameters": [ { "description": "The ID of the assistant.", @@ -531,7 +646,7 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -540,12 +655,22 @@ } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -555,7 +680,9 @@ }, "/threads": { "post": { - "tags": ["threads/create"], + "tags": [ + "Threads" + ], "summary": "Create Thread", "description": "Create a thread.", "operationId": "create_thread_threads_post", @@ -571,7 +698,7 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -580,12 +707,22 @@ } } }, + "409": { + "description": "Conflict", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -595,9 +732,11 @@ }, "/threads/search": { "post": { - "tags": ["threads/manage"], + "tags": [ + "Threads" + ], "summary": "Search Threads", - "description": "List threads.", + "description": "Search for threads.\n\nThis endpoint also functions as the endpoint to list all threads.", "operationId": "search_threads_threads_search_post", "requestBody": { "content": { @@ -611,7 +750,7 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -629,7 +768,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -639,9 +778,11 @@ }, "/threads/{thread_id}/state": { "get": { - "tags": ["threads/state"], - "summary": "Get Latest Thread State", - "description": "Get state for a thread.", + "tags": [ + "Threads" + ], + "summary": "Get Thread State", + "description": "Get state for a thread.\n\nThe latest state of the thread (i.e. latest checkpoint) is returned.", "operationId": "get_latest_thread_state_threads__thread_id__state_get", "parameters": [ { @@ -659,7 +800,7 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -673,7 +814,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -681,7 +822,9 @@ } }, "post": { - "tags": ["threads/state"], + "tags": [ + "Threads" + ], "summary": "Update Thread State", "description": "Add state to a thread.", "operationId": "update_thread_state_threads__thread_id__state_post", @@ -711,7 +854,7 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -725,7 +868,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -735,7 +878,9 @@ }, "/threads/{thread_id}/state/checkpoint": { "post": { - "tags": ["threads/state"], + "tags": [ + "Threads" + ], "summary": "Get Thread State At Checkpoint", "description": "Get state for a thread at a specific checkpoint.", "operationId": "post_thread_state_at_checkpoint_threads__thread_id__state__checkpoint_id__get", @@ -751,7 +896,7 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -765,7 +910,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -775,7 +920,9 @@ }, "/threads/{thread_id}/history": { "get": { - "tags": ["threads/state"], + "tags": [ + "Threads" + ], "summary": "Get Thread History", "description": "Get all past states for a thread.", "operationId": "get_thread_history_threads__thread_id__history_get", @@ -814,7 +961,7 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -832,7 +979,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -840,7 +987,9 @@ } }, "post": { - "tags": ["threads/state"], + "tags": [ + "Threads" + ], "summary": "Get Thread History Post", "description": "Get all past states for a thread.", "operationId": "get_thread_history_post_threads__thread_id__history_post", @@ -870,7 +1019,7 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -888,7 +1037,63 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/threads/{thread_id}/copy": { + "post": { + "tags": [ + "Threads" + ], + "summary": "Copy Thread", + "description": "Create a new thread with a copy of the state and checkpoints from an existing thread.", + "operationId": "copy_thread_post_threads__thread_id__copy_post", + "parameters": [ + { + "description": "The ID of the thread.", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Thread Id", + "description": "The ID of the thread." + }, + "name": "thread_id", + "in": "path" + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Thread" + } + } + } + }, + "409": { + "description": "Conflict", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -898,7 +1103,9 @@ }, "/threads/{thread_id}": { "get": { - "tags": ["threads/manage"], + "tags": [ + "Threads" + ], "summary": "Get Thread", "description": "Get a thread by ID.", "operationId": "get_thread_threads__thread_id__get", @@ -918,7 +1125,7 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -927,12 +1134,22 @@ } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -940,7 +1157,9 @@ } }, "delete": { - "tags": ["threads/manage"], + "tags": [ + "Threads" + ], "summary": "Delete Thread", "description": "Delete a thread by ID.", "operationId": "delete_thread_threads__thread_id__delete", @@ -960,19 +1179,29 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": {} } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -980,7 +1209,9 @@ } }, "patch": { - "tags": ["threads/manage"], + "tags": [ + "Threads" + ], "summary": "Patch Thread", "description": "Update a thread.", "operationId": "patch_thread_threads__thread_id__patch", @@ -1010,7 +1241,7 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -1019,12 +1250,22 @@ } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1034,7 +1275,9 @@ }, "/threads/{thread_id}/runs": { "get": { - "tags": ["runs/manage"], + "tags": [ + "Thread Runs" + ], "summary": "List Runs", "description": "List runs for a thread.", "operationId": "list_runs_http_threads__thread_id__runs_get", @@ -1074,7 +1317,7 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -1086,12 +1329,22 @@ } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1099,9 +1352,11 @@ } }, "post": { - "tags": ["runs/create"], + "tags": [ + "Thread Runs" + ], "summary": "Create Background Run", - "description": "Create a run, return immediately.", + "description": "Create a run in existing thread, return the run ID immediately. Don't wait for the final run output.", "operationId": "create_run_threads__thread_id__runs_post", "parameters": [ { @@ -1129,7 +1384,7 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -1138,12 +1393,32 @@ } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1153,7 +1428,9 @@ }, "/threads/{thread_id}/runs/crons": { "post": { - "tags": ["runs/create"], + "tags": [ + "Crons (Enterprise-only)" + ], "summary": "Create Thread Cron", "description": "Create a cron to schedule runs on a thread.", "operationId": "create_thread_cron_threads__thread_id__runs_crons_post", @@ -1183,7 +1460,7 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -1192,12 +1469,22 @@ } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1207,9 +1494,11 @@ }, "/threads/{thread_id}/runs/stream": { "post": { - "tags": ["runs/create"], - "summary": "Create Streaming Run", - "description": "Create a run, stream the output.", + "tags": [ + "Thread Runs" + ], + "summary": "Create Run, Stream Output", + "description": "Create a run in existing thread. Stream the output.", "operationId": "stream_run_threads__thread_id__runs_stream_post", "parameters": [ { @@ -1237,19 +1526,39 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": {} } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1259,9 +1568,11 @@ }, "/threads/{thread_id}/runs/wait": { "post": { - "tags": ["runs/create"], - "summary": "Create Run and Get Output", - "description": "Create a run, return the final output.", + "tags": [ + "Thread Runs" + ], + "summary": "Create Run, Wait for Output", + "description": "Create a run in existing thread. Wait for the final output and then return it.", "operationId": "wait_run_threads__thread_id__runs_wait_post", "parameters": [ { @@ -1289,19 +1600,39 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": {} } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1311,7 +1642,9 @@ }, "/threads/{thread_id}/runs/{run_id}": { "get": { - "tags": ["runs/manage"], + "tags": [ + "Thread Runs" + ], "summary": "Get Run", "description": "Get a run by ID.", "operationId": "get_run_http_threads__thread_id__runs__run_id__get", @@ -1343,7 +1676,7 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -1352,12 +1685,22 @@ } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1365,7 +1708,9 @@ } }, "delete": { - "tags": ["runs/manage"], + "tags": [ + "Thread Runs" + ], "summary": "Delete Run", "description": "Delete a run by ID.", "operationId": "delete_run_threads__thread_id__runs__run_id__delete", @@ -1397,19 +1742,29 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": {} } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1419,7 +1774,9 @@ }, "/threads/{thread_id}/runs/{run_id}/join": { "get": { - "tags": ["runs/manage"], + "tags": [ + "Thread Runs" + ], "summary": "Join Run", "description": "Wait for a run to finish.", "operationId": "join_run_http_threads__thread_id__runs__run_id__join_get", @@ -1451,19 +1808,29 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": {} } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1473,7 +1840,9 @@ }, "/threads/{thread_id}/runs/{run_id}/stream": { "get": { - "tags": ["runs/manage"], + "tags": [ + "Thread Runs" + ], "summary": "Join Run Stream", "description": "Join a run stream. This endpoint streams output in real-time from a run similar to the /threads/__THREAD_ID__/runs/stream endpoint. Only output produced after this endpoint is called will be streamed.", "operationId": "stream_run_http_threads__thread_id__runs__run_id__join_get", @@ -1505,19 +1874,29 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": {} } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1527,7 +1906,9 @@ }, "/threads/{thread_id}/runs/{run_id}/cancel": { "post": { - "tags": ["runs/manage"], + "tags": [ + "Thread Runs" + ], "summary": "Cancel Run", "operationId": "cancel_run_http_threads__thread_id__runs__run_id__cancel_post", "parameters": [ @@ -1564,23 +1945,48 @@ }, "name": "wait", "in": "query" + }, + { + "description": "Action to take when cancelling the run. Possible values are `interrupt` or `rollback`. `interrupt` will simply cancel the run. `rollback` will cancel the run and delete the run and associated checkpoints afterwards.", + "required": false, + "schema": { + "type": "string", + "enum": [ + "interrupt", + "rollback" + ], + "title": "Action", + "default": "interrupt" + }, + "name": "action", + "in": "query" } ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": {} } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1590,7 +1996,9 @@ }, "/runs/crons": { "post": { - "tags": ["runs/create"], + "tags": [ + "Crons (Enterprise-only)" + ], "summary": "Create Cron", "description": "Create a cron to schedule runs on new threads.", "operationId": "create_cron_runs_crons_post", @@ -1606,7 +2014,7 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -1615,12 +2023,22 @@ } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1630,7 +2048,9 @@ }, "/runs/crons/search": { "post": { - "tags": ["crons/search"], + "tags": [ + "Crons (Enterprise-only)" + ], "summary": "Search Crons", "description": "Search all active crons", "operationId": "search_crons_runs_crons_post", @@ -1646,7 +2066,7 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -1664,7 +2084,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1674,8 +2094,10 @@ }, "/runs/stream": { "post": { - "tags": ["runs/create"], - "summary": "Stream Run in new Thread", + "tags": [ + "Stateless Runs" + ], + "summary": "Create Run, Stream Output", "description": "Create a run in a new thread, stream the output.", "operationId": "stream_run_stateless_runs_stream_post", "requestBody": { @@ -1690,19 +2112,39 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": {} } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1712,9 +2154,11 @@ }, "/runs/wait": { "post": { - "tags": ["runs/create"], - "summary": "Create Run in new Thread and Get Output", - "description": "Create a run in a new thread, return the final output.", + "tags": [ + "Stateless Runs" + ], + "summary": "Create Run, Wait for Output", + "description": "Create a run in a new thread. Wait for the final output and then return it.", "operationId": "wait_run_stateless_runs_wait_post", "requestBody": { "content": { @@ -1728,19 +2172,39 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": {} } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1750,9 +2214,11 @@ }, "/runs": { "post": { - "tags": ["runs/create"], - "summary": "Create Background Run in new Thread", - "description": "Create a run in a new thread, return immediately.", + "tags": [ + "Stateless Runs" + ], + "summary": "Create Background Run", + "description": "Create a run in a new thread, return the run ID immediately. Don't wait for the final run output.", "operationId": "run_stateless_runs_post", "requestBody": { "content": { @@ -1766,19 +2232,39 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": {} } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1788,7 +2274,9 @@ }, "/runs/batch": { "post": { - "tags": ["runs/create"], + "tags": [ + "Stateless Runs" + ], "summary": "Create Run Batch", "description": "Create a batch of runs in new threads, return immediately.", "operationId": "run_batch_stateless_runs_post", @@ -1804,19 +2292,39 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": {} } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1826,7 +2334,9 @@ }, "/runs/crons/{cron_id}": { "delete": { - "tags": ["runs/manage"], + "tags": [ + "Crons (Enterprise-only)" + ], "summary": "Delete Cron", "description": "Delete a cron by ID.", "operationId": "delete_cron_runs_crons__cron_id__delete", @@ -1844,19 +2354,29 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": {} } } }, + "404": { + "description": "Not Found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, "422": { "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -1864,62 +2384,75 @@ } } }, - "/store/items": { "put": { - "tags": ["store/manage"], + "tags": [ + "Store" + ], "summary": "Store or update an item.", "operationId": "put_item", "requestBody": { "required": true, "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/StorePutRequest" } + "schema": { + "$ref": "#/components/schemas/StorePutRequest" + } } } }, "responses": { "204": { - "description": "Successful Response" + "description": "Success" }, "422": { "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } } } } } }, "delete": { - "tags": ["store/manage"], + "tags": [ + "Store" + ], "summary": "Delete an item.", "operationId": "delete_item", "requestBody": { "required": true, "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/StoreDeleteRequest" } + "schema": { + "$ref": "#/components/schemas/StoreDeleteRequest" + } } } }, "responses": { "204": { - "description": "Successful Response" + "description": "Success" }, "422": { "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } } } } } }, "get": { - "tags": ["store/manage"], + "tags": [ + "Store" + ], "summary": "Retrieve a single item.", "operationId": "get_item", "parameters": [ @@ -1945,10 +2478,22 @@ ], "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/Item" } + "schema": { + "$ref": "#/components/schemas/Item" + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } } } }, @@ -1956,7 +2501,9 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } } } } @@ -1965,23 +2512,29 @@ }, "/store/items/search": { "post": { - "tags": ["store/manage"], + "tags": [ + "Store" + ], "summary": "Search for items within a namespace prefix.", "operationId": "search_items", "requestBody": { "required": true, "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/StoreSearchRequest" } + "schema": { + "$ref": "#/components/schemas/StoreSearchRequest" + } } } }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/SearchItemsResponse" } + "schema": { + "$ref": "#/components/schemas/SearchItemsResponse" + } } } }, @@ -1989,7 +2542,9 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } } } } @@ -1998,7 +2553,9 @@ }, "/store/namespaces": { "post": { - "tags": ["store/manage"], + "tags": [ + "Store" + ], "summary": "List namespaces with optional match conditions.", "operationId": "list_namespaces", "requestBody": { @@ -2013,7 +2570,7 @@ }, "responses": { "200": { - "description": "Successful Response", + "description": "Success", "content": { "application/json": { "schema": { @@ -2026,7 +2583,9 @@ "description": "Validation Error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } } } } @@ -2041,11 +2600,13 @@ "assistant_id": { "type": "string", "format": "uuid", - "title": "Assistant Id" + "title": "Assistant Id", + "description": "The ID of the assistant." }, "graph_id": { "type": "string", - "title": "Graph Id" + "title": "Graph Id", + "description": "The ID of the graph." }, "config": { "properties": { @@ -2066,29 +2627,35 @@ } }, "type": "object", - "title": "Config" + "title": "Config", + "description": "The assistant config." }, "created_at": { "type": "string", "format": "date-time", - "title": "Created At" + "title": "Created At", + "description": "The time the assistant was created." }, "updated_at": { "type": "string", "format": "date-time", - "title": "Updated At" + "title": "Updated At", + "description": "The last time the assistant was updated." }, "metadata": { "type": "object", - "title": "Metadata" + "title": "Metadata", + "description": "The assistant metadata." }, "version": { "type": "integer", - "title": "Version" + "title": "Version", + "description": "The version of the assistant" }, "name": { "type": "string", - "title": "Assistant Name" + "title": "Assistant Name", + "description": "The name of the assistant" } }, "type": "object", @@ -2108,26 +2675,43 @@ "type": "string", "format": "uuid", "title": "Assistant Id", - "description": "The ID of the assistant. If not provided, an ID is generated." + "description": "The ID of the assistant. If not provided, a random UUID will be generated." }, "graph_id": { "type": "string", "title": "Graph Id", - "description": "The graph to use." + "description": "The ID of the graph the assistant should use. The graph ID is normally set in your langgraph.json configuration." }, "config": { "type": "object", "title": "Config", - "description": "The assistant config." + "description": "Configuration to use for the graph. Useful when graph is configurable and you want to create different assistants based on different configurations." }, "metadata": { "type": "object", "title": "Metadata", - "description": "Metadata for the assistant." + "description": "Metadata to add to assistant." + }, + "if_exists": { + "type": "string", + "enum": [ + "raise", + "do_nothing" + ], + "title": "If Exists", + "description": "How to handle duplicate creation. Must be either 'raise' (raise error if duplicate), or 'do_nothing' (return existing assistant).", + "default": "raise" + }, + "name": { + "type": "string", + "title": "Name", + "description": "The name of the assistant. Defaults to 'Untitled'." } }, "type": "object", - "required": ["graph_id"], + "required": [ + "graph_id" + ], "title": "AssistantCreate", "description": "Payload for creating an assistant." }, @@ -2136,12 +2720,12 @@ "graph_id": { "type": "string", "title": "Graph Id", - "description": "The graph to use." + "description": "The ID of the graph the assistant should use. The graph ID is normally set in your langgraph.json configuration. If not provided, assistant will keep pointing to same graph." }, "config": { "type": "object", "title": "Config", - "description": "The assistant config." + "description": "Configuration to use for the graph. Useful when graph is configurable and you want to update the assistant's configuration." }, "metadata": { "type": "object", @@ -2150,8 +2734,8 @@ }, "name": { "type": "string", - "title": "Assistant Name", - "description": "The assistant name." + "title": "Name", + "description": "The new name for the assistant. If not provided, assistant will keep its current name." } }, "type": "object", @@ -2196,35 +2780,42 @@ "cron_id": { "type": "string", "format": "uuid", - "title": "Cron Id" + "title": "Cron Id", + "description": "The ID of the cron." }, "thread_id": { "type": "string", "format": "uuid", - "title": "Thread Id" + "title": "Thread Id", + "description": "The ID of the thread." }, "end_time": { "type": "string", "format": "date-time", - "title": "End Time" + "title": "End Time", + "description": "The end date to stop running the cron." }, "schedule": { "type": "string", - "title": "Schedule" + "title": "Schedule", + "description": "The schedule to run, cron format." }, "created_at": { "type": "string", "format": "date-time", - "title": "Created At" + "title": "Created At", + "description": "The time the cron was created." }, "updated_at": { "type": "string", "format": "date-time", - "title": "Updated At" + "title": "Updated At", + "description": "The last time the cron was updated." }, "payload": { "type": "object", - "title": "Payload" + "title": "Payload", + "description": "The run payload to use for creating new run." } }, "type": "object", @@ -2237,19 +2828,21 @@ "updated_at", "payload" ], - "title": "Cron" + "title": "Cron", + "description": "Represents a scheduled task." }, "CronCreate": { "properties": { + "schedule": { + "type": "string", + "title": "Schedule", + "description": "The cron schedule to execute this job on." + }, "assistant_id": { "type": "string", "format": "uuid", "title": "Assistant Id" }, - "checkpoint_id": { - "type": "string", - "title": "Checkpoint Id" - }, "input": { "anyOf": [ { @@ -2262,12 +2855,13 @@ "type": "object" } ], - "title": "Input" + "title": "Input", + "description": "The input to the graph." }, "metadata": { "type": "object", "title": "Metadata", - "description": "Metadata for the run." + "description": "Metadata to assign to the cron job runs." }, "config": { "properties": { @@ -2288,20 +2882,24 @@ } }, "type": "object", - "title": "Config" + "title": "Config", + "description": "The configuration for the assistant." }, "webhook": { "type": "string", "maxLength": 65536, "minLength": 1, "format": "uri", - "title": "Webhook" + "title": "Webhook", + "description": "Webhook to call after LangGraph API call is done." }, "interrupt_before": { "anyOf": [ { "type": "string", - "enum": ["*"] + "enum": [ + "*" + ] }, { "items": { @@ -2310,13 +2908,16 @@ "type": "array" } ], - "title": "Interrupt Before" + "title": "Interrupt Before", + "description": "Nodes to interrupt immediately before they get executed." }, "interrupt_after": { "anyOf": [ { "type": "string", - "enum": ["*"] + "enum": [ + "*" + ] }, { "items": { @@ -2325,36 +2926,48 @@ "type": "array" } ], - "title": "Interrupt After" + "title": "Interrupt After", + "description": "Nodes to interrupt immediately after they get executed." }, "multitask_strategy": { "type": "string", - "enum": ["reject", "rollback", "interrupt", "enqueue"], + "enum": [ + "reject", + "rollback", + "interrupt", + "enqueue" + ], "title": "Multitask Strategy", + "description": "Multitask strategy to use. Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.", "default": "reject" } }, "type": "object", - "required": ["assistant_id", "schedule"], + "required": [ + "assistant_id", + "schedule" + ], "title": "CronCreate", - "description": "Payload for creating a cron." + "description": "Payload for creating a cron job." }, "CronSearch": { "properties": { "assistant_id": { "type": "string", "format": "uuid", - "title": "Assistant Id" + "title": "Assistant Id", + "description": "The assistant ID or graph name to search for." }, "thread_id": { "type": "string", "format": "uuid", - "title": "Thread Id" + "title": "Thread Id", + "description": "The thread ID to search for." }, "limit": { "type": "integer", "title": "Limit", - "description": "Maximum number to return.", + "description": "The maximum number of results to return.", "default": 10, "minimum": 1, "maximum": 1000 @@ -2362,7 +2975,7 @@ "offset": { "type": "integer", "title": "Offset", - "description": "Offset to start from.", + "description": "The number of results to skip.", "default": 0, "minimum": 0 } @@ -2376,51 +2989,71 @@ "properties": { "graph_id": { "type": "string", - "title": "Graph Id" + "title": "Graph Id", + "description": "The ID of the graph." }, "input_schema": { "type": "object", - "title": "Input Schema" + "title": "Input Schema", + "description": "The schema for the graph input. Missing if unable to generate JSON schema from graph." }, "output_schema": { "type": "object", - "title": "Input Schema" + "title": "Output Schema", + "description": "The schema for the graph output. Missing if unable to generate JSON schema from graph." }, "state_schema": { "type": "object", - "title": "State Schema" + "title": "State Schema", + "description": "The schema for the graph state. Missing if unable to generate JSON schema from graph." }, "config_schema": { "type": "object", - "title": "Config Schema" + "title": "Config Schema", + "description": "The schema for the graph config. Missing if unable to generate JSON schema from graph." } }, "type": "object", - "required": ["graph_id", "state_schema", "config_schema"], - "title": "GraphSchema" + "required": [ + "graph_id", + "state_schema", + "config_schema" + ], + "title": "GraphSchema", + "description": "Defines the structure and properties of a graph." }, "GraphSchemaNoId": { "properties": { "input_schema": { "type": "object", - "title": "Input Schema" + "title": "Input Schema", + "description": "The schema for the graph input. Missing if unable to generate JSON schema from graph." }, "output_schema": { "type": "object", - "title": "Input Schema" + "title": "Output Schema", + "description": "The schema for the graph output. Missing if unable to generate JSON schema from graph." }, "state_schema": { "type": "object", - "title": "State Schema" + "title": "State Schema", + "description": "The schema for the graph state. Missing if unable to generate JSON schema from graph." }, "config_schema": { "type": "object", - "title": "Config Schema" + "title": "Config Schema", + "description": "The schema for the graph config. Missing if unable to generate JSON schema from graph." } }, "type": "object", - "required": ["input_schema", "output_schema", "state_schema", "config_schema"], - "title": "GraphSchemaNoId" + "required": [ + "input_schema", + "output_schema", + "state_schema", + "config_schema" + ], + "title": "GraphSchemaNoId", + "description": "Defines the structure and properties of a graph without an ID." }, "Subgraphs": { "type": "object", @@ -2430,54 +3063,54 @@ "title": "Subgraphs", "description": "Map of graph name to graph schema metadata (`input_schema`, `output_schema`, `state_schema`, `config_schema`)." }, - "HTTPValidationError": { - "properties": { - "detail": { - "items": { - "$ref": "#/components/schemas/ValidationError" - }, - "type": "array", - "title": "Detail" - } - }, - "type": "object", - "title": "HTTPValidationError" - }, "Run": { "properties": { "run_id": { "type": "string", "format": "uuid", - "title": "Run Id" + "title": "Run Id", + "description": "The ID of the run." }, "thread_id": { "type": "string", "format": "uuid", - "title": "Thread Id" + "title": "Thread Id", + "description": "The ID of the thread." }, "assistant_id": { "type": "string", "format": "uuid", - "title": "Assistant Id" + "title": "Assistant Id", + "description": "The assistant that was used for this run." }, "created_at": { "type": "string", "format": "date-time", - "title": "Created At" + "title": "Created At", + "description": "The time the run was created." }, "updated_at": { "type": "string", "format": "date-time", - "title": "Updated At" + "title": "Updated At", + "description": "The last time the run was updated." }, "status": { "type": "string", - "enum": ["pending", "error", "success", "timeout", "interrupted"], - "title": "Status" + "enum": [ + "pending", + "error", + "success", + "timeout", + "interrupted" + ], + "title": "Status", + "description": "The status of the run. One of 'pending', 'error', 'success', 'timeout', 'interrupted'." }, "metadata": { "type": "object", - "title": "Metadata" + "title": "Metadata", + "description": "The run metadata." }, "kwargs": { "type": "object", @@ -2485,8 +3118,14 @@ }, "multitask_strategy": { "type": "string", - "enum": ["reject", "rollback", "interrupt", "enqueue"], - "title": "Multitask Strategy" + "enum": [ + "reject", + "rollback", + "interrupt", + "enqueue" + ], + "title": "Multitask Strategy", + "description": "Strategy to handle concurrent runs on the same thread." } }, "type": "object", @@ -2516,11 +3155,14 @@ "type": "string", "title": "Graph Id" } - ] + ], + "description": "The assistant ID or graph name to run. If using graph name, will default to first assistant created from that graph." }, - "checkpoint_id": { - "type": "string", - "title": "Checkpoint Id" + "checkpoint": { + "type": "object", + "title": "Checkpoint", + "description": "The checkpoint to resume from.", + "$ref": "#/components/schemas/CheckpointConfig" }, "input": { "anyOf": [ @@ -2537,12 +3179,13 @@ "type": "null" } ], - "title": "Input" + "title": "Input", + "description": "The input to the graph." }, "metadata": { "type": "object", "title": "Metadata", - "description": "Metadata for the run." + "description": "Metadata to assign to the run." }, "config": { "properties": { @@ -2563,20 +3206,24 @@ } }, "type": "object", - "title": "Config" + "title": "Config", + "description": "The configuration for the assistant." }, "webhook": { "type": "string", "maxLength": 65536, "minLength": 1, "format": "uri", - "title": "Webhook" + "title": "Webhook", + "description": "Webhook to call after LangGraph API call is done." }, "interrupt_before": { "anyOf": [ { "type": "string", - "enum": ["*"] + "enum": [ + "*" + ] }, { "items": { @@ -2585,13 +3232,16 @@ "type": "array" } ], - "title": "Interrupt Before" + "title": "Interrupt Before", + "description": "Nodes to interrupt immediately before they get executed." }, "interrupt_after": { "anyOf": [ { "type": "string", - "enum": ["*"] + "enum": [ + "*" + ] }, { "items": { @@ -2600,7 +3250,8 @@ "type": "array" } ], - "title": "Interrupt After" + "title": "Interrupt After", + "description": "Nodes to interrupt immediately after they get executed." }, "stream_mode": { "anyOf": [ @@ -2610,6 +3261,7 @@ "enum": [ "values", "messages", + "messages-tuple", "updates", "events", "debug", @@ -2623,6 +3275,7 @@ "enum": [ "values", "messages", + "messages-tuple", "updates", "events", "debug", @@ -2631,12 +3284,25 @@ } ], "title": "Stream Mode", - "default": ["values"] + "description": "The stream mode(s) to use.", + "default": [ + "values" + ] + }, + "stream_subgraphs": { + "type": "boolean", + "title": "Stream Subgraphs", + "description": "Whether to stream output from subgraphs.", + "default": false }, "on_disconnect": { "type": "string", - "enum": ["cancel", "continue"], + "enum": [ + "cancel", + "continue" + ], "title": "On Disconnect", + "description": "The disconnect mode to use. Must be one of 'cancel' or 'continue'.", "default": "cancel" }, "feedback_keys": { @@ -2644,22 +3310,41 @@ "type": "string" }, "type": "array", - "title": "Feedback Keys" + "title": "Feedback Keys", + "description": "Feedback keys to assign to run." }, "multitask_strategy": { "type": "string", - "enum": ["reject", "rollback", "interrupt", "enqueue"], + "enum": [ + "reject", + "rollback", + "interrupt", + "enqueue" + ], "title": "Multitask Strategy", + "description": "Multitask strategy to use. Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.", + "default": "reject" + }, + "if_not_exists": { + "type": "string", + "enum": [ + "create", + "reject" + ], + "title": "If Not Exists", + "description": "How to handle missing thread. Must be either 'reject' (raise error if missing), or 'create' (create new thread).", "default": "reject" }, "after_seconds": { "type": "integer", "title": "After Seconds", - "description": "Number of seconds to wait before starting the run." + "description": "The number of seconds to wait before starting the run. Use to schedule future runs." } }, "type": "object", - "required": ["assistant_id"], + "required": [ + "assistant_id" + ], "title": "RunCreateStateful", "description": "Payload for creating a run." }, @@ -2685,7 +3370,8 @@ "type": "string", "title": "Graph Id" } - ] + ], + "description": "The assistant ID or graph name to run. If using graph name, will default to first assistant created from that graph." }, "input": { "anyOf": [ @@ -2702,12 +3388,13 @@ "type": "null" } ], - "title": "Input" + "title": "Input", + "description": "The input to the graph." }, "metadata": { "type": "object", "title": "Metadata", - "description": "Metadata for the run." + "description": "Metadata to assign to the run." }, "config": { "properties": { @@ -2728,20 +3415,24 @@ } }, "type": "object", - "title": "Config" + "title": "Config", + "description": "The configuration for the assistant." }, "webhook": { "type": "string", "maxLength": 65536, "minLength": 1, "format": "uri", - "title": "Webhook" + "title": "Webhook", + "description": "Webhook to call after LangGraph API call is done." }, "interrupt_before": { "anyOf": [ { "type": "string", - "enum": ["*"] + "enum": [ + "*" + ] }, { "items": { @@ -2750,13 +3441,16 @@ "type": "array" } ], - "title": "Interrupt Before" + "title": "Interrupt Before", + "description": "Nodes to interrupt immediately before they get executed." }, "interrupt_after": { "anyOf": [ { "type": "string", - "enum": ["*"] + "enum": [ + "*" + ] }, { "items": { @@ -2765,7 +3459,8 @@ "type": "array" } ], - "title": "Interrupt After" + "title": "Interrupt After", + "description": "Nodes to interrupt immediately after they get executed." }, "stream_mode": { "anyOf": [ @@ -2775,6 +3470,7 @@ "enum": [ "values", "messages", + "messages-tuple", "updates", "events", "debug", @@ -2788,6 +3484,7 @@ "enum": [ "values", "messages", + "messages-tuple", "updates", "events", "debug", @@ -2796,81 +3493,74 @@ } ], "title": "Stream Mode", - "default": ["values"] + "description": "The stream mode(s) to use.", + "default": [ + "values" + ] }, "feedback_keys": { "items": { "type": "string" }, "type": "array", - "title": "Feedback Keys" + "title": "Feedback Keys", + "description": "Feedback keys to assign to run." + }, + "stream_subgraphs": { + "type": "boolean", + "title": "Stream Subgraphs", + "description": "Whether to stream output from subgraphs.", + "default": false }, "on_completion": { "type": "string", - "enum": ["delete", "keep"], + "enum": [ + "delete", + "keep" + ], "title": "On Completion", + "description": "Whether to delete or keep the thread created for a stateless run. Must be one of 'delete' or 'keep'.", "default": "delete" }, "on_disconnect": { "type": "string", - "enum": ["cancel", "continue"], + "enum": [ + "cancel", + "continue" + ], "title": "On Disconnect", + "description": "The disconnect mode to use. Must be one of 'cancel' or 'continue'.", "default": "cancel" }, "after_seconds": { "type": "integer", "title": "After Seconds", - "description": "Number of seconds to wait before starting the run." + "description": "The number of seconds to wait before starting the run. Use to schedule future runs." } }, "type": "object", - "required": ["assistant_id"], + "required": [ + "assistant_id" + ], "title": "RunCreateStateless", - "description": "Payload for creating a streaming run." - }, - "SearchRequest": { - "properties": { - "metadata": { - "type": "object", - "title": "Metadata", - "description": "Metadata to search for." - }, - "limit": { - "type": "integer", - "title": "Limit", - "description": "Maximum number to return.", - "default": 10, - "minimum": 1, - "maximum": 1000 - }, - "offset": { - "type": "integer", - "title": "Offset", - "description": "Offset to start from.", - "default": 0, - "minimum": 0 - } - }, - "type": "object", - "title": "SearchRequest", - "description": "Payload for listing runs." + "description": "Payload for creating a run." }, "AssistantSearchRequest": { "properties": { "metadata": { "type": "object", "title": "Metadata", - "description": "Metadata to search for." + "description": "Metadata to filter by. Exact match filter for each KV pair." }, "graph_id": { "type": "string", "title": "Graph Id", - "description": "Filter by graph ID." + "description": "The ID of the graph to filter by. The graph ID is normally set in your langgraph.json configuration." }, "limit": { "type": "integer", "title": "Limit", - "description": "Maximum number to return.", + "description": "The maximum number of results to return.", "default": 10, "minimum": 1, "maximum": 1000 @@ -2878,13 +3568,13 @@ "offset": { "type": "integer", "title": "Offset", - "description": "Offset to start from.", + "description": "The number of results to skip.", "default": 0, "minimum": 0 } }, "type": "object", - "title": "SearchRequest", + "title": "AssistantSearchRequest", "description": "Payload for listing assistants." }, "AssistantVersionsSearchRequest": { @@ -2892,12 +3582,12 @@ "metadata": { "type": "object", "title": "Metadata", - "description": "Metadata to search for." + "description": "Metadata to filter versions by. Exact match filter for each KV pair." }, "limit": { "type": "integer", "title": "Limit", - "description": "Maximum number to return.", + "description": "The maximum number of versions to return.", "default": 10, "minimum": 1, "maximum": 1000 @@ -2905,7 +3595,7 @@ "offset": { "type": "integer", "title": "Offset", - "description": "Offset to start from.", + "description": "The number of versions to skip.", "default": 0, "minimum": 0 } @@ -2919,7 +3609,7 @@ "metadata": { "type": "object", "title": "Metadata", - "description": "Metadata to filter on." + "description": "Thread metadata to filter on." }, "values": { "type": "object", @@ -2928,9 +3618,14 @@ }, "status": { "type": "string", - "enum": ["idle", "busy", "interrupted", "error"], + "enum": [ + "idle", + "busy", + "interrupted", + "error" + ], "title": "Status", - "description": "Filter by thread status." + "description": "Thread status to filter on." }, "limit": { "type": "integer", @@ -2949,7 +3644,7 @@ } }, "type": "object", - "title": "SearchRequest", + "title": "ThreadSearchRequest", "description": "Payload for listing threads." }, "Thread": { @@ -2957,30 +3652,41 @@ "thread_id": { "type": "string", "format": "uuid", - "title": "Thread Id" + "title": "Thread Id", + "description": "The ID of the thread." }, "created_at": { "type": "string", "format": "date-time", - "title": "Created At" + "title": "Created At", + "description": "The time the thread was created." }, "updated_at": { "type": "string", "format": "date-time", - "title": "Updated At" + "title": "Updated At", + "description": "The last time the thread was updated." }, "metadata": { "type": "object", - "title": "Metadata" + "title": "Metadata", + "description": "The thread metadata." }, "status": { "type": "string", - "enum": ["idle", "busy", "interrupted", "error"], - "title": "Status" + "enum": [ + "idle", + "busy", + "interrupted", + "error" + ], + "title": "Status", + "description": "The status of the thread." }, "values": { "type": "object", - "title": "Values" + "title": "Values", + "description": "The current state of the thread." } }, "type": "object", @@ -2999,12 +3705,22 @@ "type": "string", "format": "uuid", "title": "Thread Id", - "description": "The ID of the thread. If not provided, an ID is generated." + "description": "The ID of the thread. If not provided, a random UUID will be generated." }, "metadata": { "type": "object", "title": "Metadata", - "description": "Metadata for the thread." + "description": "Metadata to add to thread." + }, + "if_exists": { + "type": "string", + "enum": [ + "raise", + "do_nothing" + ], + "title": "If Exists", + "description": "How to handle duplicate creation. Must be either 'raise' (raise error if duplicate), or 'do_nothing' (return existing thread).", + "default": "raise" } }, "type": "object", @@ -3026,7 +3742,7 @@ "ThreadStateCheckpointRequest": { "properties": { "checkpoint": { - "type": "object", + "$ref": "#/components/schemas/CheckpointConfig", "title": "Checkpoint", "description": "The checkpoint to get the state for." }, @@ -3036,7 +3752,9 @@ "description": "Include subgraph states." } }, - "required": ["checkpoint"], + "required": [ + "checkpoint" + ], "type": "object", "title": "ThreadStateCheckpointRequest", "description": "Payload for getting the state of a thread at a checkpoint." @@ -3085,20 +3803,23 @@ "items": {} }, "checkpoint": { - "type": "object", + "$ref": "#/components/schemas/CheckpointConfig", "title": "Checkpoint" }, "state": { "$ref": "#/components/schemas/ThreadState" } }, - "required": ["id", "name"] + "required": [ + "id", + "name" + ] }, "type": "array", "title": "Tasks" }, "checkpoint": { - "type": "object", + "$ref": "#/components/schemas/CheckpointConfig", "title": "Checkpoint" }, "metadata": { @@ -3115,7 +3836,13 @@ } }, "type": "object", - "required": ["values", "next", "checkpoint", "metadata", "created_at"], + "required": [ + "values", + "next", + "checkpoint", + "metadata", + "created_at" + ], "title": "ThreadState" }, "ThreadStateSearch": { @@ -3130,15 +3857,8 @@ }, "before": { "title": "Before", - "description": "Return states before this checkpoint ID.", - "anyOf": [ - { - "type": "string" - }, - { - "type": "object" - } - ] + "description": "Return states before this checkpoint.", + "$ref": "#/components/schemas/CheckpointConfig" }, "metadata": { "type": "object", @@ -3146,7 +3866,7 @@ "description": "Filter states by metadata key-value pairs." }, "checkpoint": { - "type": "object", + "$ref": "#/components/schemas/CheckpointConfig", "title": "Checkpoint", "description": "Return states for this subgraph." } @@ -3171,20 +3891,23 @@ "type": "null" } ], - "title": "Values" + "title": "Values", + "description": "The values to update the state with." }, "checkpoint": { - "type": "object", - "title": "Checkpoint" + "$ref": "#/components/schemas/CheckpointConfig", + "title": "Checkpoint", + "description": "The checkpoint to update the state of." }, "as_node": { "type": "string", - "title": "As Node" + "title": "As Node", + "description": "Update the state as if this node had just executed." } }, "type": "object", "title": "ThreadStateUpdate", - "description": "Payload for adding state to a thread." + "description": "Payload for updating the state of a thread." }, "ThreadStateUpdateResponse": { "properties": { @@ -3197,87 +3920,208 @@ "title": "ThreadStateUpdateResponse", "description": "Response for adding state to a thread." }, + "CheckpointConfig": { + "type": "object", + "title": "CheckpointConfig", + "description": "Checkpoint config.", + "properties": { + "thread_id": { + "type": "string", + "description": "Unique identifier for the thread associated with this checkpoint." + }, + "checkpoint_ns": { + "type": "string", + "description": "Namespace for the checkpoint, used for organization and retrieval." + }, + "checkpoint_id": { + "type": "string", + "description": "Optional unique identifier for the checkpoint itself." + }, + "checkpoint_map": { + "type": "object", + "description": "Optional dictionary containing checkpoint-specific data." + } + } + }, "StorePutRequest": { "type": "object", - "required": ["namespace", "key", "value"], + "required": [ + "namespace", + "key", + "value" + ], "properties": { "namespace": { "type": "array", - "items": { "type": "string" } + "items": { + "type": "string" + }, + "title": "Namespace", + "description": "A list of strings representing the namespace path." }, - "key": { "type": "string" }, - "value": { "type": "object" } - } + "key": { + "type": "string", + "title": "Key", + "description": "The unique identifier for the item within the namespace." + }, + "value": { + "type": "object", + "title": "Value", + "description": "A dictionary containing the item's data." + } + }, + "title": "StorePutRequest", + "description": "Request to store or update an item." }, "StoreDeleteRequest": { "type": "object", - "required": ["key"], + "required": [ + "key" + ], "properties": { "namespace": { "type": "array", - "items": { "type": "string" } + "items": { + "type": "string" + }, + "title": "Namespace", + "description": "A list of strings representing the namespace path." }, - "key": { "type": "string" } - } + "key": { + "type": "string", + "title": "Key", + "description": "The unique identifier for the item." + } + }, + "title": "StoreDeleteRequest", + "description": "Request to delete an item." }, "StoreSearchRequest": { "type": "object", "properties": { "namespace_prefix": { - "type": ["array", "null"], - "items": { "type": "string" } + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "title": "Namespace Prefix", + "description": "List of strings representing the namespace prefix." }, "filter": { - "type": ["object", "null"], - "additionalProperties": true + "type": [ + "object", + "null" + ], + "additionalProperties": true, + "title": "Filter", + "description": "Optional dictionary of key-value pairs to filter results." }, - "limit": { "type": "integer", "default": 10 }, - "offset": { "type": "integer", "default": 0 } - } + "limit": { + "type": "integer", + "default": 10, + "title": "Limit", + "description": "Maximum number of items to return (default is 10)." + }, + "offset": { + "type": "integer", + "default": 0, + "title": "Offset", + "description": "Number of items to skip before returning results (default is 0)." + } + }, + "title": "StoreSearchRequest", + "description": "Request to search for items within a namespace prefix." }, "StoreListNamespacesRequest": { "type": "object", "properties": { "prefix": { "type": "array", - "items": { "type": "string" } + "items": { + "type": "string" + }, + "title": "Prefix", + "description": "Optional list of strings representing the prefix to filter namespaces." }, "suffix": { "type": "array", - "items": { "type": "string" } + "items": { + "type": "string" + }, + "title": "Suffix", + "description": "Optional list of strings representing the suffix to filter namespaces." }, - "max_depth": { "type": "integer" }, - "limit": { "type": "integer", "default": 100 }, - "offset": { "type": "integer", "default": 0 } + "max_depth": { + "type": "integer", + "title": "Max Depth", + "description": "Optional integer specifying the maximum depth of namespaces to return." + }, + "limit": { + "type": "integer", + "default": 100, + "title": "Limit", + "description": "Maximum number of namespaces to return (default is 100)." + }, + "offset": { + "type": "integer", + "default": 0, + "title": "Offset", + "description": "Number of namespaces to skip before returning results (default is 0)." + } } }, "Item": { "type": "object", - "required": ["namespace", "key", "value", "created_at", "updated_at"], + "required": [ + "namespace", + "key", + "value", + "created_at", + "updated_at" + ], "properties": { "namespace": { "type": "array", - "items": { "type": "string" } + "items": { + "type": "string" + }, + "description": "The namespace of the item. A namespace is analogous to a document's directory." + }, + "key": { + "type": "string", + "description": "The unique identifier of the item within its namespace. In general, keys needn't be globally unique." + }, + "value": { + "type": "object", + "description": "The value stored in the item. This is the document itself." }, - "key": { "type": "string" }, - "value": { "type": "object" }, "created_at": { "type": "string", - "format": "date-time" + "format": "date-time", + "description": "The timestamp when the item was created." }, "updated_at": { "type": "string", - "format": "date-time" + "format": "date-time", + "description": "The timestamp when the item was last updated." } - } + }, + "description": "Represents a single document or data entry in the graph's Store. Items are used to store cross-thread memories." }, "SearchItemsResponse": { "type": "object", - "required": ["items"], + "required": [ + "items" + ], "properties": { "items": { "type": "array", - "items": { "$ref": "#/components/schemas/Item" } + "items": { + "$ref": "#/components/schemas/Item" + } } } }, @@ -3285,15 +4129,15 @@ "type": "array", "items": { "type": "array", - "items": { "type": "string" } + "items": { + "type": "string" + } } }, "ErrorResponse": { - "type": "object", - "properties": { - "error": { "type": "string" }, - "message": { "type": "string" } - } + "type": "string", + "title": "ErrorResponse", + "description": "Error message returned from the server" } }, "responses": { @@ -3301,7 +4145,9 @@ "description": "Successful retrieval of an item.", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/Item" } + "schema": { + "$ref": "#/components/schemas/Item" + } } } }, @@ -3317,7 +4163,9 @@ "description": "Successful search operation.", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/SearchItemsResponse" } + "schema": { + "$ref": "#/components/schemas/SearchItemsResponse" + } } } }, @@ -3325,7 +4173,9 @@ "description": "Successful retrieval of namespaces.", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ListNamespaceResponse" } + "schema": { + "$ref": "#/components/schemas/ListNamespaceResponse" + } } } }, @@ -3333,38 +4183,11 @@ "description": "An error occurred.", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ErrorResponse" } + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } } } - }, - "ValidationError": { - "properties": { - "loc": { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array", - "title": "Location" - }, - "msg": { - "type": "string", - "title": "Message" - }, - "type": { - "type": "string", - "title": "Error Type" - } - }, - "type": "object", - "required": ["loc", "msg", "type"], - "title": "ValidationError" } } } diff --git a/docs/docs/cloud/reference/cli.md b/docs/docs/cloud/reference/cli.md index ee481ea20..2964d3c8c 100644 --- a/docs/docs/cloud/reference/cli.md +++ b/docs/docs/cloud/reference/cli.md @@ -1,23 +1,38 @@ # LangGraph CLI -The LangGraph CLI includes commands to build and run a LangGraph Cloud API server locally in [Docker](https://www.docker.com/). For development and testing, use the CLI to deploy a local API server. + +The LangGraph command line interface includes commands to build and run a LangGraph Cloud API server locally in [Docker](https://www.docker.com/). For development and testing, you can use the CLI to deploy a local API server as an alternative to the [Studio desktop app](../../concepts/langgraph_studio.md). ## Installation + 1. Ensure that Docker is installed (e.g. `docker --version`). -2. Install the `langgraph-cli` Python package (e.g. `pip install langgraph-cli`). +2. Install the `langgraph-cli` package: + + === "pip" + ```bash + pip install langgraph-cli + ``` + + === "Homebrew (MacOS only)" + ```bash + brew install langgraph-cli + ``` + 3. Run the command `langgraph --help` to confirm that the CLI is installed. [](){#langgraph.json} + ## Configuration File + The LangGraph CLI requires a JSON configuration file with the following keys: -| Key | Description | -| --- | ----------- | -| `dependencies` | **Required**. Array of dependencies for LangGraph Cloud API server. Dependencies can be one of the following: (1) `"."`, which will look for local Python packages, (2) `pyproject.toml`, `setup.py` or `requirements.txt` in the app directory `"./local_package"`, or (3) a package name. | -| `graphs` | **Required**. Mapping from graph ID to path where the compiled graph or a function that makes a graph is defined. Example:
  • `./your_package/your_file.py:variable`, where `variable` is an instance of `langgraph.graph.state.CompiledStateGraph`
  • `./your_package/your_file.py:make_graph`, where `make_graph` is a function that takes a config dictionary (`langchain_core.runnables.RunnableConfig`) and creates an instance of `langgraph.graph.state.StateGraph` / `langgraph.graph.state.CompiledStateGraph`.
| -| `env` | Path to `.env` file or a mapping from environment variable to its value. | -| `python_version` | `3.11` or `3.12`. Defaults to `3.11`. | -| `pip_config_file`| Path to `pip` config file. | -| `dockerfile_lines` | Array of additional lines to add to Dockerfile following the import from parent image. | +| Key | Description | +|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `dependencies` | **Required**. Array of dependencies for LangGraph Cloud API server. Dependencies can be one of the following: (1) `"."`, which will look for local Python packages, (2) `pyproject.toml`, `setup.py` or `requirements.txt` in the app directory `"./local_package"`, or (3) a package name. | +| `graphs` | **Required**. Mapping from graph ID to path where the compiled graph or a function that makes a graph is defined. Example:
  • `./your_package/your_file.py:variable`, where `variable` is an instance of `langgraph.graph.state.CompiledStateGraph`
  • `./your_package/your_file.py:make_graph`, where `make_graph` is a function that takes a config dictionary (`langchain_core.runnables.RunnableConfig`) and creates an instance of `langgraph.graph.state.StateGraph` / `langgraph.graph.state.CompiledStateGraph`.
| +| `env` | Path to `.env` file or a mapping from environment variable to its value. | +| `python_version` | `3.11` or `3.12`. Defaults to `3.11`. | +| `pip_config_file` | Path to `pip` config file. | +| `dockerfile_lines` | Array of additional lines to add to Dockerfile following the import from parent image. |

Note

@@ -27,101 +42,134 @@ The LangGraph CLI requires a JSON configuration file with the following keys:
Example: + ```json { - "dependencies": [ - "langchain_openai", - "./your_package" - ], - "graphs": { - "my_graph_id": "./your_package/your_file.py:variable" - }, - "env": "./.env" + "dependencies": ["langchain_openai", "./your_package"], + "graphs": { + "my_graph_id": "./your_package/your_file.py:variable" + }, + "env": "./.env" } ``` Example: + ```json { - "python_version": "3.11", - "dependencies": [ - "langchain_openai", - "." - ], - "graphs": { - "my_graph_id": "./your_package/your_file.py:make_graph" - }, - "env": { - "OPENAI_API_KEY": "secret-key" - } + "python_version": "3.11", + "dependencies": ["langchain_openai", "."], + "graphs": { + "my_graph_id": "./your_package/your_file.py:make_graph" + }, + "env": { + "OPENAI_API_KEY": "secret-key" + } } ``` ## Commands + The base command for the LangGraph CLI is `langgraph`. **Usage** + ``` langgraph [OPTIONS] COMMAND [ARGS] ``` ### `build` + Build LangGraph Cloud API server Docker image. **Usage** + ``` langgraph build [OPTIONS] ``` **Options** -| Option | Default | Description | -| ------ | ------- | ----------- | -| `--platform TEXT` | | Target platform(s) to build the Docker image for. Example: `langgraph build --platform linux/amd64,linux/arm64` | -| `-t, --tag TEXT` | | **Required**. Tag for the Docker image. Example: `langgraph build -t my-image` | -| `--pull / --no-pull` | `--pull` | Build with latest remote Docker image. Use `--no-pull` for running the LangGraph Cloud API server with locally built images. | -| `-c, --config FILE` | `langgraph.json` | Path to configuration file declaring dependencies, graphs and environment variables. | -| `--help` | | Display command documentation. | +| Option | Default | Description | +|----------------------|------------------|------------------------------------------------------------------------------------------------------------------------------| +| `--platform TEXT` | | Target platform(s) to build the Docker image for. Example: `langgraph build --platform linux/amd64,linux/arm64` | +| `-t, --tag TEXT` | | **Required**. Tag for the Docker image. Example: `langgraph build -t my-image` | +| `--pull / --no-pull` | `--pull` | Build with latest remote Docker image. Use `--no-pull` for running the LangGraph Cloud API server with locally built images. | +| `-c, --config FILE` | `langgraph.json` | Path to configuration file declaring dependencies, graphs and environment variables. | +| `--help` | | Display command documentation. | ### `up` + Start langgraph API server. For local testing, requires a LangSmith API key with access to LangGraph Cloud closed beta. Requires a license key for production use. **Usage** + ``` langgraph up [OPTIONS] ``` **Options** -| Option | Default | Description | -| ------ | ------- | ----------- | -| `--wait` | | Wait for services to start before returning. Implies --detach | -| `--postgres-uri TEXT` | Local database | Postgres URI to use for the database. | -| `--watch` | | Restart on file changes | -| `--debugger-base-url TEXT` | `http://127.0.0.1:[PORT]` | URL used by the debugger to access LangGraph API. | -| `--debugger-port INTEGER` | | Pull the debugger image locally and serve the UI on specified port | -| `--verbose` | | Show more output from the server logs. | -| `-c, --config FILE` | `langgraph.json` | Path to configuration file declaring dependencies, graphs and environment variables. | -| `-d, --docker-compose FILE` | | Path to docker-compose.yml file with additional services to launch. | -| `-p, --port INTEGER` | `8123` | Port to expose. Example: `langgraph test --port 8000` | -| `--pull / --no-pull` | `pull` | Pull latest images. Use --no-pull for running the server with locally-built images. Example: `langgraph up --no-pull` | -| `--recreate / --no-recreate` | `no-recreate` | Recreate containers even if their configuration and image haven't changed | -| `--help` | | Display command documentation. | +| Option | Default | Description | +|------------------------------|---------------------------|-----------------------------------------------------------------------------------------------------------------------| +| `--wait` | | Wait for services to start before returning. Implies --detach | +| `--postgres-uri TEXT` | Local database | Postgres URI to use for the database. | +| `--watch` | | Restart on file changes | +| `--debugger-base-url TEXT` | `http://127.0.0.1:[PORT]` | URL used by the debugger to access LangGraph API. | +| `--debugger-port INTEGER` | | Pull the debugger image locally and serve the UI on specified port | +| `--verbose` | | Show more output from the server logs. | +| `-c, --config FILE` | `langgraph.json` | Path to configuration file declaring dependencies, graphs and environment variables. | +| `-d, --docker-compose FILE` | | Path to docker-compose.yml file with additional services to launch. | +| `-p, --port INTEGER` | `8123` | Port to expose. Example: `langgraph test --port 8000` | +| `--pull / --no-pull` | `pull` | Pull latest images. Use --no-pull for running the server with locally-built images. Example: `langgraph up --no-pull` | +| `--recreate / --no-recreate` | `no-recreate` | Recreate containers even if their configuration and image haven't changed | +| `--help` | | Display command documentation. | -### `test` -Test your LangGraph in the cloud. The only function you can call from the SDK after testing your graph is `client.runs.stream(thread_id=None, ...)` +### `dockerfile` + +Generate a Dockerfile for building a LangGraph Cloud API server Docker image. **Usage** + ``` -langgraph test [OPTIONS] +langgraph dockerfile [OPTIONS] SAVE_PATH ``` **Options** -| Option | Default | Description | -| ------ | ------- | ----------- | -| `--verbose` | | Show more output from the server logs. | -| `-c, --config FILE` | `langgraph.json` | Path to configuration file declaring dependencies, graphs and environment variables. | -| `-p, --port INTEGER` | `8123` | Port to expose. Example: `langgraph test --port 8000` | -| `--pull / --no-pull` | `pull` | Pull latest images. Use --no-pull for running the server with locally-built images. Example: `langgraph up --no-pull` | -| `--help` | | Display command documentation. | \ No newline at end of file +| Option | Default | Description | +|---------------------|------------------|-----------------------------------------------------------------------------------------------------------------| +| `-c, --config FILE` | `langgraph.json` | Path to the [configuration file](#configuration-file) declaring dependencies, graphs and environment variables. | +| `--help` | | Show this message and exit. | + +Example: + +```bash +langgraph dockerfile -c langgraph.json Dockerfile +``` + +Would generate something like the following: + +```text +FROM langchain/langgraph-api:3.11 + +ADD ./pipconf.txt /pipconfig.txt + +RUN PIP_CONFIG_FILE=/pipconfig.txt PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt langchain_community langchain_anthropic langchain_openai wikipedia scikit-learn + +ADD ./graphs /deps/__outer_graphs/src +RUN set -ex && \ + for line in '[project]' \ + 'name = "graphs"' \ + 'version = "0.1"' \ + '[tool.setuptools.package-data]' \ + '"*" = ["**/*"]'; do \ + echo "$line" >> /deps/__outer_graphs/pyproject.toml; \ + done + +RUN PIP_CONFIG_FILE=/pipconfig.txt PYTHONDONTWRITEBYTECODE=1 pip install --no-cache-dir -c /api/constraints.txt -e /deps/* + +ENV LANGSERVE_GRAPHS='{"agent": "/deps/__outer_graphs/src/agent.py:graph", "storm": "/deps/__outer_graphs/src/storm.py:graph"}' +``` + +You can then customize, build images, push, and deploy from this file. diff --git a/docs/docs/concepts/application_structure.md b/docs/docs/concepts/application_structure.md new file mode 100644 index 000000000..d27ed60b9 --- /dev/null +++ b/docs/docs/concepts/application_structure.md @@ -0,0 +1,167 @@ +# Application Structure + +!!! info "Prerequisites" + + - [LangGraph Server](./langgraph_server.md) + - [LangGraph Glossary](./low_level.md) + +## Overview + +A LangGraph application consists of one or more graphs, a LangGraph API Configuration file (`langgraph.json`), a file that specifies dependencies, and an optional .env file that specifies environment variables. + +This guide shows a typical structure for a LangGraph application and shows how the required information to deploy a LangGraph application using the LangGraph Platform is specified. + +## Key Concepts + +To deploy using the LangGraph Platform, the following information should be provided: + +1. A [LangGraph API Configuration file](#configuration-file) (`langgraph.json`) that specifies the dependencies, graphs, environment variables to use for the application. +2. The [graphs](#graphs) that implement the logic of the application. +3. A file that specifies [dependencies](#dependencies) required to run the application. +4. [Environment variable](#environment-variables) that are required for the application to run. + +## File Structure + +Below are examples of directory structures for Python and JavaScript applications: + +=== "Python (requirements.txt)" + + ```plaintext + my-app/ + ├── my_agent # all project code lies within here + │ ├── utils # utilities for your graph + │ │ ├── __init__.py + │ │ ├── tools.py # tools for your graph + │ │ ├── nodes.py # node functions for you graph + │ │ └── state.py # state definition of your graph + │ ├── requirements.txt # package dependencies + │ ├── __init__.py + │ └── agent.py # code for constructing your graph + ├── .env # environment variables + └── langgraph.json # configuration file for LangGraph + ``` +=== "Python (pyproject.toml)" + + ```plaintext + my-app/ + ├── my_agent # all project code lies within here + │ ├── utils # utilities for your graph + │ │ ├── __init__.py + │ │ ├── tools.py # tools for your graph + │ │ ├── nodes.py # node functions for you graph + │ │ └── state.py # state definition of your graph + │ ├── __init__.py + │ └── agent.py # code for constructing your graph + ├── .env # environment variables + ├── langgraph.json # configuration file for LangGraph + └── pyproject.toml # dependencies for your project + ``` + +=== "JS (package.json)" + + ```plaintext + my-app/ + ├── src # all project code lies within here + │ ├── utils # optional utilities for your graph + │ │ ├── tools.ts # tools for your graph + │ │ ├── nodes.ts # node functions for you graph + │ │ └── state.ts # state definition of your graph + │ └── agent.ts # code for constructing your graph + ├── package.json # package dependencies + ├── .env # environment variables + └── langgraph.json # configuration file for LangGraph + ``` + +!!! note + + The directory structure of a LangGraph application can vary depending on the programming language and the package manager used. + + +## Configuration File + +The `langgraph.json` file is a JSON file that specifies the dependencies, graphs, environment variables, and other settings required to deploy a LangGraph application. + +The file supports specification of the following information: + + +| Key | Description | +|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `dependencies` | **Required**. Array of dependencies for LangGraph API server. Dependencies can be one of the following: (1) `"."`, which will look for local Python packages, (2) `pyproject.toml`, `setup.py` or `requirements.txt` in the app directory `"./local_package"`, or (3) a package name. | +| `graphs` | **Required**. Mapping from graph ID to path where the compiled graph or a function that makes a graph is defined. Example:
  • `./your_package/your_file.py:variable`, where `variable` is an instance of `langgraph.graph.state.CompiledStateGraph`
  • `./your_package/your_file.py:make_graph`, where `make_graph` is a function that takes a config dictionary (`langchain_core.runnables.RunnableConfig`) and creates an instance of `langgraph.graph.state.StateGraph` / `langgraph.graph.state.CompiledStateGraph`.
| +| `env` | Path to `.env` file or a mapping from environment variable to its value. | +| `python_version` | `3.11` or `3.12`. Defaults to `3.11`. | +| `pip_config_file` | Path to `pip` config file. | +| `dockerfile_lines` | Array of additional lines to add to Dockerfile following the import from parent image. | +!!! tip + + The LangGraph CLI defaults to using the configuration file **langgraph.json** in the current directory. + + +### Examples + +=== "Python" + + * The dependencies involve a custom local package and the `langchain_openai` package. + * A single graph will be loaded from the file `./your_package/your_file.py` with the variable `variable`. + * The environment variables are loaded from the `.env` file. + + ```json + { + "dependencies": [ + "langchain_openai", + "./your_package" + ], + "graphs": { + "my_agent": "./your_package/your_file.py:agent" + }, + "env": "./.env" + } + ``` + +=== "JavaScript" + + * The dependencies will be loaded from a dependency file in the local directory (e.g., `package.json`). + * A single graph will be loaded from the file `./your_package/your_file.js` with the function `agent`. + * The environment variable `OPENAI_API_KEY` is set inline. + + ```json + { + "dependencies": [ + "." + ], + "graphs": { + "my_agent": "./your_package/your_file.js:agent" + }, + "env": { + "OPENAI_API_KEY": "secret-key" + } + } + ``` + +## Dependencies + +A LangGraph application may depend on other Python packages or JavaScript libraries (depending on the programming language in which the application is written). + +You will generally need to specify the following information for dependencies to be set up correctly: + +1. A file in the directory that specifies the dependencies (e.g., `requirements.txt`, `pyproject.toml`, or `package.json`). +2. A `dependencies` key in the [LangGraph configuration file](#configuration-file) that specifies the dependencies required to run the LangGraph application. +3. Any additional binaries or system libraries can be specified using `dockerfile_lines` key in the [LangGraph configuration file](#configuration-file). + +## Graphs + +Use the `graphs` key in the [LangGraph configuration file](#configuration-file) to specify which graphs will be available in the deployed LangGraph application. + +You can specify one or more graphs in the configuration file. Each graph is identified by a name (which should be unique) and a path for either: (1) the compiled graph or (2) a function that makes a graph is defined. + +## Environment Variables + +If you're working with a deployed LangGraph application locally, you can configure environment variables in the `env` key of the [LangGraph configuration file](#configuration-file). + +For a production deployment, you will typically want to configure the environment variables in the deployment environment. + +## Related + +Please see the following resources for more information: + +- How-to guides for [Application Structure](../how-tos/index.md#application-structure). diff --git a/docs/docs/concepts/assistants.md b/docs/docs/concepts/assistants.md new file mode 100644 index 000000000..51f0e10f5 --- /dev/null +++ b/docs/docs/concepts/assistants.md @@ -0,0 +1,37 @@ +# Assistants + +!!! info "Prerequisites" + + - [LangGraph Server](./langgraph_server.md) + +When building agents, it is fairly common to make rapid changes that *do not* alter the graph logic. For example, simply changing prompts or the LLM selection can have significant impacts on the behavior of the agents. Assistants offer an easy way to make and save these types of changes to agent configuration. This can have at least two use-cases: + +* Assistants give developers a quick and easy way to modify and version agents for experimentation. +* Assistants can be modified via LangGraph Studio, offering a no-code way to configure agents (e.g., for business users). + +Assistants build off the concept of ["configuration"](low_level.md#configuration). +While ["configuration"](low_level.md#configuration) is available in the open source LangGraph library as well, assistants are only present in [LangGraph Platform](langgraph_platform.md). +This is because Assistants are tightly coupled to your deployed graph, and so we can only make them available when we are also deploying the graphs. + +## Configuring Assistants + +In practice, an assistant is just an *instance* of a graph with a specific configuration. Because of this, multiple assistants can reference the same graph but can contain different configurations, such as prompts, models, and other graph configuration options. The LangGraph Cloud API provides several endpoints for creating and managing assistants. See the [API reference](../cloud/reference/api/api_ref.html) and [this how-to](../cloud/how-tos/configuration_cloud.md) for more details on how to create assistants. + +## Versioning Assistants + +Once you've created an assistant, you can save and version it to track changes to the configuration over time. You can think about this at three levels: + +1) The graph lays out the general agent application logic +2) The agent configuration options represent parameters that can be changed +3) Assistant versions save and track specific settings of the agent configuration options + +For example, let's imagine you have a general writing agent. You have created a general graph architecture that works well for writing. However, there are different types of writing, e.g. blogs vs tweets. In order to get the best performance on each use case, you need to make some minor changes to the models and prompts used. In this setup, you could create an assistant for each use case - one for blog writing and one for tweeting. These would share the same graph structure, but they may use different models and different prompts. Read [this how-to](../cloud/how-tos/assistant_versioning.md) to learn how you can use assistant versioning through both the [Studio](../cloud/how-tos/index.md/#langgraph-studio) and the SDK. + +![assistant versions](img/assistants.png) + + +## Resources + +For more information on assistants, see the following resources: + +- [Assistants how-to guides](../how-tos/index.md#assistants) \ No newline at end of file diff --git a/docs/docs/concepts/bring_your_own_cloud.md b/docs/docs/concepts/bring_your_own_cloud.md new file mode 100644 index 000000000..6d0def74a --- /dev/null +++ b/docs/docs/concepts/bring_your_own_cloud.md @@ -0,0 +1,54 @@ +# Bring Your Own Cloud (BYOC) + +!!! note Prerequisites + + - [LangGraph Platform](./langgraph_platform.md) + - [Deployment Options](./deployment_options.md) + +## Architecture + +Split control plane (hosted by us) and data plane (hosted by you, managed by us). + +| | Control Plane | Data Plane | +|-----------------------------|---------------------------------|-----------------------------------------------| +| What it does | Manages deployments, revisions. | Runs your LangGraph graphs, stores your data. | +| Where it is hosted | LangChain Cloud account | Your cloud account | +| Who provisions and monitors | LangChain | LangChain | + +LangChain has no direct access to the resources created in your cloud account, and can only interact with them via AWS APIs. Your data never leaves your cloud account / VPC at rest or in transit. + +![Architecture](img/byoc_architecture.png) + +## Requirements + +- You’re using AWS already. +- You use `langgraph-cli` and/or [LangGraph Studio](./langgraph_studio.md) app to test graph locally. +- You use `langgraph build` command to build image and then push it to your AWS ECR repository (`docker push`). + +## How it works + +- We provide you a [Terraform module](https://github.com/langchain-ai/terraform/tree/main/modules/langgraph_cloud_setup) which you run to set up our requirements + 1. Creates an AWS role (which our control plane will later assume to provision and monitor resources) + - https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonVPCReadOnlyAccess.html + - Read VPCS to find subnets + - https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonECS_FullAccess.html + - Used to create/delete ECS resources for your LangGraph Cloud instances + - https://docs.aws.amazon.com/aws-managed-policy/latest/reference/SecretsManagerReadWrite.html + - Create secrets for your ECS resources + - https://docs.aws.amazon.com/aws-managed-policy/latest/reference/CloudWatchReadOnlyAccess.html + - Read CloudWatch metrics/logs to monitor your instances/push deployment logs + - https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonRDSFullAccess.html + - Provision `RDS` instances for your LangGraph Cloud instances + 2. Either + - Tags an existing vpc / subnets as `langgraph-cloud-enabled` + - Creates a new vpc and subnets and tags them as `langgraph-cloud-enabled` +- You create a LangGraph Cloud Project in `smith.langchain.com` providing + - the ID of the AWS role created in the step above + - the AWS ECR repo to pull the service image from +- We provision the resources in your cloud account using the role above +- We monitor those resources to ensure uptime and recovery from errors + +Notes for customers using [self-hosted LangSmith](https://docs.smith.langchain.com/self_hosting): + +- Creation of new LangGraph Cloud projects and revisions currently needs to be done on smith.langchain.com. +- You can however set up the project to trace to your self-hosted LangSmith instance if desired diff --git a/docs/docs/concepts/deployment_options.md b/docs/docs/concepts/deployment_options.md new file mode 100644 index 000000000..1e6789373 --- /dev/null +++ b/docs/docs/concepts/deployment_options.md @@ -0,0 +1,73 @@ +# Deployment Options + +!!! info "Prerequisites" + + - [LangGraph Platform](./langgraph_platform.md) + - [LangGraph Server](./langgraph_server.md) + +## Overview + +There are 3 main options for deploying with the LangGraph Platform: + +1. **[Self-Hosted](#self-hosted)**: Available for **a free trial** and **Enterprise** plan. + +2. **[Cloud SaaS](#cloud-saas)**: Available for **Plus** and **Enterprise** plans. + +3. **[Bring Your Own Cloud](#bring-your-own-cloud)**: Available only for **Enterprise** plans and **only on AWS**. + +Please see the [LangGraph Platform Pricing](https://www.langchain.com/langgraph-platform-pricing) for more information on the different plans. + +The guide below will explain the differences between the deployment options. + +## Self-Hosted + +!!! important + + The Self-Hosted version is only available for **a free trial** and **Enterprise** plan. + +With a Self-Hosted deployment, you are responsible for managing the infrastructure, including setting up and maintaining required databases and Redis instances. + +You’ll build a Docker image using the [LangGraph CLI](./langgraph_cli.md), which can then be deployed on your own infrastructure. + +For more information, please see: + +* [Self-Hosted Deployment how-to guide](../how-tos/deploy-self-hosted.md) + +## Cloud SaaS + +!!! important + + The Cloud SaaS version of LangGraph Platform is only available for **Plus** and **Enterprise** plans. + + +The [Cloud SaaS](./langgraph_cloud.md) version of LangGraph Platform is hosted as part of [LangSmith](https://smith.langchain.com/). + +The Cloud SaaS version of LangGraph Platform provides a simple way to deploy and manage your LangGraph applications. + +This deployment option provides an integration with GitHub, allowing you to deploy code from any of your repositories on GitHub. + +For more information, please see: + +* [Cloud SaaS Conceptual Guide](./langgraph_cloud.md) +* [How to deploy to Cloud SaaS](../cloud/deployment/cloud.md) + + +## Bring Your Own Cloud + +!!! important + + The Bring Your Own Cloud version of LangGraph Platform is only available for **Enterprise** plans. + + +This combines the best of both worlds for Cloud and Self-Hosted. We manage the infrastructure, so you don't have to, but the infrastructure all runs within your cloud. This is currently only available on AWS. + +For more information please see: + +* [Bring Your Own Cloud Conceptual Guide](./bring_your_own_cloud.md) + +## Related + +For more information please see: + +* [LangGraph Platform Pricing](https://www.langchain.com/langgraph-platform-pricing) +* [Deployment how-to guides](../how-tos/index.md#deployment) diff --git a/docs/docs/concepts/double_texting.md b/docs/docs/concepts/double_texting.md new file mode 100644 index 000000000..1a197ccf3 --- /dev/null +++ b/docs/docs/concepts/double_texting.md @@ -0,0 +1,44 @@ +# Double Texting + +!!! info "Prerequisites" + - [LangGraph Server](./langgraph_server.md) + +Many times users might interact with your graph in unintended ways. +For instance, a user may send one message and before the graph has finished running send a second message. +More generally, users may invoke the graph a second time before the first run has finished. +We call this "double texting". + +Currently, LangGraph only addresses this as part of [LangGraph Platform](langgraph_platform.md), not in the open source. +The reason for this is that in order to handle this we need to know how the graph is deployed, and since LangGraph Platform deals with deployment the logic needs to live there. +If you do not want to use LangGraph Platform, we describe the options we have implemented in detail below. + +![](img/double_texting.png) + +## Reject +This is the simplest option, this just rejects any follow up runs and does not allow double texting. +See the [how-to guide](../cloud/how-tos/reject_concurrent.md) for configuring the reject double text option. + +## Enqueue +This is a relatively simple option which continues the first run until it completes the whole run, then sends the new input as a separate run. +See the [how-to guide](../cloud/how-tos/enqueue_concurrent.md) for configuring the enqueue double text option. + +## Interrupt + +This option interrupts the current execution but saves all the work done up until that point. +It then inserts the user input and continues from there. + +If you enable this option, your graph should be able to handle weird edge cases that may arise. +For example, you could have called a tool but not yet gotten back a result from running that tool. +You may need to remove that tool call in order to not have a dangling tool call. + +See the [how-to guide](../cloud/how-tos/interrupt_concurrent.md) for configuring the interrupt double text option. + +## Rollback + +This option rolls back all work done up until that point. +It then sends the user input in, basically as if it just followed the original run input. + +This may create some weird states - for example, you may have two `User` messages in a row, with no `Asssitant` message in between them. +You will need to make sure the LLM you are calling can handle that, or combine those into a single `User` message. + +See the [how-to guide](../cloud/how-tos/rollback_concurrent.md) for configuring the rollback double text option. diff --git a/docs/docs/concepts/img/assistants.png b/docs/docs/concepts/img/assistants.png new file mode 100644 index 000000000..0da78a031 Binary files /dev/null and b/docs/docs/concepts/img/assistants.png differ diff --git a/docs/docs/concepts/img/byoc_architecture.png b/docs/docs/concepts/img/byoc_architecture.png new file mode 100644 index 000000000..97bb2db1d Binary files /dev/null and b/docs/docs/concepts/img/byoc_architecture.png differ diff --git a/docs/docs/concepts/img/double_texting.png b/docs/docs/concepts/img/double_texting.png new file mode 100644 index 000000000..f2291612c Binary files /dev/null and b/docs/docs/concepts/img/double_texting.png differ diff --git a/docs/docs/concepts/img/langgraph_cloud_architecture.png b/docs/docs/concepts/img/langgraph_cloud_architecture.png new file mode 100644 index 000000000..dc2d1b15a Binary files /dev/null and b/docs/docs/concepts/img/langgraph_cloud_architecture.png differ diff --git a/docs/docs/concepts/img/lg_platform.png b/docs/docs/concepts/img/lg_platform.png new file mode 100644 index 000000000..de54cedc5 Binary files /dev/null and b/docs/docs/concepts/img/lg_platform.png differ diff --git a/docs/docs/concepts/index.md b/docs/docs/concepts/index.md index 7ff625ca0..27f18eaa6 100644 --- a/docs/docs/concepts/index.md +++ b/docs/docs/concepts/index.md @@ -11,17 +11,57 @@ This guide provides explanations of the key concepts behind the LangGraph framew We recommend that you go through at least the [Quick Start](../tutorials/introduction.ipynb) before diving into the conceptual guide. This will provide practical context that will make it easier to understand the concepts discussed here. -The conceptual guide does not cover step-by-step instructions or specific implementation examples — those are found in the [Tutorials](../tutorials/index.md) and [How-to guides](../how-tos/index.md). -For detailed reference material, please see the [API reference](../reference/index.md). +The conceptual guide does not cover step-by-step instructions or specific implementation examples — those are found in the [Tutorials](../tutorials/index.md) and [How-to guides](../how-tos/index.md). For detailed reference material, please see the [API reference](../reference/index.md). -## Concepts +## LangGraph + +**High Level** - [Why LangGraph?](high_level.md): A high-level overview of LangGraph and its goals. + +**Concepts** + - [LangGraph Glossary](low_level.md): LangGraph workflows are designed as graphs, with nodes representing different components and edges representing the flow of information between them. This guide provides an overview of the key concepts associated with LangGraph graph primitives. -- [Common Agentic Patterns](agentic_concepts.md): An agent are LLMs that can pick its own control flow to solve more complex problems! Agents are a key building block in many LLM applications. This guide explains the different types of agent architectures and how they can be used to control the flow of an application. +- [Common Agentic Patterns](agentic_concepts.md): An agent uses an LLM to pick its own control flow to solve more complex problems! Agents are a key building block in many LLM applications. This guide explains the different types of agent architectures and how they can be used to control the flow of an application. - [Multi-Agent Systems](multi_agent.md): Complex LLM applications can often be broken down into multiple agents, each responsible for a different part of the application. This guide explains common patterns for building multi-agent systems. - [Human-in-the-Loop](human_in_the_loop.md): Explains different ways of integrating human feedback into a LangGraph application. - [Persistence](persistence.md): LangGraph has a built-in persistence layer, implemented through checkpointers. This persistence layer helps to support powerful capabilities like human-in-the-loop, memory, time travel, and fault-tolerance. - [Memory](memory.md): Memory in AI applications refers to the ability to process, store, and effectively recall information from past interactions. With memory, your agents can learn from feedback and adapt to users' preferences. - [Streaming](streaming.md): Streaming is crucial for enhancing the responsiveness of applications built on LLMs. By displaying output progressively, even before a complete response is ready, streaming significantly improves user experience (UX), particularly when dealing with the latency of LLMs. -- [FAQ](faq.md): Frequently asked questions about LangGraph. \ No newline at end of file +- [FAQ](faq.md): Frequently asked questions about LangGraph. + +## LangGraph Platform + +LangGraph Platform is a commercial solution for deploying agentic applications in production, built on the open-source LangGraph framework. + +The LangGraph Platform offers a few different deployment options described in the [deployment options guide](./deployment_options.md). + + +!!! tip + + * LangGraph is an MIT-licensed open-source library, which we are committed to maintaining and growing for the community. + * You can always deploy LangGraph applications on your own infrastructure using the open-source LangGraph project without using LangGraph Platform. + +**High Level** + +- [Why LangGraph Platform?](./langgraph_platform.md): The LangGraph platform is an opinionated way to deploy and manage LangGraph applications. This guide provides an overview of the key features and concepts behind LangGraph Platform. +- [Deployment Options](./deployment_options.md): LangGraph Platform offers three deployment options: self-hosted, [bring your own cloud (BYOC)](./bring_your_own_cloud.md), and [Cloud SaaS](./langgraph_cloud.md). This guide explains the differences between these options, and which Plans they are available on. +- [Template Applications](./template_applications.md): Reference applications designed to help you get started quickly when building with LangGraph. + +**Components** + +The LangGraph Platform comprises several components that work together to support the deployment and management of LangGraph applications: + +- [LangGraph Server](./langgraph_server.md): The LangGraph Server is designed to support a wide range of agentic application use cases, from background processing to real-time interactions. +- [LangGraph Studio](./langgraph_studio.md): LangGraph Studio is a specialized IDE that can connect to a LangGraph Server to enable visualization, interaction, and debugging of the application locally. +- [LangGraph CLI](./langgraph_cli.md): LangGraph CLI is a command-line interface that helps to interact with a local LangGraph +- [Python/JS SDK](./sdk.md): The Python/JS SDK provides a programmatic way to interact with deployed LangGraph Applications. +- [Remote Graph](../how-tos/use-remote-graph.md): A RemoteGraph allows you to interact with any deployed LangGraph application as though it were running locally. + +**LangGraph Server** + +- [Application Structure](./application_structure.md): A LangGraph application consists of one or more graphs, a LangGraph API Configuration file (`langgraph.json`), a file that specifies dependencies, and environment variables. +- [Assistants](./assistants.md): Assistants are a way to save and manage different configurations of your LangGraph applications. +- [Web-hooks](./langgraph_server.md#webhooks): Webhooks allow your running LangGraph application to send data to external services on specific events. +- [Cron Jobs](./langgraph_server.md#cron-jobs): Cron jobs are a way to schedule tasks to run at specific times in your LangGraph application. +- [Double Texting](./double_texting.md): Double texting is a common issue in LLM applications where users may send multiple messages before the graph has finished running. This guide explains how to handle double texting with LangGraph Deploy. diff --git a/docs/docs/concepts/langgraph_cli.md b/docs/docs/concepts/langgraph_cli.md new file mode 100644 index 000000000..436875a9b --- /dev/null +++ b/docs/docs/concepts/langgraph_cli.md @@ -0,0 +1,43 @@ +# LangGraph CLI + +!!! info "Prerequisites" + - [LangGraph Platform](./langgraph_platform.md) + - [LangGraph Server](./langgraph_server.md) + +The LangGraph CLI is a multi-platform command-line tool for building and running the [LangGraph API server](./langgraph_server.md) locally. This offers an alternative to the [LangGraph Studio desktop app](./langgraph_studio.md) for developing and testing agents across all major operating systems (Linux, Windows, MacOS). The resulting server includes all API endpoints for your graph's runs, threads, assistants, etc. as well as the other services required to run your agent, including a managed database for checkpointing and storage. + +## Installation + +The LangGraph CLI can be installed via Homebrew (on macOS) or pip: + +=== "Homebrew" + ```bash + brew install langgraph-cli + ``` + +=== "pip" + ```bash + pip install langgraph-cli + ``` + +## Commands + +The CLI provides the following core functionality: + +### `build` + +The `langgraph build` command builds a Docker image for the [LangGraph API server](./langgraph_server.md) that can be directly deployed. + +### `up` + +The `langgraph up` command starts an instance of the [LangGraph API server](./langgraph_server.md) locally. This requires docker to be installed and running locally. It also requires a LangSmith API key for local development or a license key for production use. + +The server includes all API endpoints for your graph's runs, threads, assistants, etc. as well as the other services required to run your agent, including a managed database for checkpointing and storage. + +### `dockerfile` + +The `langgraph dockerfile` command generates a [Dockerfile](https://docs.docker.com/reference/dockerfile/) that can be used to build images for and deploy instances of the [LangGraph API server](./langgraph_server.md). This is useful if you want to further customize the dockerfile or deploy in a more custom way. + +## Related + +- [LangGraph CLI API Reference](../cloud/reference/cli.md) diff --git a/docs/docs/concepts/langgraph_cloud.md b/docs/docs/concepts/langgraph_cloud.md new file mode 100644 index 000000000..11a26c184 --- /dev/null +++ b/docs/docs/concepts/langgraph_cloud.md @@ -0,0 +1,38 @@ +# Cloud SaaS + +!!! info "Prerequisites" + - [LangGraph Platform](./langgraph_platform.md) + - [LangGraph Server](./langgraph_server.md) + +## Overview + +LangGraph's Cloud SaaS is a managed service that provides a scalable and secure environment for deploying LangGraph APIs. It is designed to work seamlessly with your LangGraph API regardless of how it is defined, what tools it uses, or any dependencies. Cloud SaaS provides a simple way to deploy and manage your LangGraph API in the cloud. + +## Deployment + +A **deployment** is an instance of a LangGraph API. A single deployment can have many [revisions](#revision). When a deployment is created, all the necessary infrastructure (e.g. database, containers, secrets store) are automatically provisioned. See the [architecture diagram](#architecture) below for more details. + +See the [how-to guide](../cloud/deployment/cloud.md#create-new-deployment) for creating a new deployment. + +## Revision + +A revision is an iteration of a [deployment](#deployment). When a new deployment is created, an initial revision is automatically created. To deploy new code changes or update environment variable configurations for a deployment, a new revision must be created. When a revision is created, a new container image is built automatically. + +See the [how-to guide](../cloud/deployment/cloud.md#create-new-revision) for creating a new revision. + +## Asynchronous Deployment + +Infrastructure for [deployments](#deployment) and [revisions](#revision) are provisioned and deployed asynchronously. They are not deployed immediately after submission. Currently, deployment can take up to several minutes. + +## Architecture + +!!! warning "Subject to Change" +The Cloud SaaS deployment architecture may change in the future. + +A high-level diagram of a Cloud SaaS deployment. + +![diagram](img/langgraph_cloud_architecture.png) + +## Related + +- [Deployment Options](./deployment_options.md) \ No newline at end of file diff --git a/docs/docs/concepts/langgraph_platform.md b/docs/docs/concepts/langgraph_platform.md new file mode 100644 index 000000000..8b2e6b61c --- /dev/null +++ b/docs/docs/concepts/langgraph_platform.md @@ -0,0 +1,62 @@ +# LangGraph Platform + +## Overview + +LangGraph Platform is a commercial solution for deploying agentic applications to production, built on the open-source [LangGraph framework](./high_level.md). + +The LangGraph Platform consists of several components that work together to support the development, deployment, debugging, and monitoring of LangGraph applications: + +- [LangGraph Server](./langgraph_server.md): The server defines an opinionated API and architecture that incorporates best practices for deploying agentic applications, allowing you to focus on building your agent logic rather than developing server infrastructure. +- [LangGraph Studio](./langgraph_studio.md): LangGraph Studio is a specialized IDE that can connect to a LangGraph Server to enable visualization, interaction, and debugging of the application locally. +- [LangGraph CLI](./langgraph_cli.md): LangGraph CLI is a command-line interface that helps to interact with a local LangGraph +- [Python/JS SDK](./sdk.md): The Python/JS SDK provides a programmatic way to interact with deployed LangGraph Applications. +- [Remote Graph](../how-tos/use-remote-graph.md): A RemoteGraph allows you to interact with any deployed LangGraph application as though it were running locally. + +![](img/lg_platform.png) + +The LangGraph Platform offers a few different deployment options described in the [deployment options guide](./deployment_options.md). + +## Why Use LangGraph Platform? + +LangGraph Platform is designed to make deploying agentic applications seamless and production-ready. + +For simpler applications, deploying a LangGraph agent can be as straightforward as using your own server logic—for example, setting up a FastAPI endpoint and invoking LangGraph directly. + +### Option 1: Deploying with Custom Server Logic + +For basic LangGraph applications, you may choose to handle deployment using your custom server infrastructure. Setting up endpoints with frameworks like [FastAPI](https://fastapi.tiangolo.com/) allows you to quickly deploy and run LangGraph as you would any other Python application: + +```python +from fastapi import FastAPI +from your_agent_package import graph + +app = FastAPI() + +@app.get("/foo") +async def foo(...): + return await graph.ainvoke({...}) +``` + +This approach works well for simple applications with straightforward needs and provides you with full control over the deployment setup. For example, you might use this for a single-assistant application that doesn’t require long-running sessions or persistent memory. + +### Option 2: Leveraging LangGraph Platform for Complex Deployments + +As your applications scale or add complex features, the deployment requirements often evolve. Running an application with more nodes, longer processing times, or a need for persistent memory can introduce challenges that quickly become time-consuming and difficult to manage manually. [LangGraph Platform](./langgraph_platform.md) is built to handle these challenges seamlessly, allowing you to focus on agent logic rather than server infrastructure. + +Here are some common issues that arise in complex deployments, which LangGraph Platform addresses: + +- **[Streaming Support](streaming.md)**: As agents grow more sophisticated, they often benefit from streaming both token outputs and intermediate states back to the user. Without this, users are left waiting for potentially long operations with no feedback. LangGraph Server provides [multiple streaming modes](streaming.md) optimized for various application needs. + +- **Background Runs**: For agents that take longer to process (e.g., hours), maintaining an open connection can be impractical. The LangGraph Server supports launching agent runs in the background and provides both polling endpoints and webhooks to monitor run status effectively. + +- **Support for long runs**: Vanilla server setups often encounter timeouts or disruptions when handling requests that take a long time to complete. LangGraph Server’s API provides robust support for these tasks by sending regular heartbeat signals, preventing unexpected connection closures during prolonged processes. + +- **Handling Burstiness**: Certain applications, especially those with real-time user interaction, may experience "bursty" request loads where numerous requests hit the server simultaneously. LangGraph Server includes a task queue, ensuring requests are handled consistently without loss, even under heavy loads. + +- **[Double Texting](double_texting.md)**: In user-driven applications, it’s common for users to send multiple messages rapidly. This “double texting” can disrupt agent flows if not handled properly. LangGraph Server offers built-in strategies to address and manage such interactions. + +- **[Checkpointers and Memory Management](persistence.md#checkpoints)**: For agents needing persistence (e.g., conversation memory), deploying a robust storage solution can be complex. LangGraph Platform includes optimized [checkpointers](persistence.md#checkpoints) and a [memory store](persistence.md#memory-store), managing state across sessions without the need for custom solutions. + +- **[Human-in-the-loop Support](human_in_the_loop.md)**: In many applications, users require a way to intervene in agent processes. LangGraph Server provides specialized endpoints for human-in-the-loop scenarios, simplifying the integration of manual oversight into agent workflows. + +By using LangGraph Platform, you gain access to a robust, scalable deployment solution that mitigates these challenges, saving you the effort of implementing and maintaining them manually. This allows you to focus more on building effective agent behavior and less on solving deployment infrastructure issues. diff --git a/docs/docs/concepts/langgraph_server.md b/docs/docs/concepts/langgraph_server.md new file mode 100644 index 000000000..cb2d3948c --- /dev/null +++ b/docs/docs/concepts/langgraph_server.md @@ -0,0 +1,130 @@ +# LangGraph Server + +!!! info "Prerequisites" + - [LangGraph Platform](./langgraph_platform.md) + - [LangGraph Glossary](low_level.md) + +## Overview + +LangGraph Server offers an API for creating and managing agent-based applications. It is built on the concept of [assistants](assistants.md), which are agents configured for specific tasks, and includes built-in [persistence](persistence.md#memory-store) and a **task queue**. This versatile API supports a wide range of agentic application use cases, from background processing to real-time interactions. + +## Key Features + +The LangGraph Platform incorporates best practices for agent deployment, so you can focus on building your agent logic. + +* **Streaming endpoints**: Endpoints that expose [multiple different streaming modes](streaming.md). We've made these work even for long-running agents that may go minutes between consecutive stream events. +* **Background runs**: The LangGraph Server supports launching assistants in the background with endpoints for polling the status of the assistant's run and webhooks to monitor run status effectively. +- **Support for long runs**: Our blocking endpoints for running assistants send regular heartbeat signals, preventing unexpected connection closures when handling requests that take a long time to complete. +* **Task queue**: We've added a task queue to make sure we don't drop any requests if they arrive in a bursty nature. +* **Horizontally scalable infrastructure**: LangGraph Server is designed to be horizontally scalable, allowing you to scale up and down your usage as needed. +* **Double texting support**: Many times users might interact with your graph in unintended ways. For instance, a user may send one message and before the graph has finished running send a second message. We call this ["double texting"](double_texting.md) and have added four different ways to handle this. +* **Optimized checkpointer**: LangGraph Platform comes with a built-in [checkpointer](./persistence.md#checkpoints) optimized for LangGraph applications. +* **Human-in-the-loop endpoints**: We've exposed all endpoints needed to support [human-in-the-loop](human_in_the_loop.md) features. +* **Memory**: In addition to thread-level persistence (covered above by [checkpointers]l(./persistence.md#checkpoints)), LangGraph Platform also comes with a built-in [memory store](persistence.md#memory-store). +* **Cron jobs**: Built-in support for scheduling tasks, enabling you to automate regular actions like data clean-up or batch processing within your applications. +* **Webhooks**: Allows your application to send real-time notifications and data updates to external systems, making it easy to integrate with third-party services and trigger actions based on specific events. +* **Monitoring**: LangGraph Server integrates seamlessly with the [LangSmith](https://docs.smith.langchain.com/) monitoring platform, providing real-time insights into your application's performance and health. + +## What are you deploying? + +When you deploy a LangGraph Server, you are deploying one or more [graphs](#graphs), a database for [persistence](persistence.md), and a task queue. + +### Graphs + +When you deploy a graph with LangGraph Server, you are deploying a "blueprint" for an [Assistant](assistants.md). + +An [Assistant](assistants.md) is a graph paired with specific configuration settings. You can create multiple assistants per graph, each with unique settings to accommodate different use cases +that can be served by the same graph. + +Upon deployment, LangGraph Server will automatically create a default assistant for each graph using the graph's default configuration settings. + +You can interact with assistants through the [LangGraph Server API](#langgraph-server-api). + +!!! note + + We often think of a graph as implementing an [agent](agentic_concepts.md), but a graph does not necessarily need to implement an agent. For example, a graph could implement a simple + chatbot that only supports back-and-forth conversation, without the ability to influence any application control flow. In reality, as applications get more complex, a graph will often implement a more complex flow that may use [multiple agents](./multi_agent.md) working in tandem. + +### Persistence and Task Queue + +The LangGraph Server leverages a database for [persistence](persistence.md) and a task queue. + +Currently, only [Postgres](https://www.postgresql.org/) is supported as a database for LangGraph Server and [Redis](https://redis.io/) as the task queue. + +If you're deploying using [LangGraph Cloud](./langgraph_cloud.md), these components are managed for you. If you're deploying LangGraph Server on your own infrastructure, you'll need to set up and manage these components yourself. + +Please review the [deployment options](./deployment_options.md) guide for more information on how these components are set up and managed. + +## Application Structure + +To deploy a LangGraph Server application, you need to specify the graph(s) you want to deploy, as well as any relevant configuration settings, such as dependencies and environment variables. + +Read the [application structure](./application_structure.md) guide to learn how to structure your LangGraph application for deployment. + +## LangGraph Server API + +The LangGraph Server API allows you to create and manage [assistants](assistants.md), [threads](#threads), [runs](#runs), [cron jobs](#cron-jobs), and more. + +The [LangGraph Cloud API Reference](../cloud/reference/api/api_ref.html) provides detailed information on the API endpoints and data models. + +### Assistants + +An [Assistant](assistants.md) refers to a [graph](#graphs) plus specific [configuration](low_level.md#configuration) settings for that graph. + +You can think of an assistant as a saved configuration of an [agent](agentic_concepts.md). + +When building agents, it is fairly common to make rapid changes that *do not* alter the graph logic. For example, simply changing prompts or the LLM selection can have significant impacts on the behavior of the agents. Assistants offer an easy way to make and save these types of changes to agent configuration. + +### Threads + +A thread contains the accumulated state of a sequence of [runs](#runs). If a run is executed on a thread, then the [state](low_level.md#state) of the underlying graph of the assistant will be persisted to the thread. + +A thread's current and historical state can be retrieved. To persist state, a thread must be created prior to executing a run. + +The state of a thread at a particular point in time is called a [checkpoint](persistence.md#checkpoints). Checkpoints can be used to restore the state of a thread at a later time. + +For more on threads and checkpoints, see this section of the [LangGraph conceptual guide](low_level.md#persistence). + +The LangGraph Cloud API provides several endpoints for creating and managing threads and thread state. See the [API reference](../cloud/reference/api/api_ref.html#tag/threads) for more details. + +### Runs + +A run is an invocation of an [assistant](#assistants). Each run may have its own input, configuration, and metadata, which may affect execution and output of the underlying graph. A run can optionally be executed on a [thread](#threads). + +The LangGraph Cloud API provides several endpoints for creating and managing runs. See the [API reference](../cloud/reference/api/api_ref.html#tag/thread-runs/) for more details. + +### Store + +Store is an API for managing persistent [key-value store](./persistence.md#memory-store) that is available from any [thread](#threads). + +Stores are useful for implementing [memory](./memory.md) in your LangGraph application. + +### Cron Jobs + +There are many situations in which it is useful to run an assistant on a schedule. + +For example, say that you're building an assistant that runs daily and sends an email summary +of the day's news. You could use a cron job to run the assistant every day at 8:00 PM. + +LangGraph Cloud supports cron jobs, which run on a user-defined schedule. The user specifies a schedule, an assistant, and some input. After that, on the specified schedule, the server will: + +- Create a new thread with the specified assistant +- Send the specified input to that thread + +Note that this sends the same input to the thread every time. See the [how-to guide](../cloud/how-tos/cron_jobs.md) for creating cron jobs. + +The LangGraph Cloud API provides several endpoints for creating and managing cron jobs. See the [API reference](../cloud/reference/api/api_ref.html#tag/runscreate/POST/threads/{thread_id}/runs/crons) for more details. + +### Webhooks + +Webhooks enable event-driven communication from your LangGraph Cloud application to external services. For example, you may want to issue an update to a separate service once an API call to LangGraph Cloud has finished running. + +Many LangGraph Cloud endpoints accept a `webhook` parameter. If this parameter is specified by a an endpoint that can accept POST requests, LangGraph Cloud will send a request at the completion of a run. + +See the corresponding [how-to guide](../cloud/how-tos/webhooks.md) for more detail. + +## Related + +* LangGraph [Application Structure](./application_structure.md) guide explains how to structure your LangGraph application for deployment. +* [How-to guides for the LangGraph Platform](../how-tos/index.md). +* The [LangGraph Cloud API Reference](../cloud/reference/api/api_ref.html) provides detailed information on the API endpoints and data models. diff --git a/docs/docs/concepts/langgraph_studio.md b/docs/docs/concepts/langgraph_studio.md new file mode 100644 index 000000000..039419f41 --- /dev/null +++ b/docs/docs/concepts/langgraph_studio.md @@ -0,0 +1,116 @@ +# LangGraph Studio + +!!! info "Prerequisites" + + - [LangGraph Platform](./langgraph_platform.md) + - [LangGraph Server](./langgraph_server.md) + +LangGraph Studio offers a new way to develop LLM applications by providing a specialized agent IDE that enables visualization, interaction, and debugging of complex agentic applications. + +With visual graphs and the ability to edit state, you can better understand agent workflows and iterate faster. LangGraph Studio integrates with LangSmith allowing you to collaborate with teammates to debug failure modes. + +![](img/lg_studio.png) + +## Features + +The key features of LangGraph Studio are: + +- Visualizes your graph +- Test your graph by running it from the UI +- Debug your agent by [modifying its state and rerunning](human_in_the_loop.md) +- Create and manage [assistants](assistants.md) +- View and manage [threads](persistence.md#threads) +- View and manage [long term memory](memory.md) +- Add node input/outputs to [LangSmith](https://smith.langchain.com/) datasets for testing + +## Types + +### Desktop app + +LangGraph Studio is available as a [desktop app](https://studio.langchain.com/) for MacOS users. + +While in Beta, LangGraph Studio is available for free to all [LangSmith](https://smith.langchain.com/) users on any plan tier. + +### Cloud studio + +If you have deployed your LangGraph application on LangGraph Platform (Cloud), you can access the studio as part of that + +## Studio FAQs + +### Why is my project failing to start? + +There are a few reasons that your project might fail to start, here are some of the most common ones. + +#### Docker issues (desktop only) + +LangGraph Studio (desktop) requires Docker Desktop version 4.24 or higher. Please make sure you have a version of Docker installed that satisfies that requirement and also make sure you have the Docker Desktop app up and running before trying to use LangGraph Studio. In addition, make sure you have docker-compose updated to version 2.22.0 or higher. + +#### Configuration or environment issues + +Another reason your project might fail to start is because your configuration file is defined incorrectly, or you are missing required environment variables. + +### How does interrupt work? + +When you select the `Interrupts` dropdown and select a node to interrupt the graph will pause execution before and after (unless the node goes straight to `END`) that node has run. This means that you will be able to both edit the state before the node is ran and the state after the node has ran. This is intended to allow developers more fine-grained control over the behavior of a node and make it easier to observe how the node is behaving. You will not be able to edit the state after the node has ran if the node is the final node in the graph. + +### How do I reload the app? (desktop only) + +If you would like to reload the app, don't use Command+R as you might normally do. Instead, close and reopen the app for a full refresh. + +### How does automatic rebuilding work? (desktop only) + +One of the key features of LangGraph Studio is that it automatically rebuilds your image when you change the source code. This allows for a super fast development and testing cycle which makes it easy to iterate on your graph. There are two different ways that LangGraph rebuilds your image: either by editing the image or completely rebuilding it. + +#### Rebuilds from source code changes + +If you modified the source code only (no configuration or dependency changes!) then the image does not require a full rebuild, and LangGraph Studio will only update the relevant parts. The UI status in the bottom left will switch from `Online` to `Stopping` temporarily while the image gets edited. The logs will be shown as this process is happening, and after the image has been edited the status will change back to `Online` and you will be able to run your graph with the modified code! + + +#### Rebuilds from configuration or dependency changes + +If you edit your graph configuration file (`langgraph.json`) or the dependencies (either `pyproject.toml` or `requirements.txt`) then the entire image will be rebuilt. This will cause the UI to switch away from the graph view and start showing the logs of the new image building process. This can take a minute or two, and once it is done your updated image will be ready to use! + +### Why is my graph taking so long to startup? (desktop only) + +The LangGraph Studio interacts with a local LangGraph API server. To stay aligned with ongoing updates, the LangGraph API requires regular rebuilding. As a result, you may occasionally experience slight delays when starting up your project. + +## Why are extra edges showing up in my graph? + +If you don't define your conditional edges carefully, you might notice extra edges appearing in your graph. This is because without proper definition, LangGraph Studio assumes the conditional edge could access all other nodes. In order for this to not be the case, you need to be explicit about how you define the nodes the conditional edge routes to. There are two ways you can do this: + +### Solution 1: Include a path map + +The first way to solve this is to add path maps to your conditional edges. A path map is just a dictionary or array that maps the possible outputs of your router function with the names of the nodes that each output corresponds to. The path map is passed as the third argument to the `add_conditional_edges` function like so: + +=== "Python" + + ```python + graph.add_conditional_edges("node_a", routing_function, {True: "node_b", False: "node_c"}) + ``` + +=== "Javascript" + + ```ts + graph.addConditionalEdges("node_a", routingFunction, { true: "node_b", false: "node_c" }); + ``` + +In this case, the routing function returns either True or False, which map to `node_b` and `node_c` respectively. + +### Solution 2: Update the typing of the router (Python only) + +Instead of passing a path map, you can also be explicit about the typing of your routing function by specifying the nodes it can map to using the `Literal` python definition. Here is an example of how to define a routing function in that way: + +```python +def routing_function(state: GraphState) -> Literal["node_b","node_c"]: + if state['some_condition'] == True: + return "node_b" + else: + return "node_c" +``` + + +## Related + +For more information please see the following: + +* [LangGraph Studio how-to guides](../how-tos/index.md#langgraph-studio) \ No newline at end of file diff --git a/docs/docs/concepts/sdk.md b/docs/docs/concepts/sdk.md new file mode 100644 index 000000000..b3b07bc9d --- /dev/null +++ b/docs/docs/concepts/sdk.md @@ -0,0 +1,56 @@ +# LangGraph SDK + +!!! info "Prerequisites" + - [LangGraph Platform](./langgraph_platform.md) + - [LangGraph Server](./langgraph_server.md) + +The LangGraph Platform provides both a Python and JS SDK for interacting with the [LangGraph Server API](./langgraph_server.md). + +## Installation + +You can install the packages using the appropriate package manager for your language. + +=== "Python" + ```bash + pip install langgraph-sdk + ``` + +=== "JS" + ```bash + yarn add @langchain/langgraph-sdk + ``` + + +## API Reference + +You can find the API reference for the SDKs here: + +- [Python SDK Reference](../cloud/reference/sdk/python_sdk_ref.md) +- [JS/TS SDK Reference](../cloud/reference/sdk/js_ts_sdk_ref.md) + +## Python Sync vs. Async + +The Python SDK provides both synchronous (`get_sync_client`) and asynchronous (`get_client`) clients for interacting with the LangGraph Server API. + +=== "Async" + ```python + from langgraph_sdk import get_client + + client = get_client(url=..., api_key=...) + await client.assistants.search() + ``` + +=== "Sync" + + ```python + from langgraph_sdk import get_sync_client + + client = get_sync_client(url=..., api_key=...) + client.assistants.search() + ``` + +## Related + +- [LangGraph CLI API Reference](../cloud/reference/cli.md) +- [Python SDK Reference](../cloud/reference/sdk/python_sdk_ref.md) +- [JS/TS SDK Reference](../cloud/reference/sdk/js_ts_sdk_ref.md) \ No newline at end of file diff --git a/docs/docs/concepts/streaming.md b/docs/docs/concepts/streaming.md index 8c557558d..052715a01 100644 --- a/docs/docs/concepts/streaming.md +++ b/docs/docs/concepts/streaming.md @@ -9,8 +9,23 @@ There are several different modes you can specify when calling these methods (e. - [`"values"`](../how-tos/stream-values.ipynb): This streams the full value of the state after each step of the graph. - [`"updates"`](../how-tos/stream-updates.ipynb): This streams the updates to the state after each step of the graph. If multiple updates are made in the same step (e.g. multiple nodes are run) then those updates are streamed separately. +- [`"custom"`](../how-tos/streaming-content.ipynb): This streams custom data from inside your graph nodes. +- [`"messages"`](../how-tos/streaming-tokens.ipynb): This streams LLM tokens and metadata for the graph node where LLM is invoked. - `"debug"`: This streams as much information as possible throughout the execution of the graph. +You can also specify multiple streaming modes at the same time by passing them as a list. When you do this, the streamed outputs will be tuples `(stream_mode, data)`. For example: + +```python +graph.stream(..., stream_mode=["updates", "messages"]) +``` + +``` +... +('messages', (AIMessageChunk(content='Hi'), {'langgraph_step': 3, 'langgraph_node': 'agent', ...})) +... +('updates', {'agent': {'messages': [AIMessage(content="Hi, how can I help you?")]}}) +``` + The below visualization shows the difference between the `values` and `updates` modes: ![values vs updates](../static/values_vs_updates.png) @@ -130,4 +145,107 @@ guide for that [here](../how-tos/streaming-tokens.ipynb). !!! warning "ASYNC IN PYTHON<=3.10" - You may fail to see events being emitted from inside a node when using `.astream_events` in Python <= 3.10. If you're using a Langchain RunnableLambda, a RunnableGenerator, or Tool asynchronously inside your node, you will have to propagate callbacks to these objects manually. This is because LangChain cannot automatically propagate callbacks to child objects in this case. Please see examples [here](../how-tos/streaming-content.ipynb) and [here](../how-tos/streaming-events-from-within-tools.ipynb). \ No newline at end of file + You may fail to see events being emitted from inside a node when using `.astream_events` in Python <= 3.10. If you're using a Langchain RunnableLambda, a RunnableGenerator, or Tool asynchronously inside your node, you will have to propagate callbacks to these objects manually. This is because LangChain cannot automatically propagate callbacks to child objects in this case. Please see examples [here](../how-tos/streaming-content.ipynb) and [here](../how-tos/streaming-events-from-within-tools.ipynb). + + +## LangGraph Platform + +Streaming is critical for making LLM applications feel responsive to end users. When creating a streaming run, the streaming mode determines what data is streamed back to the API client. LangGraph Platform supports five streaming modes: + +- `values`: Stream the full state of the graph after each [super-step](https://langchain-ai.github.io/langgraph/concepts/low_level/#graphs) is executed. See the [how-to guide](../cloud/how-tos/stream_values.md) for streaming values. +- `messages`: Stream complete messages (at the end of node execution) as well as tokens for any messages generated inside a node. This mode is primarily meant for powering chat applications. This is only an option if your graph contains a `messages` key. See the [how-to guide](../cloud/how-tos/stream_messages.md) for streaming messages. +- `updates`: Streams updates to the state of the graph after each node is executed. See the [how-to guide](../cloud/how-tos/stream_updates.md) for streaming updates. +- `events`: Stream all events (including the state of the graph) that occur during graph execution. See the [how-to guide](../cloud/how-tos/stream_events.md) for streaming events. This can be used to do token-by-token streaming for LLMs. +- `debug`: Stream debug events throughout graph execution. See the [how-to guide](../cloud/how-tos/stream_debug.md) for streaming debug events. + +You can also specify multiple streaming modes at the same time. See the [how-to guide](../cloud/how-tos/stream_multiple.md) for configuring multiple streaming modes at the same time. + +See the [API reference](../cloud/reference/api/api_ref.html#tag/threads-runs/POST/threads/{thread_id}/runs/stream) for how to create streaming runs. + +Streaming modes `values`, `updates`, and `debug` are very similar to modes available in the LangGraph library - for a deeper conceptual explanation of those, you can see the [previous section](#streaming-graph-outputs-stream-and-astream). + +Streaming mode `events` is the same as using `.astream_events` in the LangGraph library - for a deeper conceptual explanation of this, you can see the [previous section](#streaming-graph-outputs-stream-and-astream). + +### `stream_mode="messages"` + +Streaming mode `messages` is for streaming back messages from the LLM. Assuming we have a simple [ReAct](./agentic_concepts.md#react-implementation)-style agent deployed, what does this stream look like? + +All events emitted have two attributes: + +- `event`: This is the name of the event +- `data`: This is data associated with the event + +!!! note + Streaming mode `messages` is different from the one in the LangGraph library: + + - LangGraph Server streams event objects with messages in the `data` field, while LangGraph library streams tuples (`AIMessageChunk`, metadata). + - In LangGraph Server, metadata is streamed only once per message (`messages/metadata`), before the individual tokens are streamed (`messages/partial`), while in LangGraph library it's streamed with every `AIMessageChunk` (for each LLM token). + - LangGraph Server also streams additional events (`metadata`, `messages/complete`, see below for more details). + +Let's run it on a question that should trigger a tool call: + +```python +thread = await client.threads.create() +input = {"messages": [{"role": "user", "content": "what's the weather in sf?"}]} + +events = [] +async for event in client.runs.stream( + thread["thread_id"], + assistant_id="agent", # This may need to change depending on the graph you deployed + input=input, + stream_mode="messages", +): + print(event.event) +``` +```shell +metadata +messages/metadata +messages/partial +... +messages/partial +messages/metadata +messages/complete +messages/metadata +messages/partial +... +messages/partial +end +``` + +We first get some `metadata` - this is metadata about the run. + +```python +StreamPart(event='metadata', data={'run_id': '1ef657cf-ae55-6f65-97d4-f4ed1dbdabc6'}) +``` + +We then get a `messages/metadata` - this is letting us know that a new message is starting and provides additional information about the LLM as well as the node where the LLM is invoked. + +```python +StreamPart(event='messages/metadata', data={'run-985c0f14-9f43-40d4-a505-4637fc58e333': {'metadata': {'created_by': 'system', 'run_id': '1ef657de-7594-66df-8eb2-31518e4a1ee2', 'graph_id': 'agent', 'thread_id': 'c178eab5-e293-423c-8e7d-1d113ffe7cd9', 'model_name': 'openai', 'assistant_id': 'fe096781-5601-53d2-b2f6-0d3403f7e9ca', 'langgraph_step': 1, 'langgraph_node': 'agent', 'langgraph_triggers': ['start:agent'], 'langgraph_task_idx': 0, 'ls_provider': 'openai', 'ls_model_name': 'gpt-4o', 'ls_model_type': 'chat', 'ls_temperature': 0.0}}}) +``` + +We then get a BUNCH of `messages/partial` events - these are the individual tokens from the LLM! In the case below, we can see the START of a tool call. + +```python +StreamPart(event='messages/partial', data=[{'content': '', 'additional_kwargs': {'tool_calls': [{'index': 0, 'id': 'call_w8Hr8dHGuZCPgRfd5FqRBArs', 'function': {'arguments': '', 'name': 'tavily_search_results_json'}, 'type': 'function'}]}, 'response_metadata': {}, 'type': 'ai', 'name': None, 'id': 'run-985c0f14-9f43-40d4-a505-4637fc58e333', 'example': False, 'tool_calls': [], 'invalid_tool_calls': [{'name': 'tavily_search_results_json', 'args': '', 'id': 'call_w8Hr8dHGuZCPgRfd5FqRBArs', 'error': None}], 'usage_metadata': None}]) +``` + +The last `messages/partial` event for a given message will contain all of the tokens streamed for that message. In our case, it is now a complete tool call: + +```python +StreamPart(event='messages/partial', data=[{'content': '', 'additional_kwargs': {'tool_calls': [{'index': 0, 'id': 'call_w8Hr8dHGuZCPgRfd5FqRBArs', 'function': {'arguments': '{"query":"current weather in San Francisco"}', 'name': 'tavily_search_results_json'}, 'type': 'function'}]}, 'response_metadata': {'finish_reason': 'tool_calls', 'model_name': 'gpt-4o-2024-05-13', 'system_fingerprint': 'fp_157b3831f5'}, 'type': 'ai', 'name': None, 'id': 'run-985c0f14-9f43-40d4-a505-4637fc58e333', 'example': False, 'tool_calls': [{'name': 'tavily_search_results_json', 'args': {'query': 'current weather in San Francisco'}, 'id': 'call_w8Hr8dHGuZCPgRfd5FqRBArs'}], 'invalid_tool_calls': [], 'usage_metadata': None}]) +``` + +After that, we get another `messages/metadata`, now followed by a `messages/complete` event. This event is emitted for a tool message - our agent has called a tool, gotten a response, and now inserting it into the state in the form of a tool message. + +```python +StreamPart(event='messages/complete', data=[{'content': '[{"url": "https://www.weatherapi.com/", "content": "{\'location\': {\'name\': \'San Francisco\', \'region\': \'California\', \'country\': \'United States of America\', \'lat\': 37.78, \'lon\': -122.42, \'tz_id\': \'America/Los_Angeles\', \'localtime_epoch\': 1724877689, \'localtime\': \'2024-08-28 13:41\'}, \'current\': {\'last_updated_epoch\': 1724877000, \'last_updated\': \'2024-08-28 13:30\', \'temp_c\': 23.3, \'temp_f\': 73.9, \'is_day\': 1, \'condition\': {\'text\': \'Partly cloudy\', \'icon\': \'//cdn.weatherapi.com/weather/64x64/day/116.png\', \'code\': 1003}, \'wind_mph\': 15.0, \'wind_kph\': 24.1, \'wind_degree\': 310, \'wind_dir\': \'NW\', \'pressure_mb\': 1014.0, \'pressure_in\': 29.93, \'precip_mm\': 0.0, \'precip_in\': 0.0, \'humidity\': 57, \'cloud\': 25, \'feelslike_c\': 25.0, \'feelslike_f\': 77.1, \'windchill_c\': 20.9, \'windchill_f\': 69.6, \'heatindex_c\': 23.3, \'heatindex_f\': 74.0, \'dewpoint_c\': 12.9, \'dewpoint_f\': 55.2, \'vis_km\': 16.0, \'vis_miles\': 9.0, \'uv\': 6.0, \'gust_mph\': 19.5, \'gust_kph\': 31.3}}"}]', 'additional_kwargs': {}, 'response_metadata': {}, 'type': 'tool', 'name': 'tavily_search_results_json', 'id': '0112eba5-7660-4375-9f24-c7a1d6777b97', 'tool_call_id': 'call_w8Hr8dHGuZCPgRfd5FqRBArs'}]) +``` + +After that, we see the agent doing another LLM call and streaming back a response. We then get an `end` event: + +```python +StreamPart(event='end', data=None) +``` + +And that's it! This is more focused streaming mode specifically focused on streaming back messages. See this [how-to guide](../cloud/how-tos/stream_messages.md) for more information. \ No newline at end of file diff --git a/docs/docs/concepts/template_applications.md b/docs/docs/concepts/template_applications.md new file mode 100644 index 000000000..9585c86d4 --- /dev/null +++ b/docs/docs/concepts/template_applications.md @@ -0,0 +1,27 @@ +# Template Applications + +!!! note Prerequisites + + - [LangGraph Studio](./langgraph_studio.md) + +Templates are open source reference applications designed to help you get started quickly when building with LangGraph. They provide working examples of common agentic workflows that can be customized to your needs. + +Templates can be accessed via [LangGraph Studio](langgraph_studio.md), or cloned directly from Github. You can download LangGraph Studio and see available templates [here](https://studio.langchain.com/). + +## Available templates + +- **New LangGraph Project**: A simple, minimal chatbot with memory. + - [Python](https://github.com/langchain-ai/new-langgraph-project) + - [JS/TS](https://github.com/langchain-ai/new-langgraphjs-project) +- **ReAct Agent**: A simple agent that can be flexibly extended to many tools. + - [Python](https://github.com/langchain-ai/react-agent) + - [JS/TS](https://github.com/langchain-ai/react-agent-js) +- **Memory Agent**: A ReAct-style agent with an additional tool to store memories for use across conversational threads. + - [Python](https://github.com/langchain-ai/memory-agent) + - [JS/TS](https://github.com/langchain-ai/memory-agent-js) +- **Retrieval Agent**: An agent that includes a retrieval-based question-answering system. + - [Python](https://github.com/langchain-ai/retrieval-agent-template) + - [JS/TS](https://github.com/langchain-ai/retrieval-agent-template-js) +- **Data-enrichment Agent**: An agent that performs web searches and organizes its findings into a structured format. + - [Python](https://github.com/langchain-ai/data-enrichment) + - [JS/TS](https://github.com/langchain-ai/data-enrichment-js) diff --git a/docs/docs/how-tos/deploy-self-hosted.md b/docs/docs/how-tos/deploy-self-hosted.md new file mode 100644 index 000000000..d1454c07f --- /dev/null +++ b/docs/docs/how-tos/deploy-self-hosted.md @@ -0,0 +1,132 @@ +# How to do a Self-hosted deployment of LangGraph + +!!! info "Prerequisites" + + - [Application Structure](../concepts/application_structure.md) + - [Deployment Options](../concepts/deployment_options.md) + +This how-to guide will walk you through how to create a docker image from an existing LangGraph application, so you can deploy it on your own infrastructure. + +## How it works + +With the self-hosted deployment option, you are responsible for managing the infrastructure, including setting up and maintaining necessary databases, Redis instances, and other services. + +You will need to do the following: + +1. Deploy Redis and Postgres instances on your own infrastructure. +2. Build a docker image with the LangGraph Deploy server using the LangGraph CLI. +3. Deploy a web server that will run the docker image and pass in the necessary environment variables. + +## Environment Variables + +You will eventually need to pass in the following environment variables to the LangGraph Deploy server: + +- `REDIS_URI`: Connection details to a Redis instance. Redis will be used as a pub-sub broker to enable streaming real time output from background runs. +- `DATABASE_URI`: Postgres connection details. Postgres will be used to store assistants, threads, runs, persist thread state and long term memory, and to manage the state of the background task queue with 'exactly once' semantics. +- `LANGSMITH_API_KEY`: LangSmith API key. This will be used to authenticate ONCE at server start up. + + +## Build the Docker Image + +Please read the [Application Structure](../concepts/application_structure.md) guide to understand how to structure your LangGraph application. + +If the application is structured correctly, you can build a docker image with the LangGraph Deploy server. + +To build the docker image, you first need to install the CLI: + +```shell +pip install -U langgraph-cli +``` + +You can then use: + +``` +langgraph build -t my-image +``` + +This will build a docker image with the LangGraph Deploy server. The `-t my-image` is used to tag the image with a name. + +When running this server, you need to pass three environment variables: + +## Running the application locally + +### Using Docker + +```shell +docker run \ + -e REDIS_URI="foo" \ + -e DATABASE_URI="bar" \ + -e LANGSMITH_API_KEY="baz" \ + my-image +``` + +If you want to run this quickly without setting up a separate Redis and Postgres instance, you can use this docker compose file. + +!!! note + + * You need to replace `my-image` with the name of the image you built in the previous step (from `langgraph build`). + and you should provide appropriate values for `REDIS_URI`, `DATABASE_URI`, and `LANGSMITH_API_KEY`. + * If your application requires additional environment variables, you can pass them in a similar way. + +### Using Docker Compose + +```yml +volumes: + langgraph-data: + driver: local +services: + langgraph-redis: + image: redis:6 + healthcheck: + test: redis-cli ping + interval: 5s + timeout: 1s + retries: 5 + langgraph-postgres: + image: postgres:16 + ports: + - "5433:5432" + environment: + POSTGRES_DB: postgres + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + volumes: + - langgraph-data:/var/lib/postgresql/data + healthcheck: + test: pg_isready -U postgres + start_period: 10s + timeout: 1s + retries: 5 + interval: 5s + langgraph-api: + image: ${IMAGE_NAME} + ports: + - "8123:8000" + depends_on: + langgraph-redis: + condition: service_healthy + langgraph-postgres: + condition: service_healthy + env_file: + - .env + environment: + REDIS_URI: redis://langgraph-redis:6379 + LANGSMITH_API_KEY: ${LANGSMITH_API_KEY} + POSTGRES_URI: postgres://postgres:postgres@langgraph-postgres:5432/postgres?sslmode=disable +``` + +You can then run `docker compose up` with this Docker compose file in the same folder. + +This will spin up LangGraph Deploy on port `8123` (if you want to change this, you can change this by changing the ports in the `langgraph-api` volume). + +You can test that the application is up by checking: + +```shell +curl --request GET --url 0.0.0.0:8123/ok +``` +Assuming everything is running correctly, you should see a response like: + +```shell +{"ok":true} +``` + diff --git a/docs/docs/how-tos/index.md b/docs/docs/how-tos/index.md index bb3b29c63..3b9ccbcf5 100644 --- a/docs/docs/how-tos/index.md +++ b/docs/docs/how-tos/index.md @@ -7,9 +7,11 @@ description: How to accomplish common tasks in LangGraph # How-to Guides -Welcome to the LangGraph how-to guides! These guides provide practical, step-by-step instructions for accomplishing key tasks in LangGraph. +Here you’ll find answers to “How do I...?” types of questions. These guides are **goal-oriented** and concrete; they're meant to help you complete a specific task. For conceptual explanations see the [Conceptual guide](../concepts/index.md). For end-to-end walk-throughs see [Tutorials](../tutorials/index.md). For comprehensive descriptions of every class and function see the [API Reference](../reference/index.md). -## Controllability +## LangGraph + +### Controllability LangGraph offers a high level of control over the execution of your graph. @@ -19,7 +21,7 @@ These how-to guides show how to achieve that controllability. - [How to create map-reduce branches for parallel execution](map-reduce.ipynb) - [How to control graph recursion limit](recursion-limit.ipynb) -## Persistence +### Persistence [LangGraph Persistence](../concepts/persistence.md) makes it easy to persist state across graph runs (thread-level persistence) and across threads (cross-thread persistence). These how-to guides show how to add persistence to your graph. @@ -30,7 +32,7 @@ These how-to guides show how to achieve that controllability. - [How to create a custom checkpointer using MongoDB](persistence_mongodb.ipynb) - [How to create a custom checkpointer using Redis](persistence_redis.ipynb) -## Memory +### Memory LangGraph makes it easy to manage conversation [memory](../concepts/memory.md) in your graph. These how-to guides show how to implement different strategies for that. @@ -38,7 +40,7 @@ LangGraph makes it easy to manage conversation [memory](../concepts/memory.md) i - [How to delete messages](memory/delete-messages.ipynb) - [How to add summary conversation memory](memory/add-summary-conversation-history.ipynb) -## Human in the Loop +### Human in the Loop [Human-in-the-loop](../concepts/human_in_the_loop.md) functionality allows you to involve humans in the decision-making process of your graph. These how-to guides show how to implement human-in-the-loop workflows in your graph. @@ -48,9 +50,9 @@ you to involve humans in the decision-making process of your graph. These how-to - [How to edit graph state](human_in_the_loop/edit-graph-state.ipynb) - [How to wait for user input](human_in_the_loop/wait-user-input.ipynb) - [How to view and update past graph state](human_in_the_loop/time-travel.ipynb) -- [Review tool calls](human_in_the_loop/review-tool-calls.ipynb) +- [How to review tool calls](human_in_the_loop/review-tool-calls.ipynb) -## Streaming +### Streaming [Streaming](../concepts/streaming.md) is crucial for enhancing the responsiveness of applications built on LLMs. By displaying output progressively, even before a complete response is ready, streaming significantly improves user experience (UX), particularly when dealing with the latency of LLMs. @@ -66,7 +68,7 @@ you to involve humans in the decision-making process of your graph. These how-to - [How to stream from subgraphs](streaming-subgraphs.ipynb) - [How to disable streaming for models that don't support it](disable-streaming.ipynb) -## Tool calling +### Tool calling [Tool calling](https://python.langchain.com/docs/concepts/tool_calling/) is a type of chat model API that accepts tool schemas, along with messages, as input and returns invocations of those tools as part of the output message. @@ -78,7 +80,7 @@ These how-to guides show common patterns for tool calling with LangGraph: - [How to pass config to tools](pass-config-to-tools.ipynb) - [How to handle large numbers of tools](many-tools.ipynb) -## Subgraphs +### Subgraphs [Subgraphs](../concepts/low_level.md#subgraphs) allow you to reuse an existing graph from another graph. These how-to guides show how to use subgraphs: @@ -86,13 +88,13 @@ These how-to guides show common patterns for tool calling with LangGraph: - [How to view and update state in subgraphs](subgraphs-manage-state.ipynb) - [How to transform inputs and outputs of a subgraph](subgraph-transform-state.ipynb) -## State Management +### State Management - [Use Pydantic model as state](state-model.ipynb) - [Have a separate input and output schema](input_output_schema.ipynb) - [Pass private state between nodes inside the graph](pass_private_state.ipynb) -## Other +### Other - [How to run graph asynchronously](async.ipynb) - [How to visualize your graph](visualization.ipynb) @@ -103,7 +105,7 @@ These how-to guides show common patterns for tool calling with LangGraph: - [How to pass custom LangSmith run ID for graph runs](run-id-langsmith.ipynb) - [How to return state before hitting recursion limit](return-when-recursion-limit-hits.ipynb) -## Prebuilt ReAct Agent +### Prebuilt ReAct Agent The LangGraph [prebuilt ReAct agent](../reference/prebuilt.md#langgraph.prebuilt.chat_agent_executor.create_react_agent) is pre-built implementation of a [tool calling agent](../concepts/agentic_concepts.md#tool-calling-agent). @@ -117,9 +119,107 @@ These guides show how to use the prebuilt ReAct agent: - [How to add human-in-the-loop processes to a ReAct agent](create-react-agent-hitl.ipynb) - [How to create prebuilt ReAct agent from scratch](react-agent-from-scratch.ipynb) +## LangGraph Platform + +This section includes how-to guides for LangGraph Platform. + +LangGraph Platform is a commercial solution for deploying agentic applications in production, built on the open-source LangGraph framework. + +The LangGraph Platform offers a few different deployment options described in the [deployment options guide](../concepts/deployment_options.md). + +!!! tip + + * LangGraph is an MIT-licensed open-source library, which we are committed to maintaining and growing for the community. + * You can always deploy LangGraph applications on your own infrastructure using the open-source LangGraph project without using LangGraph Platform. + +### Application Structure + +Learn how to set up your app for deployment to LangGraph Platform: + +- [How to set up app for deployment (requirements.txt)](../cloud/deployment/setup.md) +- [How to set up app for deployment (pyproject.toml)](../cloud/deployment/setup_pyproject.md) +- [How to set up app for deployment (JavaScript)](../cloud/deployment/setup_javascript.md) +- [How to customize Dockerfile](../cloud/deployment/custom_docker.md) +- [How to test locally](../cloud/deployment/test_locally.md) + +### Deployment + +LangGraph applications can be deployed using LangGraph Cloud, which provides a range of services to help you deploy, manage, and scale your applications. + +- [How to deploy to LangGraph cloud](../cloud/deployment/cloud.md) +- [How to deploy to a self-hosted environment](./deploy-self-hosted.md) +- [How to interact with the deployment using RemoteGraph](./use-remote-graph.md) +### Assistants + +[Assistants](../concepts/assistants.md) is a configured instance of a template. + +- [How to configure agents](../cloud/how-tos/configuration_cloud.md) +- [How to version assistants](../cloud/how-tos/assistant_versioning.md) + +### Threads + +- [How to copy threads](../cloud/how-tos/copy_threads.md) +- [How to check status of your threads](../cloud/how-tos/check_thread_status.md) + +### Runs + +LangGraph Cloud supports multiple types of runs besides streaming runs. + +- [How to run an agent in the background](../cloud/how-tos/background_run.md) +- [How to run multiple agents in the same thread](../cloud/how-tos/same-thread.md) +- [How to create cron jobs](../cloud/how-tos/cron_jobs.md) +- [How to create stateless runs](../cloud/how-tos/stateless_runs.md) + +### Streaming + +Streaming the results of your LLM application is vital for ensuring a good user experience, especially when your graph may call multiple models and take a long time to fully complete a run. Read about how to stream values from your graph in these how to guides: + +- [How to stream values](../cloud/how-tos/stream_values.md) +- [How to stream updates](../cloud/how-tos/stream_updates.md) +- [How to stream messages](../cloud/how-tos/stream_messages.md) +- [How to stream events](../cloud/how-tos/stream_events.md) +- [How to stream in debug mode](../cloud/how-tos/stream_debug.md) +- [How to stream multiple modes](../cloud/how-tos/stream_multiple.md) + +### Human-in-the-loop + +When creating complex graphs, leaving every decision up to the LLM can be dangerous, especially when the decisions involve invoking certain tools or accessing specific documents. To remedy this, LangGraph allows you to insert human-in-the-loop behavior to ensure your graph does not have undesired outcomes. Read more about the different ways you can add human-in-the-loop capabilities to your LangGraph Cloud projects in these how-to guides: + +- [How to add a breakpoint](../cloud/how-tos/human_in_the_loop_breakpoint.md) +- [How to wait for user input](../cloud/how-tos/human_in_the_loop_user_input.md) +- [How to edit graph state](../cloud/how-tos/human_in_the_loop_edit_state.md) +- [How to replay and branch from prior states](../cloud/how-tos/human_in_the_loop_time_travel.md) +- [How to review tool calls](../cloud/how-tos/human_in_the_loop_review_tool_calls.md) + +### Double-texting + +Graph execution can take a while, and sometimes users may change their mind about the input they wanted to send before their original input has finished running. For example, a user might notice a typo in their original request and will edit the prompt and resend it. Deciding what to do in these cases is important for ensuring a smooth user experience and preventing your graphs from behaving in unexpected ways. The following how-to guides provide information on the various options LangGraph Cloud gives you for dealing with double-texting: + +- [How to use the interrupt option](../cloud/how-tos/interrupt_concurrent.md) +- [How to use the rollback option](../cloud/how-tos/rollback_concurrent.md) +- [How to use the reject option](../cloud/how-tos/reject_concurrent.md) +- [How to use the enqueue option](../cloud/how-tos/enqueue_concurrent.md) + +### Webhooks + +- [How to integrate webhooks](../cloud/how-tos/webhooks.md) + +### Cron Jobs + +- [How to create cron jobs](../cloud/how-tos/cron_jobs.md) + +### LangGraph Studio + +LangGraph Studio is a built-in UI for visualizing, testing, and debugging your agents. + +- [How to connect to a LangGraph Cloud deployment](../cloud/how-tos/test_deployment.md) +- [How to connect to a local deployment](../cloud/how-tos/test_local_deployment.md) +- [How to test your graph in LangGraph Studio](../cloud/how-tos/invoke_studio.md) +- [How to interact with threads in LangGraph Studio](../cloud/how-tos/threads_studio.md) + ## Troubleshooting -The [Error Reference](../troubleshooting/errors/index.md) page contains guides around resolving common errors you may find while building with LangChain. Errors referenced below will have an `lc_error_code` property corresponding to one of the below codes when they are thrown in code. +The [Error Reference](../troubleshooting/errors/index.md) page contains guides around resolving common errors you may find while building with LangGraph. Errors referenced below will have an `lc_error_code` property corresponding to one of the below codes when they are thrown in code. - [GRAPH_RECURSION_LIMIT](../troubleshooting/errors/GRAPH_RECURSION_LIMIT.md) - [INVALID_CONCURRENT_GRAPH_UPDATE](../troubleshooting/errors/INVALID_CONCURRENT_GRAPH_UPDATE.md) diff --git a/docs/docs/how-tos/use-remote-graph.md b/docs/docs/how-tos/use-remote-graph.md new file mode 100644 index 000000000..b7a5ec76b --- /dev/null +++ b/docs/docs/how-tos/use-remote-graph.md @@ -0,0 +1,242 @@ +# How to interact with the deployment using RemoteGraph + +!!! info "Prerequisites" + - [LangGraph Platform](../concepts/langgraph_platform.md) + - [LangGraph Server](../concepts/langgraph_server.md) + +`RemoteGraph` is an interface that allows you to interact with your LangGraph Platform deployment as if it were a regular, locally-defined LangGraph graph (e.g. a `CompiledGraph`). This guide shows you how you can initialize a `RemoteGraph` and interact with it. + +## Initializing the graph + +When initializing a `RemoteGraph`, you must always specify: + +- `name`: the name of the graph you want to interact with. This is the same graph name you use in `langgraph.json` configuration file for your deployment. +- `api_key`: a valid LangSmith API key. Can be set as an environment variable (`LANGSMITH_API_KEY`) or passed directly via the `api_key` argument. The API key could also be provided via the `client` / `sync_client` arguments, if `LangGraphClient` / `SyncLangGraphClient` were initialized with `api_key` argument. + +Additionally, you have to provide one of the following: + +- `url`: URL of the deployment you want to interact with. If you pass `url` argument, both sync and async clients will be created using the provided URL, headers (if provided) and default configuration values (e.g. timeout, etc). +- `client`: a `LangGraphClient` instance for interacting with the deployment asynchronously (e.g. using `.astream()`, `.ainvoke()`, `.aget_state()`, `.aupdate_state()`, etc.) +- `sync_client`: a `SyncLangGraphClient` instance for interacting with the deployment synchronously (e.g. using `.stream()`, `.invoke()`, `.get_state()`, `.update_state()`, etc.) + +!!! Note + + If you pass both `client` or `sync_client` as well as `url` argument, they will take precedence over the `url` argument. If none of the `client` / `sync_client` / `url` arguments are provided, `RemoteGraph` will raise a `ValueError` at runtime. + + +### Using URL + +=== "Python" + + ```python + from langgraph.pregel.remote import RemoteGraph + + url = + graph_name = "agent" + remote_graph = RemoteGraph(graph_name, url=url) + ``` + +=== "JavaScript" + + ```js + import { RemoteGraph } from "@langchain/langgraph/remote"; + + const url = ; + const graphName = "agent"; + const remoteGraph = new RemoteGraph({ graphId: graphName, url }); + ``` + +### Using clients + +=== "Python" + + ```python + from langgraph_sdk import get_client, get_sync_client + from langgraph.pregel.remote import RemoteGraph + + url = + graph_name = "agent" + client = get_client(url=url) + sync_client = get_sync_client(url=url) + remote_graph = RemoteGraph(graph_name, client=client, sync_client=sync_client) + ``` + +=== "JavaScript" + + ```js + import { Client } from "@langchain/langgraph-sdk"; + import { RemoteGraph } from "@langchain/langgraph/remote"; + + const client = new Client({ apiUrl: }); + const graphName = "agent"; + const remoteGraph = new RemoteGraph({ graphId: graphName, client }); + ``` + +## Invoking the graph + +Since `RemoteGraph` is a `Runnable` that implements the same methods as `CompiledGraph`, you can interact with it the same way you normally would with a compiled graph, i.e. by calling `.invoke()`, `.stream()`, `.get_state()`, `.update_state()`, etc (as well as their async counterparts). + +### Asynchronously + +!!! Note + + To use the graph asynchronously, you must provide either the `url` or `client` when initializing the `RemoteGraph`. + +=== "Python" + + ```python + # invoke the graph + result = await remote_graph.ainvoke({ + "messages": [{"role": "user", "content": "what's the weather in sf"}] + }) + + # stream outputs from the graph + async for chunk in remote_graph.astream({ + "messages": [("user", "what's the weather in la?")] + }): + print(chunk) + ``` + +=== "JavaScript" + + ```js + // invoke the graph + const result = await remoteGraph.invoke({ + messages: [{role: "user", content: "what's the weather in sf"}] + }) + + // stream outputs from the graph + for await (const chunk of await remoteGraph.stream({ + messages: [{role: "user", content: "what's the weather in la"}] + })): + console.log(chunk) + ``` + +### Synchronously + +!!! Note + + To use the graph synchronously, you must provide either the `url` or `sync_client` when initializing the `RemoteGraph`. + +=== "Python" + + ```python + # invoke the graph + result = remote_graph.invoke({ + "messages": [{"role": "user", "content": "what's the weather in sf"}] + }) + + # stream outputs from the graph + for chunk in remote_graph.stream({ + "messages": [("user", "what's the weather in la?")] + }): + print(chunk) + ``` + +## Thread-level persistence + +By default, the graph runs (i.e. `.invoke()` or `.stream()` invocations) are stateless - the checkpoints and the final state of the graph are not persisted. If you would like to persist the outputs of the graph run (for example, to enable human-in-the-loop features), you can create a thread and provide the thread ID via the `config` argument, same as you would with a regular compiled graph: + +=== "Python" + + ```python + from langgraph_sdk import get_sync_client + url = + graph_name = "agent" + sync_client = get_sync_client(url=url) + remote_graph = RemoteGraph(graph_name, url=url) + + # create a thread (or use an existing thread instead) + thread = sync_client.threads.create() + + # invoke the graph with the thread config + config = {"configurable": {"thread_id": thread["thread_id"]}} + result = remote_graph.invoke({ + "messages": [{"role": "user", "content": "what's the weather in sf"}], config=config + }) + + # verify that the state was persisted to the thread + thread_state = remote_graph.get_state(config) + print(thread_state) + ``` + +=== "JavaScript" + + ```js + import { Client } from "@langchain/langgraph-sdk"; + const url = ; + const graphName = "agent"; + const client = new Client({ apiUrl: url }); + const remoteGraph = new RemoteGraph({ graphId: graphName, url }); + + // create a thread (or use an existing thread instead) + const thread = await client.threads.create(); + + // invoke the graph with the thread config + const config = { configurable: { thread_id: thread["thread_id"] }}; + const result = await remoteGraph.invoke({ + messages: [{ role: "user", content: "what's the weather in sf" }], + config + }); + + // verify that the state was persisted to the thread + const threadState = await remoteGraph.getState(config); + console.log(threadState); + ``` + +## Using as a subgraph + +!!! Note + + If you need to use a `checkpointer` with a graph that has a `RemoteGraph` subgraph node, make sure to use UUIDs as thread IDs. + + +Since the `RemoteGraph` behaves the same way as a regular `CompiledGraph`, it can be also used as a subgraph in another graph. For example: + +=== "Python" + + ```python + from langgraph_sdk import get_sync_client + from langgraph.graph import StateGraph, MessagesState, START + from typing import TypedDict + + url = + graph_name = "agent" + remote_graph = RemoteGraph(graph_name, url=url) + + # define parent graph + builder = StateGraph(MessagesState) + # add remote graph directly as a node + builder.add_node("child", remote_graph) + builder.add_edge(START, "child") + graph = builder.compile() + + # invoke the parent graph + result = graph.invoke({ + "messages": [{"role": "user", "content": "what's the weather in sf"}] + }) + print(result) + ``` + +=== "JavaScript" + + ```js + import { MessagesAnnotation, StateGraph, START } from "@langchain/langgraph"; + import { RemoteGraph } from "@langchain/langgraph-sdk"; + + const url = ; + const graphName = "agent"; + const remoteGraph = new RemoteGraph({ graphId: graphName, url }); + + // define parent graph and add remote graph directly as a node + const graph = new StateGraph(MessagesAnnotation) + .addNode("child", remoteGraph) + .addEdge("START", "child") + .compile() + + // invoke the parent graph + const result = await graph.invoke({ + messages: [{ role: "user", content: "what's the weather in sf" }] + }); + console.log(result); + ``` \ No newline at end of file diff --git a/docs/docs/tutorials/index.md b/docs/docs/tutorials/index.md index 9e570e413..0c5687fd4 100644 --- a/docs/docs/tutorials/index.md +++ b/docs/docs/tutorials/index.md @@ -12,7 +12,8 @@ Welcome to the LangGraph Tutorials! These notebooks introduce LangGraph through Learn the basics of LangGraph through a comprehensive quick start in which you will build an agent from scratch. -- [Quick Start](introduction.ipynb) +- [Quick Start](introduction.ipynb): In this tutorial, you will build a support chatbot using LangGraph. +- [LangGraph Cloud Quick Start](../cloud/quick_start.md): In this tutorial, you will build and deploy an agent to LangGraph Cloud. ## Use cases diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 2fb8bbdd6..2d760c1bb 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -79,10 +79,12 @@ plugins: filters: - "!^_" nav: - - "index.md" - - "tutorials/index.md" - - "concepts/index.md" - - "how-tos/index.md" + # Setting the names of the nav items explicitly due to mkdocs + # how-reload being a bit buggy with the names of the tabs. + - Home: "index.md" + - Tutorials: "tutorials/index.md" + - Concepts: "concepts/index.md" + - "How-to Guides": "how-tos/index.md" - Reference: - "reference/index.md" - Graphs: reference/graphs.md @@ -94,68 +96,12 @@ nav: - Errors: reference/errors.md - Types: reference/types.md - Constants: reference/constants.md - - "Cloud (beta)": - - "cloud/index.md" - - Tutorials: - - Quick Start: "cloud/quick_start.md" - - How-to Guides: - - "cloud/how-tos/index.md" - - Setup: - - Setup App: "cloud/deployment/setup.md" - - Setup App (pyproject.toml): "cloud/deployment/setup_pyproject.md" - - Setup App (JavaScript): "cloud/deployment/setup_javascript.md" - - Rebuild Graph at Runtime: "cloud/deployment/graph_rebuild.md" - - Customize Dockerfile: "cloud/deployment/custom_docker.md" - - Test App Locally: "cloud/deployment/test_locally.md" - - Deployment: - - Deploy to Cloud: "cloud/deployment/cloud.md" - - Streaming: - - Stream Values: "cloud/how-tos/stream_values.md" - - Stream Updates: "cloud/how-tos/stream_updates.md" - - Stream Messages: "cloud/how-tos/stream_messages.md" - - Stream Events: "cloud/how-tos/stream_events.md" - - Stream Debug: "cloud/how-tos/stream_debug.md" - - Multiple Modes: "cloud/how-tos/stream_multiple.md" - - Double Texting: - - Interrupt: "cloud/how-tos/interrupt_concurrent.md" - - Rollback: "cloud/how-tos/rollback_concurrent.md" - - Reject: "cloud/how-tos/reject_concurrent.md" - - Enqueue: "cloud/how-tos/enqueue_concurrent.md" - - Human-in-the-Loop: - - Add Breakpoint: "cloud/how-tos/human_in_the_loop_breakpoint.md" - - Wait for User Input: "cloud/how-tos/human_in_the_loop_user_input.md" - - Edit Graph State: "cloud/how-tos/human_in_the_loop_edit_state.md" - - Replay and Branch from Prior States: "cloud/how-tos/human_in_the_loop_time_travel.md" - - Review Tool Calls: "cloud/how-tos/human_in_the_loop_review_tool_calls.md" - - LangGraph Studio: - - Test Cloud Deployment: "cloud/how-tos/test_deployment.md" - - Test Local Deployment: "cloud/how-tos/test_local_deployment.md" - - Invoke graph in LangGraph Studio: "cloud/how-tos/invoke_studio.md" - - Interact with threads in LangGraph Studio: "cloud/how-tos/threads_studio.md" - - Different Types of Runs: - - Run an Agent in the Background: "cloud/how-tos/background_run.md" - - Run Multiple Agents in Same Thread: "cloud/how-tos/same-thread.md" - - Create Cron Jobs: "cloud/how-tos/cron_jobs.md" - - Create Stateless Runs: "cloud/how-tos/stateless_runs.md" - - Other: - - Configure Agents: "cloud/how-tos/configuration_cloud.md" - - Versioning Assistants: "cloud/how-tos/assistant_versioning.md" - - Convert LangGraph calls to LangGraph Cloud calls: "cloud/how-tos/langgraph_to_langgraph_cloud.ipynb" - - Integrate Webhooks: "cloud/how-tos/webhooks.md" - - Copy Threads: "cloud/how-tos/copy_threads.md" - - Check Status of Threads: "cloud/how-tos/check_thread_status.md" - - Conceptual Guides: - - API Concepts: "cloud/concepts/api.md" - - Cloud Concepts: "cloud/concepts/cloud.md" - - Reference: - - API: "cloud/reference/api/api_ref.md" - - SDK: - - Python: "cloud/reference/sdk/python_sdk_ref.md" - - JS/TS: "cloud/reference/sdk/js_ts_sdk_ref.md" - - CLI: "cloud/reference/cli.md" - - Environment Variables: "cloud/reference/env_var.md" - - FAQ: - - Studio: "cloud/faq/studio.md" + - LangGraph Platform: + - Server API: "cloud/reference/api/api_ref.md" + - SDK (Python): "cloud/reference/sdk/python_sdk_ref.md" + - SDK (JS/TS): "cloud/reference/sdk/js_ts_sdk_ref.md" + - CLI: "cloud/reference/cli.md" + - Environment Variables: "cloud/reference/env_var.md" markdown_extensions: - abbr