[PR #1826] [MERGED] feat(sdk): add type-safe tool call streaming with agent type inference #1761

Closed
opened 2026-02-15 20:16:44 -05:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/langchain-ai/langgraphjs/pull/1826
Author: @christian-bromann
Created: 12/16/2025
Status: Merged
Merged: 1/8/2026
Merged by: @christian-bromann

Base: mainHead: cb/type-safe-streaming-new


📝 Commits (10+)

  • ab596b3 feat(sdk): add type-safe tool call streaming with agent type inference
  • dd9ee0f use turbo for everything
  • 2a062a9 update type brand after rebase
  • 41a314e format
  • c0a4ce7 feat(sdk): enhance tool call API with uiMessages, getToolCalls, and lifecycle state
  • aa36277 update example app
  • 53c5926 revamp example website
  • 562cac7 more UI improvements + more agent examples
  • 134d3dc get examples to work
  • 67201bf add summarization middleware example

📊 Changes

90 files changed (+11112 additions, -4843 deletions)

View changed files

.changeset/fifty-donuts-notice.md (+5 -0)
.changeset/flat-buses-stay.md (+5 -0)
.changeset/funny-flies-grin.md (+5 -0)
.changeset/icy-lands-invent.md (+5 -0)
.changeset/shaggy-paws-bake.md (+5 -0)
📝 .github/workflows/test-exports.yml (+0 -14)
📝 examples/ui-react-transport/package.json (+1 -1)
📝 examples/ui-react-transport/src/server.mts (+18 -6)
📝 examples/ui-react/.gitignore (+1 -0)
📝 examples/ui-react/index.html (+8 -3)
📝 examples/ui-react/langgraph.json (+10 -2)
📝 examples/ui-react/package.json (+9 -4)
examples/ui-react/src/agent.mts (+0 -18)
📝 examples/ui-react/src/client.tsx (+3 -48)
examples/ui-react/src/components/Layout.tsx (+149 -0)
examples/ui-react/src/components/Loading.tsx (+21 -0)
examples/ui-react/src/components/MessageBubble.tsx (+237 -0)
examples/ui-react/src/components/MessageInput.tsx (+71 -0)
examples/ui-react/src/components/Sidebar.tsx (+186 -0)
examples/ui-react/src/components/States.tsx (+42 -0)

...and 70 more files

📄 Description

This PR upgrades the LangGraph JS SDK’s React streaming DX with type-safe tool call handling and agent-based type inference, plus a set of related SDK reliability + core Zod interop improvements. It also overhauls examples/ui-react into a navigable demo app showcasing common streaming/branching patterns.

Key Changes

Type-Safe Tool Call Streaming (React)

  • Agent type inference: You can now pass typeof agent (from createAgent) to useStream and get tool call name/args inferred from the agent’s tools via InferAgentToolCalls.
  • Canonical tool-call typing for graphs: For non-agent usage, tool call types are extracted from your state’s messages:
    • Define messages: Message<MyToolCalls>[] in your state
    • GetToolCallsType<StateType> is derived from that messages field
  • New tool call helpers on the stream:
    • stream.toolCalls: tool calls paired with results as ToolCallWithResult<ToolCall>[] with lifecycle state (pending | completed | error)
    • stream.getToolCalls(aiMessage): tool calls scoped to a specific AI message
  • New utility + exported types:
    • getToolCallsWithResults(messages)
    • ToolCallWithResult, ToolCallState, plus helper types ToolCallFromTool / ToolCallsFromTools for inferring tool-call unions from tools

SDK Reliability Improvements

  • Better connection errors: When the SDK can’t reach the LangGraph server, it now throws a clearer ConnectionError message (instead of opaque fetch/network errors).

Core: Improved Zod Interop

  • Zod v3/v4 plugin robustness: Updates to the LangGraph Zod plugin to improve interop across Zod versions and reduce prototype extension edge cases.

Example Application Overhaul (examples/ui-react)

Refactors the React example into a proper app shell (layout/sidebar/registry/components) and adds/updates examples:

Example Description
tool-calling-agent Basic tool-calling agent demo
human-in-the-loop HITL pattern with approval flows
multi-step-graph Multi-step state graph workflow
parallel-research Parallel research tasks with streaming
reasoning-agent Reasoning display example
summarization-agent Summarization middleware pattern
custom-streaming Custom event streaming with progress UI
session-persistence Thread/session persistence patterns
branching-chat Branching UX with branch switching

Usage

With createAgent (recommended):

import { agent } from "./agent";

function Chat() {
  const stream = useStream<typeof agent>({
    assistantId: "agent",
    apiUrl: "http://localhost:2024",
  });

  // stream.toolCalls[0].call.name is typed from your tools
  // stream.toolCalls[0].call.args is typed from the tool schema/_call signature
}

With a custom graph state (tool calls typed via messages):

import type { Message } from "@langchain/langgraph-sdk";

type MyToolCalls =
  | { name: "get_weather"; args: { location: string }; id?: string }
  | { name: "search"; args: { query: string }; id?: string };

interface MyState {
  messages: Message<MyToolCalls>[];
}

const stream = useStream<MyState>({ assistantId: "my-graph" });

Breaking Changes

None expected at runtime. (Tool-call typing is now derived from StateType["messages"] for graph-state usage, and inferred from typeof agent for createAgent usage.)


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/langchain-ai/langgraphjs/pull/1826 **Author:** [@christian-bromann](https://github.com/christian-bromann) **Created:** 12/16/2025 **Status:** ✅ Merged **Merged:** 1/8/2026 **Merged by:** [@christian-bromann](https://github.com/christian-bromann) **Base:** `main` ← **Head:** `cb/type-safe-streaming-new` --- ### 📝 Commits (10+) - [`ab596b3`](https://github.com/langchain-ai/langgraphjs/commit/ab596b3f64e314526bc03c7a5ccb387e9955064f) feat(sdk): add type-safe tool call streaming with agent type inference - [`dd9ee0f`](https://github.com/langchain-ai/langgraphjs/commit/dd9ee0f9d6bbcdf8f83b328e4e4f0182c475a68c) use turbo for everything - [`2a062a9`](https://github.com/langchain-ai/langgraphjs/commit/2a062a9fceba4c9a7057c92ab010e596e7fbc528) update type brand after rebase - [`41a314e`](https://github.com/langchain-ai/langgraphjs/commit/41a314e22b5fb5fec0f11bab960f1d8a24ea760c) format - [`c0a4ce7`](https://github.com/langchain-ai/langgraphjs/commit/c0a4ce7d944a07e3ef25153cf71ac60760cc15f0) feat(sdk): enhance tool call API with uiMessages, getToolCalls, and lifecycle state - [`aa36277`](https://github.com/langchain-ai/langgraphjs/commit/aa362775e394b61c495b57b1ba0b06488a1d10a0) update example app - [`53c5926`](https://github.com/langchain-ai/langgraphjs/commit/53c59264a7790083e5410a65e6bae08957ddc5a8) revamp example website - [`562cac7`](https://github.com/langchain-ai/langgraphjs/commit/562cac796fe3a8dd994184bf4102e8b222ac9a4d) more UI improvements + more agent examples - [`134d3dc`](https://github.com/langchain-ai/langgraphjs/commit/134d3dcdaf66182ffcda1b14d09b5fbbca82d1ea) get examples to work - [`67201bf`](https://github.com/langchain-ai/langgraphjs/commit/67201bf21a052cc8aad0ca1e27ed9626144ffb33) add summarization middleware example ### 📊 Changes **90 files changed** (+11112 additions, -4843 deletions) <details> <summary>View changed files</summary> ➕ `.changeset/fifty-donuts-notice.md` (+5 -0) ➕ `.changeset/flat-buses-stay.md` (+5 -0) ➕ `.changeset/funny-flies-grin.md` (+5 -0) ➕ `.changeset/icy-lands-invent.md` (+5 -0) ➕ `.changeset/shaggy-paws-bake.md` (+5 -0) 📝 `.github/workflows/test-exports.yml` (+0 -14) 📝 `examples/ui-react-transport/package.json` (+1 -1) 📝 `examples/ui-react-transport/src/server.mts` (+18 -6) 📝 `examples/ui-react/.gitignore` (+1 -0) 📝 `examples/ui-react/index.html` (+8 -3) 📝 `examples/ui-react/langgraph.json` (+10 -2) 📝 `examples/ui-react/package.json` (+9 -4) ➖ `examples/ui-react/src/agent.mts` (+0 -18) 📝 `examples/ui-react/src/client.tsx` (+3 -48) ➕ `examples/ui-react/src/components/Layout.tsx` (+149 -0) ➕ `examples/ui-react/src/components/Loading.tsx` (+21 -0) ➕ `examples/ui-react/src/components/MessageBubble.tsx` (+237 -0) ➕ `examples/ui-react/src/components/MessageInput.tsx` (+71 -0) ➕ `examples/ui-react/src/components/Sidebar.tsx` (+186 -0) ➕ `examples/ui-react/src/components/States.tsx` (+42 -0) _...and 70 more files_ </details> ### 📄 Description This PR upgrades the LangGraph JS SDK’s React streaming DX with **type-safe tool call handling** and **agent-based type inference**, plus a set of related SDK reliability + core Zod interop improvements. It also overhauls `examples/ui-react` into a navigable demo app showcasing common streaming/branching patterns. ## Key Changes ### Type-Safe Tool Call Streaming (React) - **Agent type inference**: You can now pass `typeof agent` (from `createAgent`) to `useStream` and get **tool call name/args inferred from the agent’s tools** via `InferAgentToolCalls`. - **Canonical tool-call typing for graphs**: For non-agent usage, tool call types are extracted from your state’s messages: - Define `messages: Message<MyToolCalls>[]` in your state - `GetToolCallsType<StateType>` is derived from that `messages` field - **New tool call helpers on the stream**: - `stream.toolCalls`: tool calls paired with results as `ToolCallWithResult<ToolCall>[]` with lifecycle state (`pending` | `completed` | `error`) - `stream.getToolCalls(aiMessage)`: tool calls scoped to a specific AI message - **New utility + exported types**: - `getToolCallsWithResults(messages)` - `ToolCallWithResult`, `ToolCallState`, plus helper types `ToolCallFromTool` / `ToolCallsFromTools` for inferring tool-call unions from tools ### SDK Reliability Improvements - **Better connection errors**: When the SDK can’t reach the LangGraph server, it now throws a clearer `ConnectionError` message (instead of opaque fetch/network errors). ### Core: Improved Zod Interop - **Zod v3/v4 plugin robustness**: Updates to the LangGraph Zod plugin to improve interop across Zod versions and reduce prototype extension edge cases. ### Example Application Overhaul (`examples/ui-react`) Refactors the React example into a proper app shell (layout/sidebar/registry/components) and adds/updates examples: | Example | Description | |---------|-------------| | `tool-calling-agent` | Basic tool-calling agent demo | | `human-in-the-loop` | HITL pattern with approval flows | | `multi-step-graph` | Multi-step state graph workflow | | `parallel-research` | Parallel research tasks with streaming | | `reasoning-agent` | Reasoning display example | | `summarization-agent` | Summarization middleware pattern | | `custom-streaming` | Custom event streaming with progress UI | | `session-persistence` | Thread/session persistence patterns | | `branching-chat` | Branching UX with branch switching | ## Usage **With `createAgent` (recommended):** ```ts import { agent } from "./agent"; function Chat() { const stream = useStream<typeof agent>({ assistantId: "agent", apiUrl: "http://localhost:2024", }); // stream.toolCalls[0].call.name is typed from your tools // stream.toolCalls[0].call.args is typed from the tool schema/_call signature } ``` **With a custom graph state (tool calls typed via `messages`):** ```ts import type { Message } from "@langchain/langgraph-sdk"; type MyToolCalls = | { name: "get_weather"; args: { location: string }; id?: string } | { name: "search"; args: { query: string }; id?: string }; interface MyState { messages: Message<MyToolCalls>[]; } const stream = useStream<MyState>({ assistantId: "my-graph" }); ``` ## Breaking Changes None expected at runtime. (Tool-call typing is now derived from `StateType["messages"]` for graph-state usage, and inferred from `typeof agent` for `createAgent` usage.) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-02-15 20:16:44 -05:00
yindo closed this issue 2026-02-15 20:16:44 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraphjs#1761