🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@langchain/langgraph-sdk

Package Overview
Dependencies
Maintainers
2
Versions
211
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@langchain/langgraph-sdk - npm Package Compare versions

Comparing version
1.9.25
to
1.9.26
+18
dist/utils/reconnect.cjs
//#region src/utils/reconnect.ts
/** Base delay (ms) for exponential reconnect backoff (`base * 2^(attempt-1)`). */
const DEFAULT_RECONNECT_BASE_DELAY_MS = 1e3;
/** Cap (ms) for exponential reconnect backoff before jitter. */
const DEFAULT_RECONNECT_MAX_DELAY_MS = 5e3;
/** Max random jitter (ms) added on top of the capped base delay. */
const DEFAULT_RECONNECT_JITTER_MS = 1e3;
/**
* Exponential backoff with jitter for stream reconnect.
* `min(base * 2^(attempt-1), max) + random(0, jitter)`.
*/
function reconnectDelayMs(attempt) {
return Math.min(DEFAULT_RECONNECT_BASE_DELAY_MS * 2 ** (attempt - 1), DEFAULT_RECONNECT_MAX_DELAY_MS) + Math.random() * DEFAULT_RECONNECT_JITTER_MS;
}
//#endregion
exports.reconnectDelayMs = reconnectDelayMs;
//# sourceMappingURL=reconnect.cjs.map
{"version":3,"file":"reconnect.cjs","names":[],"sources":["../../src/utils/reconnect.ts"],"sourcesContent":["/**\n * Shared reconnect defaults and backoff for SSE (`streamWithRetry`) and\n * protocol transports (WebSocket / SSE adapters). Keep these in one place so\n * legacy and v2 clients do not diverge.\n */\n\n/** Default max reconnect / retry attempts after an unexpected disconnect. */\nexport const DEFAULT_MAX_RECONNECT_ATTEMPTS = 5;\n\n/** Base delay (ms) for exponential reconnect backoff (`base * 2^(attempt-1)`). */\nexport const DEFAULT_RECONNECT_BASE_DELAY_MS = 1000;\n\n/** Cap (ms) for exponential reconnect backoff before jitter. */\nexport const DEFAULT_RECONNECT_MAX_DELAY_MS = 5000;\n\n/** Max random jitter (ms) added on top of the capped base delay. */\nexport const DEFAULT_RECONNECT_JITTER_MS = 1000;\n\n/**\n * Exponential backoff with jitter for stream reconnect.\n * `min(base * 2^(attempt-1), max) + random(0, jitter)`.\n */\nexport function reconnectDelayMs(attempt: number): number {\n const baseDelay = Math.min(\n DEFAULT_RECONNECT_BASE_DELAY_MS * 2 ** (attempt - 1),\n DEFAULT_RECONNECT_MAX_DELAY_MS\n );\n const jitter = Math.random() * DEFAULT_RECONNECT_JITTER_MS;\n return baseDelay + jitter;\n}\n"],"mappings":";;AAUA,MAAa,kCAAkC;;AAG/C,MAAa,iCAAiC;;AAG9C,MAAa,8BAA8B;;;;;AAM3C,SAAgB,iBAAiB,SAAyB;AAMxD,QALkB,KAAK,IACrB,kCAAkC,MAAM,UAAU,IAClD,+BACD,GACc,KAAK,QAAQ,GAAG"}
//#region src/utils/reconnect.ts
/** Base delay (ms) for exponential reconnect backoff (`base * 2^(attempt-1)`). */
const DEFAULT_RECONNECT_BASE_DELAY_MS = 1e3;
/** Cap (ms) for exponential reconnect backoff before jitter. */
const DEFAULT_RECONNECT_MAX_DELAY_MS = 5e3;
/** Max random jitter (ms) added on top of the capped base delay. */
const DEFAULT_RECONNECT_JITTER_MS = 1e3;
/**
* Exponential backoff with jitter for stream reconnect.
* `min(base * 2^(attempt-1), max) + random(0, jitter)`.
*/
function reconnectDelayMs(attempt) {
return Math.min(DEFAULT_RECONNECT_BASE_DELAY_MS * 2 ** (attempt - 1), DEFAULT_RECONNECT_MAX_DELAY_MS) + Math.random() * DEFAULT_RECONNECT_JITTER_MS;
}
//#endregion
export { reconnectDelayMs };
//# sourceMappingURL=reconnect.js.map
{"version":3,"file":"reconnect.js","names":[],"sources":["../../src/utils/reconnect.ts"],"sourcesContent":["/**\n * Shared reconnect defaults and backoff for SSE (`streamWithRetry`) and\n * protocol transports (WebSocket / SSE adapters). Keep these in one place so\n * legacy and v2 clients do not diverge.\n */\n\n/** Default max reconnect / retry attempts after an unexpected disconnect. */\nexport const DEFAULT_MAX_RECONNECT_ATTEMPTS = 5;\n\n/** Base delay (ms) for exponential reconnect backoff (`base * 2^(attempt-1)`). */\nexport const DEFAULT_RECONNECT_BASE_DELAY_MS = 1000;\n\n/** Cap (ms) for exponential reconnect backoff before jitter. */\nexport const DEFAULT_RECONNECT_MAX_DELAY_MS = 5000;\n\n/** Max random jitter (ms) added on top of the capped base delay. */\nexport const DEFAULT_RECONNECT_JITTER_MS = 1000;\n\n/**\n * Exponential backoff with jitter for stream reconnect.\n * `min(base * 2^(attempt-1), max) + random(0, jitter)`.\n */\nexport function reconnectDelayMs(attempt: number): number {\n const baseDelay = Math.min(\n DEFAULT_RECONNECT_BASE_DELAY_MS * 2 ** (attempt - 1),\n DEFAULT_RECONNECT_MAX_DELAY_MS\n );\n const jitter = Math.random() * DEFAULT_RECONNECT_JITTER_MS;\n return baseDelay + jitter;\n}\n"],"mappings":";;AAUA,MAAa,kCAAkC;;AAG/C,MAAa,iCAAiC;;AAG9C,MAAa,8BAA8B;;;;;AAM3C,SAAgB,iBAAiB,SAAyB;AAMxD,QALkB,KAAK,IACrB,kCAAkC,MAAM,UAAU,IAClD,+BACD,GACc,KAAK,QAAQ,GAAG"}
+1
-1

@@ -9,4 +9,4 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });

const require_index$1 = require("./client/stream/index.cjs");
const require_http = require("./client/stream/transport/http.cjs");
const require_websocket = require("./client/stream/transport/websocket.cjs");
const require_http = require("./client/stream/transport/http.cjs");
const require_index$2 = require("./client/threads/index.cjs");

@@ -13,0 +13,0 @@ const require_index$3 = require("./client/runs/index.cjs");

@@ -8,4 +8,4 @@ import { BaseClient, getApiKey } from "./client/base.js";

import { SubscriptionHandle, ThreadStream } from "./client/stream/index.js";
import { ProtocolSseTransportAdapter } from "./client/stream/transport/http.js";
import { ProtocolWebSocketTransportAdapter } from "./client/stream/transport/websocket.js";
import { ProtocolSseTransportAdapter } from "./client/stream/transport/http.js";
import { ThreadsClient } from "./client/threads/index.js";

@@ -12,0 +12,0 @@ import { RunsClient } from "./client/runs/index.js";

@@ -1,1 +0,1 @@

{"version":3,"file":"base.cjs","names":["getEnvironmentVariable","AsyncCaller","mergeSignals","#performFetch","#performFetchWithResponse","BytesLineDecoder","idleReconnectStream","SSEDecoder","streamWithRetry"],"sources":["../../src/client/base.ts"],"sourcesContent":["import { AsyncCaller, AsyncCallerParams } from \"../utils/async_caller.js\";\nimport { getEnvironmentVariable } from \"../utils/env.js\";\nimport { mergeSignals } from \"../utils/signals.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../utils/sse.js\";\nimport {\n streamWithRetry,\n idleReconnectStream,\n type IdleReconnectMode,\n StreamRequestParams,\n} from \"../utils/stream.js\";\nimport type { StreamProtocol } from \"../types.js\";\n\nexport type HeaderValue = string | undefined | null;\n\nexport function* iterateHeaders(\n headers: HeadersInit | Record<string, HeaderValue>\n): IterableIterator<[string, string | null]> {\n let iter: Iterable<(HeaderValue | HeaderValue | null[])[]>;\n let shouldClear = false;\n\n // eslint-disable-next-line no-instanceof/no-instanceof\n if (headers instanceof Headers) {\n const entries: [string, string][] = [];\n headers.forEach((value, name) => {\n entries.push([name, value]);\n });\n iter = entries;\n } else if (Array.isArray(headers)) {\n iter = headers;\n } else {\n shouldClear = true;\n iter = Object.entries(headers ?? {});\n }\n\n for (const item of iter) {\n const name = item[0];\n if (typeof name !== \"string\")\n throw new TypeError(\n `Expected header name to be a string, got ${typeof name}`\n );\n const values = Array.isArray(item[1]) ? item[1] : [item[1]];\n let didClear = false;\n\n for (const value of values) {\n if (value === undefined) continue;\n\n if (shouldClear && !didClear) {\n didClear = true;\n yield [name, null];\n }\n yield [name, value];\n }\n }\n}\n\nexport function mergeHeaders(\n ...headerObjects: (\n | HeadersInit\n | Record<string, HeaderValue>\n | undefined\n | null\n )[]\n) {\n const outputHeaders = new Headers();\n for (const headers of headerObjects) {\n if (!headers) continue;\n for (const [name, value] of iterateHeaders(headers)) {\n if (value === null) outputHeaders.delete(name);\n else outputHeaders.append(name, value);\n }\n }\n const headerEntries: [string, string][] = [];\n outputHeaders.forEach((value, name) => {\n headerEntries.push([name, value]);\n });\n return Object.fromEntries(headerEntries);\n}\n\n/**\n * Get the API key from the environment.\n * Precedence:\n * 1. explicit argument (if string)\n * 2. LANGGRAPH_API_KEY\n * 3. LANGSMITH_API_KEY\n * 4. LANGCHAIN_API_KEY\n *\n * @param apiKey - API key provided as an argument. If null, skips environment lookup. If undefined, tries environment.\n * @returns The API key if found, otherwise undefined\n */\nexport function getApiKey(apiKey?: string | null): string | undefined {\n if (apiKey === null) {\n return undefined;\n }\n\n if (apiKey) {\n return apiKey;\n }\n\n const prefixes = [\"LANGGRAPH\", \"LANGSMITH\", \"LANGCHAIN\"];\n\n for (const prefix of prefixes) {\n const envKey = getEnvironmentVariable(`${prefix}_API_KEY`);\n if (envKey) {\n return envKey.trim().replace(/^[\"']|[\"']$/g, \"\");\n }\n }\n\n return undefined;\n}\n\nexport type RequestHook = (\n url: URL,\n init: RequestInit\n) => Promise<RequestInit> | RequestInit;\n\n/**\n * Configuration for {@link BaseClient} and the exported LangGraph SDK\n * {@link Client}.\n */\nexport interface ClientConfig {\n /**\n * Base URL of the LangGraph API server.\n *\n * Defaults to `http://localhost:8123`, unless the runtime provides a\n * `langgraph_api:url` global override.\n */\n apiUrl?: string;\n /**\n * API key for authentication.\n * - If a string is provided, that key will be used\n * - If undefined (default), the key will be auto-loaded from environment variables (LANGGRAPH_API_KEY, LANGSMITH_API_KEY, or LANGCHAIN_API_KEY)\n * - If null, no API key will be set (skips auto-loading)\n */\n apiKey?: string | null;\n /**\n * Options forwarded to the internal {@link AsyncCaller}, such as retry,\n * concurrency, or custom `fetch` behavior.\n */\n callerOptions?: AsyncCallerParams;\n /**\n * Default timeout, in milliseconds, applied to client requests.\n *\n * Per-request `timeoutMs` values override this default. Passing `null`\n * at the request level disables the configured timeout for that request.\n */\n timeoutMs?: number;\n /**\n * Headers applied to every request.\n *\n * The configured API key, when present, is added as the `x-api-key`\n * header after these defaults are initialized.\n */\n defaultHeaders?: Record<string, HeaderValue>;\n /**\n * Hook for inspecting or mutating a request before it is sent.\n *\n * Receives the resolved URL and prepared `RequestInit`; return the\n * original init or a replacement object to continue the request.\n */\n onRequest?: RequestHook;\n /**\n * Streaming protocol used by stream-capable endpoints.\n *\n * Defaults to `\"legacy\"` for backwards compatibility.\n */\n streamProtocol?: StreamProtocol;\n}\n\nexport class BaseClient {\n protected asyncCaller: AsyncCaller;\n\n protected timeoutMs: number | undefined;\n\n protected apiUrl: string;\n\n protected defaultHeaders: Record<string, HeaderValue>;\n\n protected onRequest?: RequestHook;\n\n protected streamProtocol: StreamProtocol;\n\n constructor(config?: ClientConfig) {\n const callerOptions = {\n maxRetries: 4,\n maxConcurrency: 4,\n ...config?.callerOptions,\n };\n\n let defaultApiUrl = \"http://localhost:8123\";\n if (\n !config?.apiUrl &&\n typeof globalThis === \"object\" &&\n globalThis != null\n ) {\n const fetchSmb = Symbol.for(\"langgraph_api:fetch\");\n const urlSmb = Symbol.for(\"langgraph_api:url\");\n\n const global = globalThis as unknown as {\n [fetchSmb]?: typeof fetch;\n [urlSmb]?: string;\n };\n\n if (global[fetchSmb]) callerOptions.fetch ??= global[fetchSmb];\n if (global[urlSmb]) defaultApiUrl = global[urlSmb];\n }\n\n this.asyncCaller = new AsyncCaller(callerOptions);\n this.timeoutMs = config?.timeoutMs;\n\n this.apiUrl = config?.apiUrl?.replace(/\\/$/, \"\") || defaultApiUrl;\n this.defaultHeaders = config?.defaultHeaders || {};\n this.onRequest = config?.onRequest;\n this.streamProtocol = config?.streamProtocol ?? \"legacy\";\n const apiKey = getApiKey(config?.apiKey);\n if (apiKey) {\n this.defaultHeaders[\"x-api-key\"] = apiKey;\n }\n }\n\n protected prepareFetchOptions(\n path: string,\n options?: RequestInit & {\n json?: unknown;\n params?: Record<string, unknown>;\n timeoutMs?: number | null;\n withResponse?: boolean;\n dedupe?: boolean;\n }\n ): [url: URL, init: RequestInit] {\n const mutatedOptions = {\n ...options,\n headers: mergeHeaders(this.defaultHeaders, options?.headers),\n };\n\n if (mutatedOptions.json) {\n mutatedOptions.body = JSON.stringify(mutatedOptions.json);\n mutatedOptions.headers = mergeHeaders(mutatedOptions.headers, {\n \"content-type\": \"application/json\",\n });\n delete mutatedOptions.json;\n }\n\n if (mutatedOptions.withResponse) {\n delete mutatedOptions.withResponse;\n }\n\n if (\"dedupe\" in mutatedOptions) {\n delete mutatedOptions.dedupe;\n }\n\n let timeoutSignal: AbortSignal | null = null;\n if (typeof options?.timeoutMs !== \"undefined\") {\n if (options.timeoutMs != null) {\n timeoutSignal = AbortSignal.timeout(options.timeoutMs);\n }\n } else if (this.timeoutMs != null) {\n timeoutSignal = AbortSignal.timeout(this.timeoutMs);\n }\n\n mutatedOptions.signal = mergeSignals(timeoutSignal, mutatedOptions.signal);\n const targetUrl = new URL(`${this.apiUrl}${path}`);\n\n if (mutatedOptions.params) {\n for (const [key, value] of Object.entries(mutatedOptions.params)) {\n if (value == null) continue;\n\n const strValue =\n typeof value === \"string\" || typeof value === \"number\"\n ? value.toString()\n : JSON.stringify(value);\n\n targetUrl.searchParams.append(key, strValue);\n }\n delete mutatedOptions.params;\n }\n\n return [targetUrl, mutatedOptions];\n }\n\n protected async fetch<T>(\n path: string,\n options: RequestInit & {\n json?: unknown;\n params?: Record<string, unknown>;\n timeoutMs?: number | null;\n signal: AbortSignal | undefined;\n withResponse: true;\n }\n ): Promise<[T, Response]>;\n\n protected async fetch<T>(\n path: string,\n options?: RequestInit & {\n json?: unknown;\n params?: Record<string, unknown>;\n timeoutMs?: number | null;\n signal: AbortSignal | undefined;\n withResponse?: false;\n dedupe?: boolean;\n }\n ): Promise<T>;\n\n protected async fetch<T>(\n path: string,\n options?: RequestInit & {\n json?: unknown;\n params?: Record<string, unknown>;\n timeoutMs?: number | null;\n signal: AbortSignal | undefined;\n withResponse?: boolean;\n dedupe?: boolean;\n }\n ): Promise<T | [T, Response]> {\n const [url, init] = this.prepareFetchOptions(path, options);\n\n /**\n * Coalesce concurrent, identical idempotent reads onto a single\n * in-flight request. Only engaged when the caller opts in\n * (`dedupe: true`), is not asking for the raw `Response`, did not\n * supply its own `AbortSignal` (sharing a request across consumers\n * must never let one consumer's abort cancel another's), and no\n * `onRequest` hook is configured.\n *\n * `onRequest` is excluded because it can inject per-request headers\n * (e.g. a freshly-minted `Authorization` bearer) that are not\n * visible until *after* it runs — i.e. after the dedupe key is\n * computed — so two requests that look identical here could be sent\n * with different credentials. Coalescing them would let one\n * consumer receive a response fetched with another's auth.\n */\n const canDedupe =\n options?.dedupe === true &&\n options?.withResponse !== true &&\n options?.signal == null &&\n this.onRequest == null;\n\n if (canDedupe) {\n const body = typeof init.body === \"string\" ? init.body : \"\";\n /**\n * The key must capture the FULL request identity, including every\n * prepared header. `inFlightReads` is module-scoped across all\n * `Client` instances, so omitting headers would let two clients\n * pointed at the same URL/thread but using different credentials\n * (Authorization, custom auth headers, tenant-scoping defaults, …)\n * share one in-flight promise — a cross-tenant data leak.\n */\n const headers = serializeHeaders(init.headers);\n const key = `${init.method ?? \"GET\"} ${url.toString()} ${body} ${headers}`;\n const existing = inFlightReads.get(key);\n if (existing != null) return existing as Promise<T>;\n\n const promise = this.#performFetch<T>(url, init);\n inFlightReads.set(key, promise);\n const clear = () => {\n if (inFlightReads.get(key) === promise) inFlightReads.delete(key);\n };\n promise.then(clear, clear);\n return promise;\n }\n\n const [body, response] = await this.#performFetchWithResponse<T>(url, init);\n if (options?.withResponse) {\n return [body, response];\n }\n return body;\n }\n\n /**\n * Issue the prepared request (applying the `onRequest` hook) and\n * resolve the parsed body. Shared by the deduped and direct paths.\n */\n async #performFetch<T>(url: URL, init: RequestInit): Promise<T> {\n const [body] = await this.#performFetchWithResponse<T>(url, init);\n return body;\n }\n\n async #performFetchWithResponse<T>(\n url: URL,\n init: RequestInit\n ): Promise<[T, Response]> {\n let finalInit = init;\n if (this.onRequest) {\n finalInit = await this.onRequest(url, init);\n }\n\n const response = await this.asyncCaller.fetch(url.toString(), finalInit);\n\n const body = await (async () => {\n if (response.status === 202 || response.status === 204) {\n return undefined as T;\n }\n return response.json() as Promise<T>;\n })();\n\n return [body, response];\n }\n\n protected async *streamWithRetry<\n T extends { id?: string; event: string; data: unknown },\n >(config: {\n endpoint: string;\n method?: string;\n signal?: AbortSignal;\n headers?: Record<string, string>;\n params?: Record<string, unknown>;\n json?: unknown;\n maxRetries?: number;\n idleReconnect?: IdleReconnectMode;\n onReconnect?: (options: {\n attempt: number;\n lastEventId?: string;\n cause: unknown;\n }) => void;\n onInitialResponse?: (response: Response) => void | Promise<void>;\n }): AsyncGenerator<T> {\n const makeRequest = async (reconnectParams?: StreamRequestParams) => {\n const requestEndpoint = reconnectParams?.reconnectPath || config.endpoint;\n\n const isReconnect = !!reconnectParams?.reconnectPath;\n const method = isReconnect ? \"GET\" : config.method || \"GET\";\n\n const requestHeaders =\n isReconnect && reconnectParams?.lastEventId\n ? { ...config.headers, \"Last-Event-ID\": reconnectParams.lastEventId }\n : config.headers;\n\n // oxlint-disable-next-line prefer-const -- init is reassigned by onRequest hook\n let [url, init] = this.prepareFetchOptions(requestEndpoint, {\n method,\n timeoutMs: null,\n signal: config.signal,\n headers: requestHeaders,\n params: config.params,\n json: isReconnect ? undefined : config.json,\n });\n\n if (this.onRequest != null) {\n init = await this.onRequest(url, init);\n }\n\n const response = await this.asyncCaller.fetch(url.toString(), init);\n if (!response.body) {\n throw new Error(\"Expected response body from stream endpoint\");\n }\n\n if (!isReconnect && config.onInitialResponse) {\n await config.onInitialResponse(response);\n }\n\n // Insert the idle watchdog on the line stream (between the byte-line\n // decoder and the SSE decoder) so it can both reset on any line and\n // recognise `:` keep-alive heartbeats to drive `\"auto\"` mode. The SSE\n // decoder downstream discards those comment lines.\n const idleMode = config.idleReconnect ?? \"auto\";\n const enableIdle = idleMode === \"auto\" || idleMode > 0;\n\n const lines = response.body.pipeThrough(BytesLineDecoder());\n const watched = enableIdle\n ? lines.pipeThrough(idleReconnectStream({ mode: idleMode }))\n : lines;\n const stream: ReadableStream<T> = watched.pipeThrough(\n SSEDecoder()\n ) as ReadableStream<T>;\n\n return { response, stream };\n };\n\n yield* streamWithRetry(makeRequest, {\n maxRetries: config.maxRetries ?? 5,\n signal: config.signal,\n onReconnect: config.onReconnect,\n });\n }\n}\n\nexport const REGEX_RUN_METADATA =\n /(\\/threads\\/(?<thread_id>.+))?\\/runs\\/(?<run_id>.+)/;\n\nexport function getRunMetadataFromResponse(\n response: Response\n): { run_id: string; thread_id?: string } | undefined {\n const contentLocation = response.headers.get(\"Content-Location\");\n if (!contentLocation) return undefined;\n\n const match = REGEX_RUN_METADATA.exec(contentLocation);\n\n if (!match?.groups?.run_id) return undefined;\n return {\n run_id: match.groups.run_id,\n thread_id: match.groups.thread_id || undefined,\n };\n}\n\nexport const isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\n/**\n * Module-scoped, in-flight-only coalescing map for idempotent reads.\n *\n * Two independently-constructed clients (e.g. a React component that\n * remounts under Suspense / a reachability state flip, each minting a\n * fresh `Client`) can fire the *same* `getState` / `getHistory` read a\n * few milliseconds apart, before the first has resolved. Without\n * coalescing each pays the full round-trip — the duplicate\n * `threads/{id}/state` and `threads/{id}/history` requests seen on\n * reconnect.\n *\n * Keyed by `method + url + body + auth`, entries live only while a\n * request is in flight and are removed the moment it settles. This is\n * deliberately *not* a result cache: there is no TTL and no stored\n * payload, so it cannot serve stale data — it only ever shares a\n * promise that is already on the wire. Opt-in per call via\n * `{ dedupe: true }`, and skipped whenever the caller supplies its own\n * `AbortSignal` (so one consumer aborting can never cancel another's\n * read).\n */\nconst inFlightReads = new Map<string, Promise<unknown>>();\n\n/**\n * Deterministically serialize a prepared request's headers into a\n * stable string for use in the {@link inFlightReads} dedupe key. Header\n * names are normalized and sorted so ordering differences never produce\n * a different key, and every header (not just `x-api-key`) is included\n * so requests carrying different credentials never collide.\n */\nfunction serializeHeaders(headers: RequestInit[\"headers\"]): string {\n const normalized = mergeHeaders(\n headers as Record<string, HeaderValue> | undefined\n );\n return Object.keys(normalized)\n .sort()\n .map((name) => `${name}:${normalized[name]}`)\n .join(\"\\n\");\n}\n"],"mappings":"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"}
{"version":3,"file":"base.cjs","names":["getEnvironmentVariable","AsyncCaller","mergeSignals","#performFetch","#performFetchWithResponse","BytesLineDecoder","idleReconnectStream","SSEDecoder","streamWithRetry"],"sources":["../../src/client/base.ts"],"sourcesContent":["import { AsyncCaller, AsyncCallerParams } from \"../utils/async_caller.js\";\nimport { getEnvironmentVariable } from \"../utils/env.js\";\nimport { mergeSignals } from \"../utils/signals.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../utils/sse.js\";\nimport {\n streamWithRetry,\n idleReconnectStream,\n type IdleReconnectMode,\n StreamRequestParams,\n DEFAULT_IDLE_RECONNECT,\n} from \"../utils/stream.js\";\nimport { DEFAULT_MAX_RECONNECT_ATTEMPTS } from \"../utils/reconnect.js\";\nimport type { StreamProtocol } from \"../types.js\";\n\nexport type HeaderValue = string | undefined | null;\n\nexport function* iterateHeaders(\n headers: HeadersInit | Record<string, HeaderValue>\n): IterableIterator<[string, string | null]> {\n let iter: Iterable<(HeaderValue | HeaderValue | null[])[]>;\n let shouldClear = false;\n\n // eslint-disable-next-line no-instanceof/no-instanceof\n if (headers instanceof Headers) {\n const entries: [string, string][] = [];\n headers.forEach((value, name) => {\n entries.push([name, value]);\n });\n iter = entries;\n } else if (Array.isArray(headers)) {\n iter = headers;\n } else {\n shouldClear = true;\n iter = Object.entries(headers ?? {});\n }\n\n for (const item of iter) {\n const name = item[0];\n if (typeof name !== \"string\")\n throw new TypeError(\n `Expected header name to be a string, got ${typeof name}`\n );\n const values = Array.isArray(item[1]) ? item[1] : [item[1]];\n let didClear = false;\n\n for (const value of values) {\n if (value === undefined) continue;\n\n if (shouldClear && !didClear) {\n didClear = true;\n yield [name, null];\n }\n yield [name, value];\n }\n }\n}\n\nexport function mergeHeaders(\n ...headerObjects: (\n | HeadersInit\n | Record<string, HeaderValue>\n | undefined\n | null\n )[]\n) {\n const outputHeaders = new Headers();\n for (const headers of headerObjects) {\n if (!headers) continue;\n for (const [name, value] of iterateHeaders(headers)) {\n if (value === null) outputHeaders.delete(name);\n else outputHeaders.append(name, value);\n }\n }\n const headerEntries: [string, string][] = [];\n outputHeaders.forEach((value, name) => {\n headerEntries.push([name, value]);\n });\n return Object.fromEntries(headerEntries);\n}\n\n/**\n * Get the API key from the environment.\n * Precedence:\n * 1. explicit argument (if string)\n * 2. LANGGRAPH_API_KEY\n * 3. LANGSMITH_API_KEY\n * 4. LANGCHAIN_API_KEY\n *\n * @param apiKey - API key provided as an argument. If null, skips environment lookup. If undefined, tries environment.\n * @returns The API key if found, otherwise undefined\n */\nexport function getApiKey(apiKey?: string | null): string | undefined {\n if (apiKey === null) {\n return undefined;\n }\n\n if (apiKey) {\n return apiKey;\n }\n\n const prefixes = [\"LANGGRAPH\", \"LANGSMITH\", \"LANGCHAIN\"];\n\n for (const prefix of prefixes) {\n const envKey = getEnvironmentVariable(`${prefix}_API_KEY`);\n if (envKey) {\n return envKey.trim().replace(/^[\"']|[\"']$/g, \"\");\n }\n }\n\n return undefined;\n}\n\nexport type RequestHook = (\n url: URL,\n init: RequestInit\n) => Promise<RequestInit> | RequestInit;\n\n/**\n * Configuration for {@link BaseClient} and the exported LangGraph SDK\n * {@link Client}.\n */\nexport interface ClientConfig {\n /**\n * Base URL of the LangGraph API server.\n *\n * Defaults to `http://localhost:8123`, unless the runtime provides a\n * `langgraph_api:url` global override.\n */\n apiUrl?: string;\n /**\n * API key for authentication.\n * - If a string is provided, that key will be used\n * - If undefined (default), the key will be auto-loaded from environment variables (LANGGRAPH_API_KEY, LANGSMITH_API_KEY, or LANGCHAIN_API_KEY)\n * - If null, no API key will be set (skips auto-loading)\n */\n apiKey?: string | null;\n /**\n * Options forwarded to the internal {@link AsyncCaller}, such as retry,\n * concurrency, or custom `fetch` behavior.\n */\n callerOptions?: AsyncCallerParams;\n /**\n * Default timeout, in milliseconds, applied to client requests.\n *\n * Per-request `timeoutMs` values override this default. Passing `null`\n * at the request level disables the configured timeout for that request.\n */\n timeoutMs?: number;\n /**\n * Headers applied to every request.\n *\n * The configured API key, when present, is added as the `x-api-key`\n * header after these defaults are initialized.\n */\n defaultHeaders?: Record<string, HeaderValue>;\n /**\n * Hook for inspecting or mutating a request before it is sent.\n *\n * Receives the resolved URL and prepared `RequestInit`; return the\n * original init or a replacement object to continue the request.\n */\n onRequest?: RequestHook;\n /**\n * Streaming protocol used by stream-capable endpoints.\n *\n * Defaults to `\"legacy\"` for backwards compatibility.\n */\n streamProtocol?: StreamProtocol;\n}\n\nexport class BaseClient {\n protected asyncCaller: AsyncCaller;\n\n protected timeoutMs: number | undefined;\n\n protected apiUrl: string;\n\n protected defaultHeaders: Record<string, HeaderValue>;\n\n protected onRequest?: RequestHook;\n\n protected streamProtocol: StreamProtocol;\n\n constructor(config?: ClientConfig) {\n const callerOptions = {\n maxRetries: 4,\n maxConcurrency: 4,\n ...config?.callerOptions,\n };\n\n let defaultApiUrl = \"http://localhost:8123\";\n if (\n !config?.apiUrl &&\n typeof globalThis === \"object\" &&\n globalThis != null\n ) {\n const fetchSmb = Symbol.for(\"langgraph_api:fetch\");\n const urlSmb = Symbol.for(\"langgraph_api:url\");\n\n const global = globalThis as unknown as {\n [fetchSmb]?: typeof fetch;\n [urlSmb]?: string;\n };\n\n if (global[fetchSmb]) callerOptions.fetch ??= global[fetchSmb];\n if (global[urlSmb]) defaultApiUrl = global[urlSmb];\n }\n\n this.asyncCaller = new AsyncCaller(callerOptions);\n this.timeoutMs = config?.timeoutMs;\n\n this.apiUrl = config?.apiUrl?.replace(/\\/$/, \"\") || defaultApiUrl;\n this.defaultHeaders = config?.defaultHeaders || {};\n this.onRequest = config?.onRequest;\n this.streamProtocol = config?.streamProtocol ?? \"legacy\";\n const apiKey = getApiKey(config?.apiKey);\n if (apiKey) {\n this.defaultHeaders[\"x-api-key\"] = apiKey;\n }\n }\n\n protected prepareFetchOptions(\n path: string,\n options?: RequestInit & {\n json?: unknown;\n params?: Record<string, unknown>;\n timeoutMs?: number | null;\n withResponse?: boolean;\n dedupe?: boolean;\n }\n ): [url: URL, init: RequestInit] {\n const mutatedOptions = {\n ...options,\n headers: mergeHeaders(this.defaultHeaders, options?.headers),\n };\n\n if (mutatedOptions.json) {\n mutatedOptions.body = JSON.stringify(mutatedOptions.json);\n mutatedOptions.headers = mergeHeaders(mutatedOptions.headers, {\n \"content-type\": \"application/json\",\n });\n delete mutatedOptions.json;\n }\n\n if (mutatedOptions.withResponse) {\n delete mutatedOptions.withResponse;\n }\n\n if (\"dedupe\" in mutatedOptions) {\n delete mutatedOptions.dedupe;\n }\n\n let timeoutSignal: AbortSignal | null = null;\n if (typeof options?.timeoutMs !== \"undefined\") {\n if (options.timeoutMs != null) {\n timeoutSignal = AbortSignal.timeout(options.timeoutMs);\n }\n } else if (this.timeoutMs != null) {\n timeoutSignal = AbortSignal.timeout(this.timeoutMs);\n }\n\n mutatedOptions.signal = mergeSignals(timeoutSignal, mutatedOptions.signal);\n const targetUrl = new URL(`${this.apiUrl}${path}`);\n\n if (mutatedOptions.params) {\n for (const [key, value] of Object.entries(mutatedOptions.params)) {\n if (value == null) continue;\n\n const strValue =\n typeof value === \"string\" || typeof value === \"number\"\n ? value.toString()\n : JSON.stringify(value);\n\n targetUrl.searchParams.append(key, strValue);\n }\n delete mutatedOptions.params;\n }\n\n return [targetUrl, mutatedOptions];\n }\n\n protected async fetch<T>(\n path: string,\n options: RequestInit & {\n json?: unknown;\n params?: Record<string, unknown>;\n timeoutMs?: number | null;\n signal: AbortSignal | undefined;\n withResponse: true;\n }\n ): Promise<[T, Response]>;\n\n protected async fetch<T>(\n path: string,\n options?: RequestInit & {\n json?: unknown;\n params?: Record<string, unknown>;\n timeoutMs?: number | null;\n signal: AbortSignal | undefined;\n withResponse?: false;\n dedupe?: boolean;\n }\n ): Promise<T>;\n\n protected async fetch<T>(\n path: string,\n options?: RequestInit & {\n json?: unknown;\n params?: Record<string, unknown>;\n timeoutMs?: number | null;\n signal: AbortSignal | undefined;\n withResponse?: boolean;\n dedupe?: boolean;\n }\n ): Promise<T | [T, Response]> {\n const [url, init] = this.prepareFetchOptions(path, options);\n\n /**\n * Coalesce concurrent, identical idempotent reads onto a single\n * in-flight request. Only engaged when the caller opts in\n * (`dedupe: true`), is not asking for the raw `Response`, did not\n * supply its own `AbortSignal` (sharing a request across consumers\n * must never let one consumer's abort cancel another's), and no\n * `onRequest` hook is configured.\n *\n * `onRequest` is excluded because it can inject per-request headers\n * (e.g. a freshly-minted `Authorization` bearer) that are not\n * visible until *after* it runs — i.e. after the dedupe key is\n * computed — so two requests that look identical here could be sent\n * with different credentials. Coalescing them would let one\n * consumer receive a response fetched with another's auth.\n */\n const canDedupe =\n options?.dedupe === true &&\n options?.withResponse !== true &&\n options?.signal == null &&\n this.onRequest == null;\n\n if (canDedupe) {\n const body = typeof init.body === \"string\" ? init.body : \"\";\n /**\n * The key must capture the FULL request identity, including every\n * prepared header. `inFlightReads` is module-scoped across all\n * `Client` instances, so omitting headers would let two clients\n * pointed at the same URL/thread but using different credentials\n * (Authorization, custom auth headers, tenant-scoping defaults, …)\n * share one in-flight promise — a cross-tenant data leak.\n */\n const headers = serializeHeaders(init.headers);\n const key = `${init.method ?? \"GET\"} ${url.toString()} ${body} ${headers}`;\n const existing = inFlightReads.get(key);\n if (existing != null) return existing as Promise<T>;\n\n const promise = this.#performFetch<T>(url, init);\n inFlightReads.set(key, promise);\n const clear = () => {\n if (inFlightReads.get(key) === promise) inFlightReads.delete(key);\n };\n promise.then(clear, clear);\n return promise;\n }\n\n const [body, response] = await this.#performFetchWithResponse<T>(url, init);\n if (options?.withResponse) {\n return [body, response];\n }\n return body;\n }\n\n /**\n * Issue the prepared request (applying the `onRequest` hook) and\n * resolve the parsed body. Shared by the deduped and direct paths.\n */\n async #performFetch<T>(url: URL, init: RequestInit): Promise<T> {\n const [body] = await this.#performFetchWithResponse<T>(url, init);\n return body;\n }\n\n async #performFetchWithResponse<T>(\n url: URL,\n init: RequestInit\n ): Promise<[T, Response]> {\n let finalInit = init;\n if (this.onRequest) {\n finalInit = await this.onRequest(url, init);\n }\n\n const response = await this.asyncCaller.fetch(url.toString(), finalInit);\n\n const body = await (async () => {\n if (response.status === 202 || response.status === 204) {\n return undefined as T;\n }\n return response.json() as Promise<T>;\n })();\n\n return [body, response];\n }\n\n protected async *streamWithRetry<\n T extends { id?: string; event: string; data: unknown },\n >(config: {\n endpoint: string;\n method?: string;\n signal?: AbortSignal;\n headers?: Record<string, string>;\n params?: Record<string, unknown>;\n json?: unknown;\n maxRetries?: number;\n idleReconnect?: IdleReconnectMode;\n onReconnect?: (options: {\n attempt: number;\n lastEventId?: string;\n cause: unknown;\n }) => void;\n onInitialResponse?: (response: Response) => void | Promise<void>;\n }): AsyncGenerator<T> {\n const makeRequest = async (reconnectParams?: StreamRequestParams) => {\n const requestEndpoint = reconnectParams?.reconnectPath || config.endpoint;\n\n const isReconnect = !!reconnectParams?.reconnectPath;\n const method = isReconnect ? \"GET\" : config.method || \"GET\";\n\n const requestHeaders =\n isReconnect && reconnectParams?.lastEventId\n ? { ...config.headers, \"Last-Event-ID\": reconnectParams.lastEventId }\n : config.headers;\n\n // oxlint-disable-next-line prefer-const -- init is reassigned by onRequest hook\n let [url, init] = this.prepareFetchOptions(requestEndpoint, {\n method,\n timeoutMs: null,\n signal: config.signal,\n headers: requestHeaders,\n params: config.params,\n json: isReconnect ? undefined : config.json,\n });\n\n if (this.onRequest != null) {\n init = await this.onRequest(url, init);\n }\n\n const response = await this.asyncCaller.fetch(url.toString(), init);\n if (!response.body) {\n throw new Error(\"Expected response body from stream endpoint\");\n }\n\n if (!isReconnect && config.onInitialResponse) {\n await config.onInitialResponse(response);\n }\n\n // Insert the idle watchdog on the line stream (between the byte-line\n // decoder and the SSE decoder) so it can both reset on any line and\n // recognise `:` keep-alive heartbeats to drive `\"auto\"` mode. The SSE\n // decoder downstream discards those comment lines.\n const idleMode = config.idleReconnect ?? DEFAULT_IDLE_RECONNECT;\n const enableIdle = idleMode === \"auto\" || idleMode > 0;\n\n const lines = response.body.pipeThrough(BytesLineDecoder());\n const watched = enableIdle\n ? lines.pipeThrough(idleReconnectStream({ mode: idleMode }))\n : lines;\n const stream: ReadableStream<T> = watched.pipeThrough(\n SSEDecoder()\n ) as ReadableStream<T>;\n\n return { response, stream };\n };\n\n yield* streamWithRetry(makeRequest, {\n maxRetries: config.maxRetries ?? DEFAULT_MAX_RECONNECT_ATTEMPTS,\n signal: config.signal,\n onReconnect: config.onReconnect,\n });\n }\n}\n\nexport const REGEX_RUN_METADATA =\n /(\\/threads\\/(?<thread_id>.+))?\\/runs\\/(?<run_id>.+)/;\n\nexport function getRunMetadataFromResponse(\n response: Response\n): { run_id: string; thread_id?: string } | undefined {\n const contentLocation = response.headers.get(\"Content-Location\");\n if (!contentLocation) return undefined;\n\n const match = REGEX_RUN_METADATA.exec(contentLocation);\n\n if (!match?.groups?.run_id) return undefined;\n return {\n run_id: match.groups.run_id,\n thread_id: match.groups.thread_id || undefined,\n };\n}\n\nexport const isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\n/**\n * Module-scoped, in-flight-only coalescing map for idempotent reads.\n *\n * Two independently-constructed clients (e.g. a React component that\n * remounts under Suspense / a reachability state flip, each minting a\n * fresh `Client`) can fire the *same* `getState` / `getHistory` read a\n * few milliseconds apart, before the first has resolved. Without\n * coalescing each pays the full round-trip — the duplicate\n * `threads/{id}/state` and `threads/{id}/history` requests seen on\n * reconnect.\n *\n * Keyed by `method + url + body + auth`, entries live only while a\n * request is in flight and are removed the moment it settles. This is\n * deliberately *not* a result cache: there is no TTL and no stored\n * payload, so it cannot serve stale data — it only ever shares a\n * promise that is already on the wire. Opt-in per call via\n * `{ dedupe: true }`, and skipped whenever the caller supplies its own\n * `AbortSignal` (so one consumer aborting can never cancel another's\n * read).\n */\nconst inFlightReads = new Map<string, Promise<unknown>>();\n\n/**\n * Deterministically serialize a prepared request's headers into a\n * stable string for use in the {@link inFlightReads} dedupe key. Header\n * names are normalized and sorted so ordering differences never produce\n * a different key, and every header (not just `x-api-key`) is included\n * so requests carrying different credentials never collide.\n */\nfunction serializeHeaders(headers: RequestInit[\"headers\"]): string {\n const normalized = mergeHeaders(\n headers as Record<string, HeaderValue> | undefined\n );\n return Object.keys(normalized)\n .sort()\n .map((name) => `${name}:${normalized[name]}`)\n .join(\"\\n\");\n}\n"],"mappings":"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"}

@@ -1,1 +0,1 @@

{"version":3,"file":"base.d.cts","names":[],"sources":["../../src/client/base.ts"],"mappings":";;;;;KAYY,WAAA;;;AA6EZ;;;;;AAqBA;;;;iBArBgB,SAAA,CAAU,MAAA;AAAA,KAqBd,WAAA,IACV,GAAA,EAAK,GAAA,EACL,IAAA,EAAM,WAAA,KACH,OAAA,CAAQ,WAAA,IAAe,WAAA;;;;;UAMX,YAAA;EARf;;;;;;EAeA,MAAA;EAbqC;AAMvC;;;;;EAcE,MAAA;EA0BY;;;;EArBZ,aAAA,GAAgB,iBAAA;EALhB;;;;;;EAYA,SAAA;EAcA;;;;;;EAPA,cAAA,GAAiB,MAAA,SAAe,WAAA;EAgBX;;;;;;EATrB,SAAA,GAAY,WAAA;EAsBS;;;;;EAhBrB,cAAA,GAAiB,cAAA;AAAA;AAAA,cAGN,UAAA;EAAA;YACD,WAAA,EAAa,WAAA;EAAA,UAEb,SAAA;EAAA,UAEA,MAAA;EAAA,UAEA,cAAA,EAAgB,MAAA,SAAe,WAAA;EAAA,UAE/B,SAAA,GAAY,WAAA;EAAA,UAEZ,cAAA,EAAgB,cAAA;EAE1B,WAAA,CAAY,MAAA,GAAS,YAAA;EAAA,UAsCX,mBAAA,CACR,IAAA,UACA,OAAA,GAAU,WAAA;IACR,IAAA;IACA,MAAA,GAAS,MAAA;IACT,SAAA;IACA,YAAA;IACA,MAAA;EAAA,KAEA,GAAA,EAAK,GAAA,EAAK,IAAA,EAAM,WAAA;EAAA,UAmDJ,KAAA,GAAA,CACd,IAAA,UACA,OAAA,EAAS,WAAA;IACP,IAAA;IACA,MAAA,GAAS,MAAA;IACT,SAAA;IACA,MAAA,EAAQ,WAAA;IACR,YAAA;EAAA,IAED,OAAA,EAAS,CAAA,EAAG,QAAA;EAAA,UAEC,KAAA,GAAA,CACd,IAAA,UACA,OAAA,GAAU,WAAA;IACR,IAAA;IACA,MAAA,GAAS,MAAA;IACT,SAAA;IACA,MAAA,EAAQ,WAAA;IACR,YAAA;IACA,MAAA;EAAA,IAED,OAAA,CAAQ,CAAA;EAAA,UAiGM,eAAA;IACH,EAAA;IAAa,KAAA;IAAe,IAAA;EAAA,EAAA,CACxC,MAAA;IACA,QAAA;IACA,MAAA;IACA,MAAA,GAAS,WAAA;IACT,OAAA,GAAU,MAAA;IACV,MAAA,GAAS,MAAA;IACT,IAAA;IACA,UAAA;IACA,aAAA,GAAgB,iBAAA;IAChB,WAAA,IAAe,OAAA;MACb,OAAA;MACA,WAAA;MACA,KAAA;IAAA;IAEF,iBAAA,IAAqB,QAAA,EAAU,QAAA,YAAoB,OAAA;EAAA,IACjD,cAAA,CAAe,CAAA;AAAA"}
{"version":3,"file":"base.d.cts","names":[],"sources":["../../src/client/base.ts"],"mappings":";;;;;KAcY,WAAA;;;AA6EZ;;;;;AAqBA;;;;iBArBgB,SAAA,CAAU,MAAA;AAAA,KAqBd,WAAA,IACV,GAAA,EAAK,GAAA,EACL,IAAA,EAAM,WAAA,KACH,OAAA,CAAQ,WAAA,IAAe,WAAA;;;;;UAMX,YAAA;EARf;;;;;;EAeA,MAAA;EAbqC;AAMvC;;;;;EAcE,MAAA;EA0BY;;;;EArBZ,aAAA,GAAgB,iBAAA;EALhB;;;;;;EAYA,SAAA;EAcA;;;;;;EAPA,cAAA,GAAiB,MAAA,SAAe,WAAA;EAgBX;;;;;;EATrB,SAAA,GAAY,WAAA;EAsBS;;;;;EAhBrB,cAAA,GAAiB,cAAA;AAAA;AAAA,cAGN,UAAA;EAAA;YACD,WAAA,EAAa,WAAA;EAAA,UAEb,SAAA;EAAA,UAEA,MAAA;EAAA,UAEA,cAAA,EAAgB,MAAA,SAAe,WAAA;EAAA,UAE/B,SAAA,GAAY,WAAA;EAAA,UAEZ,cAAA,EAAgB,cAAA;EAE1B,WAAA,CAAY,MAAA,GAAS,YAAA;EAAA,UAsCX,mBAAA,CACR,IAAA,UACA,OAAA,GAAU,WAAA;IACR,IAAA;IACA,MAAA,GAAS,MAAA;IACT,SAAA;IACA,YAAA;IACA,MAAA;EAAA,KAEA,GAAA,EAAK,GAAA,EAAK,IAAA,EAAM,WAAA;EAAA,UAmDJ,KAAA,GAAA,CACd,IAAA,UACA,OAAA,EAAS,WAAA;IACP,IAAA;IACA,MAAA,GAAS,MAAA;IACT,SAAA;IACA,MAAA,EAAQ,WAAA;IACR,YAAA;EAAA,IAED,OAAA,EAAS,CAAA,EAAG,QAAA;EAAA,UAEC,KAAA,GAAA,CACd,IAAA,UACA,OAAA,GAAU,WAAA;IACR,IAAA;IACA,MAAA,GAAS,MAAA;IACT,SAAA;IACA,MAAA,EAAQ,WAAA;IACR,YAAA;IACA,MAAA;EAAA,IAED,OAAA,CAAQ,CAAA;EAAA,UAiGM,eAAA;IACH,EAAA;IAAa,KAAA;IAAe,IAAA;EAAA,EAAA,CACxC,MAAA;IACA,QAAA;IACA,MAAA;IACA,MAAA,GAAS,WAAA;IACT,OAAA,GAAU,MAAA;IACV,MAAA,GAAS,MAAA;IACT,IAAA;IACA,UAAA;IACA,aAAA,GAAgB,iBAAA;IAChB,WAAA,IAAe,OAAA;MACb,OAAA;MACA,WAAA;MACA,KAAA;IAAA;IAEF,iBAAA,IAAqB,QAAA,EAAU,QAAA,YAAoB,OAAA;EAAA,IACjD,cAAA,CAAe,CAAA;AAAA"}

@@ -1,1 +0,1 @@

{"version":3,"file":"base.d.ts","names":[],"sources":["../../src/client/base.ts"],"mappings":";;;;;KAYY,WAAA;;;AA6EZ;;;;;AAqBA;;;;iBArBgB,SAAA,CAAU,MAAA;AAAA,KAqBd,WAAA,IACV,GAAA,EAAK,GAAA,EACL,IAAA,EAAM,WAAA,KACH,OAAA,CAAQ,WAAA,IAAe,WAAA;;;;;UAMX,YAAA;EARf;;;;;;EAeA,MAAA;EAbqC;AAMvC;;;;;EAcE,MAAA;EA0BY;;;;EArBZ,aAAA,GAAgB,iBAAA;EALhB;;;;;;EAYA,SAAA;EAcA;;;;;;EAPA,cAAA,GAAiB,MAAA,SAAe,WAAA;EAgBX;;;;;;EATrB,SAAA,GAAY,WAAA;EAsBS;;;;;EAhBrB,cAAA,GAAiB,cAAA;AAAA;AAAA,cAGN,UAAA;EAAA;YACD,WAAA,EAAa,WAAA;EAAA,UAEb,SAAA;EAAA,UAEA,MAAA;EAAA,UAEA,cAAA,EAAgB,MAAA,SAAe,WAAA;EAAA,UAE/B,SAAA,GAAY,WAAA;EAAA,UAEZ,cAAA,EAAgB,cAAA;EAE1B,WAAA,CAAY,MAAA,GAAS,YAAA;EAAA,UAsCX,mBAAA,CACR,IAAA,UACA,OAAA,GAAU,WAAA;IACR,IAAA;IACA,MAAA,GAAS,MAAA;IACT,SAAA;IACA,YAAA;IACA,MAAA;EAAA,KAEA,GAAA,EAAK,GAAA,EAAK,IAAA,EAAM,WAAA;EAAA,UAmDJ,KAAA,GAAA,CACd,IAAA,UACA,OAAA,EAAS,WAAA;IACP,IAAA;IACA,MAAA,GAAS,MAAA;IACT,SAAA;IACA,MAAA,EAAQ,WAAA;IACR,YAAA;EAAA,IAED,OAAA,EAAS,CAAA,EAAG,QAAA;EAAA,UAEC,KAAA,GAAA,CACd,IAAA,UACA,OAAA,GAAU,WAAA;IACR,IAAA;IACA,MAAA,GAAS,MAAA;IACT,SAAA;IACA,MAAA,EAAQ,WAAA;IACR,YAAA;IACA,MAAA;EAAA,IAED,OAAA,CAAQ,CAAA;EAAA,UAiGM,eAAA;IACH,EAAA;IAAa,KAAA;IAAe,IAAA;EAAA,EAAA,CACxC,MAAA;IACA,QAAA;IACA,MAAA;IACA,MAAA,GAAS,WAAA;IACT,OAAA,GAAU,MAAA;IACV,MAAA,GAAS,MAAA;IACT,IAAA;IACA,UAAA;IACA,aAAA,GAAgB,iBAAA;IAChB,WAAA,IAAe,OAAA;MACb,OAAA;MACA,WAAA;MACA,KAAA;IAAA;IAEF,iBAAA,IAAqB,QAAA,EAAU,QAAA,YAAoB,OAAA;EAAA,IACjD,cAAA,CAAe,CAAA;AAAA"}
{"version":3,"file":"base.d.ts","names":[],"sources":["../../src/client/base.ts"],"mappings":";;;;;KAcY,WAAA;;;AA6EZ;;;;;AAqBA;;;;iBArBgB,SAAA,CAAU,MAAA;AAAA,KAqBd,WAAA,IACV,GAAA,EAAK,GAAA,EACL,IAAA,EAAM,WAAA,KACH,OAAA,CAAQ,WAAA,IAAe,WAAA;;;;;UAMX,YAAA;EARf;;;;;;EAeA,MAAA;EAbqC;AAMvC;;;;;EAcE,MAAA;EA0BY;;;;EArBZ,aAAA,GAAgB,iBAAA;EALhB;;;;;;EAYA,SAAA;EAcA;;;;;;EAPA,cAAA,GAAiB,MAAA,SAAe,WAAA;EAgBX;;;;;;EATrB,SAAA,GAAY,WAAA;EAsBS;;;;;EAhBrB,cAAA,GAAiB,cAAA;AAAA;AAAA,cAGN,UAAA;EAAA;YACD,WAAA,EAAa,WAAA;EAAA,UAEb,SAAA;EAAA,UAEA,MAAA;EAAA,UAEA,cAAA,EAAgB,MAAA,SAAe,WAAA;EAAA,UAE/B,SAAA,GAAY,WAAA;EAAA,UAEZ,cAAA,EAAgB,cAAA;EAE1B,WAAA,CAAY,MAAA,GAAS,YAAA;EAAA,UAsCX,mBAAA,CACR,IAAA,UACA,OAAA,GAAU,WAAA;IACR,IAAA;IACA,MAAA,GAAS,MAAA;IACT,SAAA;IACA,YAAA;IACA,MAAA;EAAA,KAEA,GAAA,EAAK,GAAA,EAAK,IAAA,EAAM,WAAA;EAAA,UAmDJ,KAAA,GAAA,CACd,IAAA,UACA,OAAA,EAAS,WAAA;IACP,IAAA;IACA,MAAA,GAAS,MAAA;IACT,SAAA;IACA,MAAA,EAAQ,WAAA;IACR,YAAA;EAAA,IAED,OAAA,EAAS,CAAA,EAAG,QAAA;EAAA,UAEC,KAAA,GAAA,CACd,IAAA,UACA,OAAA,GAAU,WAAA;IACR,IAAA;IACA,MAAA,GAAS,MAAA;IACT,SAAA;IACA,MAAA,EAAQ,WAAA;IACR,YAAA;IACA,MAAA;EAAA,IAED,OAAA,CAAQ,CAAA;EAAA,UAiGM,eAAA;IACH,EAAA;IAAa,KAAA;IAAe,IAAA;EAAA,EAAA,CACxC,MAAA;IACA,QAAA;IACA,MAAA;IACA,MAAA,GAAS,WAAA;IACT,OAAA,GAAU,MAAA;IACV,MAAA,GAAS,MAAA;IACT,IAAA;IACA,UAAA;IACA,aAAA,GAAgB,iBAAA;IAChB,WAAA,IAAe,OAAA;MACb,OAAA;MACA,WAAA;MACA,KAAA;IAAA;IAEF,iBAAA,IAAqB,QAAA,EAAU,QAAA,YAAoB,OAAA;EAAA,IACjD,cAAA,CAAe,CAAA;AAAA"}

@@ -1,1 +0,1 @@

{"version":3,"file":"base.js","names":["#performFetch","#performFetchWithResponse"],"sources":["../../src/client/base.ts"],"sourcesContent":["import { AsyncCaller, AsyncCallerParams } from \"../utils/async_caller.js\";\nimport { getEnvironmentVariable } from \"../utils/env.js\";\nimport { mergeSignals } from \"../utils/signals.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../utils/sse.js\";\nimport {\n streamWithRetry,\n idleReconnectStream,\n type IdleReconnectMode,\n StreamRequestParams,\n} from \"../utils/stream.js\";\nimport type { StreamProtocol } from \"../types.js\";\n\nexport type HeaderValue = string | undefined | null;\n\nexport function* iterateHeaders(\n headers: HeadersInit | Record<string, HeaderValue>\n): IterableIterator<[string, string | null]> {\n let iter: Iterable<(HeaderValue | HeaderValue | null[])[]>;\n let shouldClear = false;\n\n // eslint-disable-next-line no-instanceof/no-instanceof\n if (headers instanceof Headers) {\n const entries: [string, string][] = [];\n headers.forEach((value, name) => {\n entries.push([name, value]);\n });\n iter = entries;\n } else if (Array.isArray(headers)) {\n iter = headers;\n } else {\n shouldClear = true;\n iter = Object.entries(headers ?? {});\n }\n\n for (const item of iter) {\n const name = item[0];\n if (typeof name !== \"string\")\n throw new TypeError(\n `Expected header name to be a string, got ${typeof name}`\n );\n const values = Array.isArray(item[1]) ? item[1] : [item[1]];\n let didClear = false;\n\n for (const value of values) {\n if (value === undefined) continue;\n\n if (shouldClear && !didClear) {\n didClear = true;\n yield [name, null];\n }\n yield [name, value];\n }\n }\n}\n\nexport function mergeHeaders(\n ...headerObjects: (\n | HeadersInit\n | Record<string, HeaderValue>\n | undefined\n | null\n )[]\n) {\n const outputHeaders = new Headers();\n for (const headers of headerObjects) {\n if (!headers) continue;\n for (const [name, value] of iterateHeaders(headers)) {\n if (value === null) outputHeaders.delete(name);\n else outputHeaders.append(name, value);\n }\n }\n const headerEntries: [string, string][] = [];\n outputHeaders.forEach((value, name) => {\n headerEntries.push([name, value]);\n });\n return Object.fromEntries(headerEntries);\n}\n\n/**\n * Get the API key from the environment.\n * Precedence:\n * 1. explicit argument (if string)\n * 2. LANGGRAPH_API_KEY\n * 3. LANGSMITH_API_KEY\n * 4. LANGCHAIN_API_KEY\n *\n * @param apiKey - API key provided as an argument. If null, skips environment lookup. If undefined, tries environment.\n * @returns The API key if found, otherwise undefined\n */\nexport function getApiKey(apiKey?: string | null): string | undefined {\n if (apiKey === null) {\n return undefined;\n }\n\n if (apiKey) {\n return apiKey;\n }\n\n const prefixes = [\"LANGGRAPH\", \"LANGSMITH\", \"LANGCHAIN\"];\n\n for (const prefix of prefixes) {\n const envKey = getEnvironmentVariable(`${prefix}_API_KEY`);\n if (envKey) {\n return envKey.trim().replace(/^[\"']|[\"']$/g, \"\");\n }\n }\n\n return undefined;\n}\n\nexport type RequestHook = (\n url: URL,\n init: RequestInit\n) => Promise<RequestInit> | RequestInit;\n\n/**\n * Configuration for {@link BaseClient} and the exported LangGraph SDK\n * {@link Client}.\n */\nexport interface ClientConfig {\n /**\n * Base URL of the LangGraph API server.\n *\n * Defaults to `http://localhost:8123`, unless the runtime provides a\n * `langgraph_api:url` global override.\n */\n apiUrl?: string;\n /**\n * API key for authentication.\n * - If a string is provided, that key will be used\n * - If undefined (default), the key will be auto-loaded from environment variables (LANGGRAPH_API_KEY, LANGSMITH_API_KEY, or LANGCHAIN_API_KEY)\n * - If null, no API key will be set (skips auto-loading)\n */\n apiKey?: string | null;\n /**\n * Options forwarded to the internal {@link AsyncCaller}, such as retry,\n * concurrency, or custom `fetch` behavior.\n */\n callerOptions?: AsyncCallerParams;\n /**\n * Default timeout, in milliseconds, applied to client requests.\n *\n * Per-request `timeoutMs` values override this default. Passing `null`\n * at the request level disables the configured timeout for that request.\n */\n timeoutMs?: number;\n /**\n * Headers applied to every request.\n *\n * The configured API key, when present, is added as the `x-api-key`\n * header after these defaults are initialized.\n */\n defaultHeaders?: Record<string, HeaderValue>;\n /**\n * Hook for inspecting or mutating a request before it is sent.\n *\n * Receives the resolved URL and prepared `RequestInit`; return the\n * original init or a replacement object to continue the request.\n */\n onRequest?: RequestHook;\n /**\n * Streaming protocol used by stream-capable endpoints.\n *\n * Defaults to `\"legacy\"` for backwards compatibility.\n */\n streamProtocol?: StreamProtocol;\n}\n\nexport class BaseClient {\n protected asyncCaller: AsyncCaller;\n\n protected timeoutMs: number | undefined;\n\n protected apiUrl: string;\n\n protected defaultHeaders: Record<string, HeaderValue>;\n\n protected onRequest?: RequestHook;\n\n protected streamProtocol: StreamProtocol;\n\n constructor(config?: ClientConfig) {\n const callerOptions = {\n maxRetries: 4,\n maxConcurrency: 4,\n ...config?.callerOptions,\n };\n\n let defaultApiUrl = \"http://localhost:8123\";\n if (\n !config?.apiUrl &&\n typeof globalThis === \"object\" &&\n globalThis != null\n ) {\n const fetchSmb = Symbol.for(\"langgraph_api:fetch\");\n const urlSmb = Symbol.for(\"langgraph_api:url\");\n\n const global = globalThis as unknown as {\n [fetchSmb]?: typeof fetch;\n [urlSmb]?: string;\n };\n\n if (global[fetchSmb]) callerOptions.fetch ??= global[fetchSmb];\n if (global[urlSmb]) defaultApiUrl = global[urlSmb];\n }\n\n this.asyncCaller = new AsyncCaller(callerOptions);\n this.timeoutMs = config?.timeoutMs;\n\n this.apiUrl = config?.apiUrl?.replace(/\\/$/, \"\") || defaultApiUrl;\n this.defaultHeaders = config?.defaultHeaders || {};\n this.onRequest = config?.onRequest;\n this.streamProtocol = config?.streamProtocol ?? \"legacy\";\n const apiKey = getApiKey(config?.apiKey);\n if (apiKey) {\n this.defaultHeaders[\"x-api-key\"] = apiKey;\n }\n }\n\n protected prepareFetchOptions(\n path: string,\n options?: RequestInit & {\n json?: unknown;\n params?: Record<string, unknown>;\n timeoutMs?: number | null;\n withResponse?: boolean;\n dedupe?: boolean;\n }\n ): [url: URL, init: RequestInit] {\n const mutatedOptions = {\n ...options,\n headers: mergeHeaders(this.defaultHeaders, options?.headers),\n };\n\n if (mutatedOptions.json) {\n mutatedOptions.body = JSON.stringify(mutatedOptions.json);\n mutatedOptions.headers = mergeHeaders(mutatedOptions.headers, {\n \"content-type\": \"application/json\",\n });\n delete mutatedOptions.json;\n }\n\n if (mutatedOptions.withResponse) {\n delete mutatedOptions.withResponse;\n }\n\n if (\"dedupe\" in mutatedOptions) {\n delete mutatedOptions.dedupe;\n }\n\n let timeoutSignal: AbortSignal | null = null;\n if (typeof options?.timeoutMs !== \"undefined\") {\n if (options.timeoutMs != null) {\n timeoutSignal = AbortSignal.timeout(options.timeoutMs);\n }\n } else if (this.timeoutMs != null) {\n timeoutSignal = AbortSignal.timeout(this.timeoutMs);\n }\n\n mutatedOptions.signal = mergeSignals(timeoutSignal, mutatedOptions.signal);\n const targetUrl = new URL(`${this.apiUrl}${path}`);\n\n if (mutatedOptions.params) {\n for (const [key, value] of Object.entries(mutatedOptions.params)) {\n if (value == null) continue;\n\n const strValue =\n typeof value === \"string\" || typeof value === \"number\"\n ? value.toString()\n : JSON.stringify(value);\n\n targetUrl.searchParams.append(key, strValue);\n }\n delete mutatedOptions.params;\n }\n\n return [targetUrl, mutatedOptions];\n }\n\n protected async fetch<T>(\n path: string,\n options: RequestInit & {\n json?: unknown;\n params?: Record<string, unknown>;\n timeoutMs?: number | null;\n signal: AbortSignal | undefined;\n withResponse: true;\n }\n ): Promise<[T, Response]>;\n\n protected async fetch<T>(\n path: string,\n options?: RequestInit & {\n json?: unknown;\n params?: Record<string, unknown>;\n timeoutMs?: number | null;\n signal: AbortSignal | undefined;\n withResponse?: false;\n dedupe?: boolean;\n }\n ): Promise<T>;\n\n protected async fetch<T>(\n path: string,\n options?: RequestInit & {\n json?: unknown;\n params?: Record<string, unknown>;\n timeoutMs?: number | null;\n signal: AbortSignal | undefined;\n withResponse?: boolean;\n dedupe?: boolean;\n }\n ): Promise<T | [T, Response]> {\n const [url, init] = this.prepareFetchOptions(path, options);\n\n /**\n * Coalesce concurrent, identical idempotent reads onto a single\n * in-flight request. Only engaged when the caller opts in\n * (`dedupe: true`), is not asking for the raw `Response`, did not\n * supply its own `AbortSignal` (sharing a request across consumers\n * must never let one consumer's abort cancel another's), and no\n * `onRequest` hook is configured.\n *\n * `onRequest` is excluded because it can inject per-request headers\n * (e.g. a freshly-minted `Authorization` bearer) that are not\n * visible until *after* it runs — i.e. after the dedupe key is\n * computed — so two requests that look identical here could be sent\n * with different credentials. Coalescing them would let one\n * consumer receive a response fetched with another's auth.\n */\n const canDedupe =\n options?.dedupe === true &&\n options?.withResponse !== true &&\n options?.signal == null &&\n this.onRequest == null;\n\n if (canDedupe) {\n const body = typeof init.body === \"string\" ? init.body : \"\";\n /**\n * The key must capture the FULL request identity, including every\n * prepared header. `inFlightReads` is module-scoped across all\n * `Client` instances, so omitting headers would let two clients\n * pointed at the same URL/thread but using different credentials\n * (Authorization, custom auth headers, tenant-scoping defaults, …)\n * share one in-flight promise — a cross-tenant data leak.\n */\n const headers = serializeHeaders(init.headers);\n const key = `${init.method ?? \"GET\"} ${url.toString()} ${body} ${headers}`;\n const existing = inFlightReads.get(key);\n if (existing != null) return existing as Promise<T>;\n\n const promise = this.#performFetch<T>(url, init);\n inFlightReads.set(key, promise);\n const clear = () => {\n if (inFlightReads.get(key) === promise) inFlightReads.delete(key);\n };\n promise.then(clear, clear);\n return promise;\n }\n\n const [body, response] = await this.#performFetchWithResponse<T>(url, init);\n if (options?.withResponse) {\n return [body, response];\n }\n return body;\n }\n\n /**\n * Issue the prepared request (applying the `onRequest` hook) and\n * resolve the parsed body. Shared by the deduped and direct paths.\n */\n async #performFetch<T>(url: URL, init: RequestInit): Promise<T> {\n const [body] = await this.#performFetchWithResponse<T>(url, init);\n return body;\n }\n\n async #performFetchWithResponse<T>(\n url: URL,\n init: RequestInit\n ): Promise<[T, Response]> {\n let finalInit = init;\n if (this.onRequest) {\n finalInit = await this.onRequest(url, init);\n }\n\n const response = await this.asyncCaller.fetch(url.toString(), finalInit);\n\n const body = await (async () => {\n if (response.status === 202 || response.status === 204) {\n return undefined as T;\n }\n return response.json() as Promise<T>;\n })();\n\n return [body, response];\n }\n\n protected async *streamWithRetry<\n T extends { id?: string; event: string; data: unknown },\n >(config: {\n endpoint: string;\n method?: string;\n signal?: AbortSignal;\n headers?: Record<string, string>;\n params?: Record<string, unknown>;\n json?: unknown;\n maxRetries?: number;\n idleReconnect?: IdleReconnectMode;\n onReconnect?: (options: {\n attempt: number;\n lastEventId?: string;\n cause: unknown;\n }) => void;\n onInitialResponse?: (response: Response) => void | Promise<void>;\n }): AsyncGenerator<T> {\n const makeRequest = async (reconnectParams?: StreamRequestParams) => {\n const requestEndpoint = reconnectParams?.reconnectPath || config.endpoint;\n\n const isReconnect = !!reconnectParams?.reconnectPath;\n const method = isReconnect ? \"GET\" : config.method || \"GET\";\n\n const requestHeaders =\n isReconnect && reconnectParams?.lastEventId\n ? { ...config.headers, \"Last-Event-ID\": reconnectParams.lastEventId }\n : config.headers;\n\n // oxlint-disable-next-line prefer-const -- init is reassigned by onRequest hook\n let [url, init] = this.prepareFetchOptions(requestEndpoint, {\n method,\n timeoutMs: null,\n signal: config.signal,\n headers: requestHeaders,\n params: config.params,\n json: isReconnect ? undefined : config.json,\n });\n\n if (this.onRequest != null) {\n init = await this.onRequest(url, init);\n }\n\n const response = await this.asyncCaller.fetch(url.toString(), init);\n if (!response.body) {\n throw new Error(\"Expected response body from stream endpoint\");\n }\n\n if (!isReconnect && config.onInitialResponse) {\n await config.onInitialResponse(response);\n }\n\n // Insert the idle watchdog on the line stream (between the byte-line\n // decoder and the SSE decoder) so it can both reset on any line and\n // recognise `:` keep-alive heartbeats to drive `\"auto\"` mode. The SSE\n // decoder downstream discards those comment lines.\n const idleMode = config.idleReconnect ?? \"auto\";\n const enableIdle = idleMode === \"auto\" || idleMode > 0;\n\n const lines = response.body.pipeThrough(BytesLineDecoder());\n const watched = enableIdle\n ? lines.pipeThrough(idleReconnectStream({ mode: idleMode }))\n : lines;\n const stream: ReadableStream<T> = watched.pipeThrough(\n SSEDecoder()\n ) as ReadableStream<T>;\n\n return { response, stream };\n };\n\n yield* streamWithRetry(makeRequest, {\n maxRetries: config.maxRetries ?? 5,\n signal: config.signal,\n onReconnect: config.onReconnect,\n });\n }\n}\n\nexport const REGEX_RUN_METADATA =\n /(\\/threads\\/(?<thread_id>.+))?\\/runs\\/(?<run_id>.+)/;\n\nexport function getRunMetadataFromResponse(\n response: Response\n): { run_id: string; thread_id?: string } | undefined {\n const contentLocation = response.headers.get(\"Content-Location\");\n if (!contentLocation) return undefined;\n\n const match = REGEX_RUN_METADATA.exec(contentLocation);\n\n if (!match?.groups?.run_id) return undefined;\n return {\n run_id: match.groups.run_id,\n thread_id: match.groups.thread_id || undefined,\n };\n}\n\nexport const isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\n/**\n * Module-scoped, in-flight-only coalescing map for idempotent reads.\n *\n * Two independently-constructed clients (e.g. a React component that\n * remounts under Suspense / a reachability state flip, each minting a\n * fresh `Client`) can fire the *same* `getState` / `getHistory` read a\n * few milliseconds apart, before the first has resolved. Without\n * coalescing each pays the full round-trip — the duplicate\n * `threads/{id}/state` and `threads/{id}/history` requests seen on\n * reconnect.\n *\n * Keyed by `method + url + body + auth`, entries live only while a\n * request is in flight and are removed the moment it settles. This is\n * deliberately *not* a result cache: there is no TTL and no stored\n * payload, so it cannot serve stale data — it only ever shares a\n * promise that is already on the wire. Opt-in per call via\n * `{ dedupe: true }`, and skipped whenever the caller supplies its own\n * `AbortSignal` (so one consumer aborting can never cancel another's\n * read).\n */\nconst inFlightReads = new Map<string, Promise<unknown>>();\n\n/**\n * Deterministically serialize a prepared request's headers into a\n * stable string for use in the {@link inFlightReads} dedupe key. Header\n * names are normalized and sorted so ordering differences never produce\n * a different key, and every header (not just `x-api-key`) is included\n * so requests carrying different credentials never collide.\n */\nfunction serializeHeaders(headers: RequestInit[\"headers\"]): string {\n const normalized = mergeHeaders(\n headers as Record<string, HeaderValue> | undefined\n );\n return Object.keys(normalized)\n .sort()\n .map((name) => `${name}:${normalized[name]}`)\n .join(\"\\n\");\n}\n"],"mappings":"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"}
{"version":3,"file":"base.js","names":["#performFetch","#performFetchWithResponse"],"sources":["../../src/client/base.ts"],"sourcesContent":["import { AsyncCaller, AsyncCallerParams } from \"../utils/async_caller.js\";\nimport { getEnvironmentVariable } from \"../utils/env.js\";\nimport { mergeSignals } from \"../utils/signals.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../utils/sse.js\";\nimport {\n streamWithRetry,\n idleReconnectStream,\n type IdleReconnectMode,\n StreamRequestParams,\n DEFAULT_IDLE_RECONNECT,\n} from \"../utils/stream.js\";\nimport { DEFAULT_MAX_RECONNECT_ATTEMPTS } from \"../utils/reconnect.js\";\nimport type { StreamProtocol } from \"../types.js\";\n\nexport type HeaderValue = string | undefined | null;\n\nexport function* iterateHeaders(\n headers: HeadersInit | Record<string, HeaderValue>\n): IterableIterator<[string, string | null]> {\n let iter: Iterable<(HeaderValue | HeaderValue | null[])[]>;\n let shouldClear = false;\n\n // eslint-disable-next-line no-instanceof/no-instanceof\n if (headers instanceof Headers) {\n const entries: [string, string][] = [];\n headers.forEach((value, name) => {\n entries.push([name, value]);\n });\n iter = entries;\n } else if (Array.isArray(headers)) {\n iter = headers;\n } else {\n shouldClear = true;\n iter = Object.entries(headers ?? {});\n }\n\n for (const item of iter) {\n const name = item[0];\n if (typeof name !== \"string\")\n throw new TypeError(\n `Expected header name to be a string, got ${typeof name}`\n );\n const values = Array.isArray(item[1]) ? item[1] : [item[1]];\n let didClear = false;\n\n for (const value of values) {\n if (value === undefined) continue;\n\n if (shouldClear && !didClear) {\n didClear = true;\n yield [name, null];\n }\n yield [name, value];\n }\n }\n}\n\nexport function mergeHeaders(\n ...headerObjects: (\n | HeadersInit\n | Record<string, HeaderValue>\n | undefined\n | null\n )[]\n) {\n const outputHeaders = new Headers();\n for (const headers of headerObjects) {\n if (!headers) continue;\n for (const [name, value] of iterateHeaders(headers)) {\n if (value === null) outputHeaders.delete(name);\n else outputHeaders.append(name, value);\n }\n }\n const headerEntries: [string, string][] = [];\n outputHeaders.forEach((value, name) => {\n headerEntries.push([name, value]);\n });\n return Object.fromEntries(headerEntries);\n}\n\n/**\n * Get the API key from the environment.\n * Precedence:\n * 1. explicit argument (if string)\n * 2. LANGGRAPH_API_KEY\n * 3. LANGSMITH_API_KEY\n * 4. LANGCHAIN_API_KEY\n *\n * @param apiKey - API key provided as an argument. If null, skips environment lookup. If undefined, tries environment.\n * @returns The API key if found, otherwise undefined\n */\nexport function getApiKey(apiKey?: string | null): string | undefined {\n if (apiKey === null) {\n return undefined;\n }\n\n if (apiKey) {\n return apiKey;\n }\n\n const prefixes = [\"LANGGRAPH\", \"LANGSMITH\", \"LANGCHAIN\"];\n\n for (const prefix of prefixes) {\n const envKey = getEnvironmentVariable(`${prefix}_API_KEY`);\n if (envKey) {\n return envKey.trim().replace(/^[\"']|[\"']$/g, \"\");\n }\n }\n\n return undefined;\n}\n\nexport type RequestHook = (\n url: URL,\n init: RequestInit\n) => Promise<RequestInit> | RequestInit;\n\n/**\n * Configuration for {@link BaseClient} and the exported LangGraph SDK\n * {@link Client}.\n */\nexport interface ClientConfig {\n /**\n * Base URL of the LangGraph API server.\n *\n * Defaults to `http://localhost:8123`, unless the runtime provides a\n * `langgraph_api:url` global override.\n */\n apiUrl?: string;\n /**\n * API key for authentication.\n * - If a string is provided, that key will be used\n * - If undefined (default), the key will be auto-loaded from environment variables (LANGGRAPH_API_KEY, LANGSMITH_API_KEY, or LANGCHAIN_API_KEY)\n * - If null, no API key will be set (skips auto-loading)\n */\n apiKey?: string | null;\n /**\n * Options forwarded to the internal {@link AsyncCaller}, such as retry,\n * concurrency, or custom `fetch` behavior.\n */\n callerOptions?: AsyncCallerParams;\n /**\n * Default timeout, in milliseconds, applied to client requests.\n *\n * Per-request `timeoutMs` values override this default. Passing `null`\n * at the request level disables the configured timeout for that request.\n */\n timeoutMs?: number;\n /**\n * Headers applied to every request.\n *\n * The configured API key, when present, is added as the `x-api-key`\n * header after these defaults are initialized.\n */\n defaultHeaders?: Record<string, HeaderValue>;\n /**\n * Hook for inspecting or mutating a request before it is sent.\n *\n * Receives the resolved URL and prepared `RequestInit`; return the\n * original init or a replacement object to continue the request.\n */\n onRequest?: RequestHook;\n /**\n * Streaming protocol used by stream-capable endpoints.\n *\n * Defaults to `\"legacy\"` for backwards compatibility.\n */\n streamProtocol?: StreamProtocol;\n}\n\nexport class BaseClient {\n protected asyncCaller: AsyncCaller;\n\n protected timeoutMs: number | undefined;\n\n protected apiUrl: string;\n\n protected defaultHeaders: Record<string, HeaderValue>;\n\n protected onRequest?: RequestHook;\n\n protected streamProtocol: StreamProtocol;\n\n constructor(config?: ClientConfig) {\n const callerOptions = {\n maxRetries: 4,\n maxConcurrency: 4,\n ...config?.callerOptions,\n };\n\n let defaultApiUrl = \"http://localhost:8123\";\n if (\n !config?.apiUrl &&\n typeof globalThis === \"object\" &&\n globalThis != null\n ) {\n const fetchSmb = Symbol.for(\"langgraph_api:fetch\");\n const urlSmb = Symbol.for(\"langgraph_api:url\");\n\n const global = globalThis as unknown as {\n [fetchSmb]?: typeof fetch;\n [urlSmb]?: string;\n };\n\n if (global[fetchSmb]) callerOptions.fetch ??= global[fetchSmb];\n if (global[urlSmb]) defaultApiUrl = global[urlSmb];\n }\n\n this.asyncCaller = new AsyncCaller(callerOptions);\n this.timeoutMs = config?.timeoutMs;\n\n this.apiUrl = config?.apiUrl?.replace(/\\/$/, \"\") || defaultApiUrl;\n this.defaultHeaders = config?.defaultHeaders || {};\n this.onRequest = config?.onRequest;\n this.streamProtocol = config?.streamProtocol ?? \"legacy\";\n const apiKey = getApiKey(config?.apiKey);\n if (apiKey) {\n this.defaultHeaders[\"x-api-key\"] = apiKey;\n }\n }\n\n protected prepareFetchOptions(\n path: string,\n options?: RequestInit & {\n json?: unknown;\n params?: Record<string, unknown>;\n timeoutMs?: number | null;\n withResponse?: boolean;\n dedupe?: boolean;\n }\n ): [url: URL, init: RequestInit] {\n const mutatedOptions = {\n ...options,\n headers: mergeHeaders(this.defaultHeaders, options?.headers),\n };\n\n if (mutatedOptions.json) {\n mutatedOptions.body = JSON.stringify(mutatedOptions.json);\n mutatedOptions.headers = mergeHeaders(mutatedOptions.headers, {\n \"content-type\": \"application/json\",\n });\n delete mutatedOptions.json;\n }\n\n if (mutatedOptions.withResponse) {\n delete mutatedOptions.withResponse;\n }\n\n if (\"dedupe\" in mutatedOptions) {\n delete mutatedOptions.dedupe;\n }\n\n let timeoutSignal: AbortSignal | null = null;\n if (typeof options?.timeoutMs !== \"undefined\") {\n if (options.timeoutMs != null) {\n timeoutSignal = AbortSignal.timeout(options.timeoutMs);\n }\n } else if (this.timeoutMs != null) {\n timeoutSignal = AbortSignal.timeout(this.timeoutMs);\n }\n\n mutatedOptions.signal = mergeSignals(timeoutSignal, mutatedOptions.signal);\n const targetUrl = new URL(`${this.apiUrl}${path}`);\n\n if (mutatedOptions.params) {\n for (const [key, value] of Object.entries(mutatedOptions.params)) {\n if (value == null) continue;\n\n const strValue =\n typeof value === \"string\" || typeof value === \"number\"\n ? value.toString()\n : JSON.stringify(value);\n\n targetUrl.searchParams.append(key, strValue);\n }\n delete mutatedOptions.params;\n }\n\n return [targetUrl, mutatedOptions];\n }\n\n protected async fetch<T>(\n path: string,\n options: RequestInit & {\n json?: unknown;\n params?: Record<string, unknown>;\n timeoutMs?: number | null;\n signal: AbortSignal | undefined;\n withResponse: true;\n }\n ): Promise<[T, Response]>;\n\n protected async fetch<T>(\n path: string,\n options?: RequestInit & {\n json?: unknown;\n params?: Record<string, unknown>;\n timeoutMs?: number | null;\n signal: AbortSignal | undefined;\n withResponse?: false;\n dedupe?: boolean;\n }\n ): Promise<T>;\n\n protected async fetch<T>(\n path: string,\n options?: RequestInit & {\n json?: unknown;\n params?: Record<string, unknown>;\n timeoutMs?: number | null;\n signal: AbortSignal | undefined;\n withResponse?: boolean;\n dedupe?: boolean;\n }\n ): Promise<T | [T, Response]> {\n const [url, init] = this.prepareFetchOptions(path, options);\n\n /**\n * Coalesce concurrent, identical idempotent reads onto a single\n * in-flight request. Only engaged when the caller opts in\n * (`dedupe: true`), is not asking for the raw `Response`, did not\n * supply its own `AbortSignal` (sharing a request across consumers\n * must never let one consumer's abort cancel another's), and no\n * `onRequest` hook is configured.\n *\n * `onRequest` is excluded because it can inject per-request headers\n * (e.g. a freshly-minted `Authorization` bearer) that are not\n * visible until *after* it runs — i.e. after the dedupe key is\n * computed — so two requests that look identical here could be sent\n * with different credentials. Coalescing them would let one\n * consumer receive a response fetched with another's auth.\n */\n const canDedupe =\n options?.dedupe === true &&\n options?.withResponse !== true &&\n options?.signal == null &&\n this.onRequest == null;\n\n if (canDedupe) {\n const body = typeof init.body === \"string\" ? init.body : \"\";\n /**\n * The key must capture the FULL request identity, including every\n * prepared header. `inFlightReads` is module-scoped across all\n * `Client` instances, so omitting headers would let two clients\n * pointed at the same URL/thread but using different credentials\n * (Authorization, custom auth headers, tenant-scoping defaults, …)\n * share one in-flight promise — a cross-tenant data leak.\n */\n const headers = serializeHeaders(init.headers);\n const key = `${init.method ?? \"GET\"} ${url.toString()} ${body} ${headers}`;\n const existing = inFlightReads.get(key);\n if (existing != null) return existing as Promise<T>;\n\n const promise = this.#performFetch<T>(url, init);\n inFlightReads.set(key, promise);\n const clear = () => {\n if (inFlightReads.get(key) === promise) inFlightReads.delete(key);\n };\n promise.then(clear, clear);\n return promise;\n }\n\n const [body, response] = await this.#performFetchWithResponse<T>(url, init);\n if (options?.withResponse) {\n return [body, response];\n }\n return body;\n }\n\n /**\n * Issue the prepared request (applying the `onRequest` hook) and\n * resolve the parsed body. Shared by the deduped and direct paths.\n */\n async #performFetch<T>(url: URL, init: RequestInit): Promise<T> {\n const [body] = await this.#performFetchWithResponse<T>(url, init);\n return body;\n }\n\n async #performFetchWithResponse<T>(\n url: URL,\n init: RequestInit\n ): Promise<[T, Response]> {\n let finalInit = init;\n if (this.onRequest) {\n finalInit = await this.onRequest(url, init);\n }\n\n const response = await this.asyncCaller.fetch(url.toString(), finalInit);\n\n const body = await (async () => {\n if (response.status === 202 || response.status === 204) {\n return undefined as T;\n }\n return response.json() as Promise<T>;\n })();\n\n return [body, response];\n }\n\n protected async *streamWithRetry<\n T extends { id?: string; event: string; data: unknown },\n >(config: {\n endpoint: string;\n method?: string;\n signal?: AbortSignal;\n headers?: Record<string, string>;\n params?: Record<string, unknown>;\n json?: unknown;\n maxRetries?: number;\n idleReconnect?: IdleReconnectMode;\n onReconnect?: (options: {\n attempt: number;\n lastEventId?: string;\n cause: unknown;\n }) => void;\n onInitialResponse?: (response: Response) => void | Promise<void>;\n }): AsyncGenerator<T> {\n const makeRequest = async (reconnectParams?: StreamRequestParams) => {\n const requestEndpoint = reconnectParams?.reconnectPath || config.endpoint;\n\n const isReconnect = !!reconnectParams?.reconnectPath;\n const method = isReconnect ? \"GET\" : config.method || \"GET\";\n\n const requestHeaders =\n isReconnect && reconnectParams?.lastEventId\n ? { ...config.headers, \"Last-Event-ID\": reconnectParams.lastEventId }\n : config.headers;\n\n // oxlint-disable-next-line prefer-const -- init is reassigned by onRequest hook\n let [url, init] = this.prepareFetchOptions(requestEndpoint, {\n method,\n timeoutMs: null,\n signal: config.signal,\n headers: requestHeaders,\n params: config.params,\n json: isReconnect ? undefined : config.json,\n });\n\n if (this.onRequest != null) {\n init = await this.onRequest(url, init);\n }\n\n const response = await this.asyncCaller.fetch(url.toString(), init);\n if (!response.body) {\n throw new Error(\"Expected response body from stream endpoint\");\n }\n\n if (!isReconnect && config.onInitialResponse) {\n await config.onInitialResponse(response);\n }\n\n // Insert the idle watchdog on the line stream (between the byte-line\n // decoder and the SSE decoder) so it can both reset on any line and\n // recognise `:` keep-alive heartbeats to drive `\"auto\"` mode. The SSE\n // decoder downstream discards those comment lines.\n const idleMode = config.idleReconnect ?? DEFAULT_IDLE_RECONNECT;\n const enableIdle = idleMode === \"auto\" || idleMode > 0;\n\n const lines = response.body.pipeThrough(BytesLineDecoder());\n const watched = enableIdle\n ? lines.pipeThrough(idleReconnectStream({ mode: idleMode }))\n : lines;\n const stream: ReadableStream<T> = watched.pipeThrough(\n SSEDecoder()\n ) as ReadableStream<T>;\n\n return { response, stream };\n };\n\n yield* streamWithRetry(makeRequest, {\n maxRetries: config.maxRetries ?? DEFAULT_MAX_RECONNECT_ATTEMPTS,\n signal: config.signal,\n onReconnect: config.onReconnect,\n });\n }\n}\n\nexport const REGEX_RUN_METADATA =\n /(\\/threads\\/(?<thread_id>.+))?\\/runs\\/(?<run_id>.+)/;\n\nexport function getRunMetadataFromResponse(\n response: Response\n): { run_id: string; thread_id?: string } | undefined {\n const contentLocation = response.headers.get(\"Content-Location\");\n if (!contentLocation) return undefined;\n\n const match = REGEX_RUN_METADATA.exec(contentLocation);\n\n if (!match?.groups?.run_id) return undefined;\n return {\n run_id: match.groups.run_id,\n thread_id: match.groups.thread_id || undefined,\n };\n}\n\nexport const isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\n/**\n * Module-scoped, in-flight-only coalescing map for idempotent reads.\n *\n * Two independently-constructed clients (e.g. a React component that\n * remounts under Suspense / a reachability state flip, each minting a\n * fresh `Client`) can fire the *same* `getState` / `getHistory` read a\n * few milliseconds apart, before the first has resolved. Without\n * coalescing each pays the full round-trip — the duplicate\n * `threads/{id}/state` and `threads/{id}/history` requests seen on\n * reconnect.\n *\n * Keyed by `method + url + body + auth`, entries live only while a\n * request is in flight and are removed the moment it settles. This is\n * deliberately *not* a result cache: there is no TTL and no stored\n * payload, so it cannot serve stale data — it only ever shares a\n * promise that is already on the wire. Opt-in per call via\n * `{ dedupe: true }`, and skipped whenever the caller supplies its own\n * `AbortSignal` (so one consumer aborting can never cancel another's\n * read).\n */\nconst inFlightReads = new Map<string, Promise<unknown>>();\n\n/**\n * Deterministically serialize a prepared request's headers into a\n * stable string for use in the {@link inFlightReads} dedupe key. Header\n * names are normalized and sorted so ordering differences never produce\n * a different key, and every header (not just `x-api-key`) is included\n * so requests carrying different credentials never collide.\n */\nfunction serializeHeaders(headers: RequestInit[\"headers\"]): string {\n const normalized = mergeHeaders(\n headers as Record<string, HeaderValue> | undefined\n );\n return Object.keys(normalized)\n .sort()\n .map((name) => `${name}:${normalized[name]}`)\n .join(\"\\n\");\n}\n"],"mappings":"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"}

@@ -82,19 +82,20 @@ const require_base = require("../base.cjs");

async update(cronId, payload) {
const json = {};
if (payload?.schedule !== void 0) json.schedule = payload.schedule;
if (payload?.timezone !== void 0) json.timezone = payload.timezone;
if (payload?.endTime !== void 0) json.end_time = payload.endTime;
if (payload?.input !== void 0) json.input = payload.input;
if (payload?.metadata !== void 0) json.metadata = payload.metadata;
if (payload?.config !== void 0) json.config = payload.config;
if (payload?.context !== void 0) json.context = payload.context;
if (payload?.webhook !== void 0) json.webhook = payload.webhook;
if (payload?.interruptBefore !== void 0) json.interrupt_before = payload.interruptBefore;
if (payload?.interruptAfter !== void 0) json.interrupt_after = payload.interruptAfter;
if (payload?.onRunCompleted !== void 0) json.on_run_completed = payload.onRunCompleted;
if (payload?.enabled !== void 0) json.enabled = payload.enabled;
if (payload?.streamMode !== void 0) json.stream_mode = payload.streamMode;
if (payload?.streamSubgraphs !== void 0) json.stream_subgraphs = payload.streamSubgraphs;
if (payload?.streamResumable !== void 0) json.stream_resumable = payload.streamResumable;
if (payload?.durability !== void 0) json.durability = payload.durability;
const json = {
schedule: payload?.schedule,
timezone: payload?.timezone,
end_time: payload?.endTime,
input: payload?.input,
metadata: payload?.metadata,
config: payload?.config,
context: payload?.context,
webhook: payload?.webhook,
interrupt_before: payload?.interruptBefore,
interrupt_after: payload?.interruptAfter,
on_run_completed: payload?.onRunCompleted,
enabled: payload?.enabled,
stream_mode: payload?.streamMode,
stream_subgraphs: payload?.streamSubgraphs,
stream_resumable: payload?.streamResumable,
durability: payload?.durability
};
return this.fetch(`/runs/crons/${cronId}`, {

@@ -101,0 +102,0 @@ method: "PATCH",

@@ -1,1 +0,1 @@

{"version":3,"file":"index.cjs","names":["BaseClient"],"sources":["../../../src/client/crons/index.ts"],"sourcesContent":["import {\n Cron,\n CronSelectField,\n CronCreateForThreadResponse,\n CronCreateResponse,\n CronSortBy,\n Metadata,\n SortOrder,\n} from \"../../schema.js\";\nimport type { CronsCreatePayload, CronsUpdatePayload } from \"../../types.js\";\nimport { BaseClient } from \"../base.js\";\n\nexport class CronsClient extends BaseClient {\n /**\n *\n * @param threadId The ID of the thread.\n * @param assistantId Assistant ID to use for this cron job.\n * @param payload Payload for creating a cron job.\n * @returns The created background run.\n */\n async createForThread(\n threadId: string,\n assistantId: string,\n payload?: CronsCreatePayload\n ): Promise<CronCreateForThreadResponse> {\n const json: Record<string, unknown> = {\n schedule: payload?.schedule,\n input: payload?.input,\n config: payload?.config,\n context: payload?.context,\n metadata: payload?.metadata,\n assistant_id: assistantId,\n interrupt_before: payload?.interruptBefore,\n interrupt_after: payload?.interruptAfter,\n webhook: payload?.webhook,\n multitask_strategy: payload?.multitaskStrategy,\n checkpoint_during: payload?.checkpointDuring,\n durability: payload?.durability,\n enabled: payload?.enabled,\n timezone: payload?.timezone,\n stream_mode: payload?.streamMode,\n stream_subgraphs: payload?.streamSubgraphs,\n stream_resumable: payload?.streamResumable,\n end_time: payload?.endTime,\n on_run_completed: payload?.onRunCompleted,\n };\n return this.fetch<CronCreateForThreadResponse>(\n `/threads/${threadId}/runs/crons`,\n {\n method: \"POST\",\n json,\n signal: payload?.signal,\n }\n );\n }\n\n /**\n *\n * @param assistantId Assistant ID to use for this cron job.\n * @param payload Payload for creating a cron job.\n * @returns\n */\n async create(\n assistantId: string,\n payload?: CronsCreatePayload\n ): Promise<CronCreateResponse> {\n const json: Record<string, unknown> = {\n schedule: payload?.schedule,\n input: payload?.input,\n config: payload?.config,\n context: payload?.context,\n metadata: payload?.metadata,\n assistant_id: assistantId,\n interrupt_before: payload?.interruptBefore,\n interrupt_after: payload?.interruptAfter,\n webhook: payload?.webhook,\n on_run_completed: payload?.onRunCompleted,\n multitask_strategy: payload?.multitaskStrategy,\n checkpoint_during: payload?.checkpointDuring,\n durability: payload?.durability,\n enabled: payload?.enabled,\n timezone: payload?.timezone,\n stream_mode: payload?.streamMode,\n stream_subgraphs: payload?.streamSubgraphs,\n stream_resumable: payload?.streamResumable,\n end_time: payload?.endTime,\n };\n return this.fetch<CronCreateResponse>(`/runs/crons`, {\n method: \"POST\",\n json,\n signal: payload?.signal,\n });\n }\n\n /**\n * Update a cron job by ID.\n *\n * @param cronId The cron ID to update.\n * @param payload Payload for updating a cron job.\n * @returns The updated cron job.\n * ```\n */\n async update(cronId: string, payload?: CronsUpdatePayload): Promise<Cron> {\n const json: Record<string, unknown> = {};\n\n if (payload?.schedule !== undefined) {\n json.schedule = payload.schedule;\n }\n if (payload?.timezone !== undefined) {\n json.timezone = payload.timezone;\n }\n if (payload?.endTime !== undefined) {\n json.end_time = payload.endTime;\n }\n if (payload?.input !== undefined) {\n json.input = payload.input;\n }\n if (payload?.metadata !== undefined) {\n json.metadata = payload.metadata;\n }\n if (payload?.config !== undefined) {\n json.config = payload.config;\n }\n if (payload?.context !== undefined) {\n json.context = payload.context;\n }\n if (payload?.webhook !== undefined) {\n json.webhook = payload.webhook;\n }\n if (payload?.interruptBefore !== undefined) {\n json.interrupt_before = payload.interruptBefore;\n }\n if (payload?.interruptAfter !== undefined) {\n json.interrupt_after = payload.interruptAfter;\n }\n if (payload?.onRunCompleted !== undefined) {\n json.on_run_completed = payload.onRunCompleted;\n }\n if (payload?.enabled !== undefined) {\n json.enabled = payload.enabled;\n }\n if (payload?.streamMode !== undefined) {\n json.stream_mode = payload.streamMode;\n }\n if (payload?.streamSubgraphs !== undefined) {\n json.stream_subgraphs = payload.streamSubgraphs;\n }\n if (payload?.streamResumable !== undefined) {\n json.stream_resumable = payload.streamResumable;\n }\n if (payload?.durability !== undefined) {\n json.durability = payload.durability;\n }\n\n return this.fetch<Cron>(`/runs/crons/${cronId}`, {\n method: \"PATCH\",\n json,\n signal: payload?.signal,\n });\n }\n\n /**\n * Delete a cron job by ID.\n *\n * @param cronId Cron ID of Cron job to delete.\n * @param options Optional parameters for the request.\n */\n async delete(\n cronId: string,\n options?: { signal?: AbortSignal }\n ): Promise<void> {\n await this.fetch<void>(`/runs/crons/${cronId}`, {\n method: \"DELETE\",\n signal: options?.signal,\n });\n }\n\n /**\n *\n * @param query Query options.\n * @param query.metadata Metadata to filter by. Exact match filter for each KV pair.\n * Available in Agent Server version 0.9.0 and later.\n * @returns List of crons.\n */\n async search(query?: {\n assistantId?: string;\n threadId?: string;\n enabled?: boolean;\n limit?: number;\n offset?: number;\n sortBy?: CronSortBy;\n sortOrder?: SortOrder;\n select?: CronSelectField[];\n metadata?: Metadata;\n signal?: AbortSignal;\n }): Promise<Cron[]> {\n return this.fetch<Cron[]>(\"/runs/crons/search\", {\n method: \"POST\",\n json: {\n assistant_id: query?.assistantId ?? undefined,\n thread_id: query?.threadId ?? undefined,\n enabled: query?.enabled ?? undefined,\n limit: query?.limit ?? 10,\n offset: query?.offset ?? 0,\n sort_by: query?.sortBy ?? undefined,\n sort_order: query?.sortOrder ?? undefined,\n select: query?.select ?? undefined,\n metadata: query?.metadata ?? undefined,\n },\n signal: query?.signal,\n });\n }\n\n /**\n * Count cron jobs matching filters.\n *\n * @param query.assistantId Assistant ID to filter by.\n * @param query.threadId Thread ID to filter by.\n * @param query.metadata Metadata to filter by. Exact match filter for each KV pair.\n * Available in Agent Server version 0.9.0 and later.\n * @returns Number of cron jobs matching the criteria.\n */\n async count(query?: {\n assistantId?: string;\n threadId?: string;\n metadata?: Metadata;\n signal?: AbortSignal;\n }): Promise<number> {\n return this.fetch<number>(`/runs/crons/count`, {\n method: \"POST\",\n json: {\n assistant_id: query?.assistantId ?? undefined,\n thread_id: query?.threadId ?? undefined,\n metadata: query?.metadata ?? undefined,\n },\n signal: query?.signal,\n });\n }\n}\n"],"mappings":"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"}
{"version":3,"file":"index.cjs","names":["BaseClient"],"sources":["../../../src/client/crons/index.ts"],"sourcesContent":["import {\n Cron,\n CronSelectField,\n CronCreateForThreadResponse,\n CronCreateResponse,\n CronSortBy,\n Metadata,\n SortOrder,\n} from \"../../schema.js\";\nimport type { CronsCreatePayload, CronsUpdatePayload } from \"../../types.js\";\nimport { BaseClient } from \"../base.js\";\n\nexport class CronsClient extends BaseClient {\n /**\n *\n * @param threadId The ID of the thread.\n * @param assistantId Assistant ID to use for this cron job.\n * @param payload Payload for creating a cron job.\n * @returns The created background run.\n */\n async createForThread(\n threadId: string,\n assistantId: string,\n payload?: CronsCreatePayload\n ): Promise<CronCreateForThreadResponse> {\n const json: Record<string, unknown> = {\n schedule: payload?.schedule,\n input: payload?.input,\n config: payload?.config,\n context: payload?.context,\n metadata: payload?.metadata,\n assistant_id: assistantId,\n interrupt_before: payload?.interruptBefore,\n interrupt_after: payload?.interruptAfter,\n webhook: payload?.webhook,\n multitask_strategy: payload?.multitaskStrategy,\n checkpoint_during: payload?.checkpointDuring,\n durability: payload?.durability,\n enabled: payload?.enabled,\n timezone: payload?.timezone,\n stream_mode: payload?.streamMode,\n stream_subgraphs: payload?.streamSubgraphs,\n stream_resumable: payload?.streamResumable,\n end_time: payload?.endTime,\n on_run_completed: payload?.onRunCompleted,\n };\n return this.fetch<CronCreateForThreadResponse>(\n `/threads/${threadId}/runs/crons`,\n {\n method: \"POST\",\n json,\n signal: payload?.signal,\n }\n );\n }\n\n /**\n *\n * @param assistantId Assistant ID to use for this cron job.\n * @param payload Payload for creating a cron job.\n * @returns\n */\n async create(\n assistantId: string,\n payload?: CronsCreatePayload\n ): Promise<CronCreateResponse> {\n const json: Record<string, unknown> = {\n schedule: payload?.schedule,\n input: payload?.input,\n config: payload?.config,\n context: payload?.context,\n metadata: payload?.metadata,\n assistant_id: assistantId,\n interrupt_before: payload?.interruptBefore,\n interrupt_after: payload?.interruptAfter,\n webhook: payload?.webhook,\n on_run_completed: payload?.onRunCompleted,\n multitask_strategy: payload?.multitaskStrategy,\n checkpoint_during: payload?.checkpointDuring,\n durability: payload?.durability,\n enabled: payload?.enabled,\n timezone: payload?.timezone,\n stream_mode: payload?.streamMode,\n stream_subgraphs: payload?.streamSubgraphs,\n stream_resumable: payload?.streamResumable,\n end_time: payload?.endTime,\n };\n return this.fetch<CronCreateResponse>(`/runs/crons`, {\n method: \"POST\",\n json,\n signal: payload?.signal,\n });\n }\n\n /**\n * Update a cron job by ID.\n *\n * @param cronId The cron ID to update.\n * @param payload Payload for updating a cron job.\n * @returns The updated cron job.\n * ```\n */\n async update(cronId: string, payload?: CronsUpdatePayload): Promise<Cron> {\n const json: Record<string, unknown> = {\n schedule: payload?.schedule,\n timezone: payload?.timezone,\n // `null` clears a set end time; `undefined` (omitted) leaves it unchanged.\n end_time: payload?.endTime,\n input: payload?.input,\n metadata: payload?.metadata,\n config: payload?.config,\n context: payload?.context,\n webhook: payload?.webhook,\n interrupt_before: payload?.interruptBefore,\n interrupt_after: payload?.interruptAfter,\n on_run_completed: payload?.onRunCompleted,\n enabled: payload?.enabled,\n stream_mode: payload?.streamMode,\n stream_subgraphs: payload?.streamSubgraphs,\n stream_resumable: payload?.streamResumable,\n durability: payload?.durability,\n };\n\n return this.fetch<Cron>(`/runs/crons/${cronId}`, {\n method: \"PATCH\",\n json,\n signal: payload?.signal,\n });\n }\n\n /**\n * Delete a cron job by ID.\n *\n * @param cronId Cron ID of Cron job to delete.\n * @param options Optional parameters for the request.\n */\n async delete(\n cronId: string,\n options?: { signal?: AbortSignal }\n ): Promise<void> {\n await this.fetch<void>(`/runs/crons/${cronId}`, {\n method: \"DELETE\",\n signal: options?.signal,\n });\n }\n\n /**\n *\n * @param query Query options.\n * @param query.metadata Metadata to filter by. Exact match filter for each KV pair.\n * Available in Agent Server version 0.9.0 and later.\n * @returns List of crons.\n */\n async search(query?: {\n assistantId?: string;\n threadId?: string;\n enabled?: boolean;\n limit?: number;\n offset?: number;\n sortBy?: CronSortBy;\n sortOrder?: SortOrder;\n select?: CronSelectField[];\n metadata?: Metadata;\n signal?: AbortSignal;\n }): Promise<Cron[]> {\n return this.fetch<Cron[]>(\"/runs/crons/search\", {\n method: \"POST\",\n json: {\n assistant_id: query?.assistantId ?? undefined,\n thread_id: query?.threadId ?? undefined,\n enabled: query?.enabled ?? undefined,\n limit: query?.limit ?? 10,\n offset: query?.offset ?? 0,\n sort_by: query?.sortBy ?? undefined,\n sort_order: query?.sortOrder ?? undefined,\n select: query?.select ?? undefined,\n metadata: query?.metadata ?? undefined,\n },\n signal: query?.signal,\n });\n }\n\n /**\n * Count cron jobs matching filters.\n *\n * @param query.assistantId Assistant ID to filter by.\n * @param query.threadId Thread ID to filter by.\n * @param query.metadata Metadata to filter by. Exact match filter for each KV pair.\n * Available in Agent Server version 0.9.0 and later.\n * @returns Number of cron jobs matching the criteria.\n */\n async count(query?: {\n assistantId?: string;\n threadId?: string;\n metadata?: Metadata;\n signal?: AbortSignal;\n }): Promise<number> {\n return this.fetch<number>(`/runs/crons/count`, {\n method: \"POST\",\n json: {\n assistant_id: query?.assistantId ?? undefined,\n thread_id: query?.threadId ?? undefined,\n metadata: query?.metadata ?? undefined,\n },\n signal: query?.signal,\n });\n }\n}\n"],"mappings":";;AAYA,IAAa,cAAb,cAAiCA,aAAAA,WAAW;;;;;;;;CAQ1C,MAAM,gBACJ,UACA,aACA,SACsC;EACtC,MAAM,OAAgC;GACpC,UAAU,SAAS;GACnB,OAAO,SAAS;GAChB,QAAQ,SAAS;GACjB,SAAS,SAAS;GAClB,UAAU,SAAS;GACnB,cAAc;GACd,kBAAkB,SAAS;GAC3B,iBAAiB,SAAS;GAC1B,SAAS,SAAS;GAClB,oBAAoB,SAAS;GAC7B,mBAAmB,SAAS;GAC5B,YAAY,SAAS;GACrB,SAAS,SAAS;GAClB,UAAU,SAAS;GACnB,aAAa,SAAS;GACtB,kBAAkB,SAAS;GAC3B,kBAAkB,SAAS;GAC3B,UAAU,SAAS;GACnB,kBAAkB,SAAS;GAC5B;AACD,SAAO,KAAK,MACV,YAAY,SAAS,cACrB;GACE,QAAQ;GACR;GACA,QAAQ,SAAS;GAClB,CACF;;;;;;;;CASH,MAAM,OACJ,aACA,SAC6B;EAC7B,MAAM,OAAgC;GACpC,UAAU,SAAS;GACnB,OAAO,SAAS;GAChB,QAAQ,SAAS;GACjB,SAAS,SAAS;GAClB,UAAU,SAAS;GACnB,cAAc;GACd,kBAAkB,SAAS;GAC3B,iBAAiB,SAAS;GAC1B,SAAS,SAAS;GAClB,kBAAkB,SAAS;GAC3B,oBAAoB,SAAS;GAC7B,mBAAmB,SAAS;GAC5B,YAAY,SAAS;GACrB,SAAS,SAAS;GAClB,UAAU,SAAS;GACnB,aAAa,SAAS;GACtB,kBAAkB,SAAS;GAC3B,kBAAkB,SAAS;GAC3B,UAAU,SAAS;GACpB;AACD,SAAO,KAAK,MAA0B,eAAe;GACnD,QAAQ;GACR;GACA,QAAQ,SAAS;GAClB,CAAC;;;;;;;;;;CAWJ,MAAM,OAAO,QAAgB,SAA6C;EACxE,MAAM,OAAgC;GACpC,UAAU,SAAS;GACnB,UAAU,SAAS;GAEnB,UAAU,SAAS;GACnB,OAAO,SAAS;GAChB,UAAU,SAAS;GACnB,QAAQ,SAAS;GACjB,SAAS,SAAS;GAClB,SAAS,SAAS;GAClB,kBAAkB,SAAS;GAC3B,iBAAiB,SAAS;GAC1B,kBAAkB,SAAS;GAC3B,SAAS,SAAS;GAClB,aAAa,SAAS;GACtB,kBAAkB,SAAS;GAC3B,kBAAkB,SAAS;GAC3B,YAAY,SAAS;GACtB;AAED,SAAO,KAAK,MAAY,eAAe,UAAU;GAC/C,QAAQ;GACR;GACA,QAAQ,SAAS;GAClB,CAAC;;;;;;;;CASJ,MAAM,OACJ,QACA,SACe;AACf,QAAM,KAAK,MAAY,eAAe,UAAU;GAC9C,QAAQ;GACR,QAAQ,SAAS;GAClB,CAAC;;;;;;;;;CAUJ,MAAM,OAAO,OAWO;AAClB,SAAO,KAAK,MAAc,sBAAsB;GAC9C,QAAQ;GACR,MAAM;IACJ,cAAc,OAAO,eAAe,KAAA;IACpC,WAAW,OAAO,YAAY,KAAA;IAC9B,SAAS,OAAO,WAAW,KAAA;IAC3B,OAAO,OAAO,SAAS;IACvB,QAAQ,OAAO,UAAU;IACzB,SAAS,OAAO,UAAU,KAAA;IAC1B,YAAY,OAAO,aAAa,KAAA;IAChC,QAAQ,OAAO,UAAU,KAAA;IACzB,UAAU,OAAO,YAAY,KAAA;IAC9B;GACD,QAAQ,OAAO;GAChB,CAAC;;;;;;;;;;;CAYJ,MAAM,MAAM,OAKQ;AAClB,SAAO,KAAK,MAAc,qBAAqB;GAC7C,QAAQ;GACR,MAAM;IACJ,cAAc,OAAO,eAAe,KAAA;IACpC,WAAW,OAAO,YAAY,KAAA;IAC9B,UAAU,OAAO,YAAY,KAAA;IAC9B;GACD,QAAQ,OAAO;GAChB,CAAC"}

@@ -1,1 +0,1 @@

{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/client/crons/index.ts"],"mappings":";;;;;cAYa,WAAA,SAAoB,UAAA;;AAAjC;;;;;;EAQQ,eAAA,CACJ,QAAA,UACA,WAAA,UACA,OAAA,GAAU,kBAAA,GACT,OAAA,CAAQ,2BAAA;EAyCA;;;;;;EAHL,MAAA,CACJ,WAAA,UACA,OAAA,GAAU,kBAAA,GACT,OAAA,CAAQ,kBAAA;EA6HA;;;;;;;;EAxFL,MAAA,CAAO,MAAA,UAAgB,OAAA,GAAU,kBAAA,GAAqB,OAAA,CAAQ,IAAA;EA6HhE;;;;;;EA5DE,MAAA,CACJ,MAAA,UACA,OAAA;IAAY,MAAA,GAAS,WAAA;EAAA,IACpB,OAAA;EAnJD;;;;;;;EAiKI,MAAA,CAAO,KAAA;IACX,WAAA;IACA,QAAA;IACA,OAAA;IACA,KAAA;IACA,MAAA;IACA,MAAA,GAAS,UAAA;IACT,SAAA,GAAY,SAAA;IACZ,MAAA,GAAS,eAAA;IACT,QAAA,GAAW,QAAA;IACX,MAAA,GAAS,WAAA;EAAA,IACP,OAAA,CAAQ,IAAA;EA1BV;;;;;;;;;EAqDI,KAAA,CAAM,KAAA;IACV,WAAA;IACA,QAAA;IACA,QAAA,GAAW,QAAA;IACX,MAAA,GAAS,WAAA;EAAA,IACP,OAAA;AAAA"}
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/client/crons/index.ts"],"mappings":";;;;;cAYa,WAAA,SAAoB,UAAA;;AAAjC;;;;;;EAQQ,eAAA,CACJ,QAAA,UACA,WAAA,UACA,OAAA,GAAU,kBAAA,GACT,OAAA,CAAQ,2BAAA;EAyCA;;;;;;EAHL,MAAA,CACJ,WAAA,UACA,OAAA,GAAU,kBAAA,GACT,OAAA,CAAQ,kBAAA;EA8FA;;;;;;;;EAzDL,MAAA,CAAO,MAAA,UAAgB,OAAA,GAAU,kBAAA,GAAqB,OAAA,CAAQ,IAAA;EA8FhE;;;;;;EA5DE,MAAA,CACJ,MAAA,UACA,OAAA;IAAY,MAAA,GAAS,WAAA;EAAA,IACpB,OAAA;EApHD;;;;;;;EAkII,MAAA,CAAO,KAAA;IACX,WAAA;IACA,QAAA;IACA,OAAA;IACA,KAAA;IACA,MAAA;IACA,MAAA,GAAS,UAAA;IACT,SAAA,GAAY,SAAA;IACZ,MAAA,GAAS,eAAA;IACT,QAAA,GAAW,QAAA;IACX,MAAA,GAAS,WAAA;EAAA,IACP,OAAA,CAAQ,IAAA;EA1BV;;;;;;;;;EAqDI,KAAA,CAAM,KAAA;IACV,WAAA;IACA,QAAA;IACA,QAAA,GAAW,QAAA;IACX,MAAA,GAAS,WAAA;EAAA,IACP,OAAA;AAAA"}

@@ -1,1 +0,1 @@

{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/client/crons/index.ts"],"mappings":";;;;;cAYa,WAAA,SAAoB,UAAA;;AAAjC;;;;;;EAQQ,eAAA,CACJ,QAAA,UACA,WAAA,UACA,OAAA,GAAU,kBAAA,GACT,OAAA,CAAQ,2BAAA;EAyCA;;;;;;EAHL,MAAA,CACJ,WAAA,UACA,OAAA,GAAU,kBAAA,GACT,OAAA,CAAQ,kBAAA;EA6HA;;;;;;;;EAxFL,MAAA,CAAO,MAAA,UAAgB,OAAA,GAAU,kBAAA,GAAqB,OAAA,CAAQ,IAAA;EA6HhE;;;;;;EA5DE,MAAA,CACJ,MAAA,UACA,OAAA;IAAY,MAAA,GAAS,WAAA;EAAA,IACpB,OAAA;EAnJD;;;;;;;EAiKI,MAAA,CAAO,KAAA;IACX,WAAA;IACA,QAAA;IACA,OAAA;IACA,KAAA;IACA,MAAA;IACA,MAAA,GAAS,UAAA;IACT,SAAA,GAAY,SAAA;IACZ,MAAA,GAAS,eAAA;IACT,QAAA,GAAW,QAAA;IACX,MAAA,GAAS,WAAA;EAAA,IACP,OAAA,CAAQ,IAAA;EA1BV;;;;;;;;;EAqDI,KAAA,CAAM,KAAA;IACV,WAAA;IACA,QAAA;IACA,QAAA,GAAW,QAAA;IACX,MAAA,GAAS,WAAA;EAAA,IACP,OAAA;AAAA"}
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/client/crons/index.ts"],"mappings":";;;;;cAYa,WAAA,SAAoB,UAAA;;AAAjC;;;;;;EAQQ,eAAA,CACJ,QAAA,UACA,WAAA,UACA,OAAA,GAAU,kBAAA,GACT,OAAA,CAAQ,2BAAA;EAyCA;;;;;;EAHL,MAAA,CACJ,WAAA,UACA,OAAA,GAAU,kBAAA,GACT,OAAA,CAAQ,kBAAA;EA8FA;;;;;;;;EAzDL,MAAA,CAAO,MAAA,UAAgB,OAAA,GAAU,kBAAA,GAAqB,OAAA,CAAQ,IAAA;EA8FhE;;;;;;EA5DE,MAAA,CACJ,MAAA,UACA,OAAA;IAAY,MAAA,GAAS,WAAA;EAAA,IACpB,OAAA;EApHD;;;;;;;EAkII,MAAA,CAAO,KAAA;IACX,WAAA;IACA,QAAA;IACA,OAAA;IACA,KAAA;IACA,MAAA;IACA,MAAA,GAAS,UAAA;IACT,SAAA,GAAY,SAAA;IACZ,MAAA,GAAS,eAAA;IACT,QAAA,GAAW,QAAA;IACX,MAAA,GAAS,WAAA;EAAA,IACP,OAAA,CAAQ,IAAA;EA1BV;;;;;;;;;EAqDI,KAAA,CAAM,KAAA;IACV,WAAA;IACA,QAAA;IACA,QAAA,GAAW,QAAA;IACX,MAAA,GAAS,WAAA;EAAA,IACP,OAAA;AAAA"}

@@ -82,19 +82,20 @@ import { BaseClient } from "../base.js";

async update(cronId, payload) {
const json = {};
if (payload?.schedule !== void 0) json.schedule = payload.schedule;
if (payload?.timezone !== void 0) json.timezone = payload.timezone;
if (payload?.endTime !== void 0) json.end_time = payload.endTime;
if (payload?.input !== void 0) json.input = payload.input;
if (payload?.metadata !== void 0) json.metadata = payload.metadata;
if (payload?.config !== void 0) json.config = payload.config;
if (payload?.context !== void 0) json.context = payload.context;
if (payload?.webhook !== void 0) json.webhook = payload.webhook;
if (payload?.interruptBefore !== void 0) json.interrupt_before = payload.interruptBefore;
if (payload?.interruptAfter !== void 0) json.interrupt_after = payload.interruptAfter;
if (payload?.onRunCompleted !== void 0) json.on_run_completed = payload.onRunCompleted;
if (payload?.enabled !== void 0) json.enabled = payload.enabled;
if (payload?.streamMode !== void 0) json.stream_mode = payload.streamMode;
if (payload?.streamSubgraphs !== void 0) json.stream_subgraphs = payload.streamSubgraphs;
if (payload?.streamResumable !== void 0) json.stream_resumable = payload.streamResumable;
if (payload?.durability !== void 0) json.durability = payload.durability;
const json = {
schedule: payload?.schedule,
timezone: payload?.timezone,
end_time: payload?.endTime,
input: payload?.input,
metadata: payload?.metadata,
config: payload?.config,
context: payload?.context,
webhook: payload?.webhook,
interrupt_before: payload?.interruptBefore,
interrupt_after: payload?.interruptAfter,
on_run_completed: payload?.onRunCompleted,
enabled: payload?.enabled,
stream_mode: payload?.streamMode,
stream_subgraphs: payload?.streamSubgraphs,
stream_resumable: payload?.streamResumable,
durability: payload?.durability
};
return this.fetch(`/runs/crons/${cronId}`, {

@@ -101,0 +102,0 @@ method: "PATCH",

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","names":[],"sources":["../../../src/client/crons/index.ts"],"sourcesContent":["import {\n Cron,\n CronSelectField,\n CronCreateForThreadResponse,\n CronCreateResponse,\n CronSortBy,\n Metadata,\n SortOrder,\n} from \"../../schema.js\";\nimport type { CronsCreatePayload, CronsUpdatePayload } from \"../../types.js\";\nimport { BaseClient } from \"../base.js\";\n\nexport class CronsClient extends BaseClient {\n /**\n *\n * @param threadId The ID of the thread.\n * @param assistantId Assistant ID to use for this cron job.\n * @param payload Payload for creating a cron job.\n * @returns The created background run.\n */\n async createForThread(\n threadId: string,\n assistantId: string,\n payload?: CronsCreatePayload\n ): Promise<CronCreateForThreadResponse> {\n const json: Record<string, unknown> = {\n schedule: payload?.schedule,\n input: payload?.input,\n config: payload?.config,\n context: payload?.context,\n metadata: payload?.metadata,\n assistant_id: assistantId,\n interrupt_before: payload?.interruptBefore,\n interrupt_after: payload?.interruptAfter,\n webhook: payload?.webhook,\n multitask_strategy: payload?.multitaskStrategy,\n checkpoint_during: payload?.checkpointDuring,\n durability: payload?.durability,\n enabled: payload?.enabled,\n timezone: payload?.timezone,\n stream_mode: payload?.streamMode,\n stream_subgraphs: payload?.streamSubgraphs,\n stream_resumable: payload?.streamResumable,\n end_time: payload?.endTime,\n on_run_completed: payload?.onRunCompleted,\n };\n return this.fetch<CronCreateForThreadResponse>(\n `/threads/${threadId}/runs/crons`,\n {\n method: \"POST\",\n json,\n signal: payload?.signal,\n }\n );\n }\n\n /**\n *\n * @param assistantId Assistant ID to use for this cron job.\n * @param payload Payload for creating a cron job.\n * @returns\n */\n async create(\n assistantId: string,\n payload?: CronsCreatePayload\n ): Promise<CronCreateResponse> {\n const json: Record<string, unknown> = {\n schedule: payload?.schedule,\n input: payload?.input,\n config: payload?.config,\n context: payload?.context,\n metadata: payload?.metadata,\n assistant_id: assistantId,\n interrupt_before: payload?.interruptBefore,\n interrupt_after: payload?.interruptAfter,\n webhook: payload?.webhook,\n on_run_completed: payload?.onRunCompleted,\n multitask_strategy: payload?.multitaskStrategy,\n checkpoint_during: payload?.checkpointDuring,\n durability: payload?.durability,\n enabled: payload?.enabled,\n timezone: payload?.timezone,\n stream_mode: payload?.streamMode,\n stream_subgraphs: payload?.streamSubgraphs,\n stream_resumable: payload?.streamResumable,\n end_time: payload?.endTime,\n };\n return this.fetch<CronCreateResponse>(`/runs/crons`, {\n method: \"POST\",\n json,\n signal: payload?.signal,\n });\n }\n\n /**\n * Update a cron job by ID.\n *\n * @param cronId The cron ID to update.\n * @param payload Payload for updating a cron job.\n * @returns The updated cron job.\n * ```\n */\n async update(cronId: string, payload?: CronsUpdatePayload): Promise<Cron> {\n const json: Record<string, unknown> = {};\n\n if (payload?.schedule !== undefined) {\n json.schedule = payload.schedule;\n }\n if (payload?.timezone !== undefined) {\n json.timezone = payload.timezone;\n }\n if (payload?.endTime !== undefined) {\n json.end_time = payload.endTime;\n }\n if (payload?.input !== undefined) {\n json.input = payload.input;\n }\n if (payload?.metadata !== undefined) {\n json.metadata = payload.metadata;\n }\n if (payload?.config !== undefined) {\n json.config = payload.config;\n }\n if (payload?.context !== undefined) {\n json.context = payload.context;\n }\n if (payload?.webhook !== undefined) {\n json.webhook = payload.webhook;\n }\n if (payload?.interruptBefore !== undefined) {\n json.interrupt_before = payload.interruptBefore;\n }\n if (payload?.interruptAfter !== undefined) {\n json.interrupt_after = payload.interruptAfter;\n }\n if (payload?.onRunCompleted !== undefined) {\n json.on_run_completed = payload.onRunCompleted;\n }\n if (payload?.enabled !== undefined) {\n json.enabled = payload.enabled;\n }\n if (payload?.streamMode !== undefined) {\n json.stream_mode = payload.streamMode;\n }\n if (payload?.streamSubgraphs !== undefined) {\n json.stream_subgraphs = payload.streamSubgraphs;\n }\n if (payload?.streamResumable !== undefined) {\n json.stream_resumable = payload.streamResumable;\n }\n if (payload?.durability !== undefined) {\n json.durability = payload.durability;\n }\n\n return this.fetch<Cron>(`/runs/crons/${cronId}`, {\n method: \"PATCH\",\n json,\n signal: payload?.signal,\n });\n }\n\n /**\n * Delete a cron job by ID.\n *\n * @param cronId Cron ID of Cron job to delete.\n * @param options Optional parameters for the request.\n */\n async delete(\n cronId: string,\n options?: { signal?: AbortSignal }\n ): Promise<void> {\n await this.fetch<void>(`/runs/crons/${cronId}`, {\n method: \"DELETE\",\n signal: options?.signal,\n });\n }\n\n /**\n *\n * @param query Query options.\n * @param query.metadata Metadata to filter by. Exact match filter for each KV pair.\n * Available in Agent Server version 0.9.0 and later.\n * @returns List of crons.\n */\n async search(query?: {\n assistantId?: string;\n threadId?: string;\n enabled?: boolean;\n limit?: number;\n offset?: number;\n sortBy?: CronSortBy;\n sortOrder?: SortOrder;\n select?: CronSelectField[];\n metadata?: Metadata;\n signal?: AbortSignal;\n }): Promise<Cron[]> {\n return this.fetch<Cron[]>(\"/runs/crons/search\", {\n method: \"POST\",\n json: {\n assistant_id: query?.assistantId ?? undefined,\n thread_id: query?.threadId ?? undefined,\n enabled: query?.enabled ?? undefined,\n limit: query?.limit ?? 10,\n offset: query?.offset ?? 0,\n sort_by: query?.sortBy ?? undefined,\n sort_order: query?.sortOrder ?? undefined,\n select: query?.select ?? undefined,\n metadata: query?.metadata ?? undefined,\n },\n signal: query?.signal,\n });\n }\n\n /**\n * Count cron jobs matching filters.\n *\n * @param query.assistantId Assistant ID to filter by.\n * @param query.threadId Thread ID to filter by.\n * @param query.metadata Metadata to filter by. Exact match filter for each KV pair.\n * Available in Agent Server version 0.9.0 and later.\n * @returns Number of cron jobs matching the criteria.\n */\n async count(query?: {\n assistantId?: string;\n threadId?: string;\n metadata?: Metadata;\n signal?: AbortSignal;\n }): Promise<number> {\n return this.fetch<number>(`/runs/crons/count`, {\n method: \"POST\",\n json: {\n assistant_id: query?.assistantId ?? undefined,\n thread_id: query?.threadId ?? undefined,\n metadata: query?.metadata ?? undefined,\n },\n signal: query?.signal,\n });\n }\n}\n"],"mappings":"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"}
{"version":3,"file":"index.js","names":[],"sources":["../../../src/client/crons/index.ts"],"sourcesContent":["import {\n Cron,\n CronSelectField,\n CronCreateForThreadResponse,\n CronCreateResponse,\n CronSortBy,\n Metadata,\n SortOrder,\n} from \"../../schema.js\";\nimport type { CronsCreatePayload, CronsUpdatePayload } from \"../../types.js\";\nimport { BaseClient } from \"../base.js\";\n\nexport class CronsClient extends BaseClient {\n /**\n *\n * @param threadId The ID of the thread.\n * @param assistantId Assistant ID to use for this cron job.\n * @param payload Payload for creating a cron job.\n * @returns The created background run.\n */\n async createForThread(\n threadId: string,\n assistantId: string,\n payload?: CronsCreatePayload\n ): Promise<CronCreateForThreadResponse> {\n const json: Record<string, unknown> = {\n schedule: payload?.schedule,\n input: payload?.input,\n config: payload?.config,\n context: payload?.context,\n metadata: payload?.metadata,\n assistant_id: assistantId,\n interrupt_before: payload?.interruptBefore,\n interrupt_after: payload?.interruptAfter,\n webhook: payload?.webhook,\n multitask_strategy: payload?.multitaskStrategy,\n checkpoint_during: payload?.checkpointDuring,\n durability: payload?.durability,\n enabled: payload?.enabled,\n timezone: payload?.timezone,\n stream_mode: payload?.streamMode,\n stream_subgraphs: payload?.streamSubgraphs,\n stream_resumable: payload?.streamResumable,\n end_time: payload?.endTime,\n on_run_completed: payload?.onRunCompleted,\n };\n return this.fetch<CronCreateForThreadResponse>(\n `/threads/${threadId}/runs/crons`,\n {\n method: \"POST\",\n json,\n signal: payload?.signal,\n }\n );\n }\n\n /**\n *\n * @param assistantId Assistant ID to use for this cron job.\n * @param payload Payload for creating a cron job.\n * @returns\n */\n async create(\n assistantId: string,\n payload?: CronsCreatePayload\n ): Promise<CronCreateResponse> {\n const json: Record<string, unknown> = {\n schedule: payload?.schedule,\n input: payload?.input,\n config: payload?.config,\n context: payload?.context,\n metadata: payload?.metadata,\n assistant_id: assistantId,\n interrupt_before: payload?.interruptBefore,\n interrupt_after: payload?.interruptAfter,\n webhook: payload?.webhook,\n on_run_completed: payload?.onRunCompleted,\n multitask_strategy: payload?.multitaskStrategy,\n checkpoint_during: payload?.checkpointDuring,\n durability: payload?.durability,\n enabled: payload?.enabled,\n timezone: payload?.timezone,\n stream_mode: payload?.streamMode,\n stream_subgraphs: payload?.streamSubgraphs,\n stream_resumable: payload?.streamResumable,\n end_time: payload?.endTime,\n };\n return this.fetch<CronCreateResponse>(`/runs/crons`, {\n method: \"POST\",\n json,\n signal: payload?.signal,\n });\n }\n\n /**\n * Update a cron job by ID.\n *\n * @param cronId The cron ID to update.\n * @param payload Payload for updating a cron job.\n * @returns The updated cron job.\n * ```\n */\n async update(cronId: string, payload?: CronsUpdatePayload): Promise<Cron> {\n const json: Record<string, unknown> = {\n schedule: payload?.schedule,\n timezone: payload?.timezone,\n // `null` clears a set end time; `undefined` (omitted) leaves it unchanged.\n end_time: payload?.endTime,\n input: payload?.input,\n metadata: payload?.metadata,\n config: payload?.config,\n context: payload?.context,\n webhook: payload?.webhook,\n interrupt_before: payload?.interruptBefore,\n interrupt_after: payload?.interruptAfter,\n on_run_completed: payload?.onRunCompleted,\n enabled: payload?.enabled,\n stream_mode: payload?.streamMode,\n stream_subgraphs: payload?.streamSubgraphs,\n stream_resumable: payload?.streamResumable,\n durability: payload?.durability,\n };\n\n return this.fetch<Cron>(`/runs/crons/${cronId}`, {\n method: \"PATCH\",\n json,\n signal: payload?.signal,\n });\n }\n\n /**\n * Delete a cron job by ID.\n *\n * @param cronId Cron ID of Cron job to delete.\n * @param options Optional parameters for the request.\n */\n async delete(\n cronId: string,\n options?: { signal?: AbortSignal }\n ): Promise<void> {\n await this.fetch<void>(`/runs/crons/${cronId}`, {\n method: \"DELETE\",\n signal: options?.signal,\n });\n }\n\n /**\n *\n * @param query Query options.\n * @param query.metadata Metadata to filter by. Exact match filter for each KV pair.\n * Available in Agent Server version 0.9.0 and later.\n * @returns List of crons.\n */\n async search(query?: {\n assistantId?: string;\n threadId?: string;\n enabled?: boolean;\n limit?: number;\n offset?: number;\n sortBy?: CronSortBy;\n sortOrder?: SortOrder;\n select?: CronSelectField[];\n metadata?: Metadata;\n signal?: AbortSignal;\n }): Promise<Cron[]> {\n return this.fetch<Cron[]>(\"/runs/crons/search\", {\n method: \"POST\",\n json: {\n assistant_id: query?.assistantId ?? undefined,\n thread_id: query?.threadId ?? undefined,\n enabled: query?.enabled ?? undefined,\n limit: query?.limit ?? 10,\n offset: query?.offset ?? 0,\n sort_by: query?.sortBy ?? undefined,\n sort_order: query?.sortOrder ?? undefined,\n select: query?.select ?? undefined,\n metadata: query?.metadata ?? undefined,\n },\n signal: query?.signal,\n });\n }\n\n /**\n * Count cron jobs matching filters.\n *\n * @param query.assistantId Assistant ID to filter by.\n * @param query.threadId Thread ID to filter by.\n * @param query.metadata Metadata to filter by. Exact match filter for each KV pair.\n * Available in Agent Server version 0.9.0 and later.\n * @returns Number of cron jobs matching the criteria.\n */\n async count(query?: {\n assistantId?: string;\n threadId?: string;\n metadata?: Metadata;\n signal?: AbortSignal;\n }): Promise<number> {\n return this.fetch<number>(`/runs/crons/count`, {\n method: \"POST\",\n json: {\n assistant_id: query?.assistantId ?? undefined,\n thread_id: query?.threadId ?? undefined,\n metadata: query?.metadata ?? undefined,\n },\n signal: query?.signal,\n });\n }\n}\n"],"mappings":";;AAYA,IAAa,cAAb,cAAiC,WAAW;;;;;;;;CAQ1C,MAAM,gBACJ,UACA,aACA,SACsC;EACtC,MAAM,OAAgC;GACpC,UAAU,SAAS;GACnB,OAAO,SAAS;GAChB,QAAQ,SAAS;GACjB,SAAS,SAAS;GAClB,UAAU,SAAS;GACnB,cAAc;GACd,kBAAkB,SAAS;GAC3B,iBAAiB,SAAS;GAC1B,SAAS,SAAS;GAClB,oBAAoB,SAAS;GAC7B,mBAAmB,SAAS;GAC5B,YAAY,SAAS;GACrB,SAAS,SAAS;GAClB,UAAU,SAAS;GACnB,aAAa,SAAS;GACtB,kBAAkB,SAAS;GAC3B,kBAAkB,SAAS;GAC3B,UAAU,SAAS;GACnB,kBAAkB,SAAS;GAC5B;AACD,SAAO,KAAK,MACV,YAAY,SAAS,cACrB;GACE,QAAQ;GACR;GACA,QAAQ,SAAS;GAClB,CACF;;;;;;;;CASH,MAAM,OACJ,aACA,SAC6B;EAC7B,MAAM,OAAgC;GACpC,UAAU,SAAS;GACnB,OAAO,SAAS;GAChB,QAAQ,SAAS;GACjB,SAAS,SAAS;GAClB,UAAU,SAAS;GACnB,cAAc;GACd,kBAAkB,SAAS;GAC3B,iBAAiB,SAAS;GAC1B,SAAS,SAAS;GAClB,kBAAkB,SAAS;GAC3B,oBAAoB,SAAS;GAC7B,mBAAmB,SAAS;GAC5B,YAAY,SAAS;GACrB,SAAS,SAAS;GAClB,UAAU,SAAS;GACnB,aAAa,SAAS;GACtB,kBAAkB,SAAS;GAC3B,kBAAkB,SAAS;GAC3B,UAAU,SAAS;GACpB;AACD,SAAO,KAAK,MAA0B,eAAe;GACnD,QAAQ;GACR;GACA,QAAQ,SAAS;GAClB,CAAC;;;;;;;;;;CAWJ,MAAM,OAAO,QAAgB,SAA6C;EACxE,MAAM,OAAgC;GACpC,UAAU,SAAS;GACnB,UAAU,SAAS;GAEnB,UAAU,SAAS;GACnB,OAAO,SAAS;GAChB,UAAU,SAAS;GACnB,QAAQ,SAAS;GACjB,SAAS,SAAS;GAClB,SAAS,SAAS;GAClB,kBAAkB,SAAS;GAC3B,iBAAiB,SAAS;GAC1B,kBAAkB,SAAS;GAC3B,SAAS,SAAS;GAClB,aAAa,SAAS;GACtB,kBAAkB,SAAS;GAC3B,kBAAkB,SAAS;GAC3B,YAAY,SAAS;GACtB;AAED,SAAO,KAAK,MAAY,eAAe,UAAU;GAC/C,QAAQ;GACR;GACA,QAAQ,SAAS;GAClB,CAAC;;;;;;;;CASJ,MAAM,OACJ,QACA,SACe;AACf,QAAM,KAAK,MAAY,eAAe,UAAU;GAC9C,QAAQ;GACR,QAAQ,SAAS;GAClB,CAAC;;;;;;;;;CAUJ,MAAM,OAAO,OAWO;AAClB,SAAO,KAAK,MAAc,sBAAsB;GAC9C,QAAQ;GACR,MAAM;IACJ,cAAc,OAAO,eAAe,KAAA;IACpC,WAAW,OAAO,YAAY,KAAA;IAC9B,SAAS,OAAO,WAAW,KAAA;IAC3B,OAAO,OAAO,SAAS;IACvB,QAAQ,OAAO,UAAU;IACzB,SAAS,OAAO,UAAU,KAAA;IAC1B,YAAY,OAAO,aAAa,KAAA;IAChC,QAAQ,OAAO,UAAU,KAAA;IACzB,UAAU,OAAO,YAAY,KAAA;IAC9B;GACD,QAAQ,OAAO;GAChB,CAAC;;;;;;;;;;;CAYJ,MAAM,MAAM,OAKQ;AAClB,SAAO,KAAK,MAAc,qBAAqB;GAC7C,QAAQ;GACR,MAAM;IACJ,cAAc,OAAO,eAAe,KAAA;IACpC,WAAW,OAAO,YAAY,KAAA;IAC9B,UAAU,OAAO,YAAY,KAAA;IAC9B;GACD,QAAQ,OAAO;GAChB,CAAC"}

@@ -11,4 +11,4 @@ require("./base.cjs");

require("./stream/index.cjs");
require("./stream/transport/http.cjs");
require("./stream/transport/websocket.cjs");
require("./stream/transport/http.cjs");
const require_index$2 = require("./threads/index.cjs");

@@ -15,0 +15,0 @@ const require_index$3 = require("./runs/index.cjs");

@@ -11,4 +11,4 @@ import "./base.js";

import "./stream/index.js";
import "./stream/transport/http.js";
import "./stream/transport/websocket.js";
import "./stream/transport/http.js";
import { ThreadsClient } from "./threads/index.js";

@@ -15,0 +15,0 @@ import { RunsClient } from "./runs/index.js";

const require_subscription = require("./subscription.cjs");
const require_multi_cursor_buffer = require("./multi-cursor-buffer.cjs");
require("../../stream/constants.cjs");
const require_messages = require("../../ui/messages.cjs");

@@ -11,3 +12,2 @@ const require_tools = require("./handles/tools.cjs");

const require_error = require("./error.cjs");
require("../../stream/constants.cjs");
const require_headless_tools = require("../../headless-tools.cjs");

@@ -14,0 +14,0 @@ //#region src/client/stream/index.ts

import { matchesSubscription } from "./subscription.js";
import { MultiCursorBuffer } from "./multi-cursor-buffer.js";
import "../../stream/constants.js";
import { ensureMessageInstances } from "../../ui/messages.js";

@@ -11,3 +12,2 @@ import { ToolCallAssembler, toClientAssembledToolCall } from "./handles/tools.js";

import { ProtocolError } from "./error.js";
import "../../stream/constants.js";
import { isHeadlessToolInterrupt } from "../../headless-tools.js";

@@ -14,0 +14,0 @@ //#region src/client/stream/index.ts

@@ -0,3 +1,3 @@

const require_http = require("./http.cjs");
const require_websocket = require("./websocket.cjs");
const require_http = require("./http.cjs");
//#region src/client/stream/transport/agent-server.ts

@@ -4,0 +4,0 @@ var HttpAgentServerAdapter = class {

@@ -0,3 +1,3 @@

import { ProtocolSseTransportAdapter } from "./http.js";
import { ProtocolWebSocketTransportAdapter } from "./websocket.js";
import { ProtocolSseTransportAdapter } from "./http.js";
//#region src/client/stream/transport/agent-server.ts

@@ -4,0 +4,0 @@ var HttpAgentServerAdapter = class {

const require_sse = require("../../../utils/sse.cjs");
const require_reconnect = require("../../../utils/reconnect.cjs");
const require_stream = require("../../../utils/stream.cjs");
const require_queue = require("./queue.cjs");
const require_utils = require("./utils.cjs");
const require_websocket = require("./websocket.cjs");
//#region src/client/stream/transport/http.ts

@@ -39,6 +39,6 @@ /**

this.asyncCaller = options.asyncCaller;
this.maxReconnectAttempts = options.fetch != null ? 0 : options.maxReconnectAttempts ?? 5;
this.idleReconnect = options.fetch != null ? null : options.idleReconnect ?? "auto";
this.maxReconnectAttempts = options.maxReconnectAttempts ?? 5;
this.idleReconnect = options.idleReconnect ?? "auto";
this.onReconnect = options.onReconnect;
this.reconnectDelayMs = options.reconnectDelayMs ?? require_websocket.webSocketReconnectDelayMs;
this.reconnectDelayMs = options.reconnectDelayMs ?? require_reconnect.reconnectDelayMs;
this.threadId = options.threadId ?? "";

@@ -45,0 +45,0 @@ this.paths = options.paths;

@@ -1,1 +0,1 @@

{"version":3,"file":"http.cjs","names":["AsyncQueue","webSocketReconnectDelayMs","resolveProtocolPath","toAbsoluteUrl","mergeHeaders","toError","isProtocolResponse","BytesLineDecoder","idleReconnectStream","SSEDecoder","IterableReadableStream","isRecord"],"sources":["../../../../src/client/stream/transport/http.ts"],"sourcesContent":["import { AsyncQueue } from \"./queue.js\";\nimport type {\n Message,\n SubscribeParams,\n Command,\n CommandResponse,\n ErrorResponse,\n} from \"@langchain/protocol\";\n\nimport type { AsyncCaller } from \"../../../utils/async_caller.js\";\nimport type {\n HeaderValue,\n ProtocolRequestHook,\n ProtocolSseTransportOptions,\n ProtocolTransportPaths,\n} from \"./types.js\";\nimport type { TransportAdapter, EventStreamHandle } from \"../transport.js\";\nimport {\n toAbsoluteUrl,\n isRecord,\n mergeHeaders,\n toError,\n isProtocolResponse,\n resolveProtocolPath,\n} from \"./utils.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../../../utils/sse.js\";\nimport {\n IterableReadableStream,\n idleReconnectStream,\n type IdleReconnectMode,\n} from \"../../../utils/stream.js\";\nimport { webSocketReconnectDelayMs } from \"./websocket.js\";\n\n/**\n * Transport adapter that speaks the thread-centric protocol over HTTP\n * commands plus SSE event streams. Bound to a `threadId` at construction\n * or later via {@link setThreadId}; request URLs derive from the\n * currently-bound thread. Each {@link openEventStream} call opens an\n * independent filtered SSE connection via\n * `POST /threads/:thread_id/stream/events`.\n */\nexport class ProtocolSseTransportAdapter implements TransportAdapter {\n threadId: string;\n\n readonly apiUrl: string;\n\n private readonly queue = new AsyncQueue<Message>();\n\n private readonly fetchImpl: typeof fetch;\n\n private readonly defaultHeaders: Record<string, HeaderValue>;\n\n private readonly onRequest?: ProtocolRequestHook;\n\n private readonly fetchFactory?: () => typeof fetch | Promise<typeof fetch>;\n\n private readonly asyncCaller?: AsyncCaller;\n\n private readonly maxReconnectAttempts: number;\n\n private readonly idleReconnect: IdleReconnectMode | null;\n\n private readonly onReconnect?: ProtocolSseTransportOptions[\"onReconnect\"];\n\n private readonly reconnectDelayMs: (attempt: number) => number;\n\n private readonly paths?: ProtocolTransportPaths;\n\n private readonly sessionAbortController = new AbortController();\n\n private readonly eventStreams = new Set<AbortController>();\n\n private closed = false;\n\n constructor(options: ProtocolSseTransportOptions) {\n this.fetchImpl = options.fetch ?? fetch;\n this.apiUrl = options.apiUrl;\n this.defaultHeaders = options.defaultHeaders ?? {};\n this.onRequest = options.onRequest;\n this.fetchFactory = options.fetchFactory;\n this.asyncCaller = options.asyncCaller;\n // Custom fetch (tests/mocks) must not auto-reconnect — same policy as skipping AsyncCaller.\n this.maxReconnectAttempts =\n options.fetch != null ? 0 : (options.maxReconnectAttempts ?? 5);\n // Custom fetch (tests/mocks) also disables the idle watchdog, matching the\n // no-auto-reconnect policy above — a tripped watchdog would have nothing to\n // reconnect to and would surface spurious errors in those harnesses.\n // Otherwise default to heartbeat-adaptive `\"auto\"`, which stays dormant\n // unless the server actually emits keep-alive heartbeats.\n this.idleReconnect =\n options.fetch != null ? null : (options.idleReconnect ?? \"auto\");\n this.onReconnect = options.onReconnect;\n this.reconnectDelayMs =\n options.reconnectDelayMs ?? webSocketReconnectDelayMs;\n this.threadId = options.threadId ?? \"\";\n this.paths = options.paths;\n }\n\n /** {@inheritDoc TransportAdapter.setThreadId} */\n setThreadId(threadId: string): void {\n this.threadId = threadId;\n }\n\n /**\n * Command/stream/state URLs derive from the currently-bound thread so a\n * single adapter can follow {@link setThreadId} re-binds. A fixed\n * `paths.*` string overrides the default and is used as-is.\n */\n private get commandsUrl(): string {\n return resolveProtocolPath(\n this.paths?.commands,\n this.threadId,\n (id) => `/threads/${id}/commands`\n );\n }\n\n private get streamUrl(): string {\n return resolveProtocolPath(\n this.paths?.stream,\n this.threadId,\n (id) => `/threads/${id}/stream/events`\n );\n }\n\n private get stateUrl(): string {\n return resolveProtocolPath(\n this.paths?.state,\n this.threadId,\n (id) => `/threads/${id}/state`\n );\n }\n\n /**\n * Fetch checkpointed thread state for hydration.\n *\n * Uses `GET`, matching `client.threads.getState()` and both LangGraph\n * Platform and Agent Protocol custom backends (`POST` is reserved for\n * `updateState`).\n */\n async getState<StateType = unknown>(): Promise<{\n values: StateType;\n next?: unknown;\n tasks?: unknown;\n metadata?: unknown;\n checkpoint?: { checkpoint_id?: string } | null;\n parent_checkpoint?: { checkpoint_id?: string } | null;\n } | null> {\n const url = toAbsoluteUrl(this.apiUrl, this.stateUrl);\n let requestInit: RequestInit = {\n method: \"GET\",\n headers: mergeHeaders(this.defaultHeaders, {}),\n };\n\n if (this.onRequest) {\n requestInit = await this.onRequest(url, requestInit);\n }\n\n const fetchImpl = await this.resolveFetch();\n const response = await fetchImpl(url.toString(), requestInit);\n if (response.status === 404) return null;\n if (!response.ok) {\n const error = toError(\n new Error(\n `Thread state request failed: ${response.status} ${response.statusText}`\n )\n ) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n return (await response.json()) as {\n values: StateType;\n next?: unknown;\n tasks?: unknown;\n metadata?: unknown;\n checkpoint?: { checkpoint_id?: string } | null;\n parent_checkpoint?: { checkpoint_id?: string } | null;\n };\n }\n\n private async resolveFetch(): Promise<typeof fetch> {\n if (this.fetchFactory) {\n return await this.fetchFactory();\n }\n return this.fetchImpl;\n }\n\n /**\n * HTTP/SSE transports have no handshake — connections are made\n * per-command and per-subscription.\n */\n async open(): Promise<void> {\n // no-op\n }\n\n async send(\n command: Command\n ): Promise<CommandResponse | ErrorResponse | void> {\n const response = await this.request(this.commandsUrl, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(command),\n signal: this.sessionAbortController.signal,\n });\n\n if (response.status === 202 || response.status === 204) {\n return undefined;\n }\n\n const payload = (await response.json()) as unknown;\n if (!isProtocolResponse(payload)) {\n throw new Error(\"Protocol command did not return a valid response.\");\n }\n return payload;\n }\n\n /**\n * WebSocket-style single event stream.\n * For the SSE transport this returns a dummy iterable; real event\n * delivery happens via {@link openEventStream}.\n */\n events(): AsyncIterable<Message> {\n const queue = this.queue;\n return {\n [Symbol.asyncIterator]: () => ({\n next: async () => await queue.shift(),\n return: async () => {\n queue.close();\n return { done: true, value: undefined };\n },\n }),\n };\n }\n\n openEventStream(params: SubscribeParams): EventStreamHandle {\n if (this.closed) {\n throw new Error(\"Protocol transport is closed.\");\n }\n\n const ac = new AbortController();\n this.eventStreams.add(ac);\n const streamQueue = new AsyncQueue<Message>();\n const streamUrl = this.streamUrl;\n\n let resolveReady!: () => void;\n let rejectReady!: (err: unknown) => void;\n const ready = new Promise<void>((resolve, reject) => {\n resolveReady = resolve;\n rejectReady = reject;\n });\n\n let resumeAfterSeq =\n typeof (params as SubscribeParams & { since?: unknown }).since ===\n \"number\"\n ? (params as SubscribeParams & { since: number }).since\n : undefined;\n\n let readySettled = false;\n\n const startStream = async () => {\n let attempt = 0;\n\n while (!ac.signal.aborted && !this.closed) {\n try {\n const response = await this.request(\n streamUrl,\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n accept: \"text/event-stream\",\n },\n body: JSON.stringify({\n channels: params.channels,\n ...(params.namespaces ? { namespaces: params.namespaces } : {}),\n ...(params.depth != null ? { depth: params.depth } : {}),\n ...(resumeAfterSeq != null ? { since: resumeAfterSeq } : {}),\n }),\n signal: ac.signal,\n },\n { stream: true }\n );\n\n if (!readySettled) {\n readySettled = true;\n resolveReady();\n }\n\n const readable =\n response.body ??\n new ReadableStream<Uint8Array>({\n start(controller) {\n controller.close();\n },\n });\n\n // Idle watchdog on the line stream (between byte-line and SSE\n // decoding) so it can reset on any line and recognise `:` keep-alive\n // heartbeats to drive `\"auto\"` mode. On idle it errors the stream,\n // which the catch below treats like any other disconnect and\n // reconnects with `since` from the last seen sequence.\n const enableIdle =\n this.idleReconnect === \"auto\" ||\n (typeof this.idleReconnect === \"number\" && this.idleReconnect > 0);\n const lines = readable.pipeThrough(BytesLineDecoder());\n const watched = enableIdle\n ? lines.pipeThrough(\n idleReconnectStream({ mode: this.idleReconnect! })\n )\n : lines;\n const stream = watched.pipeThrough(SSEDecoder());\n const iterable = IterableReadableStream.fromReadableStream(stream);\n\n for await (const event of iterable) {\n if (ac.signal.aborted || this.closed) {\n break;\n }\n if (isRecord(event.data)) {\n const msg = event.data as Message & {\n seq?: number;\n method?: string;\n };\n if (typeof msg.seq === \"number\") {\n resumeAfterSeq = msg.seq;\n }\n streamQueue.push(msg);\n }\n }\n streamQueue.close();\n return;\n } catch (error) {\n if (ac.signal.aborted || this.closed) {\n if (!readySettled) {\n rejectReady(error);\n }\n streamQueue.close();\n return;\n }\n if (this.maxReconnectAttempts <= 0) {\n if (!readySettled) {\n rejectReady(error);\n }\n streamQueue.close(toError(error));\n return;\n }\n attempt += 1;\n if (attempt > this.maxReconnectAttempts) {\n if (!readySettled) {\n rejectReady(error);\n }\n streamQueue.close(toError(error));\n return;\n }\n this.onReconnect?.({ attempt, cause: error });\n const delay = this.reconnectDelayMs(attempt);\n if (delay > 0) {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, delay);\n });\n }\n }\n }\n };\n\n void startStream();\n\n const cleanup = () => {\n this.eventStreams.delete(ac);\n ac.abort();\n streamQueue.close();\n };\n\n return {\n events: {\n [Symbol.asyncIterator]: () => ({\n next: async () => await streamQueue.shift(),\n return: async () => {\n cleanup();\n return { done: true, value: undefined };\n },\n }),\n },\n ready,\n close: cleanup,\n };\n }\n\n async close(): Promise<void> {\n if (this.closed) {\n return;\n }\n this.closed = true;\n this.sessionAbortController.abort();\n for (const ac of this.eventStreams) ac.abort();\n this.eventStreams.clear();\n this.queue.close();\n }\n\n private async request(\n path: string,\n init: RequestInit,\n options?: { stream?: boolean }\n ): Promise<Response> {\n const url = toAbsoluteUrl(this.apiUrl, path);\n let requestInit: RequestInit = {\n ...init,\n headers: mergeHeaders(this.defaultHeaders, init.headers),\n };\n\n if (this.onRequest) {\n requestInit = await this.onRequest(url, requestInit);\n }\n\n // Long-lived SSE event streams must not run through AsyncCaller: its\n // p-queue/p-retry semantics are designed for discrete request/response\n // calls, and wrapping a streaming response stalls the call (and can\n // leak retries). Stream resilience is handled separately by the\n // reconnect loop in `openEventStream`.\n const useAsyncCaller = this.asyncCaller != null && !options?.stream;\n\n const execute = async (): Promise<Response> => {\n const fetchImpl = await this.resolveFetch();\n const response = await fetchImpl(url.toString(), requestInit);\n if (!response.ok) {\n // Reject with the Response so AsyncCaller maps it to HTTPError and\n // applies STATUS_NO_RETRY / retry policy consistently with REST.\n if (useAsyncCaller) {\n throw response;\n }\n let detail = \"\";\n try {\n const body = await response.text();\n const parsed = JSON.parse(body);\n if (typeof parsed === \"object\" && parsed != null) {\n detail =\n ((parsed as Record<string, unknown>).message as string) ??\n ((parsed as Record<string, unknown>).error as string) ??\n \"\";\n }\n if (!detail) detail = body;\n } catch {\n // body unreadable or not JSON — fall through\n }\n const message = detail\n ? `Protocol request failed: ${response.status} ${response.statusText} — ${detail}`\n : `Protocol request failed: ${response.status} ${response.statusText}`;\n throw new Error(message);\n }\n return response;\n };\n\n try {\n return useAsyncCaller\n ? await this.asyncCaller!.call(execute)\n : await execute();\n } catch (error) {\n throw toError(error);\n }\n }\n}\n"],"mappings":"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"}
{"version":3,"file":"http.cjs","names":["AsyncQueue","reconnectDelayMs","resolveProtocolPath","toAbsoluteUrl","mergeHeaders","toError","isProtocolResponse","BytesLineDecoder","idleReconnectStream","SSEDecoder","IterableReadableStream","isRecord"],"sources":["../../../../src/client/stream/transport/http.ts"],"sourcesContent":["import { AsyncQueue } from \"./queue.js\";\nimport type {\n Message,\n SubscribeParams,\n Command,\n CommandResponse,\n ErrorResponse,\n} from \"@langchain/protocol\";\n\nimport type { AsyncCaller } from \"../../../utils/async_caller.js\";\nimport type {\n HeaderValue,\n ProtocolRequestHook,\n ProtocolSseTransportOptions,\n ProtocolTransportPaths,\n} from \"./types.js\";\nimport type { TransportAdapter, EventStreamHandle } from \"../transport.js\";\nimport {\n toAbsoluteUrl,\n isRecord,\n mergeHeaders,\n toError,\n isProtocolResponse,\n resolveProtocolPath,\n} from \"./utils.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../../../utils/sse.js\";\nimport {\n IterableReadableStream,\n idleReconnectStream,\n type IdleReconnectMode,\n} from \"../../../utils/stream.js\";\nimport {\n DEFAULT_MAX_RECONNECT_ATTEMPTS,\n reconnectDelayMs,\n} from \"../../../utils/reconnect.js\";\nimport { DEFAULT_IDLE_RECONNECT } from \"../../../utils/stream.js\";\n\n/**\n * Transport adapter that speaks the thread-centric protocol over HTTP\n * commands plus SSE event streams. Bound to a `threadId` at construction\n * or later via {@link setThreadId}; request URLs derive from the\n * currently-bound thread. Each {@link openEventStream} call opens an\n * independent filtered SSE connection via\n * `POST /threads/:thread_id/stream/events`.\n */\nexport class ProtocolSseTransportAdapter implements TransportAdapter {\n threadId: string;\n\n readonly apiUrl: string;\n\n private readonly queue = new AsyncQueue<Message>();\n\n private readonly fetchImpl: typeof fetch;\n\n private readonly defaultHeaders: Record<string, HeaderValue>;\n\n private readonly onRequest?: ProtocolRequestHook;\n\n private readonly fetchFactory?: () => typeof fetch | Promise<typeof fetch>;\n\n private readonly asyncCaller?: AsyncCaller;\n\n private readonly maxReconnectAttempts: number;\n\n private readonly idleReconnect: IdleReconnectMode | null;\n\n private readonly onReconnect?: ProtocolSseTransportOptions[\"onReconnect\"];\n\n private readonly reconnectDelayMs: (attempt: number) => number;\n\n private readonly paths?: ProtocolTransportPaths;\n\n private readonly sessionAbortController = new AbortController();\n\n private readonly eventStreams = new Set<AbortController>();\n\n private closed = false;\n\n constructor(options: ProtocolSseTransportOptions) {\n this.fetchImpl = options.fetch ?? fetch;\n this.apiUrl = options.apiUrl;\n this.defaultHeaders = options.defaultHeaders ?? {};\n this.onRequest = options.onRequest;\n this.fetchFactory = options.fetchFactory;\n this.asyncCaller = options.asyncCaller;\n // Custom `fetch` (auth shims, proxies) must keep reconnect enabled — that is\n // the production path for tenant-aware browsers. Tests that need fail-fast\n // mocks should pass `maxReconnectAttempts: 0` (and `idleReconnect: 0`)\n // explicitly rather than relying on `fetch` presence.\n this.maxReconnectAttempts =\n options.maxReconnectAttempts ?? DEFAULT_MAX_RECONNECT_ATTEMPTS;\n // Default to heartbeat-adaptive idle reconnect, which stays dormant\n // unless the server actually emits keep-alive heartbeats. Pass `0` to\n // disable.\n this.idleReconnect = options.idleReconnect ?? DEFAULT_IDLE_RECONNECT;\n this.onReconnect = options.onReconnect;\n this.reconnectDelayMs = options.reconnectDelayMs ?? reconnectDelayMs;\n this.threadId = options.threadId ?? \"\";\n this.paths = options.paths;\n }\n\n /** {@inheritDoc TransportAdapter.setThreadId} */\n setThreadId(threadId: string): void {\n this.threadId = threadId;\n }\n\n /**\n * Command/stream/state URLs derive from the currently-bound thread so a\n * single adapter can follow {@link setThreadId} re-binds. A fixed\n * `paths.*` string overrides the default and is used as-is.\n */\n private get commandsUrl(): string {\n return resolveProtocolPath(\n this.paths?.commands,\n this.threadId,\n (id) => `/threads/${id}/commands`\n );\n }\n\n private get streamUrl(): string {\n return resolveProtocolPath(\n this.paths?.stream,\n this.threadId,\n (id) => `/threads/${id}/stream/events`\n );\n }\n\n private get stateUrl(): string {\n return resolveProtocolPath(\n this.paths?.state,\n this.threadId,\n (id) => `/threads/${id}/state`\n );\n }\n\n /**\n * Fetch checkpointed thread state for hydration.\n *\n * Uses `GET`, matching `client.threads.getState()` and both LangGraph\n * Platform and Agent Protocol custom backends (`POST` is reserved for\n * `updateState`).\n */\n async getState<StateType = unknown>(): Promise<{\n values: StateType;\n next?: unknown;\n tasks?: unknown;\n metadata?: unknown;\n checkpoint?: { checkpoint_id?: string } | null;\n parent_checkpoint?: { checkpoint_id?: string } | null;\n } | null> {\n const url = toAbsoluteUrl(this.apiUrl, this.stateUrl);\n let requestInit: RequestInit = {\n method: \"GET\",\n headers: mergeHeaders(this.defaultHeaders, {}),\n };\n\n if (this.onRequest) {\n requestInit = await this.onRequest(url, requestInit);\n }\n\n const fetchImpl = await this.resolveFetch();\n const response = await fetchImpl(url.toString(), requestInit);\n if (response.status === 404) return null;\n if (!response.ok) {\n const error = toError(\n new Error(\n `Thread state request failed: ${response.status} ${response.statusText}`\n )\n ) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n return (await response.json()) as {\n values: StateType;\n next?: unknown;\n tasks?: unknown;\n metadata?: unknown;\n checkpoint?: { checkpoint_id?: string } | null;\n parent_checkpoint?: { checkpoint_id?: string } | null;\n };\n }\n\n private async resolveFetch(): Promise<typeof fetch> {\n if (this.fetchFactory) {\n return await this.fetchFactory();\n }\n return this.fetchImpl;\n }\n\n /**\n * HTTP/SSE transports have no handshake — connections are made\n * per-command and per-subscription.\n */\n async open(): Promise<void> {\n // no-op\n }\n\n async send(\n command: Command\n ): Promise<CommandResponse | ErrorResponse | void> {\n const response = await this.request(this.commandsUrl, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(command),\n signal: this.sessionAbortController.signal,\n });\n\n if (response.status === 202 || response.status === 204) {\n return undefined;\n }\n\n const payload = (await response.json()) as unknown;\n if (!isProtocolResponse(payload)) {\n throw new Error(\"Protocol command did not return a valid response.\");\n }\n return payload;\n }\n\n /**\n * WebSocket-style single event stream.\n * For the SSE transport this returns a dummy iterable; real event\n * delivery happens via {@link openEventStream}.\n */\n events(): AsyncIterable<Message> {\n const queue = this.queue;\n return {\n [Symbol.asyncIterator]: () => ({\n next: async () => await queue.shift(),\n return: async () => {\n queue.close();\n return { done: true, value: undefined };\n },\n }),\n };\n }\n\n openEventStream(params: SubscribeParams): EventStreamHandle {\n if (this.closed) {\n throw new Error(\"Protocol transport is closed.\");\n }\n\n const ac = new AbortController();\n this.eventStreams.add(ac);\n const streamQueue = new AsyncQueue<Message>();\n const streamUrl = this.streamUrl;\n\n let resolveReady!: () => void;\n let rejectReady!: (err: unknown) => void;\n const ready = new Promise<void>((resolve, reject) => {\n resolveReady = resolve;\n rejectReady = reject;\n });\n\n let resumeAfterSeq =\n typeof (params as SubscribeParams & { since?: unknown }).since ===\n \"number\"\n ? (params as SubscribeParams & { since: number }).since\n : undefined;\n\n let readySettled = false;\n\n const startStream = async () => {\n let attempt = 0;\n\n while (!ac.signal.aborted && !this.closed) {\n try {\n const response = await this.request(\n streamUrl,\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n accept: \"text/event-stream\",\n },\n body: JSON.stringify({\n channels: params.channels,\n ...(params.namespaces ? { namespaces: params.namespaces } : {}),\n ...(params.depth != null ? { depth: params.depth } : {}),\n ...(resumeAfterSeq != null ? { since: resumeAfterSeq } : {}),\n }),\n signal: ac.signal,\n },\n { stream: true }\n );\n\n if (!readySettled) {\n readySettled = true;\n resolveReady();\n }\n\n const readable =\n response.body ??\n new ReadableStream<Uint8Array>({\n start(controller) {\n controller.close();\n },\n });\n\n // Idle watchdog on the line stream (between byte-line and SSE\n // decoding) so it can reset on any line and recognise `:` keep-alive\n // heartbeats to drive `\"auto\"` mode. On idle it errors the stream,\n // which the catch below treats like any other disconnect and\n // reconnects with `since` from the last seen sequence.\n const enableIdle =\n this.idleReconnect === \"auto\" ||\n (typeof this.idleReconnect === \"number\" && this.idleReconnect > 0);\n const lines = readable.pipeThrough(BytesLineDecoder());\n const watched = enableIdle\n ? lines.pipeThrough(\n idleReconnectStream({ mode: this.idleReconnect! })\n )\n : lines;\n const stream = watched.pipeThrough(SSEDecoder());\n const iterable = IterableReadableStream.fromReadableStream(stream);\n\n for await (const event of iterable) {\n if (ac.signal.aborted || this.closed) {\n break;\n }\n if (isRecord(event.data)) {\n const msg = event.data as Message & {\n seq?: number;\n method?: string;\n };\n if (typeof msg.seq === \"number\") {\n resumeAfterSeq = msg.seq;\n }\n streamQueue.push(msg);\n }\n }\n streamQueue.close();\n return;\n } catch (error) {\n if (ac.signal.aborted || this.closed) {\n if (!readySettled) {\n rejectReady(error);\n }\n streamQueue.close();\n return;\n }\n if (this.maxReconnectAttempts <= 0) {\n if (!readySettled) {\n rejectReady(error);\n }\n streamQueue.close(toError(error));\n return;\n }\n attempt += 1;\n if (attempt > this.maxReconnectAttempts) {\n if (!readySettled) {\n rejectReady(error);\n }\n streamQueue.close(toError(error));\n return;\n }\n this.onReconnect?.({ attempt, cause: error });\n const delay = this.reconnectDelayMs(attempt);\n if (delay > 0) {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, delay);\n });\n }\n }\n }\n };\n\n void startStream();\n\n const cleanup = () => {\n this.eventStreams.delete(ac);\n ac.abort();\n streamQueue.close();\n };\n\n return {\n events: {\n [Symbol.asyncIterator]: () => ({\n next: async () => await streamQueue.shift(),\n return: async () => {\n cleanup();\n return { done: true, value: undefined };\n },\n }),\n },\n ready,\n close: cleanup,\n };\n }\n\n async close(): Promise<void> {\n if (this.closed) {\n return;\n }\n this.closed = true;\n this.sessionAbortController.abort();\n for (const ac of this.eventStreams) ac.abort();\n this.eventStreams.clear();\n this.queue.close();\n }\n\n private async request(\n path: string,\n init: RequestInit,\n options?: { stream?: boolean }\n ): Promise<Response> {\n const url = toAbsoluteUrl(this.apiUrl, path);\n let requestInit: RequestInit = {\n ...init,\n headers: mergeHeaders(this.defaultHeaders, init.headers),\n };\n\n if (this.onRequest) {\n requestInit = await this.onRequest(url, requestInit);\n }\n\n // Long-lived SSE event streams must not run through AsyncCaller: its\n // p-queue/p-retry semantics are designed for discrete request/response\n // calls, and wrapping a streaming response stalls the call (and can\n // leak retries). Stream resilience is handled separately by the\n // reconnect loop in `openEventStream`.\n const useAsyncCaller = this.asyncCaller != null && !options?.stream;\n\n const execute = async (): Promise<Response> => {\n const fetchImpl = await this.resolveFetch();\n const response = await fetchImpl(url.toString(), requestInit);\n if (!response.ok) {\n // Reject with the Response so AsyncCaller maps it to HTTPError and\n // applies STATUS_NO_RETRY / retry policy consistently with REST.\n if (useAsyncCaller) {\n throw response;\n }\n let detail = \"\";\n try {\n const body = await response.text();\n const parsed = JSON.parse(body);\n if (typeof parsed === \"object\" && parsed != null) {\n detail =\n ((parsed as Record<string, unknown>).message as string) ??\n ((parsed as Record<string, unknown>).error as string) ??\n \"\";\n }\n if (!detail) detail = body;\n } catch {\n // body unreadable or not JSON — fall through\n }\n const message = detail\n ? `Protocol request failed: ${response.status} ${response.statusText} — ${detail}`\n : `Protocol request failed: ${response.status} ${response.statusText}`;\n throw new Error(message);\n }\n return response;\n };\n\n try {\n return useAsyncCaller\n ? await this.asyncCaller!.call(execute)\n : await execute();\n } catch (error) {\n throw toError(error);\n }\n }\n}\n"],"mappings":"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"}

@@ -1,1 +0,1 @@

{"version":3,"file":"http.d.cts","names":[],"sources":["../../../../src/client/stream/transport/http.ts"],"mappings":";;;;;;;AAyCA;;;;;;cAAa,2BAAA,YAAuC,gBAAA;EAClD,QAAA;EAAA,SAES,MAAA;EAAA,iBAEQ,KAAA;EAAA,iBAEA,SAAA;EAAA,iBAEA,cAAA;EAAA,iBAEA,SAAA;EAAA,iBAEA,YAAA;EAAA,iBAEA,WAAA;EAAA,iBAEA,oBAAA;EAAA,iBAEA,aAAA;EAAA,iBAEA,WAAA;EAAA,iBAEA,gBAAA;EAAA,iBAEA,KAAA;EAAA,iBAEA,sBAAA;EAAA,iBAEA,YAAA;EAAA,QAET,MAAA;EAER,WAAA,CAAY,OAAA,EAAS,2BAAA;EAxBJ;EAiDjB,WAAA,CAAY,QAAA;EA7CK;;;;;EAAA,YAsDL,WAAA,CAAA;EAAA,YAQA,SAAA,CAAA;EAAA,YAQA,QAAA,CAAA;EAtDK;;;;;;;EAqEX,QAAA,qBAAA,CAAA,GAAiC,OAAA;IACrC,MAAA,EAAQ,SAAA;IACR,IAAA;IACA,KAAA;IACA,QAAA;IACA,UAAA;MAAe,aAAA;IAAA;IACf,iBAAA;MAAsB,aAAA;IAAA;EAAA;EAAA,QAmCV,YAAA;EAnCZ;;;;EA8CI,IAAA,CAAA,GAAQ,OAAA;EAIR,IAAA,CACJ,OAAA,EAAS,OAAA,GACR,OAAA,CAAQ,eAAA,GAAkB,aAAA;EADlB;;;;;EAyBX,MAAA,CAAA,GAAU,aAAA,CAAc,OAAA;EAaxB,eAAA,CAAgB,MAAA,EAAQ,eAAA,GAAkB,iBAAA;EAyJpC,KAAA,CAAA,GAAS,OAAA;EAAA,QAWD,OAAA;AAAA"}
{"version":3,"file":"http.d.cts","names":[],"sources":["../../../../src/client/stream/transport/http.ts"],"mappings":";;;;;;;AA6CA;;;;;;cAAa,2BAAA,YAAuC,gBAAA;EAClD,QAAA;EAAA,SAES,MAAA;EAAA,iBAEQ,KAAA;EAAA,iBAEA,SAAA;EAAA,iBAEA,cAAA;EAAA,iBAEA,SAAA;EAAA,iBAEA,YAAA;EAAA,iBAEA,WAAA;EAAA,iBAEA,oBAAA;EAAA,iBAEA,aAAA;EAAA,iBAEA,WAAA;EAAA,iBAEA,gBAAA;EAAA,iBAEA,KAAA;EAAA,iBAEA,sBAAA;EAAA,iBAEA,YAAA;EAAA,QAET,MAAA;EAER,WAAA,CAAY,OAAA,EAAS,2BAAA;EAxBJ;EAgDjB,WAAA,CAAY,QAAA;EA5CK;;;;;EAAA,YAqDL,WAAA,CAAA;EAAA,YAQA,SAAA,CAAA;EAAA,YAQA,QAAA,CAAA;EArDK;;;;;;;EAoEX,QAAA,qBAAA,CAAA,GAAiC,OAAA;IACrC,MAAA,EAAQ,SAAA;IACR,IAAA;IACA,KAAA;IACA,QAAA;IACA,UAAA;MAAe,aAAA;IAAA;IACf,iBAAA;MAAsB,aAAA;IAAA;EAAA;EAAA,QAmCV,YAAA;EAnCZ;;;;EA8CI,IAAA,CAAA,GAAQ,OAAA;EAIR,IAAA,CACJ,OAAA,EAAS,OAAA,GACR,OAAA,CAAQ,eAAA,GAAkB,aAAA;EADlB;;;;;EAyBX,MAAA,CAAA,GAAU,aAAA,CAAc,OAAA;EAaxB,eAAA,CAAgB,MAAA,EAAQ,eAAA,GAAkB,iBAAA;EAyJpC,KAAA,CAAA,GAAS,OAAA;EAAA,QAWD,OAAA;AAAA"}

@@ -1,1 +0,1 @@

{"version":3,"file":"http.d.ts","names":[],"sources":["../../../../src/client/stream/transport/http.ts"],"mappings":";;;;;;;AAyCA;;;;;;cAAa,2BAAA,YAAuC,gBAAA;EAClD,QAAA;EAAA,SAES,MAAA;EAAA,iBAEQ,KAAA;EAAA,iBAEA,SAAA;EAAA,iBAEA,cAAA;EAAA,iBAEA,SAAA;EAAA,iBAEA,YAAA;EAAA,iBAEA,WAAA;EAAA,iBAEA,oBAAA;EAAA,iBAEA,aAAA;EAAA,iBAEA,WAAA;EAAA,iBAEA,gBAAA;EAAA,iBAEA,KAAA;EAAA,iBAEA,sBAAA;EAAA,iBAEA,YAAA;EAAA,QAET,MAAA;EAER,WAAA,CAAY,OAAA,EAAS,2BAAA;EAxBJ;EAiDjB,WAAA,CAAY,QAAA;EA7CK;;;;;EAAA,YAsDL,WAAA,CAAA;EAAA,YAQA,SAAA,CAAA;EAAA,YAQA,QAAA,CAAA;EAtDK;;;;;;;EAqEX,QAAA,qBAAA,CAAA,GAAiC,OAAA;IACrC,MAAA,EAAQ,SAAA;IACR,IAAA;IACA,KAAA;IACA,QAAA;IACA,UAAA;MAAe,aAAA;IAAA;IACf,iBAAA;MAAsB,aAAA;IAAA;EAAA;EAAA,QAmCV,YAAA;EAnCZ;;;;EA8CI,IAAA,CAAA,GAAQ,OAAA;EAIR,IAAA,CACJ,OAAA,EAAS,OAAA,GACR,OAAA,CAAQ,eAAA,GAAkB,aAAA;EADlB;;;;;EAyBX,MAAA,CAAA,GAAU,aAAA,CAAc,OAAA;EAaxB,eAAA,CAAgB,MAAA,EAAQ,eAAA,GAAkB,iBAAA;EAyJpC,KAAA,CAAA,GAAS,OAAA;EAAA,QAWD,OAAA;AAAA"}
{"version":3,"file":"http.d.ts","names":[],"sources":["../../../../src/client/stream/transport/http.ts"],"mappings":";;;;;;;AA6CA;;;;;;cAAa,2BAAA,YAAuC,gBAAA;EAClD,QAAA;EAAA,SAES,MAAA;EAAA,iBAEQ,KAAA;EAAA,iBAEA,SAAA;EAAA,iBAEA,cAAA;EAAA,iBAEA,SAAA;EAAA,iBAEA,YAAA;EAAA,iBAEA,WAAA;EAAA,iBAEA,oBAAA;EAAA,iBAEA,aAAA;EAAA,iBAEA,WAAA;EAAA,iBAEA,gBAAA;EAAA,iBAEA,KAAA;EAAA,iBAEA,sBAAA;EAAA,iBAEA,YAAA;EAAA,QAET,MAAA;EAER,WAAA,CAAY,OAAA,EAAS,2BAAA;EAxBJ;EAgDjB,WAAA,CAAY,QAAA;EA5CK;;;;;EAAA,YAqDL,WAAA,CAAA;EAAA,YAQA,SAAA,CAAA;EAAA,YAQA,QAAA,CAAA;EArDK;;;;;;;EAoEX,QAAA,qBAAA,CAAA,GAAiC,OAAA;IACrC,MAAA,EAAQ,SAAA;IACR,IAAA;IACA,KAAA;IACA,QAAA;IACA,UAAA;MAAe,aAAA;IAAA;IACf,iBAAA;MAAsB,aAAA;IAAA;EAAA;EAAA,QAmCV,YAAA;EAnCZ;;;;EA8CI,IAAA,CAAA,GAAQ,OAAA;EAIR,IAAA,CACJ,OAAA,EAAS,OAAA,GACR,OAAA,CAAQ,eAAA,GAAkB,aAAA;EADlB;;;;;EAyBX,MAAA,CAAA,GAAU,aAAA,CAAc,OAAA;EAaxB,eAAA,CAAgB,MAAA,EAAQ,eAAA,GAAkB,iBAAA;EAyJpC,KAAA,CAAA,GAAS,OAAA;EAAA,QAWD,OAAA;AAAA"}
import { BytesLineDecoder, SSEDecoder } from "../../../utils/sse.js";
import { reconnectDelayMs } from "../../../utils/reconnect.js";
import { IterableReadableStream, idleReconnectStream } from "../../../utils/stream.js";
import { AsyncQueue } from "./queue.js";
import { isProtocolResponse, isRecord, mergeHeaders, resolveProtocolPath, toAbsoluteUrl, toError } from "./utils.js";
import { webSocketReconnectDelayMs } from "./websocket.js";
//#region src/client/stream/transport/http.ts

@@ -39,6 +39,6 @@ /**

this.asyncCaller = options.asyncCaller;
this.maxReconnectAttempts = options.fetch != null ? 0 : options.maxReconnectAttempts ?? 5;
this.idleReconnect = options.fetch != null ? null : options.idleReconnect ?? "auto";
this.maxReconnectAttempts = options.maxReconnectAttempts ?? 5;
this.idleReconnect = options.idleReconnect ?? "auto";
this.onReconnect = options.onReconnect;
this.reconnectDelayMs = options.reconnectDelayMs ?? webSocketReconnectDelayMs;
this.reconnectDelayMs = options.reconnectDelayMs ?? reconnectDelayMs;
this.threadId = options.threadId ?? "";

@@ -45,0 +45,0 @@ this.paths = options.paths;

@@ -1,1 +0,1 @@

{"version":3,"file":"http.js","names":[],"sources":["../../../../src/client/stream/transport/http.ts"],"sourcesContent":["import { AsyncQueue } from \"./queue.js\";\nimport type {\n Message,\n SubscribeParams,\n Command,\n CommandResponse,\n ErrorResponse,\n} from \"@langchain/protocol\";\n\nimport type { AsyncCaller } from \"../../../utils/async_caller.js\";\nimport type {\n HeaderValue,\n ProtocolRequestHook,\n ProtocolSseTransportOptions,\n ProtocolTransportPaths,\n} from \"./types.js\";\nimport type { TransportAdapter, EventStreamHandle } from \"../transport.js\";\nimport {\n toAbsoluteUrl,\n isRecord,\n mergeHeaders,\n toError,\n isProtocolResponse,\n resolveProtocolPath,\n} from \"./utils.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../../../utils/sse.js\";\nimport {\n IterableReadableStream,\n idleReconnectStream,\n type IdleReconnectMode,\n} from \"../../../utils/stream.js\";\nimport { webSocketReconnectDelayMs } from \"./websocket.js\";\n\n/**\n * Transport adapter that speaks the thread-centric protocol over HTTP\n * commands plus SSE event streams. Bound to a `threadId` at construction\n * or later via {@link setThreadId}; request URLs derive from the\n * currently-bound thread. Each {@link openEventStream} call opens an\n * independent filtered SSE connection via\n * `POST /threads/:thread_id/stream/events`.\n */\nexport class ProtocolSseTransportAdapter implements TransportAdapter {\n threadId: string;\n\n readonly apiUrl: string;\n\n private readonly queue = new AsyncQueue<Message>();\n\n private readonly fetchImpl: typeof fetch;\n\n private readonly defaultHeaders: Record<string, HeaderValue>;\n\n private readonly onRequest?: ProtocolRequestHook;\n\n private readonly fetchFactory?: () => typeof fetch | Promise<typeof fetch>;\n\n private readonly asyncCaller?: AsyncCaller;\n\n private readonly maxReconnectAttempts: number;\n\n private readonly idleReconnect: IdleReconnectMode | null;\n\n private readonly onReconnect?: ProtocolSseTransportOptions[\"onReconnect\"];\n\n private readonly reconnectDelayMs: (attempt: number) => number;\n\n private readonly paths?: ProtocolTransportPaths;\n\n private readonly sessionAbortController = new AbortController();\n\n private readonly eventStreams = new Set<AbortController>();\n\n private closed = false;\n\n constructor(options: ProtocolSseTransportOptions) {\n this.fetchImpl = options.fetch ?? fetch;\n this.apiUrl = options.apiUrl;\n this.defaultHeaders = options.defaultHeaders ?? {};\n this.onRequest = options.onRequest;\n this.fetchFactory = options.fetchFactory;\n this.asyncCaller = options.asyncCaller;\n // Custom fetch (tests/mocks) must not auto-reconnect — same policy as skipping AsyncCaller.\n this.maxReconnectAttempts =\n options.fetch != null ? 0 : (options.maxReconnectAttempts ?? 5);\n // Custom fetch (tests/mocks) also disables the idle watchdog, matching the\n // no-auto-reconnect policy above — a tripped watchdog would have nothing to\n // reconnect to and would surface spurious errors in those harnesses.\n // Otherwise default to heartbeat-adaptive `\"auto\"`, which stays dormant\n // unless the server actually emits keep-alive heartbeats.\n this.idleReconnect =\n options.fetch != null ? null : (options.idleReconnect ?? \"auto\");\n this.onReconnect = options.onReconnect;\n this.reconnectDelayMs =\n options.reconnectDelayMs ?? webSocketReconnectDelayMs;\n this.threadId = options.threadId ?? \"\";\n this.paths = options.paths;\n }\n\n /** {@inheritDoc TransportAdapter.setThreadId} */\n setThreadId(threadId: string): void {\n this.threadId = threadId;\n }\n\n /**\n * Command/stream/state URLs derive from the currently-bound thread so a\n * single adapter can follow {@link setThreadId} re-binds. A fixed\n * `paths.*` string overrides the default and is used as-is.\n */\n private get commandsUrl(): string {\n return resolveProtocolPath(\n this.paths?.commands,\n this.threadId,\n (id) => `/threads/${id}/commands`\n );\n }\n\n private get streamUrl(): string {\n return resolveProtocolPath(\n this.paths?.stream,\n this.threadId,\n (id) => `/threads/${id}/stream/events`\n );\n }\n\n private get stateUrl(): string {\n return resolveProtocolPath(\n this.paths?.state,\n this.threadId,\n (id) => `/threads/${id}/state`\n );\n }\n\n /**\n * Fetch checkpointed thread state for hydration.\n *\n * Uses `GET`, matching `client.threads.getState()` and both LangGraph\n * Platform and Agent Protocol custom backends (`POST` is reserved for\n * `updateState`).\n */\n async getState<StateType = unknown>(): Promise<{\n values: StateType;\n next?: unknown;\n tasks?: unknown;\n metadata?: unknown;\n checkpoint?: { checkpoint_id?: string } | null;\n parent_checkpoint?: { checkpoint_id?: string } | null;\n } | null> {\n const url = toAbsoluteUrl(this.apiUrl, this.stateUrl);\n let requestInit: RequestInit = {\n method: \"GET\",\n headers: mergeHeaders(this.defaultHeaders, {}),\n };\n\n if (this.onRequest) {\n requestInit = await this.onRequest(url, requestInit);\n }\n\n const fetchImpl = await this.resolveFetch();\n const response = await fetchImpl(url.toString(), requestInit);\n if (response.status === 404) return null;\n if (!response.ok) {\n const error = toError(\n new Error(\n `Thread state request failed: ${response.status} ${response.statusText}`\n )\n ) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n return (await response.json()) as {\n values: StateType;\n next?: unknown;\n tasks?: unknown;\n metadata?: unknown;\n checkpoint?: { checkpoint_id?: string } | null;\n parent_checkpoint?: { checkpoint_id?: string } | null;\n };\n }\n\n private async resolveFetch(): Promise<typeof fetch> {\n if (this.fetchFactory) {\n return await this.fetchFactory();\n }\n return this.fetchImpl;\n }\n\n /**\n * HTTP/SSE transports have no handshake — connections are made\n * per-command and per-subscription.\n */\n async open(): Promise<void> {\n // no-op\n }\n\n async send(\n command: Command\n ): Promise<CommandResponse | ErrorResponse | void> {\n const response = await this.request(this.commandsUrl, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(command),\n signal: this.sessionAbortController.signal,\n });\n\n if (response.status === 202 || response.status === 204) {\n return undefined;\n }\n\n const payload = (await response.json()) as unknown;\n if (!isProtocolResponse(payload)) {\n throw new Error(\"Protocol command did not return a valid response.\");\n }\n return payload;\n }\n\n /**\n * WebSocket-style single event stream.\n * For the SSE transport this returns a dummy iterable; real event\n * delivery happens via {@link openEventStream}.\n */\n events(): AsyncIterable<Message> {\n const queue = this.queue;\n return {\n [Symbol.asyncIterator]: () => ({\n next: async () => await queue.shift(),\n return: async () => {\n queue.close();\n return { done: true, value: undefined };\n },\n }),\n };\n }\n\n openEventStream(params: SubscribeParams): EventStreamHandle {\n if (this.closed) {\n throw new Error(\"Protocol transport is closed.\");\n }\n\n const ac = new AbortController();\n this.eventStreams.add(ac);\n const streamQueue = new AsyncQueue<Message>();\n const streamUrl = this.streamUrl;\n\n let resolveReady!: () => void;\n let rejectReady!: (err: unknown) => void;\n const ready = new Promise<void>((resolve, reject) => {\n resolveReady = resolve;\n rejectReady = reject;\n });\n\n let resumeAfterSeq =\n typeof (params as SubscribeParams & { since?: unknown }).since ===\n \"number\"\n ? (params as SubscribeParams & { since: number }).since\n : undefined;\n\n let readySettled = false;\n\n const startStream = async () => {\n let attempt = 0;\n\n while (!ac.signal.aborted && !this.closed) {\n try {\n const response = await this.request(\n streamUrl,\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n accept: \"text/event-stream\",\n },\n body: JSON.stringify({\n channels: params.channels,\n ...(params.namespaces ? { namespaces: params.namespaces } : {}),\n ...(params.depth != null ? { depth: params.depth } : {}),\n ...(resumeAfterSeq != null ? { since: resumeAfterSeq } : {}),\n }),\n signal: ac.signal,\n },\n { stream: true }\n );\n\n if (!readySettled) {\n readySettled = true;\n resolveReady();\n }\n\n const readable =\n response.body ??\n new ReadableStream<Uint8Array>({\n start(controller) {\n controller.close();\n },\n });\n\n // Idle watchdog on the line stream (between byte-line and SSE\n // decoding) so it can reset on any line and recognise `:` keep-alive\n // heartbeats to drive `\"auto\"` mode. On idle it errors the stream,\n // which the catch below treats like any other disconnect and\n // reconnects with `since` from the last seen sequence.\n const enableIdle =\n this.idleReconnect === \"auto\" ||\n (typeof this.idleReconnect === \"number\" && this.idleReconnect > 0);\n const lines = readable.pipeThrough(BytesLineDecoder());\n const watched = enableIdle\n ? lines.pipeThrough(\n idleReconnectStream({ mode: this.idleReconnect! })\n )\n : lines;\n const stream = watched.pipeThrough(SSEDecoder());\n const iterable = IterableReadableStream.fromReadableStream(stream);\n\n for await (const event of iterable) {\n if (ac.signal.aborted || this.closed) {\n break;\n }\n if (isRecord(event.data)) {\n const msg = event.data as Message & {\n seq?: number;\n method?: string;\n };\n if (typeof msg.seq === \"number\") {\n resumeAfterSeq = msg.seq;\n }\n streamQueue.push(msg);\n }\n }\n streamQueue.close();\n return;\n } catch (error) {\n if (ac.signal.aborted || this.closed) {\n if (!readySettled) {\n rejectReady(error);\n }\n streamQueue.close();\n return;\n }\n if (this.maxReconnectAttempts <= 0) {\n if (!readySettled) {\n rejectReady(error);\n }\n streamQueue.close(toError(error));\n return;\n }\n attempt += 1;\n if (attempt > this.maxReconnectAttempts) {\n if (!readySettled) {\n rejectReady(error);\n }\n streamQueue.close(toError(error));\n return;\n }\n this.onReconnect?.({ attempt, cause: error });\n const delay = this.reconnectDelayMs(attempt);\n if (delay > 0) {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, delay);\n });\n }\n }\n }\n };\n\n void startStream();\n\n const cleanup = () => {\n this.eventStreams.delete(ac);\n ac.abort();\n streamQueue.close();\n };\n\n return {\n events: {\n [Symbol.asyncIterator]: () => ({\n next: async () => await streamQueue.shift(),\n return: async () => {\n cleanup();\n return { done: true, value: undefined };\n },\n }),\n },\n ready,\n close: cleanup,\n };\n }\n\n async close(): Promise<void> {\n if (this.closed) {\n return;\n }\n this.closed = true;\n this.sessionAbortController.abort();\n for (const ac of this.eventStreams) ac.abort();\n this.eventStreams.clear();\n this.queue.close();\n }\n\n private async request(\n path: string,\n init: RequestInit,\n options?: { stream?: boolean }\n ): Promise<Response> {\n const url = toAbsoluteUrl(this.apiUrl, path);\n let requestInit: RequestInit = {\n ...init,\n headers: mergeHeaders(this.defaultHeaders, init.headers),\n };\n\n if (this.onRequest) {\n requestInit = await this.onRequest(url, requestInit);\n }\n\n // Long-lived SSE event streams must not run through AsyncCaller: its\n // p-queue/p-retry semantics are designed for discrete request/response\n // calls, and wrapping a streaming response stalls the call (and can\n // leak retries). Stream resilience is handled separately by the\n // reconnect loop in `openEventStream`.\n const useAsyncCaller = this.asyncCaller != null && !options?.stream;\n\n const execute = async (): Promise<Response> => {\n const fetchImpl = await this.resolveFetch();\n const response = await fetchImpl(url.toString(), requestInit);\n if (!response.ok) {\n // Reject with the Response so AsyncCaller maps it to HTTPError and\n // applies STATUS_NO_RETRY / retry policy consistently with REST.\n if (useAsyncCaller) {\n throw response;\n }\n let detail = \"\";\n try {\n const body = await response.text();\n const parsed = JSON.parse(body);\n if (typeof parsed === \"object\" && parsed != null) {\n detail =\n ((parsed as Record<string, unknown>).message as string) ??\n ((parsed as Record<string, unknown>).error as string) ??\n \"\";\n }\n if (!detail) detail = body;\n } catch {\n // body unreadable or not JSON — fall through\n }\n const message = detail\n ? `Protocol request failed: ${response.status} ${response.statusText} — ${detail}`\n : `Protocol request failed: ${response.status} ${response.statusText}`;\n throw new Error(message);\n }\n return response;\n };\n\n try {\n return useAsyncCaller\n ? await this.asyncCaller!.call(execute)\n : await execute();\n } catch (error) {\n throw toError(error);\n }\n }\n}\n"],"mappings":"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"}
{"version":3,"file":"http.js","names":[],"sources":["../../../../src/client/stream/transport/http.ts"],"sourcesContent":["import { AsyncQueue } from \"./queue.js\";\nimport type {\n Message,\n SubscribeParams,\n Command,\n CommandResponse,\n ErrorResponse,\n} from \"@langchain/protocol\";\n\nimport type { AsyncCaller } from \"../../../utils/async_caller.js\";\nimport type {\n HeaderValue,\n ProtocolRequestHook,\n ProtocolSseTransportOptions,\n ProtocolTransportPaths,\n} from \"./types.js\";\nimport type { TransportAdapter, EventStreamHandle } from \"../transport.js\";\nimport {\n toAbsoluteUrl,\n isRecord,\n mergeHeaders,\n toError,\n isProtocolResponse,\n resolveProtocolPath,\n} from \"./utils.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../../../utils/sse.js\";\nimport {\n IterableReadableStream,\n idleReconnectStream,\n type IdleReconnectMode,\n} from \"../../../utils/stream.js\";\nimport {\n DEFAULT_MAX_RECONNECT_ATTEMPTS,\n reconnectDelayMs,\n} from \"../../../utils/reconnect.js\";\nimport { DEFAULT_IDLE_RECONNECT } from \"../../../utils/stream.js\";\n\n/**\n * Transport adapter that speaks the thread-centric protocol over HTTP\n * commands plus SSE event streams. Bound to a `threadId` at construction\n * or later via {@link setThreadId}; request URLs derive from the\n * currently-bound thread. Each {@link openEventStream} call opens an\n * independent filtered SSE connection via\n * `POST /threads/:thread_id/stream/events`.\n */\nexport class ProtocolSseTransportAdapter implements TransportAdapter {\n threadId: string;\n\n readonly apiUrl: string;\n\n private readonly queue = new AsyncQueue<Message>();\n\n private readonly fetchImpl: typeof fetch;\n\n private readonly defaultHeaders: Record<string, HeaderValue>;\n\n private readonly onRequest?: ProtocolRequestHook;\n\n private readonly fetchFactory?: () => typeof fetch | Promise<typeof fetch>;\n\n private readonly asyncCaller?: AsyncCaller;\n\n private readonly maxReconnectAttempts: number;\n\n private readonly idleReconnect: IdleReconnectMode | null;\n\n private readonly onReconnect?: ProtocolSseTransportOptions[\"onReconnect\"];\n\n private readonly reconnectDelayMs: (attempt: number) => number;\n\n private readonly paths?: ProtocolTransportPaths;\n\n private readonly sessionAbortController = new AbortController();\n\n private readonly eventStreams = new Set<AbortController>();\n\n private closed = false;\n\n constructor(options: ProtocolSseTransportOptions) {\n this.fetchImpl = options.fetch ?? fetch;\n this.apiUrl = options.apiUrl;\n this.defaultHeaders = options.defaultHeaders ?? {};\n this.onRequest = options.onRequest;\n this.fetchFactory = options.fetchFactory;\n this.asyncCaller = options.asyncCaller;\n // Custom `fetch` (auth shims, proxies) must keep reconnect enabled — that is\n // the production path for tenant-aware browsers. Tests that need fail-fast\n // mocks should pass `maxReconnectAttempts: 0` (and `idleReconnect: 0`)\n // explicitly rather than relying on `fetch` presence.\n this.maxReconnectAttempts =\n options.maxReconnectAttempts ?? DEFAULT_MAX_RECONNECT_ATTEMPTS;\n // Default to heartbeat-adaptive idle reconnect, which stays dormant\n // unless the server actually emits keep-alive heartbeats. Pass `0` to\n // disable.\n this.idleReconnect = options.idleReconnect ?? DEFAULT_IDLE_RECONNECT;\n this.onReconnect = options.onReconnect;\n this.reconnectDelayMs = options.reconnectDelayMs ?? reconnectDelayMs;\n this.threadId = options.threadId ?? \"\";\n this.paths = options.paths;\n }\n\n /** {@inheritDoc TransportAdapter.setThreadId} */\n setThreadId(threadId: string): void {\n this.threadId = threadId;\n }\n\n /**\n * Command/stream/state URLs derive from the currently-bound thread so a\n * single adapter can follow {@link setThreadId} re-binds. A fixed\n * `paths.*` string overrides the default and is used as-is.\n */\n private get commandsUrl(): string {\n return resolveProtocolPath(\n this.paths?.commands,\n this.threadId,\n (id) => `/threads/${id}/commands`\n );\n }\n\n private get streamUrl(): string {\n return resolveProtocolPath(\n this.paths?.stream,\n this.threadId,\n (id) => `/threads/${id}/stream/events`\n );\n }\n\n private get stateUrl(): string {\n return resolveProtocolPath(\n this.paths?.state,\n this.threadId,\n (id) => `/threads/${id}/state`\n );\n }\n\n /**\n * Fetch checkpointed thread state for hydration.\n *\n * Uses `GET`, matching `client.threads.getState()` and both LangGraph\n * Platform and Agent Protocol custom backends (`POST` is reserved for\n * `updateState`).\n */\n async getState<StateType = unknown>(): Promise<{\n values: StateType;\n next?: unknown;\n tasks?: unknown;\n metadata?: unknown;\n checkpoint?: { checkpoint_id?: string } | null;\n parent_checkpoint?: { checkpoint_id?: string } | null;\n } | null> {\n const url = toAbsoluteUrl(this.apiUrl, this.stateUrl);\n let requestInit: RequestInit = {\n method: \"GET\",\n headers: mergeHeaders(this.defaultHeaders, {}),\n };\n\n if (this.onRequest) {\n requestInit = await this.onRequest(url, requestInit);\n }\n\n const fetchImpl = await this.resolveFetch();\n const response = await fetchImpl(url.toString(), requestInit);\n if (response.status === 404) return null;\n if (!response.ok) {\n const error = toError(\n new Error(\n `Thread state request failed: ${response.status} ${response.statusText}`\n )\n ) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n return (await response.json()) as {\n values: StateType;\n next?: unknown;\n tasks?: unknown;\n metadata?: unknown;\n checkpoint?: { checkpoint_id?: string } | null;\n parent_checkpoint?: { checkpoint_id?: string } | null;\n };\n }\n\n private async resolveFetch(): Promise<typeof fetch> {\n if (this.fetchFactory) {\n return await this.fetchFactory();\n }\n return this.fetchImpl;\n }\n\n /**\n * HTTP/SSE transports have no handshake — connections are made\n * per-command and per-subscription.\n */\n async open(): Promise<void> {\n // no-op\n }\n\n async send(\n command: Command\n ): Promise<CommandResponse | ErrorResponse | void> {\n const response = await this.request(this.commandsUrl, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(command),\n signal: this.sessionAbortController.signal,\n });\n\n if (response.status === 202 || response.status === 204) {\n return undefined;\n }\n\n const payload = (await response.json()) as unknown;\n if (!isProtocolResponse(payload)) {\n throw new Error(\"Protocol command did not return a valid response.\");\n }\n return payload;\n }\n\n /**\n * WebSocket-style single event stream.\n * For the SSE transport this returns a dummy iterable; real event\n * delivery happens via {@link openEventStream}.\n */\n events(): AsyncIterable<Message> {\n const queue = this.queue;\n return {\n [Symbol.asyncIterator]: () => ({\n next: async () => await queue.shift(),\n return: async () => {\n queue.close();\n return { done: true, value: undefined };\n },\n }),\n };\n }\n\n openEventStream(params: SubscribeParams): EventStreamHandle {\n if (this.closed) {\n throw new Error(\"Protocol transport is closed.\");\n }\n\n const ac = new AbortController();\n this.eventStreams.add(ac);\n const streamQueue = new AsyncQueue<Message>();\n const streamUrl = this.streamUrl;\n\n let resolveReady!: () => void;\n let rejectReady!: (err: unknown) => void;\n const ready = new Promise<void>((resolve, reject) => {\n resolveReady = resolve;\n rejectReady = reject;\n });\n\n let resumeAfterSeq =\n typeof (params as SubscribeParams & { since?: unknown }).since ===\n \"number\"\n ? (params as SubscribeParams & { since: number }).since\n : undefined;\n\n let readySettled = false;\n\n const startStream = async () => {\n let attempt = 0;\n\n while (!ac.signal.aborted && !this.closed) {\n try {\n const response = await this.request(\n streamUrl,\n {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n accept: \"text/event-stream\",\n },\n body: JSON.stringify({\n channels: params.channels,\n ...(params.namespaces ? { namespaces: params.namespaces } : {}),\n ...(params.depth != null ? { depth: params.depth } : {}),\n ...(resumeAfterSeq != null ? { since: resumeAfterSeq } : {}),\n }),\n signal: ac.signal,\n },\n { stream: true }\n );\n\n if (!readySettled) {\n readySettled = true;\n resolveReady();\n }\n\n const readable =\n response.body ??\n new ReadableStream<Uint8Array>({\n start(controller) {\n controller.close();\n },\n });\n\n // Idle watchdog on the line stream (between byte-line and SSE\n // decoding) so it can reset on any line and recognise `:` keep-alive\n // heartbeats to drive `\"auto\"` mode. On idle it errors the stream,\n // which the catch below treats like any other disconnect and\n // reconnects with `since` from the last seen sequence.\n const enableIdle =\n this.idleReconnect === \"auto\" ||\n (typeof this.idleReconnect === \"number\" && this.idleReconnect > 0);\n const lines = readable.pipeThrough(BytesLineDecoder());\n const watched = enableIdle\n ? lines.pipeThrough(\n idleReconnectStream({ mode: this.idleReconnect! })\n )\n : lines;\n const stream = watched.pipeThrough(SSEDecoder());\n const iterable = IterableReadableStream.fromReadableStream(stream);\n\n for await (const event of iterable) {\n if (ac.signal.aborted || this.closed) {\n break;\n }\n if (isRecord(event.data)) {\n const msg = event.data as Message & {\n seq?: number;\n method?: string;\n };\n if (typeof msg.seq === \"number\") {\n resumeAfterSeq = msg.seq;\n }\n streamQueue.push(msg);\n }\n }\n streamQueue.close();\n return;\n } catch (error) {\n if (ac.signal.aborted || this.closed) {\n if (!readySettled) {\n rejectReady(error);\n }\n streamQueue.close();\n return;\n }\n if (this.maxReconnectAttempts <= 0) {\n if (!readySettled) {\n rejectReady(error);\n }\n streamQueue.close(toError(error));\n return;\n }\n attempt += 1;\n if (attempt > this.maxReconnectAttempts) {\n if (!readySettled) {\n rejectReady(error);\n }\n streamQueue.close(toError(error));\n return;\n }\n this.onReconnect?.({ attempt, cause: error });\n const delay = this.reconnectDelayMs(attempt);\n if (delay > 0) {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, delay);\n });\n }\n }\n }\n };\n\n void startStream();\n\n const cleanup = () => {\n this.eventStreams.delete(ac);\n ac.abort();\n streamQueue.close();\n };\n\n return {\n events: {\n [Symbol.asyncIterator]: () => ({\n next: async () => await streamQueue.shift(),\n return: async () => {\n cleanup();\n return { done: true, value: undefined };\n },\n }),\n },\n ready,\n close: cleanup,\n };\n }\n\n async close(): Promise<void> {\n if (this.closed) {\n return;\n }\n this.closed = true;\n this.sessionAbortController.abort();\n for (const ac of this.eventStreams) ac.abort();\n this.eventStreams.clear();\n this.queue.close();\n }\n\n private async request(\n path: string,\n init: RequestInit,\n options?: { stream?: boolean }\n ): Promise<Response> {\n const url = toAbsoluteUrl(this.apiUrl, path);\n let requestInit: RequestInit = {\n ...init,\n headers: mergeHeaders(this.defaultHeaders, init.headers),\n };\n\n if (this.onRequest) {\n requestInit = await this.onRequest(url, requestInit);\n }\n\n // Long-lived SSE event streams must not run through AsyncCaller: its\n // p-queue/p-retry semantics are designed for discrete request/response\n // calls, and wrapping a streaming response stalls the call (and can\n // leak retries). Stream resilience is handled separately by the\n // reconnect loop in `openEventStream`.\n const useAsyncCaller = this.asyncCaller != null && !options?.stream;\n\n const execute = async (): Promise<Response> => {\n const fetchImpl = await this.resolveFetch();\n const response = await fetchImpl(url.toString(), requestInit);\n if (!response.ok) {\n // Reject with the Response so AsyncCaller maps it to HTTPError and\n // applies STATUS_NO_RETRY / retry policy consistently with REST.\n if (useAsyncCaller) {\n throw response;\n }\n let detail = \"\";\n try {\n const body = await response.text();\n const parsed = JSON.parse(body);\n if (typeof parsed === \"object\" && parsed != null) {\n detail =\n ((parsed as Record<string, unknown>).message as string) ??\n ((parsed as Record<string, unknown>).error as string) ??\n \"\";\n }\n if (!detail) detail = body;\n } catch {\n // body unreadable or not JSON — fall through\n }\n const message = detail\n ? `Protocol request failed: ${response.status} ${response.statusText} — ${detail}`\n : `Protocol request failed: ${response.status} ${response.statusText}`;\n throw new Error(message);\n }\n return response;\n };\n\n try {\n return useAsyncCaller\n ? await this.asyncCaller!.call(execute)\n : await execute();\n } catch (error) {\n throw toError(error);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AA6CA,IAAa,8BAAb,MAAqE;CACnE;CAEA;CAEA,QAAyB,IAAI,YAAqB;CAElD;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA,yBAA0C,IAAI,iBAAiB;CAE/D,+BAAgC,IAAI,KAAsB;CAE1D,SAAiB;CAEjB,YAAY,SAAsC;AAChD,OAAK,YAAY,QAAQ,SAAS;AAClC,OAAK,SAAS,QAAQ;AACtB,OAAK,iBAAiB,QAAQ,kBAAkB,EAAE;AAClD,OAAK,YAAY,QAAQ;AACzB,OAAK,eAAe,QAAQ;AAC5B,OAAK,cAAc,QAAQ;AAK3B,OAAK,uBACH,QAAQ,wBAAA;AAIV,OAAK,gBAAgB,QAAQ,iBAAA;AAC7B,OAAK,cAAc,QAAQ;AAC3B,OAAK,mBAAmB,QAAQ,oBAAoB;AACpD,OAAK,WAAW,QAAQ,YAAY;AACpC,OAAK,QAAQ,QAAQ;;;CAIvB,YAAY,UAAwB;AAClC,OAAK,WAAW;;;;;;;CAQlB,IAAY,cAAsB;AAChC,SAAO,oBACL,KAAK,OAAO,UACZ,KAAK,WACJ,OAAO,YAAY,GAAG,WACxB;;CAGH,IAAY,YAAoB;AAC9B,SAAO,oBACL,KAAK,OAAO,QACZ,KAAK,WACJ,OAAO,YAAY,GAAG,gBACxB;;CAGH,IAAY,WAAmB;AAC7B,SAAO,oBACL,KAAK,OAAO,OACZ,KAAK,WACJ,OAAO,YAAY,GAAG,QACxB;;;;;;;;;CAUH,MAAM,WAOI;EACR,MAAM,MAAM,cAAc,KAAK,QAAQ,KAAK,SAAS;EACrD,IAAI,cAA2B;GAC7B,QAAQ;GACR,SAAS,aAAa,KAAK,gBAAgB,EAAE,CAAC;GAC/C;AAED,MAAI,KAAK,UACP,eAAc,MAAM,KAAK,UAAU,KAAK,YAAY;EAItD,MAAM,WAAW,OADC,MAAM,KAAK,cAAc,EACV,IAAI,UAAU,EAAE,YAAY;AAC7D,MAAI,SAAS,WAAW,IAAK,QAAO;AACpC,MAAI,CAAC,SAAS,IAAI;GAChB,MAAM,QAAQ,wBACZ,IAAI,MACF,gCAAgC,SAAS,OAAO,GAAG,SAAS,aAC7D,CACF;AACD,SAAM,SAAS,SAAS;AACxB,SAAM;;AAGR,SAAQ,MAAM,SAAS,MAAM;;CAU/B,MAAc,eAAsC;AAClD,MAAI,KAAK,aACP,QAAO,MAAM,KAAK,cAAc;AAElC,SAAO,KAAK;;;;;;CAOd,MAAM,OAAsB;CAI5B,MAAM,KACJ,SACiD;EACjD,MAAM,WAAW,MAAM,KAAK,QAAQ,KAAK,aAAa;GACpD,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAC/C,MAAM,KAAK,UAAU,QAAQ;GAC7B,QAAQ,KAAK,uBAAuB;GACrC,CAAC;AAEF,MAAI,SAAS,WAAW,OAAO,SAAS,WAAW,IACjD;EAGF,MAAM,UAAW,MAAM,SAAS,MAAM;AACtC,MAAI,CAAC,mBAAmB,QAAQ,CAC9B,OAAM,IAAI,MAAM,oDAAoD;AAEtE,SAAO;;;;;;;CAQT,SAAiC;EAC/B,MAAM,QAAQ,KAAK;AACnB,SAAO,GACJ,OAAO,uBAAuB;GAC7B,MAAM,YAAY,MAAM,MAAM,OAAO;GACrC,QAAQ,YAAY;AAClB,UAAM,OAAO;AACb,WAAO;KAAE,MAAM;KAAM,OAAO,KAAA;KAAW;;GAE1C,GACF;;CAGH,gBAAgB,QAA4C;AAC1D,MAAI,KAAK,OACP,OAAM,IAAI,MAAM,gCAAgC;EAGlD,MAAM,KAAK,IAAI,iBAAiB;AAChC,OAAK,aAAa,IAAI,GAAG;EACzB,MAAM,cAAc,IAAI,YAAqB;EAC7C,MAAM,YAAY,KAAK;EAEvB,IAAI;EACJ,IAAI;EACJ,MAAM,QAAQ,IAAI,SAAe,SAAS,WAAW;AACnD,kBAAe;AACf,iBAAc;IACd;EAEF,IAAI,iBACF,OAAQ,OAAiD,UACzD,WACK,OAA+C,QAChD,KAAA;EAEN,IAAI,eAAe;EAEnB,MAAM,cAAc,YAAY;GAC9B,IAAI,UAAU;AAEd,UAAO,CAAC,GAAG,OAAO,WAAW,CAAC,KAAK,OACjC,KAAI;IACF,MAAM,WAAW,MAAM,KAAK,QAC1B,WACA;KACE,QAAQ;KACR,SAAS;MACP,gBAAgB;MAChB,QAAQ;MACT;KACD,MAAM,KAAK,UAAU;MACnB,UAAU,OAAO;MACjB,GAAI,OAAO,aAAa,EAAE,YAAY,OAAO,YAAY,GAAG,EAAE;MAC9D,GAAI,OAAO,SAAS,OAAO,EAAE,OAAO,OAAO,OAAO,GAAG,EAAE;MACvD,GAAI,kBAAkB,OAAO,EAAE,OAAO,gBAAgB,GAAG,EAAE;MAC5D,CAAC;KACF,QAAQ,GAAG;KACZ,EACD,EAAE,QAAQ,MAAM,CACjB;AAED,QAAI,CAAC,cAAc;AACjB,oBAAe;AACf,mBAAc;;IAGhB,MAAM,WACJ,SAAS,QACT,IAAI,eAA2B,EAC7B,MAAM,YAAY;AAChB,gBAAW,OAAO;OAErB,CAAC;IAOJ,MAAM,aACJ,KAAK,kBAAkB,UACtB,OAAO,KAAK,kBAAkB,YAAY,KAAK,gBAAgB;IAClE,MAAM,QAAQ,SAAS,YAAY,kBAAkB,CAAC;IAMtD,MAAM,UALU,aACZ,MAAM,YACJ,oBAAoB,EAAE,MAAM,KAAK,eAAgB,CAAC,CACnD,GACD,OACmB,YAAY,YAAY,CAAC;IAChD,MAAM,WAAW,uBAAuB,mBAAmB,OAAO;AAElE,eAAW,MAAM,SAAS,UAAU;AAClC,SAAI,GAAG,OAAO,WAAW,KAAK,OAC5B;AAEF,SAAI,SAAS,MAAM,KAAK,EAAE;MACxB,MAAM,MAAM,MAAM;AAIlB,UAAI,OAAO,IAAI,QAAQ,SACrB,kBAAiB,IAAI;AAEvB,kBAAY,KAAK,IAAI;;;AAGzB,gBAAY,OAAO;AACnB;YACO,OAAO;AACd,QAAI,GAAG,OAAO,WAAW,KAAK,QAAQ;AACpC,SAAI,CAAC,aACH,aAAY,MAAM;AAEpB,iBAAY,OAAO;AACnB;;AAEF,QAAI,KAAK,wBAAwB,GAAG;AAClC,SAAI,CAAC,aACH,aAAY,MAAM;AAEpB,iBAAY,MAAM,QAAQ,MAAM,CAAC;AACjC;;AAEF,eAAW;AACX,QAAI,UAAU,KAAK,sBAAsB;AACvC,SAAI,CAAC,aACH,aAAY,MAAM;AAEpB,iBAAY,MAAM,QAAQ,MAAM,CAAC;AACjC;;AAEF,SAAK,cAAc;KAAE;KAAS,OAAO;KAAO,CAAC;IAC7C,MAAM,QAAQ,KAAK,iBAAiB,QAAQ;AAC5C,QAAI,QAAQ,EACV,OAAM,IAAI,SAAe,YAAY;AACnC,gBAAW,SAAS,MAAM;MAC1B;;;AAML,eAAa;EAElB,MAAM,gBAAgB;AACpB,QAAK,aAAa,OAAO,GAAG;AAC5B,MAAG,OAAO;AACV,eAAY,OAAO;;AAGrB,SAAO;GACL,QAAQ,GACL,OAAO,uBAAuB;IAC7B,MAAM,YAAY,MAAM,YAAY,OAAO;IAC3C,QAAQ,YAAY;AAClB,cAAS;AACT,YAAO;MAAE,MAAM;MAAM,OAAO,KAAA;MAAW;;IAE1C,GACF;GACD;GACA,OAAO;GACR;;CAGH,MAAM,QAAuB;AAC3B,MAAI,KAAK,OACP;AAEF,OAAK,SAAS;AACd,OAAK,uBAAuB,OAAO;AACnC,OAAK,MAAM,MAAM,KAAK,aAAc,IAAG,OAAO;AAC9C,OAAK,aAAa,OAAO;AACzB,OAAK,MAAM,OAAO;;CAGpB,MAAc,QACZ,MACA,MACA,SACmB;EACnB,MAAM,MAAM,cAAc,KAAK,QAAQ,KAAK;EAC5C,IAAI,cAA2B;GAC7B,GAAG;GACH,SAAS,aAAa,KAAK,gBAAgB,KAAK,QAAQ;GACzD;AAED,MAAI,KAAK,UACP,eAAc,MAAM,KAAK,UAAU,KAAK,YAAY;EAQtD,MAAM,iBAAiB,KAAK,eAAe,QAAQ,CAAC,SAAS;EAE7D,MAAM,UAAU,YAA+B;GAE7C,MAAM,WAAW,OADC,MAAM,KAAK,cAAc,EACV,IAAI,UAAU,EAAE,YAAY;AAC7D,OAAI,CAAC,SAAS,IAAI;AAGhB,QAAI,eACF,OAAM;IAER,IAAI,SAAS;AACb,QAAI;KACF,MAAM,OAAO,MAAM,SAAS,MAAM;KAClC,MAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,SAAI,OAAO,WAAW,YAAY,UAAU,KAC1C,UACI,OAAmC,WACnC,OAAmC,SACrC;AAEJ,SAAI,CAAC,OAAQ,UAAS;YAChB;IAGR,MAAM,UAAU,SACZ,4BAA4B,SAAS,OAAO,GAAG,SAAS,WAAW,KAAK,WACxE,4BAA4B,SAAS,OAAO,GAAG,SAAS;AAC5D,UAAM,IAAI,MAAM,QAAQ;;AAE1B,UAAO;;AAGT,MAAI;AACF,UAAO,iBACH,MAAM,KAAK,YAAa,KAAK,QAAQ,GACrC,MAAM,SAAS;WACZ,OAAO;AACd,SAAM,QAAQ,MAAM"}
require("../error.cjs");
require("./http.cjs");
require("./websocket.cjs");
require("./http.cjs");
require("./agent-server.cjs");
import "../error.js";
import "./http.js";
import "./websocket.js";
import "./http.js";
import "./agent-server.js";
export {};

@@ -43,3 +43,8 @@ import { AsyncCaller } from "../../../utils/async_caller.cjs";

* Maximum reconnect attempts after an unexpected SSE disconnect.
* Defaults to 5. Set to 0 to disable automatic reconnection.
* Defaults to `DEFAULT_MAX_RECONNECT_ATTEMPTS` from `utils/reconnect`.
* Set to 0 to disable automatic reconnection.
*
* Independent of whether a custom {@link ProtocolSseTransportOptions.fetch}
* is supplied — auth/proxy fetch wrappers keep reconnect enabled. Pass `0`
* explicitly in unit tests that mock a failing `fetch` and expect fail-fast.
*/

@@ -54,9 +59,13 @@ maxReconnectAttempts?: number;

*
* - `"auto"`: arm only once the server's SSE keep-alive heartbeats
* (LangGraph Platform: `: heartbeat` every ~5s) are observed, sizing the
* window from their cadence. Independent of agent activity; stays dormant
* on heartbeat-less servers.
* - `"auto"` (`DEFAULT_IDLE_RECONNECT` from `utils/stream`): arm only once
* the server's SSE keep-alive heartbeats (LangGraph Platform:
* `: heartbeat` every ~5s) are observed, sizing the window from their
* cadence. Independent of agent activity; stays dormant on
* heartbeat-less servers.
* - a `number`: a fixed idle window in milliseconds.
* - `0`: disables it.
*
* Independent of custom {@link ProtocolSseTransportOptions.fetch}; pass `0`
* in fail-fast test harnesses.
*
* @see {@link IdleReconnectMode}

@@ -72,3 +81,3 @@ */

* Backoff before each SSE reconnect attempt. Defaults to
* {@link webSocketReconnectDelayMs} from `./websocket.js`.
* `reconnectDelayMs` from `utils/reconnect`.
*/

@@ -90,3 +99,4 @@ reconnectDelayMs?: (attempt: number) => number;

* Maximum reconnect attempts after an unexpected socket close.
* Defaults to 5. Set to 0 to disable automatic reconnection.
* Defaults to `DEFAULT_MAX_RECONNECT_ATTEMPTS` from `utils/reconnect`.
* Set to 0 to disable automatic reconnection.
*/

@@ -108,3 +118,3 @@ maxReconnectAttempts?: number;

* Backoff before each reconnect attempt. Defaults to
* {@link webSocketReconnectDelayMs}.
* `reconnectDelayMs` from `utils/reconnect`.
*/

@@ -111,0 +121,0 @@ reconnectDelayMs?: (attempt: number) => number;

@@ -1,1 +0,1 @@

{"version":3,"file":"types.d.cts","names":[],"sources":["../../../../src/client/stream/transport/types.ts"],"mappings":";;;;;KAIY,mBAAA,IACV,GAAA,EAAK,GAAA,EACL,IAAA,EAAM,WAAA,KACH,OAAA,CAAQ,WAAA,IAAe,WAAA;;AAH5B;;;;;;KAYY,YAAA,cAA0B,QAAA;AAAA,UAErB,sBAAA;EACf,QAAA,GAAW,YAAA;EACX,MAAA,GAAS,YAAA;EAfJ;EAiBL,KAAA,GAAQ,YAAA;AAAA;AAAA,UAGO,2BAAA;EACf,MAAA;EAnBW;;;;AASb;;EAiBE,QAAA;EACA,cAAA,GAAiB,MAAA,SAAe,WAAA;EAChC,SAAA,GAAY,mBAAA;EACZ,KAAA,UAAe,KAAA;EACf,YAAA,gBAA4B,KAAA,GAAQ,OAAA,QAAe,KAAA;;;;;;EAMnD,WAAA,GAAc,WAAA;EACd,KAAA,GAAQ,sBAAA;EAzBG;;;;EA8BX,oBAAA;EA3BoB;;AAGtB;;;;;;;;;;;;;;EAyCE,aAAA,GAAgB,iBAAA;EAxChB;EA0CA,WAAA,IAAe,OAAA;IAAW,OAAA;IAAiB,KAAA;EAAA;EAjC3C;;;;EAsCA,gBAAA,IAAoB,OAAA;AAAA;AAAA,UAGL,iCAAA;EACf,MAAA;EAlCA;;;;EAuCA,QAAA;EACA,cAAA,GAAiB,MAAA,SAAe,WAAA;EAChC,SAAA,GAAY,mBAAA;EACZ,gBAAA,IAAoB,GAAA,aAAgB,SAAA;EACpC,KAAA,GAAQ,IAAA,CAAK,sBAAA;EAlB8B;;;;EAuB3C,oBAAA;EAlBmC;AAGrC;;EAmBE,WAAA,IAAe,OAAA;IAAW,OAAA;IAAiB,KAAA;EAAA;EAVP;;;;EAepC,aAAA,gBAA6B,OAAA;EAAO;;;;EAKpC,gBAAA,IAAoB,OAAA;AAAA;AAAA,KAGV,WAAA"}
{"version":3,"file":"types.d.cts","names":[],"sources":["../../../../src/client/stream/transport/types.ts"],"mappings":";;;;;KAIY,mBAAA,IACV,GAAA,EAAK,GAAA,EACL,IAAA,EAAM,WAAA,KACH,OAAA,CAAQ,WAAA,IAAe,WAAA;;AAH5B;;;;;;KAYY,YAAA,cAA0B,QAAA;AAAA,UAErB,sBAAA;EACf,QAAA,GAAW,YAAA;EACX,MAAA,GAAS,YAAA;EAfJ;EAiBL,KAAA,GAAQ,YAAA;AAAA;AAAA,UAGO,2BAAA;EACf,MAAA;EAnBW;;;;AASb;;EAiBE,QAAA;EACA,cAAA,GAAiB,MAAA,SAAe,WAAA;EAChC,SAAA,GAAY,mBAAA;EACZ,KAAA,UAAe,KAAA;EACf,YAAA,gBAA4B,KAAA,GAAQ,OAAA,QAAe,KAAA;;;;;;EAMnD,WAAA,GAAc,WAAA;EACd,KAAA,GAAQ,sBAAA;EAzBG;;;;;;;AAMb;;EA6BE,oBAAA;EApBgC;;;;;;;;;;;;;;;;;;;;EAyChC,aAAA,GAAgB,iBAAA;EAtChB;EAwCA,WAAA,IAAe,OAAA;IAAW,OAAA;IAAiB,KAAA;EAAA;EAlC7B;;;;EAuCd,gBAAA,IAAoB,OAAA;AAAA;AAAA,UAGL,iCAAA;EACf,MAAA;EAT2C;;;;EAc3C,QAAA;EACA,cAAA,GAAiB,MAAA,SAAe,WAAA;EAChC,SAAA,GAAY,mBAAA;EACZ,gBAAA,IAAoB,GAAA,aAAgB,SAAA;EACpC,KAAA,GAAQ,IAAA,CAAK,sBAAA;EAHmB;;;;;EAShC,oBAAA;EAS6B;;;EAL7B,WAAA,IAAe,OAAA;IAAW,OAAA;IAAiB,KAAA;EAAA;EAbX;;;;EAkBhC,aAAA,gBAA6B,OAAA;EAhBO;;;;EAqBpC,gBAAA,IAAoB,OAAA;AAAA;AAAA,KAGV,WAAA"}

@@ -43,3 +43,8 @@ import { AsyncCaller } from "../../../utils/async_caller.js";

* Maximum reconnect attempts after an unexpected SSE disconnect.
* Defaults to 5. Set to 0 to disable automatic reconnection.
* Defaults to `DEFAULT_MAX_RECONNECT_ATTEMPTS` from `utils/reconnect`.
* Set to 0 to disable automatic reconnection.
*
* Independent of whether a custom {@link ProtocolSseTransportOptions.fetch}
* is supplied — auth/proxy fetch wrappers keep reconnect enabled. Pass `0`
* explicitly in unit tests that mock a failing `fetch` and expect fail-fast.
*/

@@ -54,9 +59,13 @@ maxReconnectAttempts?: number;

*
* - `"auto"`: arm only once the server's SSE keep-alive heartbeats
* (LangGraph Platform: `: heartbeat` every ~5s) are observed, sizing the
* window from their cadence. Independent of agent activity; stays dormant
* on heartbeat-less servers.
* - `"auto"` (`DEFAULT_IDLE_RECONNECT` from `utils/stream`): arm only once
* the server's SSE keep-alive heartbeats (LangGraph Platform:
* `: heartbeat` every ~5s) are observed, sizing the window from their
* cadence. Independent of agent activity; stays dormant on
* heartbeat-less servers.
* - a `number`: a fixed idle window in milliseconds.
* - `0`: disables it.
*
* Independent of custom {@link ProtocolSseTransportOptions.fetch}; pass `0`
* in fail-fast test harnesses.
*
* @see {@link IdleReconnectMode}

@@ -72,3 +81,3 @@ */

* Backoff before each SSE reconnect attempt. Defaults to
* {@link webSocketReconnectDelayMs} from `./websocket.js`.
* `reconnectDelayMs` from `utils/reconnect`.
*/

@@ -90,3 +99,4 @@ reconnectDelayMs?: (attempt: number) => number;

* Maximum reconnect attempts after an unexpected socket close.
* Defaults to 5. Set to 0 to disable automatic reconnection.
* Defaults to `DEFAULT_MAX_RECONNECT_ATTEMPTS` from `utils/reconnect`.
* Set to 0 to disable automatic reconnection.
*/

@@ -108,3 +118,3 @@ maxReconnectAttempts?: number;

* Backoff before each reconnect attempt. Defaults to
* {@link webSocketReconnectDelayMs}.
* `reconnectDelayMs` from `utils/reconnect`.
*/

@@ -111,0 +121,0 @@ reconnectDelayMs?: (attempt: number) => number;

@@ -1,1 +0,1 @@

{"version":3,"file":"types.d.ts","names":[],"sources":["../../../../src/client/stream/transport/types.ts"],"mappings":";;;;;KAIY,mBAAA,IACV,GAAA,EAAK,GAAA,EACL,IAAA,EAAM,WAAA,KACH,OAAA,CAAQ,WAAA,IAAe,WAAA;;AAH5B;;;;;;KAYY,YAAA,cAA0B,QAAA;AAAA,UAErB,sBAAA;EACf,QAAA,GAAW,YAAA;EACX,MAAA,GAAS,YAAA;EAfJ;EAiBL,KAAA,GAAQ,YAAA;AAAA;AAAA,UAGO,2BAAA;EACf,MAAA;EAnBW;;;;AASb;;EAiBE,QAAA;EACA,cAAA,GAAiB,MAAA,SAAe,WAAA;EAChC,SAAA,GAAY,mBAAA;EACZ,KAAA,UAAe,KAAA;EACf,YAAA,gBAA4B,KAAA,GAAQ,OAAA,QAAe,KAAA;;;;;;EAMnD,WAAA,GAAc,WAAA;EACd,KAAA,GAAQ,sBAAA;EAzBG;;;;EA8BX,oBAAA;EA3BoB;;AAGtB;;;;;;;;;;;;;;EAyCE,aAAA,GAAgB,iBAAA;EAxChB;EA0CA,WAAA,IAAe,OAAA;IAAW,OAAA;IAAiB,KAAA;EAAA;EAjC3C;;;;EAsCA,gBAAA,IAAoB,OAAA;AAAA;AAAA,UAGL,iCAAA;EACf,MAAA;EAlCA;;;;EAuCA,QAAA;EACA,cAAA,GAAiB,MAAA,SAAe,WAAA;EAChC,SAAA,GAAY,mBAAA;EACZ,gBAAA,IAAoB,GAAA,aAAgB,SAAA;EACpC,KAAA,GAAQ,IAAA,CAAK,sBAAA;EAlB8B;;;;EAuB3C,oBAAA;EAlBmC;AAGrC;;EAmBE,WAAA,IAAe,OAAA;IAAW,OAAA;IAAiB,KAAA;EAAA;EAVP;;;;EAepC,aAAA,gBAA6B,OAAA;EAAO;;;;EAKpC,gBAAA,IAAoB,OAAA;AAAA;AAAA,KAGV,WAAA"}
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../../src/client/stream/transport/types.ts"],"mappings":";;;;;KAIY,mBAAA,IACV,GAAA,EAAK,GAAA,EACL,IAAA,EAAM,WAAA,KACH,OAAA,CAAQ,WAAA,IAAe,WAAA;;AAH5B;;;;;;KAYY,YAAA,cAA0B,QAAA;AAAA,UAErB,sBAAA;EACf,QAAA,GAAW,YAAA;EACX,MAAA,GAAS,YAAA;EAfJ;EAiBL,KAAA,GAAQ,YAAA;AAAA;AAAA,UAGO,2BAAA;EACf,MAAA;EAnBW;;;;AASb;;EAiBE,QAAA;EACA,cAAA,GAAiB,MAAA,SAAe,WAAA;EAChC,SAAA,GAAY,mBAAA;EACZ,KAAA,UAAe,KAAA;EACf,YAAA,gBAA4B,KAAA,GAAQ,OAAA,QAAe,KAAA;;;;;;EAMnD,WAAA,GAAc,WAAA;EACd,KAAA,GAAQ,sBAAA;EAzBG;;;;;;;AAMb;;EA6BE,oBAAA;EApBgC;;;;;;;;;;;;;;;;;;;;EAyChC,aAAA,GAAgB,iBAAA;EAtChB;EAwCA,WAAA,IAAe,OAAA;IAAW,OAAA;IAAiB,KAAA;EAAA;EAlC7B;;;;EAuCd,gBAAA,IAAoB,OAAA;AAAA;AAAA,UAGL,iCAAA;EACf,MAAA;EAT2C;;;;EAc3C,QAAA;EACA,cAAA,GAAiB,MAAA,SAAe,WAAA;EAChC,SAAA,GAAY,mBAAA;EACZ,gBAAA,IAAoB,GAAA,aAAgB,SAAA;EACpC,KAAA,GAAQ,IAAA,CAAK,sBAAA;EAHmB;;;;;EAShC,oBAAA;EAS6B;;;EAL7B,WAAA,IAAe,OAAA;IAAW,OAAA;IAAiB,KAAA;EAAA;EAbX;;;;EAkBhC,aAAA,gBAA6B,OAAA;EAhBO;;;;EAqBpC,gBAAA,IAAoB,OAAA;AAAA;AAAA,KAGV,WAAA"}

@@ -0,1 +1,2 @@

const require_reconnect = require("../../../utils/reconnect.cjs");
const require_error = require("../error.cjs");

@@ -9,9 +10,2 @@ const require_queue = require("./queue.cjs");

/**
* Exponential backoff with jitter for WebSocket reconnect. Mirrors
* {@link streamWithRetry} in `utils/stream.ts` (capped at 5s + 1s jitter).
*/
function webSocketReconnectDelayMs(attempt) {
return Math.min(1e3 * 2 ** (attempt - 1), 5e3) + Math.random() * 1e3;
}
/**
* Transport adapter that speaks the thread-centric protocol over a

@@ -56,3 +50,3 @@ * bidirectional WebSocket. Bound to a `threadId` at construction or later

this.onReconnected = options.onReconnected;
this.reconnectDelayMs = options.reconnectDelayMs ?? webSocketReconnectDelayMs;
this.reconnectDelayMs = options.reconnectDelayMs ?? require_reconnect.reconnectDelayMs;
}

@@ -259,4 +253,3 @@ /** {@inheritDoc TransportAdapter.setThreadId} */

exports.ProtocolWebSocketTransportAdapter = ProtocolWebSocketTransportAdapter;
exports.webSocketReconnectDelayMs = webSocketReconnectDelayMs;
//# sourceMappingURL=websocket.cjs.map

@@ -1,1 +0,1 @@

{"version":3,"file":"websocket.cjs","names":["AsyncQueue","resolveProtocolPath","#detachSocket","toWebSocketUrl","toAbsoluteUrl","#attachSocket","hasHeaders","toError","isRecord","#handleUnexpectedDisconnect","#scheduleReconnect","#runReconnectLoop","MaxWebSocketReconnectAttemptsError"],"sources":["../../../../src/client/stream/transport/websocket.ts"],"sourcesContent":["import { AsyncQueue } from \"./queue.js\";\nimport type {\n Message,\n Command,\n CommandResponse,\n ErrorResponse,\n} from \"@langchain/protocol\";\n\nimport {\n toAbsoluteUrl,\n toWebSocketUrl,\n isRecord,\n hasHeaders,\n toError,\n resolveProtocolPath,\n} from \"./utils.js\";\nimport type {\n HeaderValue,\n ProtocolRequestHook,\n PendingResponse,\n ProtocolTransportPaths,\n ProtocolWebSocketTransportOptions,\n} from \"./types.js\";\nimport type { TransportAdapter } from \"../transport.js\";\nimport { MaxWebSocketReconnectAttemptsError } from \"../error.js\";\n\nconst WEB_SOCKET_CONNECTING = 0;\nconst WEB_SOCKET_OPEN = 1;\nconst WEB_SOCKET_CLOSED = 3;\n\n/**\n * Reconnect tuning for {@link ProtocolWebSocketTransportAdapter}. A subset\n * of {@link ProtocolWebSocketTransportOptions}.\n */\nexport interface WebSocketReconnectOptions {\n /**\n * Maximum reconnection attempts after an unexpected disconnect.\n * Defaults to 5.\n */\n maxReconnectAttempts?: number;\n\n /**\n * Invoked before each reconnect attempt (after backoff).\n */\n onReconnect?: (options: { attempt: number; cause: unknown }) => void;\n}\n\n/**\n * Exponential backoff with jitter for WebSocket reconnect. Mirrors\n * {@link streamWithRetry} in `utils/stream.ts` (capped at 5s + 1s jitter).\n */\nexport function webSocketReconnectDelayMs(attempt: number): number {\n const baseDelay = Math.min(1000 * 2 ** (attempt - 1), 5000);\n const jitter = Math.random() * 1000;\n return baseDelay + jitter;\n}\n\n/**\n * Transport adapter that speaks the thread-centric protocol over a\n * bidirectional WebSocket. Bound to a `threadId` at construction or later\n * via {@link setThreadId} — the socket connects to\n * `ws://.../threads/:thread_id/stream/events`.\n *\n * On unexpected disconnect the adapter reconnects with exponential\n * backoff (see {@link ProtocolWebSocketTransportOptions.maxReconnectAttempts}).\n * The server replays buffered events on the new socket; the SDK\n * deduplicates by `event_id`. {@link ProtocolWebSocketTransportOptions.onReconnected}\n * runs after each successful reconnect so `ThreadStream` can re-issue\n * `subscription.subscribe` commands.\n */\nexport class ProtocolWebSocketTransportAdapter implements TransportAdapter {\n threadId: string;\n\n private readonly queue = new AsyncQueue<Message>();\n\n private readonly apiUrl: string;\n\n private readonly defaultHeaders?: Record<string, HeaderValue>;\n\n private readonly onRequest?: ProtocolRequestHook;\n\n private readonly webSocketFactory: (url: string) => WebSocket;\n\n private readonly paths?: Pick<ProtocolTransportPaths, \"stream\">;\n\n private readonly maxReconnectAttempts: number;\n\n private readonly onReconnect?: ProtocolWebSocketTransportOptions[\"onReconnect\"];\n\n private readonly reconnectDelayMs: (attempt: number) => number;\n\n private onReconnected?: () => void | Promise<void>;\n\n private readonly pending = new Map<number, PendingResponse>();\n\n private socket: WebSocket | null = null;\n\n private closed = false;\n\n private intentionalClose = false;\n\n private reconnectInFlight: Promise<void> | null = null;\n\n constructor(options: ProtocolWebSocketTransportOptions) {\n this.apiUrl = options.apiUrl;\n this.threadId = options.threadId ?? \"\";\n this.defaultHeaders = options.defaultHeaders;\n this.onRequest = options.onRequest;\n this.webSocketFactory =\n options.webSocketFactory ?? ((url) => new WebSocket(url));\n this.paths = options.paths;\n this.maxReconnectAttempts = options.maxReconnectAttempts ?? 5;\n this.onReconnect = options.onReconnect;\n this.onReconnected = options.onReconnected;\n this.reconnectDelayMs =\n options.reconnectDelayMs ?? webSocketReconnectDelayMs;\n }\n\n /** {@inheritDoc TransportAdapter.setThreadId} */\n setThreadId(threadId: string): void {\n if (threadId === this.threadId) {\n return;\n }\n if (\n this.reconnectInFlight != null ||\n (this.socket != null && this.socket.readyState !== WEB_SOCKET_CLOSED)\n ) {\n throw new Error(\n \"Protocol WebSocket transport cannot be rebound to a different thread while the socket is open. Close the current stream and create a new WebSocket transport for the new thread.\"\n );\n }\n this.threadId = threadId;\n }\n\n /**\n * Socket URL derives from the currently-bound thread so a single adapter\n * can follow {@link setThreadId} re-binds; the next {@link open} connects\n * to the new thread. A fixed `paths.stream` string overrides the default.\n */\n private get streamUrl(): string {\n return resolveProtocolPath(\n this.paths?.stream,\n this.threadId,\n (id) => `/threads/${id}/stream/events`\n );\n }\n\n /**\n * Register a callback invoked after each successful reconnect. Used\n * by {@link ThreadStream} to re-send active `subscription.subscribe`\n * commands.\n */\n setOnReconnected(handler: () => void | Promise<void>): void {\n this.onReconnected = handler;\n }\n\n async open(): Promise<void> {\n if (this.closed) {\n throw new Error(\"Protocol WebSocket transport is closed.\");\n }\n if (this.socket?.readyState === WEB_SOCKET_OPEN) {\n return;\n }\n if (this.socket != null) {\n this.#detachSocket(this.socket);\n this.socket = null;\n }\n\n this.assertBrowserSafeTransportConfig();\n\n const wsUrl = toWebSocketUrl(\n toAbsoluteUrl(this.apiUrl, this.streamUrl).toString()\n );\n const socket = this.webSocketFactory(wsUrl);\n this.socket = socket;\n this.intentionalClose = false;\n\n this.#attachSocket(socket);\n\n await new Promise<void>((resolve, reject) => {\n const onOpen = () => {\n cleanup();\n resolve();\n };\n const onError = () => {\n cleanup();\n reject(new Error(\"Failed to open protocol WebSocket.\"));\n };\n const cleanup = () => {\n socket.removeEventListener(\"open\", onOpen);\n socket.removeEventListener(\"error\", onError);\n };\n socket.addEventListener(\"open\", onOpen, { once: true });\n socket.addEventListener(\"error\", onError, { once: true });\n });\n }\n\n async send(\n command: Command\n ): Promise<CommandResponse | ErrorResponse | void> {\n return await this.sendCommand(command);\n }\n\n events(): AsyncIterable<Message> {\n const queue = this.queue;\n return {\n [Symbol.asyncIterator]: () => ({\n next: async () => await queue.shift(),\n return: async () => {\n queue.close();\n return { done: true, value: undefined };\n },\n }),\n };\n }\n\n async close(): Promise<void> {\n if (this.closed) {\n return;\n }\n\n this.closed = true;\n this.intentionalClose = true;\n\n for (const { reject } of this.pending.values()) {\n reject(new Error(\"Protocol WebSocket connection closed.\"));\n }\n this.pending.clear();\n this.queue.close();\n\n const socket = this.socket;\n this.socket = null;\n if (!socket) {\n return;\n }\n\n this.#detachSocket(socket);\n\n await new Promise<void>((resolve) => {\n if (socket.readyState === WEB_SOCKET_CLOSED) {\n resolve();\n return;\n }\n\n const onClose = () => {\n socket.removeEventListener(\"close\", onClose);\n resolve();\n };\n\n socket.addEventListener(\"close\", onClose, { once: true });\n if (\n socket.readyState === WEB_SOCKET_OPEN ||\n socket.readyState === WEB_SOCKET_CONNECTING\n ) {\n socket.close();\n } else {\n resolve();\n }\n });\n }\n\n private assertBrowserSafeTransportConfig(): void {\n if (hasHeaders(this.defaultHeaders) || this.onRequest != null) {\n throw new Error(\n \"Browser WebSocket protocol transport does not support defaultHeaders or onRequest hooks. Supply a custom protocolWebSocketFactory if you need custom WebSocket setup.\"\n );\n }\n }\n\n private async sendCommand(\n command: Command\n ): Promise<CommandResponse | ErrorResponse> {\n // Wait for an in-flight reconnect only when the socket is not usable.\n // After `open()` succeeds, `#runReconnectLoop` may still be awaiting\n // `onReconnected` (e.g. ThreadStream resubscribe). Those callbacks call\n // `sendCommand` and must not await the same `reconnectInFlight` promise.\n let socket = this.socket;\n if (\n this.reconnectInFlight != null &&\n (socket == null || socket.readyState !== WEB_SOCKET_OPEN)\n ) {\n await this.reconnectInFlight.catch(() => undefined);\n socket = this.socket;\n }\n\n if (socket == null || socket.readyState !== WEB_SOCKET_OPEN) {\n throw new Error(\"Protocol WebSocket is not open.\");\n }\n\n return await new Promise<CommandResponse | ErrorResponse>(\n (resolve, reject) => {\n this.pending.set(command.id, { resolve, reject });\n\n try {\n socket.send(JSON.stringify(command));\n } catch (error) {\n this.pending.delete(command.id);\n reject(toError(error));\n }\n }\n );\n }\n\n #attachSocket(socket: WebSocket): void {\n socket.addEventListener(\"message\", this.handleMessage);\n socket.addEventListener(\"close\", this.handleClose);\n socket.addEventListener(\"error\", this.handleSocketError);\n }\n\n #detachSocket(socket: WebSocket): void {\n socket.removeEventListener(\"message\", this.handleMessage);\n socket.removeEventListener(\"close\", this.handleClose);\n socket.removeEventListener(\"error\", this.handleSocketError);\n }\n\n private readonly handleMessage = (event: MessageEvent): void => {\n let payload: unknown;\n try {\n payload = JSON.parse(String(event.data));\n } catch {\n return;\n }\n\n if (\n isRecord(payload) &&\n typeof payload.id === \"number\" &&\n (payload.type === \"success\" || payload.type === \"error\")\n ) {\n const pending = this.pending.get(payload.id);\n if (pending) {\n this.pending.delete(payload.id);\n pending.resolve(payload as CommandResponse | ErrorResponse);\n }\n return;\n }\n\n if (isRecord(payload) && payload.type === \"event\") {\n this.queue.push(payload as Message);\n }\n };\n\n private readonly handleClose = (): void => {\n const socket = this.socket;\n if (socket != null) {\n this.#detachSocket(socket);\n }\n this.socket = null;\n\n if (this.intentionalClose || this.closed) {\n this.queue.close();\n return;\n }\n\n this.#handleUnexpectedDisconnect(\n new Error(\"Protocol WebSocket closed unexpectedly.\")\n );\n };\n\n private readonly handleSocketError = (): void => {\n if (this.closed || this.intentionalClose) {\n return;\n }\n\n this.#handleUnexpectedDisconnect(\n new Error(\"Protocol WebSocket encountered an error.\")\n );\n };\n\n #handleUnexpectedDisconnect(cause: unknown): void {\n const error = toError(cause);\n for (const { reject } of this.pending.values()) {\n reject(error);\n }\n this.pending.clear();\n\n if (this.maxReconnectAttempts <= 0) {\n this.queue.close(error);\n return;\n }\n\n this.#scheduleReconnect(cause);\n }\n\n #scheduleReconnect(cause: unknown): void {\n if (this.closed || this.intentionalClose) {\n return;\n }\n if (this.reconnectInFlight != null) {\n return;\n }\n\n this.reconnectInFlight = this.#runReconnectLoop(cause).finally(() => {\n this.reconnectInFlight = null;\n });\n }\n\n async #runReconnectLoop(initialCause: unknown): Promise<void> {\n let lastError: unknown = initialCause;\n\n for (let attempt = 1; attempt <= this.maxReconnectAttempts; attempt += 1) {\n if (this.closed || this.intentionalClose) {\n return;\n }\n\n this.onReconnect?.({ attempt, cause: lastError });\n\n const delay = this.reconnectDelayMs(attempt);\n if (delay > 0) {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, delay);\n });\n }\n\n if (this.closed || this.intentionalClose) {\n return;\n }\n\n try {\n await this.open();\n if (this.onReconnected) {\n await this.onReconnected();\n }\n return;\n } catch (error) {\n lastError = error;\n }\n }\n\n this.queue.close(\n new MaxWebSocketReconnectAttemptsError(\n this.maxReconnectAttempts,\n lastError\n )\n );\n }\n}\n"],"mappings":"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"}
{"version":3,"file":"websocket.cjs","names":["AsyncQueue","reconnectDelayMs","resolveProtocolPath","#detachSocket","toWebSocketUrl","toAbsoluteUrl","#attachSocket","hasHeaders","toError","isRecord","#handleUnexpectedDisconnect","#scheduleReconnect","#runReconnectLoop","MaxWebSocketReconnectAttemptsError"],"sources":["../../../../src/client/stream/transport/websocket.ts"],"sourcesContent":["import { AsyncQueue } from \"./queue.js\";\nimport type {\n Message,\n Command,\n CommandResponse,\n ErrorResponse,\n} from \"@langchain/protocol\";\n\nimport {\n toAbsoluteUrl,\n toWebSocketUrl,\n isRecord,\n hasHeaders,\n toError,\n resolveProtocolPath,\n} from \"./utils.js\";\nimport type {\n HeaderValue,\n ProtocolRequestHook,\n PendingResponse,\n ProtocolTransportPaths,\n ProtocolWebSocketTransportOptions,\n} from \"./types.js\";\nimport type { TransportAdapter } from \"../transport.js\";\nimport { MaxWebSocketReconnectAttemptsError } from \"../error.js\";\nimport {\n DEFAULT_MAX_RECONNECT_ATTEMPTS,\n reconnectDelayMs,\n} from \"../../../utils/reconnect.js\";\n\nconst WEB_SOCKET_CONNECTING = 0;\nconst WEB_SOCKET_OPEN = 1;\nconst WEB_SOCKET_CLOSED = 3;\n\n/**\n * Reconnect tuning for {@link ProtocolWebSocketTransportAdapter}. A subset\n * of {@link ProtocolWebSocketTransportOptions}.\n */\nexport interface WebSocketReconnectOptions {\n /**\n * Maximum reconnection attempts after an unexpected disconnect.\n * Defaults to {@link DEFAULT_MAX_RECONNECT_ATTEMPTS}.\n */\n maxReconnectAttempts?: number;\n\n /**\n * Invoked before each reconnect attempt (after backoff).\n */\n onReconnect?: (options: { attempt: number; cause: unknown }) => void;\n}\n\n/**\n * Transport adapter that speaks the thread-centric protocol over a\n * bidirectional WebSocket. Bound to a `threadId` at construction or later\n * via {@link setThreadId} — the socket connects to\n * `ws://.../threads/:thread_id/stream/events`.\n *\n * On unexpected disconnect the adapter reconnects with exponential\n * backoff (see {@link ProtocolWebSocketTransportOptions.maxReconnectAttempts}).\n * The server replays buffered events on the new socket; the SDK\n * deduplicates by `event_id`. {@link ProtocolWebSocketTransportOptions.onReconnected}\n * runs after each successful reconnect so `ThreadStream` can re-issue\n * `subscription.subscribe` commands.\n */\nexport class ProtocolWebSocketTransportAdapter implements TransportAdapter {\n threadId: string;\n\n private readonly queue = new AsyncQueue<Message>();\n\n private readonly apiUrl: string;\n\n private readonly defaultHeaders?: Record<string, HeaderValue>;\n\n private readonly onRequest?: ProtocolRequestHook;\n\n private readonly webSocketFactory: (url: string) => WebSocket;\n\n private readonly paths?: Pick<ProtocolTransportPaths, \"stream\">;\n\n private readonly maxReconnectAttempts: number;\n\n private readonly onReconnect?: ProtocolWebSocketTransportOptions[\"onReconnect\"];\n\n private readonly reconnectDelayMs: (attempt: number) => number;\n\n private onReconnected?: () => void | Promise<void>;\n\n private readonly pending = new Map<number, PendingResponse>();\n\n private socket: WebSocket | null = null;\n\n private closed = false;\n\n private intentionalClose = false;\n\n private reconnectInFlight: Promise<void> | null = null;\n\n constructor(options: ProtocolWebSocketTransportOptions) {\n this.apiUrl = options.apiUrl;\n this.threadId = options.threadId ?? \"\";\n this.defaultHeaders = options.defaultHeaders;\n this.onRequest = options.onRequest;\n this.webSocketFactory =\n options.webSocketFactory ?? ((url) => new WebSocket(url));\n this.paths = options.paths;\n this.maxReconnectAttempts =\n options.maxReconnectAttempts ?? DEFAULT_MAX_RECONNECT_ATTEMPTS;\n this.onReconnect = options.onReconnect;\n this.onReconnected = options.onReconnected;\n this.reconnectDelayMs = options.reconnectDelayMs ?? reconnectDelayMs;\n }\n\n /** {@inheritDoc TransportAdapter.setThreadId} */\n setThreadId(threadId: string): void {\n if (threadId === this.threadId) {\n return;\n }\n if (\n this.reconnectInFlight != null ||\n (this.socket != null && this.socket.readyState !== WEB_SOCKET_CLOSED)\n ) {\n throw new Error(\n \"Protocol WebSocket transport cannot be rebound to a different thread while the socket is open. Close the current stream and create a new WebSocket transport for the new thread.\"\n );\n }\n this.threadId = threadId;\n }\n\n /**\n * Socket URL derives from the currently-bound thread so a single adapter\n * can follow {@link setThreadId} re-binds; the next {@link open} connects\n * to the new thread. A fixed `paths.stream` string overrides the default.\n */\n private get streamUrl(): string {\n return resolveProtocolPath(\n this.paths?.stream,\n this.threadId,\n (id) => `/threads/${id}/stream/events`\n );\n }\n\n /**\n * Register a callback invoked after each successful reconnect. Used\n * by {@link ThreadStream} to re-send active `subscription.subscribe`\n * commands.\n */\n setOnReconnected(handler: () => void | Promise<void>): void {\n this.onReconnected = handler;\n }\n\n async open(): Promise<void> {\n if (this.closed) {\n throw new Error(\"Protocol WebSocket transport is closed.\");\n }\n if (this.socket?.readyState === WEB_SOCKET_OPEN) {\n return;\n }\n if (this.socket != null) {\n this.#detachSocket(this.socket);\n this.socket = null;\n }\n\n this.assertBrowserSafeTransportConfig();\n\n const wsUrl = toWebSocketUrl(\n toAbsoluteUrl(this.apiUrl, this.streamUrl).toString()\n );\n const socket = this.webSocketFactory(wsUrl);\n this.socket = socket;\n this.intentionalClose = false;\n\n this.#attachSocket(socket);\n\n await new Promise<void>((resolve, reject) => {\n const onOpen = () => {\n cleanup();\n resolve();\n };\n const onError = () => {\n cleanup();\n reject(new Error(\"Failed to open protocol WebSocket.\"));\n };\n const cleanup = () => {\n socket.removeEventListener(\"open\", onOpen);\n socket.removeEventListener(\"error\", onError);\n };\n socket.addEventListener(\"open\", onOpen, { once: true });\n socket.addEventListener(\"error\", onError, { once: true });\n });\n }\n\n async send(\n command: Command\n ): Promise<CommandResponse | ErrorResponse | void> {\n return await this.sendCommand(command);\n }\n\n events(): AsyncIterable<Message> {\n const queue = this.queue;\n return {\n [Symbol.asyncIterator]: () => ({\n next: async () => await queue.shift(),\n return: async () => {\n queue.close();\n return { done: true, value: undefined };\n },\n }),\n };\n }\n\n async close(): Promise<void> {\n if (this.closed) {\n return;\n }\n\n this.closed = true;\n this.intentionalClose = true;\n\n for (const { reject } of this.pending.values()) {\n reject(new Error(\"Protocol WebSocket connection closed.\"));\n }\n this.pending.clear();\n this.queue.close();\n\n const socket = this.socket;\n this.socket = null;\n if (!socket) {\n return;\n }\n\n this.#detachSocket(socket);\n\n await new Promise<void>((resolve) => {\n if (socket.readyState === WEB_SOCKET_CLOSED) {\n resolve();\n return;\n }\n\n const onClose = () => {\n socket.removeEventListener(\"close\", onClose);\n resolve();\n };\n\n socket.addEventListener(\"close\", onClose, { once: true });\n if (\n socket.readyState === WEB_SOCKET_OPEN ||\n socket.readyState === WEB_SOCKET_CONNECTING\n ) {\n socket.close();\n } else {\n resolve();\n }\n });\n }\n\n private assertBrowserSafeTransportConfig(): void {\n if (hasHeaders(this.defaultHeaders) || this.onRequest != null) {\n throw new Error(\n \"Browser WebSocket protocol transport does not support defaultHeaders or onRequest hooks. Supply a custom protocolWebSocketFactory if you need custom WebSocket setup.\"\n );\n }\n }\n\n private async sendCommand(\n command: Command\n ): Promise<CommandResponse | ErrorResponse> {\n // Wait for an in-flight reconnect only when the socket is not usable.\n // After `open()` succeeds, `#runReconnectLoop` may still be awaiting\n // `onReconnected` (e.g. ThreadStream resubscribe). Those callbacks call\n // `sendCommand` and must not await the same `reconnectInFlight` promise.\n let socket = this.socket;\n if (\n this.reconnectInFlight != null &&\n (socket == null || socket.readyState !== WEB_SOCKET_OPEN)\n ) {\n await this.reconnectInFlight.catch(() => undefined);\n socket = this.socket;\n }\n\n if (socket == null || socket.readyState !== WEB_SOCKET_OPEN) {\n throw new Error(\"Protocol WebSocket is not open.\");\n }\n\n return await new Promise<CommandResponse | ErrorResponse>(\n (resolve, reject) => {\n this.pending.set(command.id, { resolve, reject });\n\n try {\n socket.send(JSON.stringify(command));\n } catch (error) {\n this.pending.delete(command.id);\n reject(toError(error));\n }\n }\n );\n }\n\n #attachSocket(socket: WebSocket): void {\n socket.addEventListener(\"message\", this.handleMessage);\n socket.addEventListener(\"close\", this.handleClose);\n socket.addEventListener(\"error\", this.handleSocketError);\n }\n\n #detachSocket(socket: WebSocket): void {\n socket.removeEventListener(\"message\", this.handleMessage);\n socket.removeEventListener(\"close\", this.handleClose);\n socket.removeEventListener(\"error\", this.handleSocketError);\n }\n\n private readonly handleMessage = (event: MessageEvent): void => {\n let payload: unknown;\n try {\n payload = JSON.parse(String(event.data));\n } catch {\n return;\n }\n\n if (\n isRecord(payload) &&\n typeof payload.id === \"number\" &&\n (payload.type === \"success\" || payload.type === \"error\")\n ) {\n const pending = this.pending.get(payload.id);\n if (pending) {\n this.pending.delete(payload.id);\n pending.resolve(payload as CommandResponse | ErrorResponse);\n }\n return;\n }\n\n if (isRecord(payload) && payload.type === \"event\") {\n this.queue.push(payload as Message);\n }\n };\n\n private readonly handleClose = (): void => {\n const socket = this.socket;\n if (socket != null) {\n this.#detachSocket(socket);\n }\n this.socket = null;\n\n if (this.intentionalClose || this.closed) {\n this.queue.close();\n return;\n }\n\n this.#handleUnexpectedDisconnect(\n new Error(\"Protocol WebSocket closed unexpectedly.\")\n );\n };\n\n private readonly handleSocketError = (): void => {\n if (this.closed || this.intentionalClose) {\n return;\n }\n\n this.#handleUnexpectedDisconnect(\n new Error(\"Protocol WebSocket encountered an error.\")\n );\n };\n\n #handleUnexpectedDisconnect(cause: unknown): void {\n const error = toError(cause);\n for (const { reject } of this.pending.values()) {\n reject(error);\n }\n this.pending.clear();\n\n if (this.maxReconnectAttempts <= 0) {\n this.queue.close(error);\n return;\n }\n\n this.#scheduleReconnect(cause);\n }\n\n #scheduleReconnect(cause: unknown): void {\n if (this.closed || this.intentionalClose) {\n return;\n }\n if (this.reconnectInFlight != null) {\n return;\n }\n\n this.reconnectInFlight = this.#runReconnectLoop(cause).finally(() => {\n this.reconnectInFlight = null;\n });\n }\n\n async #runReconnectLoop(initialCause: unknown): Promise<void> {\n let lastError: unknown = initialCause;\n\n for (let attempt = 1; attempt <= this.maxReconnectAttempts; attempt += 1) {\n if (this.closed || this.intentionalClose) {\n return;\n }\n\n this.onReconnect?.({ attempt, cause: lastError });\n\n const delay = this.reconnectDelayMs(attempt);\n if (delay > 0) {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, delay);\n });\n }\n\n if (this.closed || this.intentionalClose) {\n return;\n }\n\n try {\n await this.open();\n if (this.onReconnected) {\n await this.onReconnected();\n }\n return;\n } catch (error) {\n lastError = error;\n }\n }\n\n this.queue.close(\n new MaxWebSocketReconnectAttemptsError(\n this.maxReconnectAttempts,\n lastError\n )\n );\n }\n}\n"],"mappings":"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"}

@@ -1,1 +0,1 @@

{"version":3,"file":"websocket.d.cts","names":[],"sources":["../../../../src/client/stream/transport/websocket.ts"],"mappings":";;;;;;;;;;;;;;;;;;cAsEa,iCAAA,YAA6C,gBAAA;EAAA;EACxD,QAAA;EAAA,iBAEiB,KAAA;EAAA,iBAEA,MAAA;EAAA,iBAEA,cAAA;EAAA,iBAEA,SAAA;EAAA,iBAEA,gBAAA;EAAA,iBAEA,KAAA;EAAA,iBAEA,oBAAA;EAAA,iBAEA,WAAA;EAAA,iBAEA,gBAAA;EAAA,QAET,aAAA;EAAA,iBAES,OAAA;EAAA,QAET,MAAA;EAAA,QAEA,MAAA;EAAA,QAEA,gBAAA;EAAA,QAEA,iBAAA;EAER,WAAA,CAAY,OAAA,EAAS,iCAAA;EAoGG;EApFxB,WAAA,CAAY,QAAA;EAiGG;;;;;EAAA,YA7EH,SAAA,CAAA;EA2NsB;;;;;EA9MlC,gBAAA,CAAiB,OAAA,eAAsB,OAAA;EAIjC,IAAA,CAAA,GAAQ,OAAA;EAyCR,IAAA,CACJ,OAAA,EAAS,OAAA,GACR,OAAA,CAAQ,eAAA,GAAkB,aAAA;EAI7B,MAAA,CAAA,GAAU,aAAA,CAAc,OAAA;EAalB,KAAA,CAAA,GAAS,OAAA;EAAA,QA6CP,gCAAA;EAAA,QAQM,WAAA;EAAA,iBA8CG,aAAA;EAAA,iBA0BA,WAAA;EAAA,iBAiBA,iBAAA;AAAA"}
{"version":3,"file":"websocket.d.cts","names":[],"sources":["../../../../src/client/stream/transport/websocket.ts"],"mappings":";;;;;;;;;;;;;;;;;;cAgEa,iCAAA,YAA6C,gBAAA;EAAA;EACxD,QAAA;EAAA,iBAEiB,KAAA;EAAA,iBAEA,MAAA;EAAA,iBAEA,cAAA;EAAA,iBAEA,SAAA;EAAA,iBAEA,gBAAA;EAAA,iBAEA,KAAA;EAAA,iBAEA,oBAAA;EAAA,iBAEA,WAAA;EAAA,iBAEA,gBAAA;EAAA,QAET,aAAA;EAAA,iBAES,OAAA;EAAA,QAET,MAAA;EAAA,QAEA,MAAA;EAAA,QAEA,gBAAA;EAAA,QAEA,iBAAA;EAER,WAAA,CAAY,OAAA,EAAS,iCAAA;EAgGlB;EAhFH,WAAA,CAAY,QAAA;EAgFiB;;;;;EAAA,YA5DjB,SAAA,CAAA;EA0HJ;;;;;EA7GR,gBAAA,CAAiB,OAAA,eAAsB,OAAA;EAIjC,IAAA,CAAA,GAAQ,OAAA;EAyCR,IAAA,CACJ,OAAA,EAAS,OAAA,GACR,OAAA,CAAQ,eAAA,GAAkB,aAAA;EAI7B,MAAA,CAAA,GAAU,aAAA,CAAc,OAAA;EAalB,KAAA,CAAA,GAAS,OAAA;EAAA,QA6CP,gCAAA;EAAA,QAQM,WAAA;EAAA,iBA8CG,aAAA;EAAA,iBA0BA,WAAA;EAAA,iBAiBA,iBAAA;AAAA"}

@@ -1,1 +0,1 @@

{"version":3,"file":"websocket.d.ts","names":[],"sources":["../../../../src/client/stream/transport/websocket.ts"],"mappings":";;;;;;;;;;;;;;;;;;cAsEa,iCAAA,YAA6C,gBAAA;EAAA;EACxD,QAAA;EAAA,iBAEiB,KAAA;EAAA,iBAEA,MAAA;EAAA,iBAEA,cAAA;EAAA,iBAEA,SAAA;EAAA,iBAEA,gBAAA;EAAA,iBAEA,KAAA;EAAA,iBAEA,oBAAA;EAAA,iBAEA,WAAA;EAAA,iBAEA,gBAAA;EAAA,QAET,aAAA;EAAA,iBAES,OAAA;EAAA,QAET,MAAA;EAAA,QAEA,MAAA;EAAA,QAEA,gBAAA;EAAA,QAEA,iBAAA;EAER,WAAA,CAAY,OAAA,EAAS,iCAAA;EAoGG;EApFxB,WAAA,CAAY,QAAA;EAiGG;;;;;EAAA,YA7EH,SAAA,CAAA;EA2NsB;;;;;EA9MlC,gBAAA,CAAiB,OAAA,eAAsB,OAAA;EAIjC,IAAA,CAAA,GAAQ,OAAA;EAyCR,IAAA,CACJ,OAAA,EAAS,OAAA,GACR,OAAA,CAAQ,eAAA,GAAkB,aAAA;EAI7B,MAAA,CAAA,GAAU,aAAA,CAAc,OAAA;EAalB,KAAA,CAAA,GAAS,OAAA;EAAA,QA6CP,gCAAA;EAAA,QAQM,WAAA;EAAA,iBA8CG,aAAA;EAAA,iBA0BA,WAAA;EAAA,iBAiBA,iBAAA;AAAA"}
{"version":3,"file":"websocket.d.ts","names":[],"sources":["../../../../src/client/stream/transport/websocket.ts"],"mappings":";;;;;;;;;;;;;;;;;;cAgEa,iCAAA,YAA6C,gBAAA;EAAA;EACxD,QAAA;EAAA,iBAEiB,KAAA;EAAA,iBAEA,MAAA;EAAA,iBAEA,cAAA;EAAA,iBAEA,SAAA;EAAA,iBAEA,gBAAA;EAAA,iBAEA,KAAA;EAAA,iBAEA,oBAAA;EAAA,iBAEA,WAAA;EAAA,iBAEA,gBAAA;EAAA,QAET,aAAA;EAAA,iBAES,OAAA;EAAA,QAET,MAAA;EAAA,QAEA,MAAA;EAAA,QAEA,gBAAA;EAAA,QAEA,iBAAA;EAER,WAAA,CAAY,OAAA,EAAS,iCAAA;EAgGlB;EAhFH,WAAA,CAAY,QAAA;EAgFiB;;;;;EAAA,YA5DjB,SAAA,CAAA;EA0HJ;;;;;EA7GR,gBAAA,CAAiB,OAAA,eAAsB,OAAA;EAIjC,IAAA,CAAA,GAAQ,OAAA;EAyCR,IAAA,CACJ,OAAA,EAAS,OAAA,GACR,OAAA,CAAQ,eAAA,GAAkB,aAAA;EAI7B,MAAA,CAAA,GAAU,aAAA,CAAc,OAAA;EAalB,KAAA,CAAA,GAAS,OAAA;EAAA,QA6CP,gCAAA;EAAA,QAQM,WAAA;EAAA,iBA8CG,aAAA;EAAA,iBA0BA,WAAA;EAAA,iBAiBA,iBAAA;AAAA"}

@@ -0,1 +1,2 @@

import { reconnectDelayMs } from "../../../utils/reconnect.js";
import { MaxWebSocketReconnectAttemptsError } from "../error.js";

@@ -9,9 +10,2 @@ import { AsyncQueue } from "./queue.js";

/**
* Exponential backoff with jitter for WebSocket reconnect. Mirrors
* {@link streamWithRetry} in `utils/stream.ts` (capped at 5s + 1s jitter).
*/
function webSocketReconnectDelayMs(attempt) {
return Math.min(1e3 * 2 ** (attempt - 1), 5e3) + Math.random() * 1e3;
}
/**
* Transport adapter that speaks the thread-centric protocol over a

@@ -56,3 +50,3 @@ * bidirectional WebSocket. Bound to a `threadId` at construction or later

this.onReconnected = options.onReconnected;
this.reconnectDelayMs = options.reconnectDelayMs ?? webSocketReconnectDelayMs;
this.reconnectDelayMs = options.reconnectDelayMs ?? reconnectDelayMs;
}

@@ -258,4 +252,4 @@ /** {@inheritDoc TransportAdapter.setThreadId} */

//#endregion
export { ProtocolWebSocketTransportAdapter, webSocketReconnectDelayMs };
export { ProtocolWebSocketTransportAdapter };
//# sourceMappingURL=websocket.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"websocket.js","names":["#detachSocket","#attachSocket","#handleUnexpectedDisconnect","#scheduleReconnect","#runReconnectLoop"],"sources":["../../../../src/client/stream/transport/websocket.ts"],"sourcesContent":["import { AsyncQueue } from \"./queue.js\";\nimport type {\n Message,\n Command,\n CommandResponse,\n ErrorResponse,\n} from \"@langchain/protocol\";\n\nimport {\n toAbsoluteUrl,\n toWebSocketUrl,\n isRecord,\n hasHeaders,\n toError,\n resolveProtocolPath,\n} from \"./utils.js\";\nimport type {\n HeaderValue,\n ProtocolRequestHook,\n PendingResponse,\n ProtocolTransportPaths,\n ProtocolWebSocketTransportOptions,\n} from \"./types.js\";\nimport type { TransportAdapter } from \"../transport.js\";\nimport { MaxWebSocketReconnectAttemptsError } from \"../error.js\";\n\nconst WEB_SOCKET_CONNECTING = 0;\nconst WEB_SOCKET_OPEN = 1;\nconst WEB_SOCKET_CLOSED = 3;\n\n/**\n * Reconnect tuning for {@link ProtocolWebSocketTransportAdapter}. A subset\n * of {@link ProtocolWebSocketTransportOptions}.\n */\nexport interface WebSocketReconnectOptions {\n /**\n * Maximum reconnection attempts after an unexpected disconnect.\n * Defaults to 5.\n */\n maxReconnectAttempts?: number;\n\n /**\n * Invoked before each reconnect attempt (after backoff).\n */\n onReconnect?: (options: { attempt: number; cause: unknown }) => void;\n}\n\n/**\n * Exponential backoff with jitter for WebSocket reconnect. Mirrors\n * {@link streamWithRetry} in `utils/stream.ts` (capped at 5s + 1s jitter).\n */\nexport function webSocketReconnectDelayMs(attempt: number): number {\n const baseDelay = Math.min(1000 * 2 ** (attempt - 1), 5000);\n const jitter = Math.random() * 1000;\n return baseDelay + jitter;\n}\n\n/**\n * Transport adapter that speaks the thread-centric protocol over a\n * bidirectional WebSocket. Bound to a `threadId` at construction or later\n * via {@link setThreadId} — the socket connects to\n * `ws://.../threads/:thread_id/stream/events`.\n *\n * On unexpected disconnect the adapter reconnects with exponential\n * backoff (see {@link ProtocolWebSocketTransportOptions.maxReconnectAttempts}).\n * The server replays buffered events on the new socket; the SDK\n * deduplicates by `event_id`. {@link ProtocolWebSocketTransportOptions.onReconnected}\n * runs after each successful reconnect so `ThreadStream` can re-issue\n * `subscription.subscribe` commands.\n */\nexport class ProtocolWebSocketTransportAdapter implements TransportAdapter {\n threadId: string;\n\n private readonly queue = new AsyncQueue<Message>();\n\n private readonly apiUrl: string;\n\n private readonly defaultHeaders?: Record<string, HeaderValue>;\n\n private readonly onRequest?: ProtocolRequestHook;\n\n private readonly webSocketFactory: (url: string) => WebSocket;\n\n private readonly paths?: Pick<ProtocolTransportPaths, \"stream\">;\n\n private readonly maxReconnectAttempts: number;\n\n private readonly onReconnect?: ProtocolWebSocketTransportOptions[\"onReconnect\"];\n\n private readonly reconnectDelayMs: (attempt: number) => number;\n\n private onReconnected?: () => void | Promise<void>;\n\n private readonly pending = new Map<number, PendingResponse>();\n\n private socket: WebSocket | null = null;\n\n private closed = false;\n\n private intentionalClose = false;\n\n private reconnectInFlight: Promise<void> | null = null;\n\n constructor(options: ProtocolWebSocketTransportOptions) {\n this.apiUrl = options.apiUrl;\n this.threadId = options.threadId ?? \"\";\n this.defaultHeaders = options.defaultHeaders;\n this.onRequest = options.onRequest;\n this.webSocketFactory =\n options.webSocketFactory ?? ((url) => new WebSocket(url));\n this.paths = options.paths;\n this.maxReconnectAttempts = options.maxReconnectAttempts ?? 5;\n this.onReconnect = options.onReconnect;\n this.onReconnected = options.onReconnected;\n this.reconnectDelayMs =\n options.reconnectDelayMs ?? webSocketReconnectDelayMs;\n }\n\n /** {@inheritDoc TransportAdapter.setThreadId} */\n setThreadId(threadId: string): void {\n if (threadId === this.threadId) {\n return;\n }\n if (\n this.reconnectInFlight != null ||\n (this.socket != null && this.socket.readyState !== WEB_SOCKET_CLOSED)\n ) {\n throw new Error(\n \"Protocol WebSocket transport cannot be rebound to a different thread while the socket is open. Close the current stream and create a new WebSocket transport for the new thread.\"\n );\n }\n this.threadId = threadId;\n }\n\n /**\n * Socket URL derives from the currently-bound thread so a single adapter\n * can follow {@link setThreadId} re-binds; the next {@link open} connects\n * to the new thread. A fixed `paths.stream` string overrides the default.\n */\n private get streamUrl(): string {\n return resolveProtocolPath(\n this.paths?.stream,\n this.threadId,\n (id) => `/threads/${id}/stream/events`\n );\n }\n\n /**\n * Register a callback invoked after each successful reconnect. Used\n * by {@link ThreadStream} to re-send active `subscription.subscribe`\n * commands.\n */\n setOnReconnected(handler: () => void | Promise<void>): void {\n this.onReconnected = handler;\n }\n\n async open(): Promise<void> {\n if (this.closed) {\n throw new Error(\"Protocol WebSocket transport is closed.\");\n }\n if (this.socket?.readyState === WEB_SOCKET_OPEN) {\n return;\n }\n if (this.socket != null) {\n this.#detachSocket(this.socket);\n this.socket = null;\n }\n\n this.assertBrowserSafeTransportConfig();\n\n const wsUrl = toWebSocketUrl(\n toAbsoluteUrl(this.apiUrl, this.streamUrl).toString()\n );\n const socket = this.webSocketFactory(wsUrl);\n this.socket = socket;\n this.intentionalClose = false;\n\n this.#attachSocket(socket);\n\n await new Promise<void>((resolve, reject) => {\n const onOpen = () => {\n cleanup();\n resolve();\n };\n const onError = () => {\n cleanup();\n reject(new Error(\"Failed to open protocol WebSocket.\"));\n };\n const cleanup = () => {\n socket.removeEventListener(\"open\", onOpen);\n socket.removeEventListener(\"error\", onError);\n };\n socket.addEventListener(\"open\", onOpen, { once: true });\n socket.addEventListener(\"error\", onError, { once: true });\n });\n }\n\n async send(\n command: Command\n ): Promise<CommandResponse | ErrorResponse | void> {\n return await this.sendCommand(command);\n }\n\n events(): AsyncIterable<Message> {\n const queue = this.queue;\n return {\n [Symbol.asyncIterator]: () => ({\n next: async () => await queue.shift(),\n return: async () => {\n queue.close();\n return { done: true, value: undefined };\n },\n }),\n };\n }\n\n async close(): Promise<void> {\n if (this.closed) {\n return;\n }\n\n this.closed = true;\n this.intentionalClose = true;\n\n for (const { reject } of this.pending.values()) {\n reject(new Error(\"Protocol WebSocket connection closed.\"));\n }\n this.pending.clear();\n this.queue.close();\n\n const socket = this.socket;\n this.socket = null;\n if (!socket) {\n return;\n }\n\n this.#detachSocket(socket);\n\n await new Promise<void>((resolve) => {\n if (socket.readyState === WEB_SOCKET_CLOSED) {\n resolve();\n return;\n }\n\n const onClose = () => {\n socket.removeEventListener(\"close\", onClose);\n resolve();\n };\n\n socket.addEventListener(\"close\", onClose, { once: true });\n if (\n socket.readyState === WEB_SOCKET_OPEN ||\n socket.readyState === WEB_SOCKET_CONNECTING\n ) {\n socket.close();\n } else {\n resolve();\n }\n });\n }\n\n private assertBrowserSafeTransportConfig(): void {\n if (hasHeaders(this.defaultHeaders) || this.onRequest != null) {\n throw new Error(\n \"Browser WebSocket protocol transport does not support defaultHeaders or onRequest hooks. Supply a custom protocolWebSocketFactory if you need custom WebSocket setup.\"\n );\n }\n }\n\n private async sendCommand(\n command: Command\n ): Promise<CommandResponse | ErrorResponse> {\n // Wait for an in-flight reconnect only when the socket is not usable.\n // After `open()` succeeds, `#runReconnectLoop` may still be awaiting\n // `onReconnected` (e.g. ThreadStream resubscribe). Those callbacks call\n // `sendCommand` and must not await the same `reconnectInFlight` promise.\n let socket = this.socket;\n if (\n this.reconnectInFlight != null &&\n (socket == null || socket.readyState !== WEB_SOCKET_OPEN)\n ) {\n await this.reconnectInFlight.catch(() => undefined);\n socket = this.socket;\n }\n\n if (socket == null || socket.readyState !== WEB_SOCKET_OPEN) {\n throw new Error(\"Protocol WebSocket is not open.\");\n }\n\n return await new Promise<CommandResponse | ErrorResponse>(\n (resolve, reject) => {\n this.pending.set(command.id, { resolve, reject });\n\n try {\n socket.send(JSON.stringify(command));\n } catch (error) {\n this.pending.delete(command.id);\n reject(toError(error));\n }\n }\n );\n }\n\n #attachSocket(socket: WebSocket): void {\n socket.addEventListener(\"message\", this.handleMessage);\n socket.addEventListener(\"close\", this.handleClose);\n socket.addEventListener(\"error\", this.handleSocketError);\n }\n\n #detachSocket(socket: WebSocket): void {\n socket.removeEventListener(\"message\", this.handleMessage);\n socket.removeEventListener(\"close\", this.handleClose);\n socket.removeEventListener(\"error\", this.handleSocketError);\n }\n\n private readonly handleMessage = (event: MessageEvent): void => {\n let payload: unknown;\n try {\n payload = JSON.parse(String(event.data));\n } catch {\n return;\n }\n\n if (\n isRecord(payload) &&\n typeof payload.id === \"number\" &&\n (payload.type === \"success\" || payload.type === \"error\")\n ) {\n const pending = this.pending.get(payload.id);\n if (pending) {\n this.pending.delete(payload.id);\n pending.resolve(payload as CommandResponse | ErrorResponse);\n }\n return;\n }\n\n if (isRecord(payload) && payload.type === \"event\") {\n this.queue.push(payload as Message);\n }\n };\n\n private readonly handleClose = (): void => {\n const socket = this.socket;\n if (socket != null) {\n this.#detachSocket(socket);\n }\n this.socket = null;\n\n if (this.intentionalClose || this.closed) {\n this.queue.close();\n return;\n }\n\n this.#handleUnexpectedDisconnect(\n new Error(\"Protocol WebSocket closed unexpectedly.\")\n );\n };\n\n private readonly handleSocketError = (): void => {\n if (this.closed || this.intentionalClose) {\n return;\n }\n\n this.#handleUnexpectedDisconnect(\n new Error(\"Protocol WebSocket encountered an error.\")\n );\n };\n\n #handleUnexpectedDisconnect(cause: unknown): void {\n const error = toError(cause);\n for (const { reject } of this.pending.values()) {\n reject(error);\n }\n this.pending.clear();\n\n if (this.maxReconnectAttempts <= 0) {\n this.queue.close(error);\n return;\n }\n\n this.#scheduleReconnect(cause);\n }\n\n #scheduleReconnect(cause: unknown): void {\n if (this.closed || this.intentionalClose) {\n return;\n }\n if (this.reconnectInFlight != null) {\n return;\n }\n\n this.reconnectInFlight = this.#runReconnectLoop(cause).finally(() => {\n this.reconnectInFlight = null;\n });\n }\n\n async #runReconnectLoop(initialCause: unknown): Promise<void> {\n let lastError: unknown = initialCause;\n\n for (let attempt = 1; attempt <= this.maxReconnectAttempts; attempt += 1) {\n if (this.closed || this.intentionalClose) {\n return;\n }\n\n this.onReconnect?.({ attempt, cause: lastError });\n\n const delay = this.reconnectDelayMs(attempt);\n if (delay > 0) {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, delay);\n });\n }\n\n if (this.closed || this.intentionalClose) {\n return;\n }\n\n try {\n await this.open();\n if (this.onReconnected) {\n await this.onReconnected();\n }\n return;\n } catch (error) {\n lastError = error;\n }\n }\n\n this.queue.close(\n new MaxWebSocketReconnectAttemptsError(\n this.maxReconnectAttempts,\n lastError\n )\n );\n }\n}\n"],"mappings":"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"}
{"version":3,"file":"websocket.js","names":["#detachSocket","#attachSocket","#handleUnexpectedDisconnect","#scheduleReconnect","#runReconnectLoop"],"sources":["../../../../src/client/stream/transport/websocket.ts"],"sourcesContent":["import { AsyncQueue } from \"./queue.js\";\nimport type {\n Message,\n Command,\n CommandResponse,\n ErrorResponse,\n} from \"@langchain/protocol\";\n\nimport {\n toAbsoluteUrl,\n toWebSocketUrl,\n isRecord,\n hasHeaders,\n toError,\n resolveProtocolPath,\n} from \"./utils.js\";\nimport type {\n HeaderValue,\n ProtocolRequestHook,\n PendingResponse,\n ProtocolTransportPaths,\n ProtocolWebSocketTransportOptions,\n} from \"./types.js\";\nimport type { TransportAdapter } from \"../transport.js\";\nimport { MaxWebSocketReconnectAttemptsError } from \"../error.js\";\nimport {\n DEFAULT_MAX_RECONNECT_ATTEMPTS,\n reconnectDelayMs,\n} from \"../../../utils/reconnect.js\";\n\nconst WEB_SOCKET_CONNECTING = 0;\nconst WEB_SOCKET_OPEN = 1;\nconst WEB_SOCKET_CLOSED = 3;\n\n/**\n * Reconnect tuning for {@link ProtocolWebSocketTransportAdapter}. A subset\n * of {@link ProtocolWebSocketTransportOptions}.\n */\nexport interface WebSocketReconnectOptions {\n /**\n * Maximum reconnection attempts after an unexpected disconnect.\n * Defaults to {@link DEFAULT_MAX_RECONNECT_ATTEMPTS}.\n */\n maxReconnectAttempts?: number;\n\n /**\n * Invoked before each reconnect attempt (after backoff).\n */\n onReconnect?: (options: { attempt: number; cause: unknown }) => void;\n}\n\n/**\n * Transport adapter that speaks the thread-centric protocol over a\n * bidirectional WebSocket. Bound to a `threadId` at construction or later\n * via {@link setThreadId} — the socket connects to\n * `ws://.../threads/:thread_id/stream/events`.\n *\n * On unexpected disconnect the adapter reconnects with exponential\n * backoff (see {@link ProtocolWebSocketTransportOptions.maxReconnectAttempts}).\n * The server replays buffered events on the new socket; the SDK\n * deduplicates by `event_id`. {@link ProtocolWebSocketTransportOptions.onReconnected}\n * runs after each successful reconnect so `ThreadStream` can re-issue\n * `subscription.subscribe` commands.\n */\nexport class ProtocolWebSocketTransportAdapter implements TransportAdapter {\n threadId: string;\n\n private readonly queue = new AsyncQueue<Message>();\n\n private readonly apiUrl: string;\n\n private readonly defaultHeaders?: Record<string, HeaderValue>;\n\n private readonly onRequest?: ProtocolRequestHook;\n\n private readonly webSocketFactory: (url: string) => WebSocket;\n\n private readonly paths?: Pick<ProtocolTransportPaths, \"stream\">;\n\n private readonly maxReconnectAttempts: number;\n\n private readonly onReconnect?: ProtocolWebSocketTransportOptions[\"onReconnect\"];\n\n private readonly reconnectDelayMs: (attempt: number) => number;\n\n private onReconnected?: () => void | Promise<void>;\n\n private readonly pending = new Map<number, PendingResponse>();\n\n private socket: WebSocket | null = null;\n\n private closed = false;\n\n private intentionalClose = false;\n\n private reconnectInFlight: Promise<void> | null = null;\n\n constructor(options: ProtocolWebSocketTransportOptions) {\n this.apiUrl = options.apiUrl;\n this.threadId = options.threadId ?? \"\";\n this.defaultHeaders = options.defaultHeaders;\n this.onRequest = options.onRequest;\n this.webSocketFactory =\n options.webSocketFactory ?? ((url) => new WebSocket(url));\n this.paths = options.paths;\n this.maxReconnectAttempts =\n options.maxReconnectAttempts ?? DEFAULT_MAX_RECONNECT_ATTEMPTS;\n this.onReconnect = options.onReconnect;\n this.onReconnected = options.onReconnected;\n this.reconnectDelayMs = options.reconnectDelayMs ?? reconnectDelayMs;\n }\n\n /** {@inheritDoc TransportAdapter.setThreadId} */\n setThreadId(threadId: string): void {\n if (threadId === this.threadId) {\n return;\n }\n if (\n this.reconnectInFlight != null ||\n (this.socket != null && this.socket.readyState !== WEB_SOCKET_CLOSED)\n ) {\n throw new Error(\n \"Protocol WebSocket transport cannot be rebound to a different thread while the socket is open. Close the current stream and create a new WebSocket transport for the new thread.\"\n );\n }\n this.threadId = threadId;\n }\n\n /**\n * Socket URL derives from the currently-bound thread so a single adapter\n * can follow {@link setThreadId} re-binds; the next {@link open} connects\n * to the new thread. A fixed `paths.stream` string overrides the default.\n */\n private get streamUrl(): string {\n return resolveProtocolPath(\n this.paths?.stream,\n this.threadId,\n (id) => `/threads/${id}/stream/events`\n );\n }\n\n /**\n * Register a callback invoked after each successful reconnect. Used\n * by {@link ThreadStream} to re-send active `subscription.subscribe`\n * commands.\n */\n setOnReconnected(handler: () => void | Promise<void>): void {\n this.onReconnected = handler;\n }\n\n async open(): Promise<void> {\n if (this.closed) {\n throw new Error(\"Protocol WebSocket transport is closed.\");\n }\n if (this.socket?.readyState === WEB_SOCKET_OPEN) {\n return;\n }\n if (this.socket != null) {\n this.#detachSocket(this.socket);\n this.socket = null;\n }\n\n this.assertBrowserSafeTransportConfig();\n\n const wsUrl = toWebSocketUrl(\n toAbsoluteUrl(this.apiUrl, this.streamUrl).toString()\n );\n const socket = this.webSocketFactory(wsUrl);\n this.socket = socket;\n this.intentionalClose = false;\n\n this.#attachSocket(socket);\n\n await new Promise<void>((resolve, reject) => {\n const onOpen = () => {\n cleanup();\n resolve();\n };\n const onError = () => {\n cleanup();\n reject(new Error(\"Failed to open protocol WebSocket.\"));\n };\n const cleanup = () => {\n socket.removeEventListener(\"open\", onOpen);\n socket.removeEventListener(\"error\", onError);\n };\n socket.addEventListener(\"open\", onOpen, { once: true });\n socket.addEventListener(\"error\", onError, { once: true });\n });\n }\n\n async send(\n command: Command\n ): Promise<CommandResponse | ErrorResponse | void> {\n return await this.sendCommand(command);\n }\n\n events(): AsyncIterable<Message> {\n const queue = this.queue;\n return {\n [Symbol.asyncIterator]: () => ({\n next: async () => await queue.shift(),\n return: async () => {\n queue.close();\n return { done: true, value: undefined };\n },\n }),\n };\n }\n\n async close(): Promise<void> {\n if (this.closed) {\n return;\n }\n\n this.closed = true;\n this.intentionalClose = true;\n\n for (const { reject } of this.pending.values()) {\n reject(new Error(\"Protocol WebSocket connection closed.\"));\n }\n this.pending.clear();\n this.queue.close();\n\n const socket = this.socket;\n this.socket = null;\n if (!socket) {\n return;\n }\n\n this.#detachSocket(socket);\n\n await new Promise<void>((resolve) => {\n if (socket.readyState === WEB_SOCKET_CLOSED) {\n resolve();\n return;\n }\n\n const onClose = () => {\n socket.removeEventListener(\"close\", onClose);\n resolve();\n };\n\n socket.addEventListener(\"close\", onClose, { once: true });\n if (\n socket.readyState === WEB_SOCKET_OPEN ||\n socket.readyState === WEB_SOCKET_CONNECTING\n ) {\n socket.close();\n } else {\n resolve();\n }\n });\n }\n\n private assertBrowserSafeTransportConfig(): void {\n if (hasHeaders(this.defaultHeaders) || this.onRequest != null) {\n throw new Error(\n \"Browser WebSocket protocol transport does not support defaultHeaders or onRequest hooks. Supply a custom protocolWebSocketFactory if you need custom WebSocket setup.\"\n );\n }\n }\n\n private async sendCommand(\n command: Command\n ): Promise<CommandResponse | ErrorResponse> {\n // Wait for an in-flight reconnect only when the socket is not usable.\n // After `open()` succeeds, `#runReconnectLoop` may still be awaiting\n // `onReconnected` (e.g. ThreadStream resubscribe). Those callbacks call\n // `sendCommand` and must not await the same `reconnectInFlight` promise.\n let socket = this.socket;\n if (\n this.reconnectInFlight != null &&\n (socket == null || socket.readyState !== WEB_SOCKET_OPEN)\n ) {\n await this.reconnectInFlight.catch(() => undefined);\n socket = this.socket;\n }\n\n if (socket == null || socket.readyState !== WEB_SOCKET_OPEN) {\n throw new Error(\"Protocol WebSocket is not open.\");\n }\n\n return await new Promise<CommandResponse | ErrorResponse>(\n (resolve, reject) => {\n this.pending.set(command.id, { resolve, reject });\n\n try {\n socket.send(JSON.stringify(command));\n } catch (error) {\n this.pending.delete(command.id);\n reject(toError(error));\n }\n }\n );\n }\n\n #attachSocket(socket: WebSocket): void {\n socket.addEventListener(\"message\", this.handleMessage);\n socket.addEventListener(\"close\", this.handleClose);\n socket.addEventListener(\"error\", this.handleSocketError);\n }\n\n #detachSocket(socket: WebSocket): void {\n socket.removeEventListener(\"message\", this.handleMessage);\n socket.removeEventListener(\"close\", this.handleClose);\n socket.removeEventListener(\"error\", this.handleSocketError);\n }\n\n private readonly handleMessage = (event: MessageEvent): void => {\n let payload: unknown;\n try {\n payload = JSON.parse(String(event.data));\n } catch {\n return;\n }\n\n if (\n isRecord(payload) &&\n typeof payload.id === \"number\" &&\n (payload.type === \"success\" || payload.type === \"error\")\n ) {\n const pending = this.pending.get(payload.id);\n if (pending) {\n this.pending.delete(payload.id);\n pending.resolve(payload as CommandResponse | ErrorResponse);\n }\n return;\n }\n\n if (isRecord(payload) && payload.type === \"event\") {\n this.queue.push(payload as Message);\n }\n };\n\n private readonly handleClose = (): void => {\n const socket = this.socket;\n if (socket != null) {\n this.#detachSocket(socket);\n }\n this.socket = null;\n\n if (this.intentionalClose || this.closed) {\n this.queue.close();\n return;\n }\n\n this.#handleUnexpectedDisconnect(\n new Error(\"Protocol WebSocket closed unexpectedly.\")\n );\n };\n\n private readonly handleSocketError = (): void => {\n if (this.closed || this.intentionalClose) {\n return;\n }\n\n this.#handleUnexpectedDisconnect(\n new Error(\"Protocol WebSocket encountered an error.\")\n );\n };\n\n #handleUnexpectedDisconnect(cause: unknown): void {\n const error = toError(cause);\n for (const { reject } of this.pending.values()) {\n reject(error);\n }\n this.pending.clear();\n\n if (this.maxReconnectAttempts <= 0) {\n this.queue.close(error);\n return;\n }\n\n this.#scheduleReconnect(cause);\n }\n\n #scheduleReconnect(cause: unknown): void {\n if (this.closed || this.intentionalClose) {\n return;\n }\n if (this.reconnectInFlight != null) {\n return;\n }\n\n this.reconnectInFlight = this.#runReconnectLoop(cause).finally(() => {\n this.reconnectInFlight = null;\n });\n }\n\n async #runReconnectLoop(initialCause: unknown): Promise<void> {\n let lastError: unknown = initialCause;\n\n for (let attempt = 1; attempt <= this.maxReconnectAttempts; attempt += 1) {\n if (this.closed || this.intentionalClose) {\n return;\n }\n\n this.onReconnect?.({ attempt, cause: lastError });\n\n const delay = this.reconnectDelayMs(attempt);\n if (delay > 0) {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, delay);\n });\n }\n\n if (this.closed || this.intentionalClose) {\n return;\n }\n\n try {\n await this.open();\n if (this.onReconnected) {\n await this.onReconnected();\n }\n return;\n } catch (error) {\n lastError = error;\n }\n }\n\n this.queue.close(\n new MaxWebSocketReconnectAttemptsError(\n this.maxReconnectAttempts,\n lastError\n )\n );\n }\n}\n"],"mappings":"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"}

@@ -102,3 +102,4 @@ import { IdleReconnectMode } from "../../utils/stream.cjs";

* Built-in `"sse"` / `"websocket"` transports only: max reconnect
* attempts after an unexpected disconnect. Defaults to 5.
* attempts after an unexpected disconnect. Defaults to
* {@link DEFAULT_MAX_RECONNECT_ATTEMPTS}.
*/

@@ -111,8 +112,10 @@ maxReconnectAttempts?: number;

*
* - `"auto"` (default): arm only once the server's SSE keep-alive
* heartbeats are observed (LangGraph Platform emits `: heartbeat` every
* ~5s), sizing the window from their cadence. Independent of agent
* activity; stays dormant on heartbeat-less servers.
* - {@link DEFAULT_IDLE_RECONNECT} (`"auto"`): arm only once the server's
* SSE keep-alive heartbeats are observed (LangGraph Platform emits
* `: heartbeat` every ~5s), sizing the window from their cadence.
* Independent of agent activity; stays dormant on heartbeat-less servers.
* - a `number`: a fixed idle window in milliseconds.
* - `0`: disables it.
*
* @default DEFAULT_IDLE_RECONNECT
*/

@@ -122,3 +125,3 @@ streamIdleReconnect?: IdleReconnectMode;

* Built-in transports only: delay before each reconnect attempt.
* Defaults to exponential backoff with jitter.
* Defaults to {@link reconnectDelayMs}.
*/

@@ -125,0 +128,0 @@ reconnectDelayMs?: (attempt: number) => number;

@@ -1,1 +0,1 @@

{"version":3,"file":"types.d.cts","names":[],"sources":["../../../src/client/stream/types.ts"],"mappings":"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"}
{"version":3,"file":"types.d.cts","names":[],"sources":["../../../src/client/stream/types.ts"],"mappings":"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"}

@@ -102,3 +102,4 @@ import { IdleReconnectMode } from "../../utils/stream.js";

* Built-in `"sse"` / `"websocket"` transports only: max reconnect
* attempts after an unexpected disconnect. Defaults to 5.
* attempts after an unexpected disconnect. Defaults to
* {@link DEFAULT_MAX_RECONNECT_ATTEMPTS}.
*/

@@ -111,8 +112,10 @@ maxReconnectAttempts?: number;

*
* - `"auto"` (default): arm only once the server's SSE keep-alive
* heartbeats are observed (LangGraph Platform emits `: heartbeat` every
* ~5s), sizing the window from their cadence. Independent of agent
* activity; stays dormant on heartbeat-less servers.
* - {@link DEFAULT_IDLE_RECONNECT} (`"auto"`): arm only once the server's
* SSE keep-alive heartbeats are observed (LangGraph Platform emits
* `: heartbeat` every ~5s), sizing the window from their cadence.
* Independent of agent activity; stays dormant on heartbeat-less servers.
* - a `number`: a fixed idle window in milliseconds.
* - `0`: disables it.
*
* @default DEFAULT_IDLE_RECONNECT
*/

@@ -122,3 +125,3 @@ streamIdleReconnect?: IdleReconnectMode;

* Built-in transports only: delay before each reconnect attempt.
* Defaults to exponential backoff with jitter.
* Defaults to {@link reconnectDelayMs}.
*/

@@ -125,0 +128,0 @@ reconnectDelayMs?: (attempt: number) => number;

@@ -1,1 +0,1 @@

{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/client/stream/types.ts"],"mappings":"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"}
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/client/stream/types.ts"],"mappings":"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"}
require("../../_virtual/_rolldown/runtime.cjs");
const require_base = require("../base.cjs");
const require_index = require("../stream/index.cjs");
const require_http = require("../stream/transport/http.cjs");
const require_websocket = require("../stream/transport/websocket.cjs");
const require_http = require("../stream/transport/http.cjs");
let _langchain_core_utils_uuid = require("@langchain/core/utils/uuid");

@@ -7,0 +7,0 @@ //#region src/client/threads/index.ts

@@ -1,1 +0,1 @@

{"version":3,"file":"index.cjs","names":["BaseClient","ProtocolWebSocketTransportAdapter","ProtocolSseTransportAdapter","ThreadStream"],"sources":["../../../src/client/threads/index.ts"],"sourcesContent":["import { v7 as uuidv7 } from \"@langchain/core/utils/uuid\";\n\nimport {\n Checkpoint,\n Config,\n DefaultValues,\n Metadata,\n SortOrder,\n Thread,\n ThreadSelectField,\n ThreadSortBy,\n ThreadState,\n ThreadStatus,\n ThreadValuesFilter,\n} from \"../../schema.js\";\nimport type { Command, OnConflictBehavior, StreamEvent } from \"../../types.js\";\nimport type { ThreadStreamMode } from \"../../types.stream.js\";\nimport { BaseClient } from \"../base.js\";\nimport { ThreadStream } from \"../stream/index.js\";\nimport type {\n ThreadStreamOptions,\n ThreadStreamTransportKind,\n} from \"../stream/types.js\";\nimport { ProtocolSseTransportAdapter } from \"../stream/transport/http.js\";\nimport { ProtocolWebSocketTransportAdapter } from \"../stream/transport/websocket.js\";\nimport type { TransportAdapter } from \"../stream/transport.js\";\n\nexport class ThreadsClient<\n TStateType = DefaultValues,\n TUpdateType = TStateType,\n> extends BaseClient {\n /**\n * Get a thread by ID.\n *\n * @param threadId ID of the thread.\n * @returns The thread.\n */\n async get<ValuesType = TStateType>(\n threadId: string,\n options?: { signal?: AbortSignal; include?: string[] }\n ): Promise<Thread<ValuesType>> {\n return this.fetch<Thread<ValuesType>>(`/threads/${threadId}`, {\n params: {\n include: options?.include ?? undefined,\n },\n signal: options?.signal,\n });\n }\n\n /**\n * Create a new thread.\n *\n * @param payload Payload for creating a thread.\n * @returns The created thread.\n */\n async create(payload?: {\n metadata?: Metadata;\n threadId?: string;\n ifExists?: OnConflictBehavior;\n graphId?: string;\n supersteps?: Array<{\n updates: Array<{ values: unknown; command?: Command; asNode: string }>;\n }>;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n signal?: AbortSignal;\n }): Promise<Thread<TStateType>> {\n const ttlPayload =\n typeof payload?.ttl === \"number\"\n ? { ttl: payload.ttl, strategy: \"delete\" as const }\n : payload?.ttl;\n\n return this.fetch<Thread<TStateType>>(`/threads`, {\n method: \"POST\",\n json: {\n metadata: {\n ...payload?.metadata,\n graph_id: payload?.graphId,\n },\n thread_id: payload?.threadId,\n if_exists: payload?.ifExists,\n supersteps: payload?.supersteps?.map((s) => ({\n updates: s.updates.map((u) => ({\n values: u.values,\n command: u.command,\n as_node: u.asNode,\n })),\n })),\n ttl: ttlPayload,\n },\n signal: payload?.signal,\n });\n }\n\n /**\n * Copy an existing thread\n * @param threadId ID of the thread to be copied\n * @returns Newly copied thread\n */\n async copy(\n threadId: string,\n options?: { signal?: AbortSignal }\n ): Promise<Thread<TStateType>> {\n return this.fetch<Thread<TStateType>>(`/threads/${threadId}/copy`, {\n method: \"POST\",\n signal: options?.signal,\n });\n }\n\n /**\n * Update a thread.\n *\n * @param threadId ID of the thread.\n * @param payload Payload for updating the thread.\n * @returns The updated thread.\n */\n async update(\n threadId: string,\n payload?: {\n metadata?: Metadata;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n returnMinimal?: false;\n signal?: AbortSignal;\n }\n ): Promise<Thread>;\n async update(\n threadId: string,\n payload: {\n metadata?: Metadata;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n returnMinimal: true;\n signal?: AbortSignal;\n }\n ): Promise<void>;\n async update(\n threadId: string,\n payload: {\n metadata?: Metadata;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n returnMinimal: boolean;\n signal?: AbortSignal;\n }\n ): Promise<Thread | void>;\n async update(\n threadId: string,\n payload?: {\n metadata?: Metadata;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n returnMinimal?: boolean;\n signal?: AbortSignal;\n }\n ): Promise<Thread | void> {\n const ttlPayload =\n typeof payload?.ttl === \"number\"\n ? { ttl: payload.ttl, strategy: \"delete\" as const }\n : payload?.ttl;\n\n return this.fetch<Thread | void>(`/threads/${threadId}`, {\n method: \"PATCH\",\n headers: payload?.returnMinimal\n ? { Prefer: \"return=minimal\" }\n : undefined,\n json: { metadata: payload?.metadata, ttl: ttlPayload },\n signal: payload?.signal,\n });\n }\n\n /**\n * Delete a thread.\n *\n * @param threadId ID of the thread.\n */\n async delete(\n threadId: string,\n options?: { signal?: AbortSignal }\n ): Promise<void> {\n return this.fetch<void>(`/threads/${threadId}`, {\n method: \"DELETE\",\n signal: options?.signal,\n });\n }\n\n /**\n * Prune threads by ID. The 'delete' strategy removes threads entirely.\n * The 'keep_latest' strategy prunes old checkpoints but keeps threads\n * and their latest state.\n *\n * @param threadIds List of thread IDs to prune.\n * @param options Additional options for pruning.\n * @param options.strategy The prune strategy. Defaults to 'delete'.\n * @param options.signal Signal to abort the request.\n * @returns An object containing `pruned_count`.\n */\n async prune(\n threadIds: string[],\n options?: {\n strategy?: \"delete\" | \"keep_latest\";\n signal?: AbortSignal;\n }\n ): Promise<{ pruned_count: number }> {\n return this.fetch<{ pruned_count: number }>(\"/threads/prune\", {\n method: \"POST\",\n json: {\n thread_ids: threadIds,\n strategy: options?.strategy ?? \"delete\",\n },\n signal: options?.signal,\n });\n }\n\n /**\n * List threads\n *\n * @param query Query options\n * @returns List of threads\n */\n async search<ValuesType = TStateType>(query?: {\n metadata?: Metadata;\n ids?: string[];\n limit?: number;\n offset?: number;\n status?: ThreadStatus;\n sortBy?: ThreadSortBy;\n sortOrder?: SortOrder;\n select?: ThreadSelectField[];\n values?: ThreadValuesFilter;\n extract?: Record<string, string>;\n signal?: AbortSignal;\n }): Promise<Thread<ValuesType>[]> {\n return this.fetch<Thread<ValuesType>[]>(\"/threads/search\", {\n method: \"POST\",\n json: {\n metadata: query?.metadata ?? undefined,\n ids: query?.ids ?? undefined,\n limit: query?.limit ?? 10,\n offset: query?.offset ?? 0,\n status: query?.status,\n sort_by: query?.sortBy,\n sort_order: query?.sortOrder,\n select: query?.select ?? undefined,\n values: query?.values ?? undefined,\n extract: query?.extract ?? undefined,\n },\n signal: query?.signal,\n });\n }\n\n /**\n * Count threads matching filters.\n *\n * @param query.metadata Thread metadata to filter on.\n * @param query.values State values to filter on.\n * @param query.status Thread status to filter on.\n * @returns Number of threads matching the criteria.\n */\n async count<ValuesType = TStateType>(query?: {\n metadata?: Metadata;\n values?: ValuesType;\n status?: ThreadStatus;\n signal?: AbortSignal;\n }): Promise<number> {\n return this.fetch<number>(`/threads/count`, {\n method: \"POST\",\n json: {\n metadata: query?.metadata ?? undefined,\n values: query?.values ?? undefined,\n status: query?.status ?? undefined,\n },\n signal: query?.signal,\n });\n }\n\n /**\n * Get state for a thread.\n *\n * @param threadId ID of the thread.\n * @returns Thread state.\n */\n async getState<ValuesType = TStateType>(\n threadId: string,\n checkpoint?: Checkpoint | string,\n options?: { subgraphs?: boolean; signal?: AbortSignal }\n ): Promise<ThreadState<ValuesType>> {\n if (checkpoint != null) {\n if (typeof checkpoint !== \"string\") {\n return this.fetch<ThreadState<ValuesType>>(\n `/threads/${threadId}/state/checkpoint`,\n {\n method: \"POST\",\n json: { checkpoint, subgraphs: options?.subgraphs },\n signal: options?.signal,\n }\n );\n }\n\n // deprecated\n return this.fetch<ThreadState<ValuesType>>(\n `/threads/${threadId}/state/${checkpoint}`,\n { params: { subgraphs: options?.subgraphs }, signal: options?.signal }\n );\n }\n\n return this.fetch<ThreadState<ValuesType>>(`/threads/${threadId}/state`, {\n params: { subgraphs: options?.subgraphs },\n signal: options?.signal,\n // Coalesce concurrent identical reads (e.g. two controllers\n // hydrating the same thread on reconnect). Skipped automatically\n // when a caller supplies its own `signal`.\n dedupe: true,\n });\n }\n\n /**\n * Add state to a thread.\n *\n * @param threadId The ID of the thread.\n * @returns\n */\n async updateState<ValuesType = TUpdateType>(\n threadId: string,\n options: {\n values: ValuesType;\n checkpoint?: Checkpoint;\n checkpointId?: string;\n asNode?: string;\n signal?: AbortSignal;\n }\n ): Promise<Pick<Config, \"configurable\">> {\n return this.fetch<Pick<Config, \"configurable\">>(\n `/threads/${threadId}/state`,\n {\n method: \"POST\",\n json: {\n values: options.values,\n checkpoint: options.checkpoint,\n checkpoint_id: options.checkpointId,\n as_node: options?.asNode,\n },\n signal: options?.signal,\n }\n );\n }\n\n /**\n * Patch the metadata of a thread.\n *\n * @param threadIdOrConfig Thread ID or config to patch the state of.\n * @param metadata Metadata to patch the state with.\n */\n async patchState(\n threadIdOrConfig: string | Config,\n metadata: Metadata,\n options?: { signal?: AbortSignal }\n ): Promise<void> {\n let threadId: string;\n\n if (typeof threadIdOrConfig !== \"string\") {\n if (typeof threadIdOrConfig.configurable?.thread_id !== \"string\") {\n throw new Error(\n \"Thread ID is required when updating state with a config.\"\n );\n }\n threadId = threadIdOrConfig.configurable.thread_id;\n } else {\n threadId = threadIdOrConfig;\n }\n\n return this.fetch<void>(`/threads/${threadId}/state`, {\n method: \"PATCH\",\n json: { metadata },\n signal: options?.signal,\n });\n }\n\n /**\n * Get all past states for a thread.\n *\n * @param threadId ID of the thread.\n * @param options Additional options.\n * @returns List of thread states.\n */\n async getHistory<ValuesType = TStateType>(\n threadId: string,\n options?: {\n limit?: number;\n before?: Config;\n checkpoint?: Partial<Omit<Checkpoint, \"thread_id\">>;\n metadata?: Metadata;\n signal?: AbortSignal;\n }\n ): Promise<ThreadState<ValuesType>[]> {\n return this.fetch<ThreadState<ValuesType>[]>(\n `/threads/${threadId}/history`,\n {\n method: \"POST\",\n json: {\n limit: options?.limit ?? 10,\n before: options?.before,\n metadata: options?.metadata,\n checkpoint: options?.checkpoint,\n },\n signal: options?.signal,\n // `getHistory` is a read despite using POST — coalesce the\n // hydrate-time discovery seed when two controllers reconnect to\n // the same thread concurrently. Skipped when `signal` is set.\n dedupe: true,\n }\n );\n }\n\n async *joinStream(\n threadId: string,\n options?: {\n lastEventId?: string;\n streamMode?: ThreadStreamMode | ThreadStreamMode[];\n signal?: AbortSignal;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): AsyncGenerator<{ id?: string; event: StreamEvent; data: any }> {\n yield* this.streamWithRetry({\n endpoint: `/threads/${threadId}/stream`,\n method: \"GET\",\n signal: options?.signal,\n headers: options?.lastEventId\n ? { \"Last-Event-ID\": options.lastEventId }\n : undefined,\n params: options?.streamMode\n ? { stream_mode: options.streamMode }\n : undefined,\n });\n }\n\n /**\n * Open a protocol stream over the thread-centric v2 protocol.\n *\n * Returns a {@link ThreadStream} with lazy getters\n * (`.messages`, `.values`, `.toolCalls`, `.subgraphs`, `.subagents`,\n * `.output`) and `thread.run.start({ input, ... })` for starting runs.\n * Mirrors the in-process `graph.streamEvents(..., { version: \"v3\" })` API.\n *\n * The thread is bound to `options.assistantId` for its lifetime.\n * The wire transport defaults to SSE; pass `transport: \"websocket\"`\n * in options (or configure `streamProtocol: \"v2-websocket\"` on the\n * client) to use a WebSocket instead.\n *\n * @example New thread (UUID generated client-side)\n * ```ts\n * const thread = client.threads.stream({ assistantId: \"my-agent\" });\n * ```\n *\n * @example Attach to an existing thread\n * ```ts\n * const thread = client.threads.stream(threadId, { assistantId: \"my-agent\" });\n * ```\n *\n * @example WebSocket transport\n * ```ts\n * const thread = client.threads.stream({\n * assistantId: \"my-agent\",\n * transport: \"websocket\",\n * });\n * ```\n */\n stream<TExtensions extends Record<string, unknown> = Record<string, unknown>>(\n options: ThreadStreamOptions\n ): ThreadStream<TExtensions>;\n stream<TExtensions extends Record<string, unknown> = Record<string, unknown>>(\n threadId: string,\n options: ThreadStreamOptions\n ): ThreadStream<TExtensions>;\n stream<TExtensions extends Record<string, unknown> = Record<string, unknown>>(\n threadIdOrOptions: string | ThreadStreamOptions,\n maybeOptions?: ThreadStreamOptions\n ): ThreadStream<TExtensions> {\n const { threadId, options } =\n typeof threadIdOrOptions === \"string\"\n ? {\n threadId: threadIdOrOptions,\n options: maybeOptions as ThreadStreamOptions,\n }\n : { threadId: uuidv7(), options: threadIdOrOptions };\n\n // `transport` accepts either a preset string (`\"sse\"` / `\"websocket\"`)\n // or a custom {@link AgentServerAdapter}. A custom adapter replaces\n // the built-in factories entirely — this is the seam that lets users\n // point `useStream` at any agent server (including the thin wrappers\n // produced by `HttpAgentServerAdapter`).\n // When callers supply `fetch`, use it verbatim (tests, auth shims). Otherwise\n // route protocol HTTP and media URL fetches through AsyncCaller like REST.\n const userFetch = options.fetch;\n const protocolFetch =\n userFetch ?? this.asyncCaller.fetch.bind(this.asyncCaller);\n\n let transport: TransportAdapter;\n if (options.transport != null && typeof options.transport !== \"string\") {\n transport = options.transport;\n // Bind (or re-bind) the caller-supplied adapter to this thread so a\n // single instance can follow lazy creation (the first `submit()` on a\n // `threadId: null` controller mints the id here) and thread switches.\n // No-op for adapters that bake `threadId` at construction.\n transport.setThreadId?.(threadId);\n } else {\n const transportKind: ThreadStreamTransportKind =\n options.transport ??\n (this.streamProtocol === \"v2-websocket\" ? \"websocket\" : \"sse\");\n const maxReconnectAttempts = options.maxReconnectAttempts ?? 5;\n\n /**\n * Common options for both transports.\n */\n const commonOpts = {\n apiUrl: this.apiUrl,\n threadId,\n defaultHeaders: this.defaultHeaders,\n onRequest: this.onRequest,\n maxReconnectAttempts,\n reconnectDelayMs: options.reconnectDelayMs,\n onReconnect: options.onReconnect,\n };\n\n transport =\n transportKind === \"websocket\"\n ? new ProtocolWebSocketTransportAdapter({\n ...commonOpts,\n webSocketFactory: options.webSocketFactory,\n })\n : new ProtocolSseTransportAdapter({\n ...commonOpts,\n idleReconnect: options.streamIdleReconnect,\n fetch: userFetch,\n asyncCaller: userFetch ? undefined : this.asyncCaller,\n });\n }\n\n return new ThreadStream<TExtensions>(transport, {\n ...options,\n fetch: protocolFetch,\n });\n }\n}\n"],"mappings":"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"}
{"version":3,"file":"index.cjs","names":["BaseClient","ProtocolWebSocketTransportAdapter","ProtocolSseTransportAdapter","ThreadStream"],"sources":["../../../src/client/threads/index.ts"],"sourcesContent":["import { v7 as uuidv7 } from \"@langchain/core/utils/uuid\";\n\nimport {\n Checkpoint,\n Config,\n DefaultValues,\n Metadata,\n SortOrder,\n Thread,\n ThreadSelectField,\n ThreadSortBy,\n ThreadState,\n ThreadStatus,\n ThreadValuesFilter,\n} from \"../../schema.js\";\nimport type { Command, OnConflictBehavior, StreamEvent } from \"../../types.js\";\nimport type { ThreadStreamMode } from \"../../types.stream.js\";\nimport { BaseClient } from \"../base.js\";\nimport { ThreadStream } from \"../stream/index.js\";\nimport type {\n ThreadStreamOptions,\n ThreadStreamTransportKind,\n} from \"../stream/types.js\";\nimport { DEFAULT_MAX_RECONNECT_ATTEMPTS } from \"../../utils/reconnect.js\";\nimport { ProtocolSseTransportAdapter } from \"../stream/transport/http.js\";\nimport { ProtocolWebSocketTransportAdapter } from \"../stream/transport/websocket.js\";\nimport type { TransportAdapter } from \"../stream/transport.js\";\n\nexport class ThreadsClient<\n TStateType = DefaultValues,\n TUpdateType = TStateType,\n> extends BaseClient {\n /**\n * Get a thread by ID.\n *\n * @param threadId ID of the thread.\n * @returns The thread.\n */\n async get<ValuesType = TStateType>(\n threadId: string,\n options?: { signal?: AbortSignal; include?: string[] }\n ): Promise<Thread<ValuesType>> {\n return this.fetch<Thread<ValuesType>>(`/threads/${threadId}`, {\n params: {\n include: options?.include ?? undefined,\n },\n signal: options?.signal,\n });\n }\n\n /**\n * Create a new thread.\n *\n * @param payload Payload for creating a thread.\n * @returns The created thread.\n */\n async create(payload?: {\n metadata?: Metadata;\n threadId?: string;\n ifExists?: OnConflictBehavior;\n graphId?: string;\n supersteps?: Array<{\n updates: Array<{ values: unknown; command?: Command; asNode: string }>;\n }>;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n signal?: AbortSignal;\n }): Promise<Thread<TStateType>> {\n const ttlPayload =\n typeof payload?.ttl === \"number\"\n ? { ttl: payload.ttl, strategy: \"delete\" as const }\n : payload?.ttl;\n\n return this.fetch<Thread<TStateType>>(`/threads`, {\n method: \"POST\",\n json: {\n metadata: {\n ...payload?.metadata,\n graph_id: payload?.graphId,\n },\n thread_id: payload?.threadId,\n if_exists: payload?.ifExists,\n supersteps: payload?.supersteps?.map((s) => ({\n updates: s.updates.map((u) => ({\n values: u.values,\n command: u.command,\n as_node: u.asNode,\n })),\n })),\n ttl: ttlPayload,\n },\n signal: payload?.signal,\n });\n }\n\n /**\n * Copy an existing thread\n * @param threadId ID of the thread to be copied\n * @returns Newly copied thread\n */\n async copy(\n threadId: string,\n options?: { signal?: AbortSignal }\n ): Promise<Thread<TStateType>> {\n return this.fetch<Thread<TStateType>>(`/threads/${threadId}/copy`, {\n method: \"POST\",\n signal: options?.signal,\n });\n }\n\n /**\n * Update a thread.\n *\n * @param threadId ID of the thread.\n * @param payload Payload for updating the thread.\n * @returns The updated thread.\n */\n async update(\n threadId: string,\n payload?: {\n metadata?: Metadata;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n returnMinimal?: false;\n signal?: AbortSignal;\n }\n ): Promise<Thread>;\n async update(\n threadId: string,\n payload: {\n metadata?: Metadata;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n returnMinimal: true;\n signal?: AbortSignal;\n }\n ): Promise<void>;\n async update(\n threadId: string,\n payload: {\n metadata?: Metadata;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n returnMinimal: boolean;\n signal?: AbortSignal;\n }\n ): Promise<Thread | void>;\n async update(\n threadId: string,\n payload?: {\n metadata?: Metadata;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n returnMinimal?: boolean;\n signal?: AbortSignal;\n }\n ): Promise<Thread | void> {\n const ttlPayload =\n typeof payload?.ttl === \"number\"\n ? { ttl: payload.ttl, strategy: \"delete\" as const }\n : payload?.ttl;\n\n return this.fetch<Thread | void>(`/threads/${threadId}`, {\n method: \"PATCH\",\n headers: payload?.returnMinimal\n ? { Prefer: \"return=minimal\" }\n : undefined,\n json: { metadata: payload?.metadata, ttl: ttlPayload },\n signal: payload?.signal,\n });\n }\n\n /**\n * Delete a thread.\n *\n * @param threadId ID of the thread.\n */\n async delete(\n threadId: string,\n options?: { signal?: AbortSignal }\n ): Promise<void> {\n return this.fetch<void>(`/threads/${threadId}`, {\n method: \"DELETE\",\n signal: options?.signal,\n });\n }\n\n /**\n * Prune threads by ID. The 'delete' strategy removes threads entirely.\n * The 'keep_latest' strategy prunes old checkpoints but keeps threads\n * and their latest state.\n *\n * @param threadIds List of thread IDs to prune.\n * @param options Additional options for pruning.\n * @param options.strategy The prune strategy. Defaults to 'delete'.\n * @param options.signal Signal to abort the request.\n * @returns An object containing `pruned_count`.\n */\n async prune(\n threadIds: string[],\n options?: {\n strategy?: \"delete\" | \"keep_latest\";\n signal?: AbortSignal;\n }\n ): Promise<{ pruned_count: number }> {\n return this.fetch<{ pruned_count: number }>(\"/threads/prune\", {\n method: \"POST\",\n json: {\n thread_ids: threadIds,\n strategy: options?.strategy ?? \"delete\",\n },\n signal: options?.signal,\n });\n }\n\n /**\n * List threads\n *\n * @param query Query options\n * @returns List of threads\n */\n async search<ValuesType = TStateType>(query?: {\n metadata?: Metadata;\n ids?: string[];\n limit?: number;\n offset?: number;\n status?: ThreadStatus;\n sortBy?: ThreadSortBy;\n sortOrder?: SortOrder;\n select?: ThreadSelectField[];\n values?: ThreadValuesFilter;\n extract?: Record<string, string>;\n signal?: AbortSignal;\n }): Promise<Thread<ValuesType>[]> {\n return this.fetch<Thread<ValuesType>[]>(\"/threads/search\", {\n method: \"POST\",\n json: {\n metadata: query?.metadata ?? undefined,\n ids: query?.ids ?? undefined,\n limit: query?.limit ?? 10,\n offset: query?.offset ?? 0,\n status: query?.status,\n sort_by: query?.sortBy,\n sort_order: query?.sortOrder,\n select: query?.select ?? undefined,\n values: query?.values ?? undefined,\n extract: query?.extract ?? undefined,\n },\n signal: query?.signal,\n });\n }\n\n /**\n * Count threads matching filters.\n *\n * @param query.metadata Thread metadata to filter on.\n * @param query.values State values to filter on.\n * @param query.status Thread status to filter on.\n * @returns Number of threads matching the criteria.\n */\n async count<ValuesType = TStateType>(query?: {\n metadata?: Metadata;\n values?: ValuesType;\n status?: ThreadStatus;\n signal?: AbortSignal;\n }): Promise<number> {\n return this.fetch<number>(`/threads/count`, {\n method: \"POST\",\n json: {\n metadata: query?.metadata ?? undefined,\n values: query?.values ?? undefined,\n status: query?.status ?? undefined,\n },\n signal: query?.signal,\n });\n }\n\n /**\n * Get state for a thread.\n *\n * @param threadId ID of the thread.\n * @returns Thread state.\n */\n async getState<ValuesType = TStateType>(\n threadId: string,\n checkpoint?: Checkpoint | string,\n options?: { subgraphs?: boolean; signal?: AbortSignal }\n ): Promise<ThreadState<ValuesType>> {\n if (checkpoint != null) {\n if (typeof checkpoint !== \"string\") {\n return this.fetch<ThreadState<ValuesType>>(\n `/threads/${threadId}/state/checkpoint`,\n {\n method: \"POST\",\n json: { checkpoint, subgraphs: options?.subgraphs },\n signal: options?.signal,\n }\n );\n }\n\n // deprecated\n return this.fetch<ThreadState<ValuesType>>(\n `/threads/${threadId}/state/${checkpoint}`,\n { params: { subgraphs: options?.subgraphs }, signal: options?.signal }\n );\n }\n\n return this.fetch<ThreadState<ValuesType>>(`/threads/${threadId}/state`, {\n params: { subgraphs: options?.subgraphs },\n signal: options?.signal,\n // Coalesce concurrent identical reads (e.g. two controllers\n // hydrating the same thread on reconnect). Skipped automatically\n // when a caller supplies its own `signal`.\n dedupe: true,\n });\n }\n\n /**\n * Add state to a thread.\n *\n * @param threadId The ID of the thread.\n * @returns\n */\n async updateState<ValuesType = TUpdateType>(\n threadId: string,\n options: {\n values: ValuesType;\n checkpoint?: Checkpoint;\n checkpointId?: string;\n asNode?: string;\n signal?: AbortSignal;\n }\n ): Promise<Pick<Config, \"configurable\">> {\n return this.fetch<Pick<Config, \"configurable\">>(\n `/threads/${threadId}/state`,\n {\n method: \"POST\",\n json: {\n values: options.values,\n checkpoint: options.checkpoint,\n checkpoint_id: options.checkpointId,\n as_node: options?.asNode,\n },\n signal: options?.signal,\n }\n );\n }\n\n /**\n * Patch the metadata of a thread.\n *\n * @param threadIdOrConfig Thread ID or config to patch the state of.\n * @param metadata Metadata to patch the state with.\n */\n async patchState(\n threadIdOrConfig: string | Config,\n metadata: Metadata,\n options?: { signal?: AbortSignal }\n ): Promise<void> {\n let threadId: string;\n\n if (typeof threadIdOrConfig !== \"string\") {\n if (typeof threadIdOrConfig.configurable?.thread_id !== \"string\") {\n throw new Error(\n \"Thread ID is required when updating state with a config.\"\n );\n }\n threadId = threadIdOrConfig.configurable.thread_id;\n } else {\n threadId = threadIdOrConfig;\n }\n\n return this.fetch<void>(`/threads/${threadId}/state`, {\n method: \"PATCH\",\n json: { metadata },\n signal: options?.signal,\n });\n }\n\n /**\n * Get all past states for a thread.\n *\n * @param threadId ID of the thread.\n * @param options Additional options.\n * @returns List of thread states.\n */\n async getHistory<ValuesType = TStateType>(\n threadId: string,\n options?: {\n limit?: number;\n before?: Config;\n checkpoint?: Partial<Omit<Checkpoint, \"thread_id\">>;\n metadata?: Metadata;\n signal?: AbortSignal;\n }\n ): Promise<ThreadState<ValuesType>[]> {\n return this.fetch<ThreadState<ValuesType>[]>(\n `/threads/${threadId}/history`,\n {\n method: \"POST\",\n json: {\n limit: options?.limit ?? 10,\n before: options?.before,\n metadata: options?.metadata,\n checkpoint: options?.checkpoint,\n },\n signal: options?.signal,\n // `getHistory` is a read despite using POST — coalesce the\n // hydrate-time discovery seed when two controllers reconnect to\n // the same thread concurrently. Skipped when `signal` is set.\n dedupe: true,\n }\n );\n }\n\n async *joinStream(\n threadId: string,\n options?: {\n lastEventId?: string;\n streamMode?: ThreadStreamMode | ThreadStreamMode[];\n signal?: AbortSignal;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): AsyncGenerator<{ id?: string; event: StreamEvent; data: any }> {\n yield* this.streamWithRetry({\n endpoint: `/threads/${threadId}/stream`,\n method: \"GET\",\n signal: options?.signal,\n headers: options?.lastEventId\n ? { \"Last-Event-ID\": options.lastEventId }\n : undefined,\n params: options?.streamMode\n ? { stream_mode: options.streamMode }\n : undefined,\n });\n }\n\n /**\n * Open a protocol stream over the thread-centric v2 protocol.\n *\n * Returns a {@link ThreadStream} with lazy getters\n * (`.messages`, `.values`, `.toolCalls`, `.subgraphs`, `.subagents`,\n * `.output`) and `thread.run.start({ input, ... })` for starting runs.\n * Mirrors the in-process `graph.streamEvents(..., { version: \"v3\" })` API.\n *\n * The thread is bound to `options.assistantId` for its lifetime.\n * The wire transport defaults to SSE; pass `transport: \"websocket\"`\n * in options (or configure `streamProtocol: \"v2-websocket\"` on the\n * client) to use a WebSocket instead.\n *\n * @example New thread (UUID generated client-side)\n * ```ts\n * const thread = client.threads.stream({ assistantId: \"my-agent\" });\n * ```\n *\n * @example Attach to an existing thread\n * ```ts\n * const thread = client.threads.stream(threadId, { assistantId: \"my-agent\" });\n * ```\n *\n * @example WebSocket transport\n * ```ts\n * const thread = client.threads.stream({\n * assistantId: \"my-agent\",\n * transport: \"websocket\",\n * });\n * ```\n */\n stream<TExtensions extends Record<string, unknown> = Record<string, unknown>>(\n options: ThreadStreamOptions\n ): ThreadStream<TExtensions>;\n stream<TExtensions extends Record<string, unknown> = Record<string, unknown>>(\n threadId: string,\n options: ThreadStreamOptions\n ): ThreadStream<TExtensions>;\n stream<TExtensions extends Record<string, unknown> = Record<string, unknown>>(\n threadIdOrOptions: string | ThreadStreamOptions,\n maybeOptions?: ThreadStreamOptions\n ): ThreadStream<TExtensions> {\n const { threadId, options } =\n typeof threadIdOrOptions === \"string\"\n ? {\n threadId: threadIdOrOptions,\n options: maybeOptions as ThreadStreamOptions,\n }\n : { threadId: uuidv7(), options: threadIdOrOptions };\n\n // `transport` accepts either a preset string (`\"sse\"` / `\"websocket\"`)\n // or a custom {@link AgentServerAdapter}. A custom adapter replaces\n // the built-in factories entirely — this is the seam that lets users\n // point `useStream` at any agent server (including the thin wrappers\n // produced by `HttpAgentServerAdapter`).\n // When callers supply `fetch`, use it verbatim (tests, auth shims). Otherwise\n // route protocol HTTP and media URL fetches through AsyncCaller like REST.\n const userFetch = options.fetch;\n const protocolFetch =\n userFetch ?? this.asyncCaller.fetch.bind(this.asyncCaller);\n\n let transport: TransportAdapter;\n if (options.transport != null && typeof options.transport !== \"string\") {\n transport = options.transport;\n // Bind (or re-bind) the caller-supplied adapter to this thread so a\n // single instance can follow lazy creation (the first `submit()` on a\n // `threadId: null` controller mints the id here) and thread switches.\n // No-op for adapters that bake `threadId` at construction.\n transport.setThreadId?.(threadId);\n } else {\n const transportKind: ThreadStreamTransportKind =\n options.transport ??\n (this.streamProtocol === \"v2-websocket\" ? \"websocket\" : \"sse\");\n const maxReconnectAttempts =\n options.maxReconnectAttempts ?? DEFAULT_MAX_RECONNECT_ATTEMPTS;\n\n /**\n * Common options for both transports.\n */\n const commonOpts = {\n apiUrl: this.apiUrl,\n threadId,\n defaultHeaders: this.defaultHeaders,\n onRequest: this.onRequest,\n maxReconnectAttempts,\n reconnectDelayMs: options.reconnectDelayMs,\n onReconnect: options.onReconnect,\n };\n\n transport =\n transportKind === \"websocket\"\n ? new ProtocolWebSocketTransportAdapter({\n ...commonOpts,\n webSocketFactory: options.webSocketFactory,\n })\n : new ProtocolSseTransportAdapter({\n ...commonOpts,\n idleReconnect: options.streamIdleReconnect,\n fetch: userFetch,\n asyncCaller: userFetch ? undefined : this.asyncCaller,\n });\n }\n\n return new ThreadStream<TExtensions>(transport, {\n ...options,\n fetch: protocolFetch,\n });\n }\n}\n"],"mappings":"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"}

@@ -1,1 +0,1 @@

{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/client/threads/index.ts"],"mappings":"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"}
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/client/threads/index.ts"],"mappings":"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"}

@@ -1,1 +0,1 @@

{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/client/threads/index.ts"],"mappings":"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"}
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/client/threads/index.ts"],"mappings":"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"}
import { BaseClient } from "../base.js";
import { ThreadStream } from "../stream/index.js";
import { ProtocolSseTransportAdapter } from "../stream/transport/http.js";
import { ProtocolWebSocketTransportAdapter } from "../stream/transport/websocket.js";
import { ProtocolSseTransportAdapter } from "../stream/transport/http.js";
import { v7 } from "@langchain/core/utils/uuid";

@@ -6,0 +6,0 @@ //#region src/client/threads/index.ts

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","names":["uuidv7"],"sources":["../../../src/client/threads/index.ts"],"sourcesContent":["import { v7 as uuidv7 } from \"@langchain/core/utils/uuid\";\n\nimport {\n Checkpoint,\n Config,\n DefaultValues,\n Metadata,\n SortOrder,\n Thread,\n ThreadSelectField,\n ThreadSortBy,\n ThreadState,\n ThreadStatus,\n ThreadValuesFilter,\n} from \"../../schema.js\";\nimport type { Command, OnConflictBehavior, StreamEvent } from \"../../types.js\";\nimport type { ThreadStreamMode } from \"../../types.stream.js\";\nimport { BaseClient } from \"../base.js\";\nimport { ThreadStream } from \"../stream/index.js\";\nimport type {\n ThreadStreamOptions,\n ThreadStreamTransportKind,\n} from \"../stream/types.js\";\nimport { ProtocolSseTransportAdapter } from \"../stream/transport/http.js\";\nimport { ProtocolWebSocketTransportAdapter } from \"../stream/transport/websocket.js\";\nimport type { TransportAdapter } from \"../stream/transport.js\";\n\nexport class ThreadsClient<\n TStateType = DefaultValues,\n TUpdateType = TStateType,\n> extends BaseClient {\n /**\n * Get a thread by ID.\n *\n * @param threadId ID of the thread.\n * @returns The thread.\n */\n async get<ValuesType = TStateType>(\n threadId: string,\n options?: { signal?: AbortSignal; include?: string[] }\n ): Promise<Thread<ValuesType>> {\n return this.fetch<Thread<ValuesType>>(`/threads/${threadId}`, {\n params: {\n include: options?.include ?? undefined,\n },\n signal: options?.signal,\n });\n }\n\n /**\n * Create a new thread.\n *\n * @param payload Payload for creating a thread.\n * @returns The created thread.\n */\n async create(payload?: {\n metadata?: Metadata;\n threadId?: string;\n ifExists?: OnConflictBehavior;\n graphId?: string;\n supersteps?: Array<{\n updates: Array<{ values: unknown; command?: Command; asNode: string }>;\n }>;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n signal?: AbortSignal;\n }): Promise<Thread<TStateType>> {\n const ttlPayload =\n typeof payload?.ttl === \"number\"\n ? { ttl: payload.ttl, strategy: \"delete\" as const }\n : payload?.ttl;\n\n return this.fetch<Thread<TStateType>>(`/threads`, {\n method: \"POST\",\n json: {\n metadata: {\n ...payload?.metadata,\n graph_id: payload?.graphId,\n },\n thread_id: payload?.threadId,\n if_exists: payload?.ifExists,\n supersteps: payload?.supersteps?.map((s) => ({\n updates: s.updates.map((u) => ({\n values: u.values,\n command: u.command,\n as_node: u.asNode,\n })),\n })),\n ttl: ttlPayload,\n },\n signal: payload?.signal,\n });\n }\n\n /**\n * Copy an existing thread\n * @param threadId ID of the thread to be copied\n * @returns Newly copied thread\n */\n async copy(\n threadId: string,\n options?: { signal?: AbortSignal }\n ): Promise<Thread<TStateType>> {\n return this.fetch<Thread<TStateType>>(`/threads/${threadId}/copy`, {\n method: \"POST\",\n signal: options?.signal,\n });\n }\n\n /**\n * Update a thread.\n *\n * @param threadId ID of the thread.\n * @param payload Payload for updating the thread.\n * @returns The updated thread.\n */\n async update(\n threadId: string,\n payload?: {\n metadata?: Metadata;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n returnMinimal?: false;\n signal?: AbortSignal;\n }\n ): Promise<Thread>;\n async update(\n threadId: string,\n payload: {\n metadata?: Metadata;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n returnMinimal: true;\n signal?: AbortSignal;\n }\n ): Promise<void>;\n async update(\n threadId: string,\n payload: {\n metadata?: Metadata;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n returnMinimal: boolean;\n signal?: AbortSignal;\n }\n ): Promise<Thread | void>;\n async update(\n threadId: string,\n payload?: {\n metadata?: Metadata;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n returnMinimal?: boolean;\n signal?: AbortSignal;\n }\n ): Promise<Thread | void> {\n const ttlPayload =\n typeof payload?.ttl === \"number\"\n ? { ttl: payload.ttl, strategy: \"delete\" as const }\n : payload?.ttl;\n\n return this.fetch<Thread | void>(`/threads/${threadId}`, {\n method: \"PATCH\",\n headers: payload?.returnMinimal\n ? { Prefer: \"return=minimal\" }\n : undefined,\n json: { metadata: payload?.metadata, ttl: ttlPayload },\n signal: payload?.signal,\n });\n }\n\n /**\n * Delete a thread.\n *\n * @param threadId ID of the thread.\n */\n async delete(\n threadId: string,\n options?: { signal?: AbortSignal }\n ): Promise<void> {\n return this.fetch<void>(`/threads/${threadId}`, {\n method: \"DELETE\",\n signal: options?.signal,\n });\n }\n\n /**\n * Prune threads by ID. The 'delete' strategy removes threads entirely.\n * The 'keep_latest' strategy prunes old checkpoints but keeps threads\n * and their latest state.\n *\n * @param threadIds List of thread IDs to prune.\n * @param options Additional options for pruning.\n * @param options.strategy The prune strategy. Defaults to 'delete'.\n * @param options.signal Signal to abort the request.\n * @returns An object containing `pruned_count`.\n */\n async prune(\n threadIds: string[],\n options?: {\n strategy?: \"delete\" | \"keep_latest\";\n signal?: AbortSignal;\n }\n ): Promise<{ pruned_count: number }> {\n return this.fetch<{ pruned_count: number }>(\"/threads/prune\", {\n method: \"POST\",\n json: {\n thread_ids: threadIds,\n strategy: options?.strategy ?? \"delete\",\n },\n signal: options?.signal,\n });\n }\n\n /**\n * List threads\n *\n * @param query Query options\n * @returns List of threads\n */\n async search<ValuesType = TStateType>(query?: {\n metadata?: Metadata;\n ids?: string[];\n limit?: number;\n offset?: number;\n status?: ThreadStatus;\n sortBy?: ThreadSortBy;\n sortOrder?: SortOrder;\n select?: ThreadSelectField[];\n values?: ThreadValuesFilter;\n extract?: Record<string, string>;\n signal?: AbortSignal;\n }): Promise<Thread<ValuesType>[]> {\n return this.fetch<Thread<ValuesType>[]>(\"/threads/search\", {\n method: \"POST\",\n json: {\n metadata: query?.metadata ?? undefined,\n ids: query?.ids ?? undefined,\n limit: query?.limit ?? 10,\n offset: query?.offset ?? 0,\n status: query?.status,\n sort_by: query?.sortBy,\n sort_order: query?.sortOrder,\n select: query?.select ?? undefined,\n values: query?.values ?? undefined,\n extract: query?.extract ?? undefined,\n },\n signal: query?.signal,\n });\n }\n\n /**\n * Count threads matching filters.\n *\n * @param query.metadata Thread metadata to filter on.\n * @param query.values State values to filter on.\n * @param query.status Thread status to filter on.\n * @returns Number of threads matching the criteria.\n */\n async count<ValuesType = TStateType>(query?: {\n metadata?: Metadata;\n values?: ValuesType;\n status?: ThreadStatus;\n signal?: AbortSignal;\n }): Promise<number> {\n return this.fetch<number>(`/threads/count`, {\n method: \"POST\",\n json: {\n metadata: query?.metadata ?? undefined,\n values: query?.values ?? undefined,\n status: query?.status ?? undefined,\n },\n signal: query?.signal,\n });\n }\n\n /**\n * Get state for a thread.\n *\n * @param threadId ID of the thread.\n * @returns Thread state.\n */\n async getState<ValuesType = TStateType>(\n threadId: string,\n checkpoint?: Checkpoint | string,\n options?: { subgraphs?: boolean; signal?: AbortSignal }\n ): Promise<ThreadState<ValuesType>> {\n if (checkpoint != null) {\n if (typeof checkpoint !== \"string\") {\n return this.fetch<ThreadState<ValuesType>>(\n `/threads/${threadId}/state/checkpoint`,\n {\n method: \"POST\",\n json: { checkpoint, subgraphs: options?.subgraphs },\n signal: options?.signal,\n }\n );\n }\n\n // deprecated\n return this.fetch<ThreadState<ValuesType>>(\n `/threads/${threadId}/state/${checkpoint}`,\n { params: { subgraphs: options?.subgraphs }, signal: options?.signal }\n );\n }\n\n return this.fetch<ThreadState<ValuesType>>(`/threads/${threadId}/state`, {\n params: { subgraphs: options?.subgraphs },\n signal: options?.signal,\n // Coalesce concurrent identical reads (e.g. two controllers\n // hydrating the same thread on reconnect). Skipped automatically\n // when a caller supplies its own `signal`.\n dedupe: true,\n });\n }\n\n /**\n * Add state to a thread.\n *\n * @param threadId The ID of the thread.\n * @returns\n */\n async updateState<ValuesType = TUpdateType>(\n threadId: string,\n options: {\n values: ValuesType;\n checkpoint?: Checkpoint;\n checkpointId?: string;\n asNode?: string;\n signal?: AbortSignal;\n }\n ): Promise<Pick<Config, \"configurable\">> {\n return this.fetch<Pick<Config, \"configurable\">>(\n `/threads/${threadId}/state`,\n {\n method: \"POST\",\n json: {\n values: options.values,\n checkpoint: options.checkpoint,\n checkpoint_id: options.checkpointId,\n as_node: options?.asNode,\n },\n signal: options?.signal,\n }\n );\n }\n\n /**\n * Patch the metadata of a thread.\n *\n * @param threadIdOrConfig Thread ID or config to patch the state of.\n * @param metadata Metadata to patch the state with.\n */\n async patchState(\n threadIdOrConfig: string | Config,\n metadata: Metadata,\n options?: { signal?: AbortSignal }\n ): Promise<void> {\n let threadId: string;\n\n if (typeof threadIdOrConfig !== \"string\") {\n if (typeof threadIdOrConfig.configurable?.thread_id !== \"string\") {\n throw new Error(\n \"Thread ID is required when updating state with a config.\"\n );\n }\n threadId = threadIdOrConfig.configurable.thread_id;\n } else {\n threadId = threadIdOrConfig;\n }\n\n return this.fetch<void>(`/threads/${threadId}/state`, {\n method: \"PATCH\",\n json: { metadata },\n signal: options?.signal,\n });\n }\n\n /**\n * Get all past states for a thread.\n *\n * @param threadId ID of the thread.\n * @param options Additional options.\n * @returns List of thread states.\n */\n async getHistory<ValuesType = TStateType>(\n threadId: string,\n options?: {\n limit?: number;\n before?: Config;\n checkpoint?: Partial<Omit<Checkpoint, \"thread_id\">>;\n metadata?: Metadata;\n signal?: AbortSignal;\n }\n ): Promise<ThreadState<ValuesType>[]> {\n return this.fetch<ThreadState<ValuesType>[]>(\n `/threads/${threadId}/history`,\n {\n method: \"POST\",\n json: {\n limit: options?.limit ?? 10,\n before: options?.before,\n metadata: options?.metadata,\n checkpoint: options?.checkpoint,\n },\n signal: options?.signal,\n // `getHistory` is a read despite using POST — coalesce the\n // hydrate-time discovery seed when two controllers reconnect to\n // the same thread concurrently. Skipped when `signal` is set.\n dedupe: true,\n }\n );\n }\n\n async *joinStream(\n threadId: string,\n options?: {\n lastEventId?: string;\n streamMode?: ThreadStreamMode | ThreadStreamMode[];\n signal?: AbortSignal;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): AsyncGenerator<{ id?: string; event: StreamEvent; data: any }> {\n yield* this.streamWithRetry({\n endpoint: `/threads/${threadId}/stream`,\n method: \"GET\",\n signal: options?.signal,\n headers: options?.lastEventId\n ? { \"Last-Event-ID\": options.lastEventId }\n : undefined,\n params: options?.streamMode\n ? { stream_mode: options.streamMode }\n : undefined,\n });\n }\n\n /**\n * Open a protocol stream over the thread-centric v2 protocol.\n *\n * Returns a {@link ThreadStream} with lazy getters\n * (`.messages`, `.values`, `.toolCalls`, `.subgraphs`, `.subagents`,\n * `.output`) and `thread.run.start({ input, ... })` for starting runs.\n * Mirrors the in-process `graph.streamEvents(..., { version: \"v3\" })` API.\n *\n * The thread is bound to `options.assistantId` for its lifetime.\n * The wire transport defaults to SSE; pass `transport: \"websocket\"`\n * in options (or configure `streamProtocol: \"v2-websocket\"` on the\n * client) to use a WebSocket instead.\n *\n * @example New thread (UUID generated client-side)\n * ```ts\n * const thread = client.threads.stream({ assistantId: \"my-agent\" });\n * ```\n *\n * @example Attach to an existing thread\n * ```ts\n * const thread = client.threads.stream(threadId, { assistantId: \"my-agent\" });\n * ```\n *\n * @example WebSocket transport\n * ```ts\n * const thread = client.threads.stream({\n * assistantId: \"my-agent\",\n * transport: \"websocket\",\n * });\n * ```\n */\n stream<TExtensions extends Record<string, unknown> = Record<string, unknown>>(\n options: ThreadStreamOptions\n ): ThreadStream<TExtensions>;\n stream<TExtensions extends Record<string, unknown> = Record<string, unknown>>(\n threadId: string,\n options: ThreadStreamOptions\n ): ThreadStream<TExtensions>;\n stream<TExtensions extends Record<string, unknown> = Record<string, unknown>>(\n threadIdOrOptions: string | ThreadStreamOptions,\n maybeOptions?: ThreadStreamOptions\n ): ThreadStream<TExtensions> {\n const { threadId, options } =\n typeof threadIdOrOptions === \"string\"\n ? {\n threadId: threadIdOrOptions,\n options: maybeOptions as ThreadStreamOptions,\n }\n : { threadId: uuidv7(), options: threadIdOrOptions };\n\n // `transport` accepts either a preset string (`\"sse\"` / `\"websocket\"`)\n // or a custom {@link AgentServerAdapter}. A custom adapter replaces\n // the built-in factories entirely — this is the seam that lets users\n // point `useStream` at any agent server (including the thin wrappers\n // produced by `HttpAgentServerAdapter`).\n // When callers supply `fetch`, use it verbatim (tests, auth shims). Otherwise\n // route protocol HTTP and media URL fetches through AsyncCaller like REST.\n const userFetch = options.fetch;\n const protocolFetch =\n userFetch ?? this.asyncCaller.fetch.bind(this.asyncCaller);\n\n let transport: TransportAdapter;\n if (options.transport != null && typeof options.transport !== \"string\") {\n transport = options.transport;\n // Bind (or re-bind) the caller-supplied adapter to this thread so a\n // single instance can follow lazy creation (the first `submit()` on a\n // `threadId: null` controller mints the id here) and thread switches.\n // No-op for adapters that bake `threadId` at construction.\n transport.setThreadId?.(threadId);\n } else {\n const transportKind: ThreadStreamTransportKind =\n options.transport ??\n (this.streamProtocol === \"v2-websocket\" ? \"websocket\" : \"sse\");\n const maxReconnectAttempts = options.maxReconnectAttempts ?? 5;\n\n /**\n * Common options for both transports.\n */\n const commonOpts = {\n apiUrl: this.apiUrl,\n threadId,\n defaultHeaders: this.defaultHeaders,\n onRequest: this.onRequest,\n maxReconnectAttempts,\n reconnectDelayMs: options.reconnectDelayMs,\n onReconnect: options.onReconnect,\n };\n\n transport =\n transportKind === \"websocket\"\n ? new ProtocolWebSocketTransportAdapter({\n ...commonOpts,\n webSocketFactory: options.webSocketFactory,\n })\n : new ProtocolSseTransportAdapter({\n ...commonOpts,\n idleReconnect: options.streamIdleReconnect,\n fetch: userFetch,\n asyncCaller: userFetch ? undefined : this.asyncCaller,\n });\n }\n\n return new ThreadStream<TExtensions>(transport, {\n ...options,\n fetch: protocolFetch,\n });\n }\n}\n"],"mappings":"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"}
{"version":3,"file":"index.js","names":["uuidv7"],"sources":["../../../src/client/threads/index.ts"],"sourcesContent":["import { v7 as uuidv7 } from \"@langchain/core/utils/uuid\";\n\nimport {\n Checkpoint,\n Config,\n DefaultValues,\n Metadata,\n SortOrder,\n Thread,\n ThreadSelectField,\n ThreadSortBy,\n ThreadState,\n ThreadStatus,\n ThreadValuesFilter,\n} from \"../../schema.js\";\nimport type { Command, OnConflictBehavior, StreamEvent } from \"../../types.js\";\nimport type { ThreadStreamMode } from \"../../types.stream.js\";\nimport { BaseClient } from \"../base.js\";\nimport { ThreadStream } from \"../stream/index.js\";\nimport type {\n ThreadStreamOptions,\n ThreadStreamTransportKind,\n} from \"../stream/types.js\";\nimport { DEFAULT_MAX_RECONNECT_ATTEMPTS } from \"../../utils/reconnect.js\";\nimport { ProtocolSseTransportAdapter } from \"../stream/transport/http.js\";\nimport { ProtocolWebSocketTransportAdapter } from \"../stream/transport/websocket.js\";\nimport type { TransportAdapter } from \"../stream/transport.js\";\n\nexport class ThreadsClient<\n TStateType = DefaultValues,\n TUpdateType = TStateType,\n> extends BaseClient {\n /**\n * Get a thread by ID.\n *\n * @param threadId ID of the thread.\n * @returns The thread.\n */\n async get<ValuesType = TStateType>(\n threadId: string,\n options?: { signal?: AbortSignal; include?: string[] }\n ): Promise<Thread<ValuesType>> {\n return this.fetch<Thread<ValuesType>>(`/threads/${threadId}`, {\n params: {\n include: options?.include ?? undefined,\n },\n signal: options?.signal,\n });\n }\n\n /**\n * Create a new thread.\n *\n * @param payload Payload for creating a thread.\n * @returns The created thread.\n */\n async create(payload?: {\n metadata?: Metadata;\n threadId?: string;\n ifExists?: OnConflictBehavior;\n graphId?: string;\n supersteps?: Array<{\n updates: Array<{ values: unknown; command?: Command; asNode: string }>;\n }>;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n signal?: AbortSignal;\n }): Promise<Thread<TStateType>> {\n const ttlPayload =\n typeof payload?.ttl === \"number\"\n ? { ttl: payload.ttl, strategy: \"delete\" as const }\n : payload?.ttl;\n\n return this.fetch<Thread<TStateType>>(`/threads`, {\n method: \"POST\",\n json: {\n metadata: {\n ...payload?.metadata,\n graph_id: payload?.graphId,\n },\n thread_id: payload?.threadId,\n if_exists: payload?.ifExists,\n supersteps: payload?.supersteps?.map((s) => ({\n updates: s.updates.map((u) => ({\n values: u.values,\n command: u.command,\n as_node: u.asNode,\n })),\n })),\n ttl: ttlPayload,\n },\n signal: payload?.signal,\n });\n }\n\n /**\n * Copy an existing thread\n * @param threadId ID of the thread to be copied\n * @returns Newly copied thread\n */\n async copy(\n threadId: string,\n options?: { signal?: AbortSignal }\n ): Promise<Thread<TStateType>> {\n return this.fetch<Thread<TStateType>>(`/threads/${threadId}/copy`, {\n method: \"POST\",\n signal: options?.signal,\n });\n }\n\n /**\n * Update a thread.\n *\n * @param threadId ID of the thread.\n * @param payload Payload for updating the thread.\n * @returns The updated thread.\n */\n async update(\n threadId: string,\n payload?: {\n metadata?: Metadata;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n returnMinimal?: false;\n signal?: AbortSignal;\n }\n ): Promise<Thread>;\n async update(\n threadId: string,\n payload: {\n metadata?: Metadata;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n returnMinimal: true;\n signal?: AbortSignal;\n }\n ): Promise<void>;\n async update(\n threadId: string,\n payload: {\n metadata?: Metadata;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n returnMinimal: boolean;\n signal?: AbortSignal;\n }\n ): Promise<Thread | void>;\n async update(\n threadId: string,\n payload?: {\n metadata?: Metadata;\n ttl?: number | { ttl: number; strategy?: \"delete\" };\n returnMinimal?: boolean;\n signal?: AbortSignal;\n }\n ): Promise<Thread | void> {\n const ttlPayload =\n typeof payload?.ttl === \"number\"\n ? { ttl: payload.ttl, strategy: \"delete\" as const }\n : payload?.ttl;\n\n return this.fetch<Thread | void>(`/threads/${threadId}`, {\n method: \"PATCH\",\n headers: payload?.returnMinimal\n ? { Prefer: \"return=minimal\" }\n : undefined,\n json: { metadata: payload?.metadata, ttl: ttlPayload },\n signal: payload?.signal,\n });\n }\n\n /**\n * Delete a thread.\n *\n * @param threadId ID of the thread.\n */\n async delete(\n threadId: string,\n options?: { signal?: AbortSignal }\n ): Promise<void> {\n return this.fetch<void>(`/threads/${threadId}`, {\n method: \"DELETE\",\n signal: options?.signal,\n });\n }\n\n /**\n * Prune threads by ID. The 'delete' strategy removes threads entirely.\n * The 'keep_latest' strategy prunes old checkpoints but keeps threads\n * and their latest state.\n *\n * @param threadIds List of thread IDs to prune.\n * @param options Additional options for pruning.\n * @param options.strategy The prune strategy. Defaults to 'delete'.\n * @param options.signal Signal to abort the request.\n * @returns An object containing `pruned_count`.\n */\n async prune(\n threadIds: string[],\n options?: {\n strategy?: \"delete\" | \"keep_latest\";\n signal?: AbortSignal;\n }\n ): Promise<{ pruned_count: number }> {\n return this.fetch<{ pruned_count: number }>(\"/threads/prune\", {\n method: \"POST\",\n json: {\n thread_ids: threadIds,\n strategy: options?.strategy ?? \"delete\",\n },\n signal: options?.signal,\n });\n }\n\n /**\n * List threads\n *\n * @param query Query options\n * @returns List of threads\n */\n async search<ValuesType = TStateType>(query?: {\n metadata?: Metadata;\n ids?: string[];\n limit?: number;\n offset?: number;\n status?: ThreadStatus;\n sortBy?: ThreadSortBy;\n sortOrder?: SortOrder;\n select?: ThreadSelectField[];\n values?: ThreadValuesFilter;\n extract?: Record<string, string>;\n signal?: AbortSignal;\n }): Promise<Thread<ValuesType>[]> {\n return this.fetch<Thread<ValuesType>[]>(\"/threads/search\", {\n method: \"POST\",\n json: {\n metadata: query?.metadata ?? undefined,\n ids: query?.ids ?? undefined,\n limit: query?.limit ?? 10,\n offset: query?.offset ?? 0,\n status: query?.status,\n sort_by: query?.sortBy,\n sort_order: query?.sortOrder,\n select: query?.select ?? undefined,\n values: query?.values ?? undefined,\n extract: query?.extract ?? undefined,\n },\n signal: query?.signal,\n });\n }\n\n /**\n * Count threads matching filters.\n *\n * @param query.metadata Thread metadata to filter on.\n * @param query.values State values to filter on.\n * @param query.status Thread status to filter on.\n * @returns Number of threads matching the criteria.\n */\n async count<ValuesType = TStateType>(query?: {\n metadata?: Metadata;\n values?: ValuesType;\n status?: ThreadStatus;\n signal?: AbortSignal;\n }): Promise<number> {\n return this.fetch<number>(`/threads/count`, {\n method: \"POST\",\n json: {\n metadata: query?.metadata ?? undefined,\n values: query?.values ?? undefined,\n status: query?.status ?? undefined,\n },\n signal: query?.signal,\n });\n }\n\n /**\n * Get state for a thread.\n *\n * @param threadId ID of the thread.\n * @returns Thread state.\n */\n async getState<ValuesType = TStateType>(\n threadId: string,\n checkpoint?: Checkpoint | string,\n options?: { subgraphs?: boolean; signal?: AbortSignal }\n ): Promise<ThreadState<ValuesType>> {\n if (checkpoint != null) {\n if (typeof checkpoint !== \"string\") {\n return this.fetch<ThreadState<ValuesType>>(\n `/threads/${threadId}/state/checkpoint`,\n {\n method: \"POST\",\n json: { checkpoint, subgraphs: options?.subgraphs },\n signal: options?.signal,\n }\n );\n }\n\n // deprecated\n return this.fetch<ThreadState<ValuesType>>(\n `/threads/${threadId}/state/${checkpoint}`,\n { params: { subgraphs: options?.subgraphs }, signal: options?.signal }\n );\n }\n\n return this.fetch<ThreadState<ValuesType>>(`/threads/${threadId}/state`, {\n params: { subgraphs: options?.subgraphs },\n signal: options?.signal,\n // Coalesce concurrent identical reads (e.g. two controllers\n // hydrating the same thread on reconnect). Skipped automatically\n // when a caller supplies its own `signal`.\n dedupe: true,\n });\n }\n\n /**\n * Add state to a thread.\n *\n * @param threadId The ID of the thread.\n * @returns\n */\n async updateState<ValuesType = TUpdateType>(\n threadId: string,\n options: {\n values: ValuesType;\n checkpoint?: Checkpoint;\n checkpointId?: string;\n asNode?: string;\n signal?: AbortSignal;\n }\n ): Promise<Pick<Config, \"configurable\">> {\n return this.fetch<Pick<Config, \"configurable\">>(\n `/threads/${threadId}/state`,\n {\n method: \"POST\",\n json: {\n values: options.values,\n checkpoint: options.checkpoint,\n checkpoint_id: options.checkpointId,\n as_node: options?.asNode,\n },\n signal: options?.signal,\n }\n );\n }\n\n /**\n * Patch the metadata of a thread.\n *\n * @param threadIdOrConfig Thread ID or config to patch the state of.\n * @param metadata Metadata to patch the state with.\n */\n async patchState(\n threadIdOrConfig: string | Config,\n metadata: Metadata,\n options?: { signal?: AbortSignal }\n ): Promise<void> {\n let threadId: string;\n\n if (typeof threadIdOrConfig !== \"string\") {\n if (typeof threadIdOrConfig.configurable?.thread_id !== \"string\") {\n throw new Error(\n \"Thread ID is required when updating state with a config.\"\n );\n }\n threadId = threadIdOrConfig.configurable.thread_id;\n } else {\n threadId = threadIdOrConfig;\n }\n\n return this.fetch<void>(`/threads/${threadId}/state`, {\n method: \"PATCH\",\n json: { metadata },\n signal: options?.signal,\n });\n }\n\n /**\n * Get all past states for a thread.\n *\n * @param threadId ID of the thread.\n * @param options Additional options.\n * @returns List of thread states.\n */\n async getHistory<ValuesType = TStateType>(\n threadId: string,\n options?: {\n limit?: number;\n before?: Config;\n checkpoint?: Partial<Omit<Checkpoint, \"thread_id\">>;\n metadata?: Metadata;\n signal?: AbortSignal;\n }\n ): Promise<ThreadState<ValuesType>[]> {\n return this.fetch<ThreadState<ValuesType>[]>(\n `/threads/${threadId}/history`,\n {\n method: \"POST\",\n json: {\n limit: options?.limit ?? 10,\n before: options?.before,\n metadata: options?.metadata,\n checkpoint: options?.checkpoint,\n },\n signal: options?.signal,\n // `getHistory` is a read despite using POST — coalesce the\n // hydrate-time discovery seed when two controllers reconnect to\n // the same thread concurrently. Skipped when `signal` is set.\n dedupe: true,\n }\n );\n }\n\n async *joinStream(\n threadId: string,\n options?: {\n lastEventId?: string;\n streamMode?: ThreadStreamMode | ThreadStreamMode[];\n signal?: AbortSignal;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): AsyncGenerator<{ id?: string; event: StreamEvent; data: any }> {\n yield* this.streamWithRetry({\n endpoint: `/threads/${threadId}/stream`,\n method: \"GET\",\n signal: options?.signal,\n headers: options?.lastEventId\n ? { \"Last-Event-ID\": options.lastEventId }\n : undefined,\n params: options?.streamMode\n ? { stream_mode: options.streamMode }\n : undefined,\n });\n }\n\n /**\n * Open a protocol stream over the thread-centric v2 protocol.\n *\n * Returns a {@link ThreadStream} with lazy getters\n * (`.messages`, `.values`, `.toolCalls`, `.subgraphs`, `.subagents`,\n * `.output`) and `thread.run.start({ input, ... })` for starting runs.\n * Mirrors the in-process `graph.streamEvents(..., { version: \"v3\" })` API.\n *\n * The thread is bound to `options.assistantId` for its lifetime.\n * The wire transport defaults to SSE; pass `transport: \"websocket\"`\n * in options (or configure `streamProtocol: \"v2-websocket\"` on the\n * client) to use a WebSocket instead.\n *\n * @example New thread (UUID generated client-side)\n * ```ts\n * const thread = client.threads.stream({ assistantId: \"my-agent\" });\n * ```\n *\n * @example Attach to an existing thread\n * ```ts\n * const thread = client.threads.stream(threadId, { assistantId: \"my-agent\" });\n * ```\n *\n * @example WebSocket transport\n * ```ts\n * const thread = client.threads.stream({\n * assistantId: \"my-agent\",\n * transport: \"websocket\",\n * });\n * ```\n */\n stream<TExtensions extends Record<string, unknown> = Record<string, unknown>>(\n options: ThreadStreamOptions\n ): ThreadStream<TExtensions>;\n stream<TExtensions extends Record<string, unknown> = Record<string, unknown>>(\n threadId: string,\n options: ThreadStreamOptions\n ): ThreadStream<TExtensions>;\n stream<TExtensions extends Record<string, unknown> = Record<string, unknown>>(\n threadIdOrOptions: string | ThreadStreamOptions,\n maybeOptions?: ThreadStreamOptions\n ): ThreadStream<TExtensions> {\n const { threadId, options } =\n typeof threadIdOrOptions === \"string\"\n ? {\n threadId: threadIdOrOptions,\n options: maybeOptions as ThreadStreamOptions,\n }\n : { threadId: uuidv7(), options: threadIdOrOptions };\n\n // `transport` accepts either a preset string (`\"sse\"` / `\"websocket\"`)\n // or a custom {@link AgentServerAdapter}. A custom adapter replaces\n // the built-in factories entirely — this is the seam that lets users\n // point `useStream` at any agent server (including the thin wrappers\n // produced by `HttpAgentServerAdapter`).\n // When callers supply `fetch`, use it verbatim (tests, auth shims). Otherwise\n // route protocol HTTP and media URL fetches through AsyncCaller like REST.\n const userFetch = options.fetch;\n const protocolFetch =\n userFetch ?? this.asyncCaller.fetch.bind(this.asyncCaller);\n\n let transport: TransportAdapter;\n if (options.transport != null && typeof options.transport !== \"string\") {\n transport = options.transport;\n // Bind (or re-bind) the caller-supplied adapter to this thread so a\n // single instance can follow lazy creation (the first `submit()` on a\n // `threadId: null` controller mints the id here) and thread switches.\n // No-op for adapters that bake `threadId` at construction.\n transport.setThreadId?.(threadId);\n } else {\n const transportKind: ThreadStreamTransportKind =\n options.transport ??\n (this.streamProtocol === \"v2-websocket\" ? \"websocket\" : \"sse\");\n const maxReconnectAttempts =\n options.maxReconnectAttempts ?? DEFAULT_MAX_RECONNECT_ATTEMPTS;\n\n /**\n * Common options for both transports.\n */\n const commonOpts = {\n apiUrl: this.apiUrl,\n threadId,\n defaultHeaders: this.defaultHeaders,\n onRequest: this.onRequest,\n maxReconnectAttempts,\n reconnectDelayMs: options.reconnectDelayMs,\n onReconnect: options.onReconnect,\n };\n\n transport =\n transportKind === \"websocket\"\n ? new ProtocolWebSocketTransportAdapter({\n ...commonOpts,\n webSocketFactory: options.webSocketFactory,\n })\n : new ProtocolSseTransportAdapter({\n ...commonOpts,\n idleReconnect: options.streamIdleReconnect,\n fetch: userFetch,\n asyncCaller: userFetch ? undefined : this.asyncCaller,\n });\n }\n\n return new ThreadStream<TExtensions>(transport, {\n ...options,\n fetch: protocolFetch,\n });\n }\n}\n"],"mappings":"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"}
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_fetch = require("./singletons/fetch.cjs");
const require_base = require("./client/base.cjs");
const require_constants = require("./stream/constants.cjs");
const require_messages = require("./client/stream/messages.cjs");
const require_media = require("./client/stream/media.cjs");
const require_error = require("./client/stream/error.cjs");
const require_constants = require("./stream/constants.cjs");
const require_headless_tools = require("./headless-tools.cjs");
const require_index = require("./client/stream/index.cjs");
const require_http = require("./client/stream/transport/http.cjs");
const require_websocket = require("./client/stream/transport/websocket.cjs");
const require_http = require("./client/stream/transport/http.cjs");
const require_agent_server = require("./client/stream/transport/agent-server.cjs");

@@ -18,2 +18,3 @@ const require_index$1 = require("./client/index.cjs");

exports.Client = require_index$1.Client;
exports.DEFAULT_MESSAGES_KEY = require_constants.DEFAULT_MESSAGES_KEY;
exports.HttpAgentServerAdapter = require_agent_server.HttpAgentServerAdapter;

@@ -20,0 +21,0 @@ exports.MediaAssembler = require_media.MediaAssembler;

@@ -24,4 +24,4 @@ import { Assistant, AssistantBase, AssistantGraph, AssistantVersion, AssistantsSearchResponse, Checkpoint, Config, Cron, CronCreateForThreadResponse, CronCreateResponse, DefaultValues, GraphSchema, Interrupt, Item, ListNamespaceResponse, Metadata, Run, SearchItem, SearchItemsResponse, Thread, ThreadState, ThreadStatus, ThreadTask } from "./schema.cjs";

import { InferBag, InferNodeNames, InferNodeReturnTypes, InferStateType, InferSubagentStates, InferToolCalls, ResolveStreamInterface, ResolveStreamOptions } from "./ui/stream/index.cjs";
import { NAMESPACE_SEPARATOR } from "./stream/constants.cjs";
import { DEFAULT_MESSAGES_KEY, NAMESPACE_SEPARATOR } from "./stream/constants.cjs";
import { StreamError } from "./ui/errors.cjs";
export { type AIMessage, type AgentServerAdapter, type AnyHeadlessToolImplementation, type AnyMediaHandle, type AssembledMessage, type Assistant, type AssistantBase, type AssistantGraph, type AssistantVersion, type AssistantsSearchResponse, type AudioMedia, type BagTemplate, BaseStream, type Checkpoint, Client, type ClientConfig, type Command, type Config, type Cron, type CronCreateForThreadResponse, type CronCreateResponse, type CustomStreamEvent, type DebugStreamEvent, type DefaultToolCall, type DefaultValues, type ErrorStreamEvent, type EventSubscription, type EventsStreamEvent, type FeedbackStreamEvent, type FileMedia, type FlushPendingHeadlessToolInterruptsOptions, type FunctionMessage, type GraphSchema, type HeadlessToolImplementation, type HeadlessToolInterrupt, type HeadlessToolResumeCommand, type HeadlessToolResumeController, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type HumanMessage, type ImageMedia, InferBag, InferNodeNames, InferNodeReturnTypes, InferStateType, InferSubagentStates, InferToolCalls, type InferToolOutput, type Interrupt, type Item, type ListNamespaceResponse, MediaAssembler, type MediaAssemblerCallbacks, type MediaAssemblerOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type Message, MessageAssembler, type MessageSubscription, type MessagesStreamEvent, type MessagesTupleStreamEvent, type Metadata, type MetadataStreamEvent, NAMESPACE_SEPARATOR, type OnConflictBehavior, type OnToolCallback, ProtocolError, type ProtocolRequestHook, ProtocolSseTransportAdapter, type ProtocolSseTransportOptions, type ProtocolTransportPaths, ProtocolWebSocketTransportAdapter, type ProtocolWebSocketTransportOptions, type RemoveMessage, type RequestHook, ResolveStreamInterface, ResolveStreamOptions, type Run, type RunsInvokePayload, type SearchItem, type SearchItemsResponse, type SessionOrderingState, StateRecord, StreamError, type StreamEvent, type StreamMode, SubscriptionHandle, type SystemMessage, type Thread, type ThreadExtension, type ThreadExtensions, type ThreadState, type ThreadStatus, ThreadStream, type ThreadStreamOptions, type ThreadTask, type ToolCallFromTool, type ToolCallState, type ToolCallWithResult, type ToolCallsFromTools, type ToolEvent, type ToolMessage, type ToolProgress, type ToolsStreamEvent, type TransportAdapter, type UnwrapExtension, type UpdatesStreamEvent, UseAgentStream, UseAgentStreamOptions, UseDeepAgentStream, UseDeepAgentStreamOptions, type ValuesStreamEvent, type VideoMedia, applyHeadlessToolResumeCommand, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, getApiKey, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, overrideFetchImplementation, parseHeadlessToolInterruptPayload, scheduleCoalescedHeadlessToolFlush };
export { type AIMessage, type AgentServerAdapter, type AnyHeadlessToolImplementation, type AnyMediaHandle, type AssembledMessage, type Assistant, type AssistantBase, type AssistantGraph, type AssistantVersion, type AssistantsSearchResponse, type AudioMedia, type BagTemplate, BaseStream, type Checkpoint, Client, type ClientConfig, type Command, type Config, type Cron, type CronCreateForThreadResponse, type CronCreateResponse, type CustomStreamEvent, DEFAULT_MESSAGES_KEY, type DebugStreamEvent, type DefaultToolCall, type DefaultValues, type ErrorStreamEvent, type EventSubscription, type EventsStreamEvent, type FeedbackStreamEvent, type FileMedia, type FlushPendingHeadlessToolInterruptsOptions, type FunctionMessage, type GraphSchema, type HeadlessToolImplementation, type HeadlessToolInterrupt, type HeadlessToolResumeCommand, type HeadlessToolResumeController, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type HumanMessage, type ImageMedia, InferBag, InferNodeNames, InferNodeReturnTypes, InferStateType, InferSubagentStates, InferToolCalls, type InferToolOutput, type Interrupt, type Item, type ListNamespaceResponse, MediaAssembler, type MediaAssemblerCallbacks, type MediaAssemblerOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type Message, MessageAssembler, type MessageSubscription, type MessagesStreamEvent, type MessagesTupleStreamEvent, type Metadata, type MetadataStreamEvent, NAMESPACE_SEPARATOR, type OnConflictBehavior, type OnToolCallback, ProtocolError, type ProtocolRequestHook, ProtocolSseTransportAdapter, type ProtocolSseTransportOptions, type ProtocolTransportPaths, ProtocolWebSocketTransportAdapter, type ProtocolWebSocketTransportOptions, type RemoveMessage, type RequestHook, ResolveStreamInterface, ResolveStreamOptions, type Run, type RunsInvokePayload, type SearchItem, type SearchItemsResponse, type SessionOrderingState, StateRecord, StreamError, type StreamEvent, type StreamMode, SubscriptionHandle, type SystemMessage, type Thread, type ThreadExtension, type ThreadExtensions, type ThreadState, type ThreadStatus, ThreadStream, type ThreadStreamOptions, type ThreadTask, type ToolCallFromTool, type ToolCallState, type ToolCallWithResult, type ToolCallsFromTools, type ToolEvent, type ToolMessage, type ToolProgress, type ToolsStreamEvent, type TransportAdapter, type UnwrapExtension, type UpdatesStreamEvent, UseAgentStream, UseAgentStreamOptions, UseDeepAgentStream, UseDeepAgentStreamOptions, type ValuesStreamEvent, type VideoMedia, applyHeadlessToolResumeCommand, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, getApiKey, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, overrideFetchImplementation, parseHeadlessToolInterruptPayload, scheduleCoalescedHeadlessToolFlush };

@@ -24,4 +24,4 @@ import { Assistant, AssistantBase, AssistantGraph, AssistantVersion, AssistantsSearchResponse, Checkpoint, Config, Cron, CronCreateForThreadResponse, CronCreateResponse, DefaultValues, GraphSchema, Interrupt, Item, ListNamespaceResponse, Metadata, Run, SearchItem, SearchItemsResponse, Thread, ThreadState, ThreadStatus, ThreadTask } from "./schema.js";

import { InferBag, InferNodeNames, InferNodeReturnTypes, InferStateType, InferSubagentStates, InferToolCalls, ResolveStreamInterface, ResolveStreamOptions } from "./ui/stream/index.js";
import { NAMESPACE_SEPARATOR } from "./stream/constants.js";
import { DEFAULT_MESSAGES_KEY, NAMESPACE_SEPARATOR } from "./stream/constants.js";
import { StreamError } from "./ui/errors.js";
export { type AIMessage, type AgentServerAdapter, type AnyHeadlessToolImplementation, type AnyMediaHandle, type AssembledMessage, type Assistant, type AssistantBase, type AssistantGraph, type AssistantVersion, type AssistantsSearchResponse, type AudioMedia, type BagTemplate, BaseStream, type Checkpoint, Client, type ClientConfig, type Command, type Config, type Cron, type CronCreateForThreadResponse, type CronCreateResponse, type CustomStreamEvent, type DebugStreamEvent, type DefaultToolCall, type DefaultValues, type ErrorStreamEvent, type EventSubscription, type EventsStreamEvent, type FeedbackStreamEvent, type FileMedia, type FlushPendingHeadlessToolInterruptsOptions, type FunctionMessage, type GraphSchema, type HeadlessToolImplementation, type HeadlessToolInterrupt, type HeadlessToolResumeCommand, type HeadlessToolResumeController, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type HumanMessage, type ImageMedia, InferBag, InferNodeNames, InferNodeReturnTypes, InferStateType, InferSubagentStates, InferToolCalls, type InferToolOutput, type Interrupt, type Item, type ListNamespaceResponse, MediaAssembler, type MediaAssemblerCallbacks, type MediaAssemblerOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type Message, MessageAssembler, type MessageSubscription, type MessagesStreamEvent, type MessagesTupleStreamEvent, type Metadata, type MetadataStreamEvent, NAMESPACE_SEPARATOR, type OnConflictBehavior, type OnToolCallback, ProtocolError, type ProtocolRequestHook, ProtocolSseTransportAdapter, type ProtocolSseTransportOptions, type ProtocolTransportPaths, ProtocolWebSocketTransportAdapter, type ProtocolWebSocketTransportOptions, type RemoveMessage, type RequestHook, ResolveStreamInterface, ResolveStreamOptions, type Run, type RunsInvokePayload, type SearchItem, type SearchItemsResponse, type SessionOrderingState, StateRecord, StreamError, type StreamEvent, type StreamMode, SubscriptionHandle, type SystemMessage, type Thread, type ThreadExtension, type ThreadExtensions, type ThreadState, type ThreadStatus, ThreadStream, type ThreadStreamOptions, type ThreadTask, type ToolCallFromTool, type ToolCallState, type ToolCallWithResult, type ToolCallsFromTools, type ToolEvent, type ToolMessage, type ToolProgress, type ToolsStreamEvent, type TransportAdapter, type UnwrapExtension, type UpdatesStreamEvent, UseAgentStream, UseAgentStreamOptions, UseDeepAgentStream, UseDeepAgentStreamOptions, type ValuesStreamEvent, type VideoMedia, applyHeadlessToolResumeCommand, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, getApiKey, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, overrideFetchImplementation, parseHeadlessToolInterruptPayload, scheduleCoalescedHeadlessToolFlush };
export { type AIMessage, type AgentServerAdapter, type AnyHeadlessToolImplementation, type AnyMediaHandle, type AssembledMessage, type Assistant, type AssistantBase, type AssistantGraph, type AssistantVersion, type AssistantsSearchResponse, type AudioMedia, type BagTemplate, BaseStream, type Checkpoint, Client, type ClientConfig, type Command, type Config, type Cron, type CronCreateForThreadResponse, type CronCreateResponse, type CustomStreamEvent, DEFAULT_MESSAGES_KEY, type DebugStreamEvent, type DefaultToolCall, type DefaultValues, type ErrorStreamEvent, type EventSubscription, type EventsStreamEvent, type FeedbackStreamEvent, type FileMedia, type FlushPendingHeadlessToolInterruptsOptions, type FunctionMessage, type GraphSchema, type HeadlessToolImplementation, type HeadlessToolInterrupt, type HeadlessToolResumeCommand, type HeadlessToolResumeController, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type HumanMessage, type ImageMedia, InferBag, InferNodeNames, InferNodeReturnTypes, InferStateType, InferSubagentStates, InferToolCalls, type InferToolOutput, type Interrupt, type Item, type ListNamespaceResponse, MediaAssembler, type MediaAssemblerCallbacks, type MediaAssemblerOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type Message, MessageAssembler, type MessageSubscription, type MessagesStreamEvent, type MessagesTupleStreamEvent, type Metadata, type MetadataStreamEvent, NAMESPACE_SEPARATOR, type OnConflictBehavior, type OnToolCallback, ProtocolError, type ProtocolRequestHook, ProtocolSseTransportAdapter, type ProtocolSseTransportOptions, type ProtocolTransportPaths, ProtocolWebSocketTransportAdapter, type ProtocolWebSocketTransportOptions, type RemoveMessage, type RequestHook, ResolveStreamInterface, ResolveStreamOptions, type Run, type RunsInvokePayload, type SearchItem, type SearchItemsResponse, type SessionOrderingState, StateRecord, StreamError, type StreamEvent, type StreamMode, SubscriptionHandle, type SystemMessage, type Thread, type ThreadExtension, type ThreadExtensions, type ThreadState, type ThreadStatus, ThreadStream, type ThreadStreamOptions, type ThreadTask, type ToolCallFromTool, type ToolCallState, type ToolCallWithResult, type ToolCallsFromTools, type ToolEvent, type ToolMessage, type ToolProgress, type ToolsStreamEvent, type TransportAdapter, type UnwrapExtension, type UpdatesStreamEvent, UseAgentStream, UseAgentStreamOptions, UseDeepAgentStream, UseDeepAgentStreamOptions, type ValuesStreamEvent, type VideoMedia, applyHeadlessToolResumeCommand, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, getApiKey, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, overrideFetchImplementation, parseHeadlessToolInterruptPayload, scheduleCoalescedHeadlessToolFlush };
import { overrideFetchImplementation } from "./singletons/fetch.js";
import { getApiKey } from "./client/base.js";
import { DEFAULT_MESSAGES_KEY, NAMESPACE_SEPARATOR } from "./stream/constants.js";
import { MessageAssembler } from "./client/stream/messages.js";
import { MediaAssembler, MediaAssemblyError } from "./client/stream/media.js";
import { ProtocolError } from "./client/stream/error.js";
import { NAMESPACE_SEPARATOR } from "./stream/constants.js";
import { applyHeadlessToolResumeCommand, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, scheduleCoalescedHeadlessToolFlush } from "./headless-tools.js";
import { SubscriptionHandle, ThreadStream } from "./client/stream/index.js";
import { ProtocolSseTransportAdapter } from "./client/stream/transport/http.js";
import { ProtocolWebSocketTransportAdapter } from "./client/stream/transport/websocket.js";
import { ProtocolSseTransportAdapter } from "./client/stream/transport/http.js";
import { HttpAgentServerAdapter } from "./client/stream/transport/agent-server.js";

@@ -16,2 +16,2 @@ import { Client } from "./client/index.js";

import { StreamError } from "./ui/errors.js";
export { Client, HttpAgentServerAdapter, MediaAssembler, MediaAssemblyError, MessageAssembler, NAMESPACE_SEPARATOR, ProtocolError, ProtocolSseTransportAdapter, ProtocolWebSocketTransportAdapter, StreamError, SubscriptionHandle, ThreadStream, applyHeadlessToolResumeCommand, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, getApiKey, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, overrideFetchImplementation, parseHeadlessToolInterruptPayload, scheduleCoalescedHeadlessToolFlush };
export { Client, DEFAULT_MESSAGES_KEY, HttpAgentServerAdapter, MediaAssembler, MediaAssemblyError, MessageAssembler, NAMESPACE_SEPARATOR, ProtocolError, ProtocolSseTransportAdapter, ProtocolWebSocketTransportAdapter, StreamError, SubscriptionHandle, ThreadStream, applyHeadlessToolResumeCommand, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, getApiKey, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, overrideFetchImplementation, parseHeadlessToolInterruptPayload, scheduleCoalescedHeadlessToolFlush };

@@ -5,2 +5,3 @@ "use client";

const require_stream = require("../utils/stream.cjs");
require("../stream/constants.cjs");
const require_messages = require("../ui/messages.cjs");

@@ -7,0 +8,0 @@ const require_headless_tools = require("../headless-tools.cjs");

@@ -1,1 +0,1 @@

{"version":3,"file":"stream.custom.cjs","names":["BytesLineDecoder","SSEDecoder","IterableReadableStream","MessageTupleManager","StreamManager","useControllableThreadId","userFacingInterruptsFromValuesArray","getToolCallsWithResults"],"sources":["../../src/react/stream.custom.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useRef, useState, useSyncExternalStore } from \"react\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport type {\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetToolCallsType,\n GetConfigurableType,\n UseStreamTransport,\n AnyStreamCustomOptions,\n CustomSubmitOptions,\n} from \"../ui/types.js\";\nimport type { UseStreamCustom } from \"./types.js\";\nimport { type Message } from \"../types.messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport { userFacingInterruptsFromValuesArray } from \"../ui/interrupts.js\";\nimport { Interrupt, type ThreadState } from \"../schema.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../utils/sse.js\";\nimport { IterableReadableStream } from \"../utils/stream.js\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport { Command } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport { flushPendingHeadlessToolInterrupts } from \"../headless-tools.js\";\n\ninterface FetchStreamTransportOptions {\n /**\n * The URL of the API to use.\n */\n apiUrl: string;\n\n /**\n * Default headers to send with requests.\n */\n defaultHeaders?: HeadersInit;\n\n /**\n * Specify a custom fetch implementation.\n */\n fetch?: typeof fetch | ((...args: any[]) => any); // eslint-disable-line @typescript-eslint/no-explicit-any\n\n /**\n * Callback that is called before the request is made.\n */\n onRequest?: (\n url: string,\n init: RequestInit\n ) => Promise<RequestInit> | RequestInit;\n}\n\nexport class FetchStreamTransport<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n> implements UseStreamTransport<StateType, Bag> {\n constructor(private readonly options: FetchStreamTransportOptions) {}\n\n async stream(payload: {\n input: GetUpdateType<Bag, StateType> | null | undefined;\n context: GetConfigurableType<Bag> | undefined;\n command: Command | undefined;\n signal: AbortSignal;\n }): Promise<AsyncGenerator<{ id?: string; event: string; data: unknown }>> {\n const { signal, ...body } = payload;\n\n let requestInit: RequestInit = {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.options.defaultHeaders,\n },\n body: JSON.stringify(body),\n signal,\n };\n\n if (this.options.onRequest) {\n requestInit = await this.options.onRequest(\n this.options.apiUrl,\n requestInit\n );\n }\n const fetchFn = this.options.fetch ?? fetch;\n\n const response = await fetchFn(this.options.apiUrl, requestInit);\n if (!response.ok) {\n throw new Error(`Failed to stream: ${response.statusText}`);\n }\n\n const stream = (\n response.body || new ReadableStream({ start: (ctrl) => ctrl.close() })\n )\n .pipeThrough(BytesLineDecoder())\n .pipeThrough(SSEDecoder());\n\n return IterableReadableStream.fromReadableStream(stream);\n }\n}\n\nfunction createCustomTransportThreadState<\n StateType extends Record<string, unknown>,\n>(values: StateType, threadId: string): ThreadState<StateType> {\n return {\n values,\n next: [],\n tasks: [],\n metadata: undefined,\n created_at: null,\n checkpoint: {\n thread_id: threadId,\n checkpoint_id: null,\n checkpoint_ns: \"\",\n checkpoint_map: null,\n },\n parent_checkpoint: null,\n };\n}\n\nexport function useStreamCustom<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: AnyStreamCustomOptions<StateType, Bag>\n): UseStreamCustom<StateType, Bag> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n type InterruptType = GetInterruptType<Bag>;\n type ConfigurableType = GetConfigurableType<Bag>;\n type ToolCallType = GetToolCallsType<StateType>;\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const threadIdRef = useRef<string | null>(threadId);\n\n // Cancel the stream if thread ID has changed\n useEffect(() => {\n if (threadIdRef.current !== threadId) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n }, [threadId, stream]);\n\n const getMessages = (value: StateType): Message[] => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n const setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return { ...current, [messagesKey]: messages };\n };\n\n const historyValues = options.initialValues ?? ({} as StateType);\n\n // Reconstruct subagents from initialValues when:\n // 1. Subagent filtering is enabled\n // 2. Not currently streaming\n // 3. initialValues has messages\n // This ensures subagent visualization works with cached/persisted state\n const historyMessages = getMessages(historyValues);\n const shouldReconstructSubagents =\n options.filterSubagentMessages &&\n !stream.isLoading &&\n historyMessages.length > 0;\n\n useEffect(() => {\n if (shouldReconstructSubagents) {\n // skipIfPopulated: true ensures we don't overwrite subagents from active streaming\n stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });\n }\n // We intentionally only run this when shouldReconstructSubagents changes\n // to avoid unnecessary reconstructions during streaming\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [shouldReconstructSubagents, historyMessages.length]);\n\n const stop = () => stream.stop(historyValues, { onStop: options.onStop });\n\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>\n ) => {\n let usableThreadId = threadId;\n\n stream.setStreamValues(() => {\n if (submitOptions?.optimisticValues != null) {\n return {\n ...historyValues,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(historyValues)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...historyValues };\n });\n\n await stream.start(\n async (signal: AbortSignal) => {\n if (!usableThreadId) {\n // generate random thread id\n usableThreadId = crypto.randomUUID();\n threadIdRef.current = usableThreadId;\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n return options.transport.stream({\n input: values,\n context: submitOptions?.context,\n command: submitOptions?.command,\n signal,\n config: {\n ...submitOptions?.config,\n configurable: {\n thread_id: usableThreadId,\n ...submitOptions?.config?.configurable,\n } as unknown as GetConfigurableType<Bag>,\n },\n }) as Promise<\n AsyncGenerator<EventStreamEvent<StateType, UpdateType, CustomType>>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: {} as StateType,\n callbacks: options,\n\n onSuccess: () => {\n if (!usableThreadId) return undefined;\n\n const finalValues = stream.values ?? historyValues;\n options.onFinish?.(\n createCustomTransportThreadState(finalValues, usableThreadId),\n undefined\n );\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, undefined);\n },\n }\n );\n };\n\n const handledToolsRef = useRef<Set<string>>(new Set());\n useEffect(() => {\n handledToolsRef.current.clear();\n }, [threadId]);\n\n useEffect(() => {\n flushPendingHeadlessToolInterrupts(\n stream.values as Record<string, unknown> | null,\n options.tools,\n handledToolsRef.current,\n {\n onTool: options.onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n submit(null, {\n command,\n }),\n }\n );\n }, [options.onTool, options.tools, stream.values, submit]);\n\n return {\n get values() {\n return stream.values ?? ({} as StateType);\n },\n\n error: stream.error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n\n get interrupts(): Interrupt<InterruptType>[] {\n if (\n stream.values != null &&\n \"__interrupt__\" in stream.values &&\n Array.isArray(stream.values.__interrupt__)\n ) {\n return userFacingInterruptsFromValuesArray<InterruptType>(\n stream.values.__interrupt__ as Interrupt<InterruptType>[]\n );\n }\n\n return [];\n },\n\n get interrupt(): Interrupt<InterruptType> | undefined {\n const all = this.interrupts;\n if (all.length === 0) return undefined;\n if (all.length === 1) return all[0];\n\n // Multiple interrupts: return the array for backward compat\n return all as Interrupt<InterruptType>;\n },\n\n get messages(): Message<ToolCallType>[] {\n if (!stream.values) return [];\n return getMessages(stream.values);\n },\n\n get toolCalls() {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n getToolCalls(message) {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n get subagents() {\n return stream.getSubagents();\n },\n\n get activeSubagents() {\n return stream.getActiveSubagents();\n },\n\n getSubagent(toolCallId: string) {\n return stream.getSubagent(toolCallId);\n },\n\n getSubagentsByType(type: string) {\n return stream.getSubagentsByType(type);\n },\n\n getSubagentsByMessage(messageId: string) {\n return stream.getSubagentsByMessage(messageId);\n },\n };\n}\n"],"mappings":"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"}
{"version":3,"file":"stream.custom.cjs","names":["BytesLineDecoder","SSEDecoder","IterableReadableStream","MessageTupleManager","StreamManager","useControllableThreadId","userFacingInterruptsFromValuesArray","getToolCallsWithResults"],"sources":["../../src/react/stream.custom.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useRef, useState, useSyncExternalStore } from \"react\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport { DEFAULT_MESSAGES_KEY } from \"../stream/constants.js\";\nimport type {\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetToolCallsType,\n GetConfigurableType,\n UseStreamTransport,\n AnyStreamCustomOptions,\n CustomSubmitOptions,\n} from \"../ui/types.js\";\nimport type { UseStreamCustom } from \"./types.js\";\nimport { type Message } from \"../types.messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport { userFacingInterruptsFromValuesArray } from \"../ui/interrupts.js\";\nimport { Interrupt, type ThreadState } from \"../schema.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../utils/sse.js\";\nimport { IterableReadableStream } from \"../utils/stream.js\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport { Command } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport { flushPendingHeadlessToolInterrupts } from \"../headless-tools.js\";\n\ninterface FetchStreamTransportOptions {\n /**\n * The URL of the API to use.\n */\n apiUrl: string;\n\n /**\n * Default headers to send with requests.\n */\n defaultHeaders?: HeadersInit;\n\n /**\n * Specify a custom fetch implementation.\n */\n fetch?: typeof fetch | ((...args: any[]) => any); // eslint-disable-line @typescript-eslint/no-explicit-any\n\n /**\n * Callback that is called before the request is made.\n */\n onRequest?: (\n url: string,\n init: RequestInit\n ) => Promise<RequestInit> | RequestInit;\n}\n\nexport class FetchStreamTransport<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n> implements UseStreamTransport<StateType, Bag> {\n constructor(private readonly options: FetchStreamTransportOptions) {}\n\n async stream(payload: {\n input: GetUpdateType<Bag, StateType> | null | undefined;\n context: GetConfigurableType<Bag> | undefined;\n command: Command | undefined;\n signal: AbortSignal;\n }): Promise<AsyncGenerator<{ id?: string; event: string; data: unknown }>> {\n const { signal, ...body } = payload;\n\n let requestInit: RequestInit = {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.options.defaultHeaders,\n },\n body: JSON.stringify(body),\n signal,\n };\n\n if (this.options.onRequest) {\n requestInit = await this.options.onRequest(\n this.options.apiUrl,\n requestInit\n );\n }\n const fetchFn = this.options.fetch ?? fetch;\n\n const response = await fetchFn(this.options.apiUrl, requestInit);\n if (!response.ok) {\n throw new Error(`Failed to stream: ${response.statusText}`);\n }\n\n const stream = (\n response.body || new ReadableStream({ start: (ctrl) => ctrl.close() })\n )\n .pipeThrough(BytesLineDecoder())\n .pipeThrough(SSEDecoder());\n\n return IterableReadableStream.fromReadableStream(stream);\n }\n}\n\nfunction createCustomTransportThreadState<\n StateType extends Record<string, unknown>,\n>(values: StateType, threadId: string): ThreadState<StateType> {\n return {\n values,\n next: [],\n tasks: [],\n metadata: undefined,\n created_at: null,\n checkpoint: {\n thread_id: threadId,\n checkpoint_id: null,\n checkpoint_ns: \"\",\n checkpoint_map: null,\n },\n parent_checkpoint: null,\n };\n}\n\nexport function useStreamCustom<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: AnyStreamCustomOptions<StateType, Bag>\n): UseStreamCustom<StateType, Bag> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n type InterruptType = GetInterruptType<Bag>;\n type ConfigurableType = GetConfigurableType<Bag>;\n type ToolCallType = GetToolCallsType<StateType>;\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const threadIdRef = useRef<string | null>(threadId);\n\n // Cancel the stream if thread ID has changed\n useEffect(() => {\n if (threadIdRef.current !== threadId) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n }, [threadId, stream]);\n\n const getMessages = (value: StateType): Message[] => {\n const messagesKey = options.messagesKey ?? DEFAULT_MESSAGES_KEY;\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n const setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = options.messagesKey ?? DEFAULT_MESSAGES_KEY;\n return { ...current, [messagesKey]: messages };\n };\n\n const historyValues = options.initialValues ?? ({} as StateType);\n\n // Reconstruct subagents from initialValues when:\n // 1. Subagent filtering is enabled\n // 2. Not currently streaming\n // 3. initialValues has messages\n // This ensures subagent visualization works with cached/persisted state\n const historyMessages = getMessages(historyValues);\n const shouldReconstructSubagents =\n options.filterSubagentMessages &&\n !stream.isLoading &&\n historyMessages.length > 0;\n\n useEffect(() => {\n if (shouldReconstructSubagents) {\n // skipIfPopulated: true ensures we don't overwrite subagents from active streaming\n stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });\n }\n // We intentionally only run this when shouldReconstructSubagents changes\n // to avoid unnecessary reconstructions during streaming\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [shouldReconstructSubagents, historyMessages.length]);\n\n const stop = () => stream.stop(historyValues, { onStop: options.onStop });\n\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>\n ) => {\n let usableThreadId = threadId;\n\n stream.setStreamValues(() => {\n if (submitOptions?.optimisticValues != null) {\n return {\n ...historyValues,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(historyValues)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...historyValues };\n });\n\n await stream.start(\n async (signal: AbortSignal) => {\n if (!usableThreadId) {\n // generate random thread id\n usableThreadId = crypto.randomUUID();\n threadIdRef.current = usableThreadId;\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n return options.transport.stream({\n input: values,\n context: submitOptions?.context,\n command: submitOptions?.command,\n signal,\n config: {\n ...submitOptions?.config,\n configurable: {\n thread_id: usableThreadId,\n ...submitOptions?.config?.configurable,\n } as unknown as GetConfigurableType<Bag>,\n },\n }) as Promise<\n AsyncGenerator<EventStreamEvent<StateType, UpdateType, CustomType>>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: {} as StateType,\n callbacks: options,\n\n onSuccess: () => {\n if (!usableThreadId) return undefined;\n\n const finalValues = stream.values ?? historyValues;\n options.onFinish?.(\n createCustomTransportThreadState(finalValues, usableThreadId),\n undefined\n );\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, undefined);\n },\n }\n );\n };\n\n const handledToolsRef = useRef<Set<string>>(new Set());\n useEffect(() => {\n handledToolsRef.current.clear();\n }, [threadId]);\n\n useEffect(() => {\n flushPendingHeadlessToolInterrupts(\n stream.values as Record<string, unknown> | null,\n options.tools,\n handledToolsRef.current,\n {\n onTool: options.onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n submit(null, {\n command,\n }),\n }\n );\n }, [options.onTool, options.tools, stream.values, submit]);\n\n return {\n get values() {\n return stream.values ?? ({} as StateType);\n },\n\n error: stream.error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n\n get interrupts(): Interrupt<InterruptType>[] {\n if (\n stream.values != null &&\n \"__interrupt__\" in stream.values &&\n Array.isArray(stream.values.__interrupt__)\n ) {\n return userFacingInterruptsFromValuesArray<InterruptType>(\n stream.values.__interrupt__ as Interrupt<InterruptType>[]\n );\n }\n\n return [];\n },\n\n get interrupt(): Interrupt<InterruptType> | undefined {\n const all = this.interrupts;\n if (all.length === 0) return undefined;\n if (all.length === 1) return all[0];\n\n // Multiple interrupts: return the array for backward compat\n return all as Interrupt<InterruptType>;\n },\n\n get messages(): Message<ToolCallType>[] {\n if (!stream.values) return [];\n return getMessages(stream.values);\n },\n\n get toolCalls() {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n getToolCalls(message) {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n get subagents() {\n return stream.getSubagents();\n },\n\n get activeSubagents() {\n return stream.getActiveSubagents();\n },\n\n getSubagent(toolCallId: string) {\n return stream.getSubagent(toolCallId);\n },\n\n getSubagentsByType(type: string) {\n return stream.getSubagentsByType(type);\n },\n\n getSubagentsByMessage(messageId: string) {\n return stream.getSubagentsByMessage(messageId);\n },\n };\n}\n"],"mappings":"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"}

@@ -1,1 +0,1 @@

{"version":3,"file":"stream.custom.d.cts","names":[],"sources":["../../src/react/stream.custom.tsx"],"mappings":";;;;;UA6BU,2BAAA;EAAA;;;EAIR,MAAA;EAUe;;;EALf,cAAA,GAAiB,WAAA;EAaW;;;EAR5B,KAAA,UAAe,KAAA,QAAa,IAAA;EAL5B;;;EAUA,SAAA,IACE,GAAA,UACA,IAAA,EAAM,WAAA,KACH,OAAA,CAAQ,WAAA,IAAe,WAAA;AAAA;AAAA,cAGjB,oBAAA,mBACO,MAAA,oBAA0B,MAAA,+BAChC,WAAA,GAAc,WAAA,aACf,kBAAA,CAAmB,SAAA,EAAW,GAAA;EAAA,iBACZ,OAAA;EAA7B,WAAA,CAA6B,OAAA,EAAS,2BAAA;EAEhC,MAAA,CAAO,OAAA;IACX,KAAA,EAAO,aAAA,CAAc,GAAA,EAAK,SAAA;IAC1B,OAAA,EAAS,mBAAA,CAAoB,GAAA;IAC7B,OAAA,EAAS,OAAA;IACT,MAAA,EAAQ,WAAA;EAAA,IACN,OAAA,CAAQ,cAAA;IAAiB,EAAA;IAAa,KAAA;IAAe,IAAA;EAAA;AAAA"}
{"version":3,"file":"stream.custom.d.cts","names":[],"sources":["../../src/react/stream.custom.tsx"],"mappings":";;;;;UA8BU,2BAAA;EAAA;;;EAIR,MAAA;EAUe;;;EALf,cAAA,GAAiB,WAAA;EAaW;;;EAR5B,KAAA,UAAe,KAAA,QAAa,IAAA;EAL5B;;;EAUA,SAAA,IACE,GAAA,UACA,IAAA,EAAM,WAAA,KACH,OAAA,CAAQ,WAAA,IAAe,WAAA;AAAA;AAAA,cAGjB,oBAAA,mBACO,MAAA,oBAA0B,MAAA,+BAChC,WAAA,GAAc,WAAA,aACf,kBAAA,CAAmB,SAAA,EAAW,GAAA;EAAA,iBACZ,OAAA;EAA7B,WAAA,CAA6B,OAAA,EAAS,2BAAA;EAEhC,MAAA,CAAO,OAAA;IACX,KAAA,EAAO,aAAA,CAAc,GAAA,EAAK,SAAA;IAC1B,OAAA,EAAS,mBAAA,CAAoB,GAAA;IAC7B,OAAA,EAAS,OAAA;IACT,MAAA,EAAQ,WAAA;EAAA,IACN,OAAA,CAAQ,cAAA;IAAiB,EAAA;IAAa,KAAA;IAAe,IAAA;EAAA;AAAA"}

@@ -1,1 +0,1 @@

{"version":3,"file":"stream.custom.d.ts","names":[],"sources":["../../src/react/stream.custom.tsx"],"mappings":";;;;UA6BU,2BAAA;;AAH8C;;EAOtD,MAAA;EAKiB;;;EAAjB,cAAA,GAAiB,WAAA;EAaZ;;;EARL,KAAA,UAAe,KAAA,QAAa,IAAA;EAV5B;;;EAeA,SAAA,IACE,GAAA,UACA,IAAA,EAAM,WAAA,KACH,OAAA,CAAQ,WAAA,IAAe,WAAA;AAAA;AAAA,cAGjB,oBAAA,mBACO,MAAA,oBAA0B,MAAA,+BAChC,WAAA,GAAc,WAAA,aACf,kBAAA,CAAmB,SAAA,EAAW,GAAA;EAAA,iBACZ,OAAA;EAA7B,WAAA,CAA6B,OAAA,EAAS,2BAAA;EAEhC,MAAA,CAAO,OAAA;IACX,KAAA,EAAO,aAAA,CAAc,GAAA,EAAK,SAAA;IAC1B,OAAA,EAAS,mBAAA,CAAoB,GAAA;IAC7B,OAAA,EAAS,OAAA;IACT,MAAA,EAAQ,WAAA;EAAA,IACN,OAAA,CAAQ,cAAA;IAAiB,EAAA;IAAa,KAAA;IAAe,IAAA;EAAA;AAAA"}
{"version":3,"file":"stream.custom.d.ts","names":[],"sources":["../../src/react/stream.custom.tsx"],"mappings":";;;;UA8BU,2BAAA;;AAH8C;;EAOtD,MAAA;EAKiB;;;EAAjB,cAAA,GAAiB,WAAA;EAaZ;;;EARL,KAAA,UAAe,KAAA,QAAa,IAAA;EAV5B;;;EAeA,SAAA,IACE,GAAA,UACA,IAAA,EAAM,WAAA,KACH,OAAA,CAAQ,WAAA,IAAe,WAAA;AAAA;AAAA,cAGjB,oBAAA,mBACO,MAAA,oBAA0B,MAAA,+BAChC,WAAA,GAAc,WAAA,aACf,kBAAA,CAAmB,SAAA,EAAW,GAAA;EAAA,iBACZ,OAAA;EAA7B,WAAA,CAA6B,OAAA,EAAS,2BAAA;EAEhC,MAAA,CAAO,OAAA;IACX,KAAA,EAAO,aAAA,CAAc,GAAA,EAAK,SAAA;IAC1B,OAAA,EAAS,mBAAA,CAAoB,GAAA;IAC7B,OAAA,EAAS,OAAA;IACT,MAAA,EAAQ,WAAA;EAAA,IACN,OAAA,CAAQ,cAAA;IAAiB,EAAA;IAAa,KAAA;IAAe,IAAA;EAAA;AAAA"}
"use client";
import { BytesLineDecoder, SSEDecoder } from "../utils/sse.js";
import { IterableReadableStream } from "../utils/stream.js";
import "../stream/constants.js";
import { MessageTupleManager } from "../ui/messages.js";

@@ -5,0 +6,0 @@ import { flushPendingHeadlessToolInterrupts } from "../headless-tools.js";

@@ -1,1 +0,1 @@

{"version":3,"file":"stream.custom.js","names":[],"sources":["../../src/react/stream.custom.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useRef, useState, useSyncExternalStore } from \"react\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport type {\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetToolCallsType,\n GetConfigurableType,\n UseStreamTransport,\n AnyStreamCustomOptions,\n CustomSubmitOptions,\n} from \"../ui/types.js\";\nimport type { UseStreamCustom } from \"./types.js\";\nimport { type Message } from \"../types.messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport { userFacingInterruptsFromValuesArray } from \"../ui/interrupts.js\";\nimport { Interrupt, type ThreadState } from \"../schema.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../utils/sse.js\";\nimport { IterableReadableStream } from \"../utils/stream.js\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport { Command } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport { flushPendingHeadlessToolInterrupts } from \"../headless-tools.js\";\n\ninterface FetchStreamTransportOptions {\n /**\n * The URL of the API to use.\n */\n apiUrl: string;\n\n /**\n * Default headers to send with requests.\n */\n defaultHeaders?: HeadersInit;\n\n /**\n * Specify a custom fetch implementation.\n */\n fetch?: typeof fetch | ((...args: any[]) => any); // eslint-disable-line @typescript-eslint/no-explicit-any\n\n /**\n * Callback that is called before the request is made.\n */\n onRequest?: (\n url: string,\n init: RequestInit\n ) => Promise<RequestInit> | RequestInit;\n}\n\nexport class FetchStreamTransport<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n> implements UseStreamTransport<StateType, Bag> {\n constructor(private readonly options: FetchStreamTransportOptions) {}\n\n async stream(payload: {\n input: GetUpdateType<Bag, StateType> | null | undefined;\n context: GetConfigurableType<Bag> | undefined;\n command: Command | undefined;\n signal: AbortSignal;\n }): Promise<AsyncGenerator<{ id?: string; event: string; data: unknown }>> {\n const { signal, ...body } = payload;\n\n let requestInit: RequestInit = {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.options.defaultHeaders,\n },\n body: JSON.stringify(body),\n signal,\n };\n\n if (this.options.onRequest) {\n requestInit = await this.options.onRequest(\n this.options.apiUrl,\n requestInit\n );\n }\n const fetchFn = this.options.fetch ?? fetch;\n\n const response = await fetchFn(this.options.apiUrl, requestInit);\n if (!response.ok) {\n throw new Error(`Failed to stream: ${response.statusText}`);\n }\n\n const stream = (\n response.body || new ReadableStream({ start: (ctrl) => ctrl.close() })\n )\n .pipeThrough(BytesLineDecoder())\n .pipeThrough(SSEDecoder());\n\n return IterableReadableStream.fromReadableStream(stream);\n }\n}\n\nfunction createCustomTransportThreadState<\n StateType extends Record<string, unknown>,\n>(values: StateType, threadId: string): ThreadState<StateType> {\n return {\n values,\n next: [],\n tasks: [],\n metadata: undefined,\n created_at: null,\n checkpoint: {\n thread_id: threadId,\n checkpoint_id: null,\n checkpoint_ns: \"\",\n checkpoint_map: null,\n },\n parent_checkpoint: null,\n };\n}\n\nexport function useStreamCustom<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: AnyStreamCustomOptions<StateType, Bag>\n): UseStreamCustom<StateType, Bag> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n type InterruptType = GetInterruptType<Bag>;\n type ConfigurableType = GetConfigurableType<Bag>;\n type ToolCallType = GetToolCallsType<StateType>;\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const threadIdRef = useRef<string | null>(threadId);\n\n // Cancel the stream if thread ID has changed\n useEffect(() => {\n if (threadIdRef.current !== threadId) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n }, [threadId, stream]);\n\n const getMessages = (value: StateType): Message[] => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n const setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return { ...current, [messagesKey]: messages };\n };\n\n const historyValues = options.initialValues ?? ({} as StateType);\n\n // Reconstruct subagents from initialValues when:\n // 1. Subagent filtering is enabled\n // 2. Not currently streaming\n // 3. initialValues has messages\n // This ensures subagent visualization works with cached/persisted state\n const historyMessages = getMessages(historyValues);\n const shouldReconstructSubagents =\n options.filterSubagentMessages &&\n !stream.isLoading &&\n historyMessages.length > 0;\n\n useEffect(() => {\n if (shouldReconstructSubagents) {\n // skipIfPopulated: true ensures we don't overwrite subagents from active streaming\n stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });\n }\n // We intentionally only run this when shouldReconstructSubagents changes\n // to avoid unnecessary reconstructions during streaming\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [shouldReconstructSubagents, historyMessages.length]);\n\n const stop = () => stream.stop(historyValues, { onStop: options.onStop });\n\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>\n ) => {\n let usableThreadId = threadId;\n\n stream.setStreamValues(() => {\n if (submitOptions?.optimisticValues != null) {\n return {\n ...historyValues,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(historyValues)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...historyValues };\n });\n\n await stream.start(\n async (signal: AbortSignal) => {\n if (!usableThreadId) {\n // generate random thread id\n usableThreadId = crypto.randomUUID();\n threadIdRef.current = usableThreadId;\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n return options.transport.stream({\n input: values,\n context: submitOptions?.context,\n command: submitOptions?.command,\n signal,\n config: {\n ...submitOptions?.config,\n configurable: {\n thread_id: usableThreadId,\n ...submitOptions?.config?.configurable,\n } as unknown as GetConfigurableType<Bag>,\n },\n }) as Promise<\n AsyncGenerator<EventStreamEvent<StateType, UpdateType, CustomType>>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: {} as StateType,\n callbacks: options,\n\n onSuccess: () => {\n if (!usableThreadId) return undefined;\n\n const finalValues = stream.values ?? historyValues;\n options.onFinish?.(\n createCustomTransportThreadState(finalValues, usableThreadId),\n undefined\n );\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, undefined);\n },\n }\n );\n };\n\n const handledToolsRef = useRef<Set<string>>(new Set());\n useEffect(() => {\n handledToolsRef.current.clear();\n }, [threadId]);\n\n useEffect(() => {\n flushPendingHeadlessToolInterrupts(\n stream.values as Record<string, unknown> | null,\n options.tools,\n handledToolsRef.current,\n {\n onTool: options.onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n submit(null, {\n command,\n }),\n }\n );\n }, [options.onTool, options.tools, stream.values, submit]);\n\n return {\n get values() {\n return stream.values ?? ({} as StateType);\n },\n\n error: stream.error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n\n get interrupts(): Interrupt<InterruptType>[] {\n if (\n stream.values != null &&\n \"__interrupt__\" in stream.values &&\n Array.isArray(stream.values.__interrupt__)\n ) {\n return userFacingInterruptsFromValuesArray<InterruptType>(\n stream.values.__interrupt__ as Interrupt<InterruptType>[]\n );\n }\n\n return [];\n },\n\n get interrupt(): Interrupt<InterruptType> | undefined {\n const all = this.interrupts;\n if (all.length === 0) return undefined;\n if (all.length === 1) return all[0];\n\n // Multiple interrupts: return the array for backward compat\n return all as Interrupt<InterruptType>;\n },\n\n get messages(): Message<ToolCallType>[] {\n if (!stream.values) return [];\n return getMessages(stream.values);\n },\n\n get toolCalls() {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n getToolCalls(message) {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n get subagents() {\n return stream.getSubagents();\n },\n\n get activeSubagents() {\n return stream.getActiveSubagents();\n },\n\n getSubagent(toolCallId: string) {\n return stream.getSubagent(toolCallId);\n },\n\n getSubagentsByType(type: string) {\n return stream.getSubagentsByType(type);\n },\n\n getSubagentsByMessage(messageId: string) {\n return stream.getSubagentsByMessage(messageId);\n },\n };\n}\n"],"mappings":"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"}
{"version":3,"file":"stream.custom.js","names":[],"sources":["../../src/react/stream.custom.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport { useEffect, useRef, useState, useSyncExternalStore } from \"react\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport { DEFAULT_MESSAGES_KEY } from \"../stream/constants.js\";\nimport type {\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetToolCallsType,\n GetConfigurableType,\n UseStreamTransport,\n AnyStreamCustomOptions,\n CustomSubmitOptions,\n} from \"../ui/types.js\";\nimport type { UseStreamCustom } from \"./types.js\";\nimport { type Message } from \"../types.messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport { userFacingInterruptsFromValuesArray } from \"../ui/interrupts.js\";\nimport { Interrupt, type ThreadState } from \"../schema.js\";\nimport { BytesLineDecoder, SSEDecoder } from \"../utils/sse.js\";\nimport { IterableReadableStream } from \"../utils/stream.js\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport { Command } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport { flushPendingHeadlessToolInterrupts } from \"../headless-tools.js\";\n\ninterface FetchStreamTransportOptions {\n /**\n * The URL of the API to use.\n */\n apiUrl: string;\n\n /**\n * Default headers to send with requests.\n */\n defaultHeaders?: HeadersInit;\n\n /**\n * Specify a custom fetch implementation.\n */\n fetch?: typeof fetch | ((...args: any[]) => any); // eslint-disable-line @typescript-eslint/no-explicit-any\n\n /**\n * Callback that is called before the request is made.\n */\n onRequest?: (\n url: string,\n init: RequestInit\n ) => Promise<RequestInit> | RequestInit;\n}\n\nexport class FetchStreamTransport<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n> implements UseStreamTransport<StateType, Bag> {\n constructor(private readonly options: FetchStreamTransportOptions) {}\n\n async stream(payload: {\n input: GetUpdateType<Bag, StateType> | null | undefined;\n context: GetConfigurableType<Bag> | undefined;\n command: Command | undefined;\n signal: AbortSignal;\n }): Promise<AsyncGenerator<{ id?: string; event: string; data: unknown }>> {\n const { signal, ...body } = payload;\n\n let requestInit: RequestInit = {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.options.defaultHeaders,\n },\n body: JSON.stringify(body),\n signal,\n };\n\n if (this.options.onRequest) {\n requestInit = await this.options.onRequest(\n this.options.apiUrl,\n requestInit\n );\n }\n const fetchFn = this.options.fetch ?? fetch;\n\n const response = await fetchFn(this.options.apiUrl, requestInit);\n if (!response.ok) {\n throw new Error(`Failed to stream: ${response.statusText}`);\n }\n\n const stream = (\n response.body || new ReadableStream({ start: (ctrl) => ctrl.close() })\n )\n .pipeThrough(BytesLineDecoder())\n .pipeThrough(SSEDecoder());\n\n return IterableReadableStream.fromReadableStream(stream);\n }\n}\n\nfunction createCustomTransportThreadState<\n StateType extends Record<string, unknown>,\n>(values: StateType, threadId: string): ThreadState<StateType> {\n return {\n values,\n next: [],\n tasks: [],\n metadata: undefined,\n created_at: null,\n checkpoint: {\n thread_id: threadId,\n checkpoint_id: null,\n checkpoint_ns: \"\",\n checkpoint_map: null,\n },\n parent_checkpoint: null,\n };\n}\n\nexport function useStreamCustom<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(\n options: AnyStreamCustomOptions<StateType, Bag>\n): UseStreamCustom<StateType, Bag> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n type InterruptType = GetInterruptType<Bag>;\n type ConfigurableType = GetConfigurableType<Bag>;\n type ToolCallType = GetToolCallsType<StateType>;\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const threadIdRef = useRef<string | null>(threadId);\n\n // Cancel the stream if thread ID has changed\n useEffect(() => {\n if (threadIdRef.current !== threadId) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n }, [threadId, stream]);\n\n const getMessages = (value: StateType): Message[] => {\n const messagesKey = options.messagesKey ?? DEFAULT_MESSAGES_KEY;\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n const setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = options.messagesKey ?? DEFAULT_MESSAGES_KEY;\n return { ...current, [messagesKey]: messages };\n };\n\n const historyValues = options.initialValues ?? ({} as StateType);\n\n // Reconstruct subagents from initialValues when:\n // 1. Subagent filtering is enabled\n // 2. Not currently streaming\n // 3. initialValues has messages\n // This ensures subagent visualization works with cached/persisted state\n const historyMessages = getMessages(historyValues);\n const shouldReconstructSubagents =\n options.filterSubagentMessages &&\n !stream.isLoading &&\n historyMessages.length > 0;\n\n useEffect(() => {\n if (shouldReconstructSubagents) {\n // skipIfPopulated: true ensures we don't overwrite subagents from active streaming\n stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });\n }\n // We intentionally only run this when shouldReconstructSubagents changes\n // to avoid unnecessary reconstructions during streaming\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [shouldReconstructSubagents, historyMessages.length]);\n\n const stop = () => stream.stop(historyValues, { onStop: options.onStop });\n\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, ConfigurableType>\n ) => {\n let usableThreadId = threadId;\n\n stream.setStreamValues(() => {\n if (submitOptions?.optimisticValues != null) {\n return {\n ...historyValues,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(historyValues)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...historyValues };\n });\n\n await stream.start(\n async (signal: AbortSignal) => {\n if (!usableThreadId) {\n // generate random thread id\n usableThreadId = crypto.randomUUID();\n threadIdRef.current = usableThreadId;\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n return options.transport.stream({\n input: values,\n context: submitOptions?.context,\n command: submitOptions?.command,\n signal,\n config: {\n ...submitOptions?.config,\n configurable: {\n thread_id: usableThreadId,\n ...submitOptions?.config?.configurable,\n } as unknown as GetConfigurableType<Bag>,\n },\n }) as Promise<\n AsyncGenerator<EventStreamEvent<StateType, UpdateType, CustomType>>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: {} as StateType,\n callbacks: options,\n\n onSuccess: () => {\n if (!usableThreadId) return undefined;\n\n const finalValues = stream.values ?? historyValues;\n options.onFinish?.(\n createCustomTransportThreadState(finalValues, usableThreadId),\n undefined\n );\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, undefined);\n },\n }\n );\n };\n\n const handledToolsRef = useRef<Set<string>>(new Set());\n useEffect(() => {\n handledToolsRef.current.clear();\n }, [threadId]);\n\n useEffect(() => {\n flushPendingHeadlessToolInterrupts(\n stream.values as Record<string, unknown> | null,\n options.tools,\n handledToolsRef.current,\n {\n onTool: options.onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n submit(null, {\n command,\n }),\n }\n );\n }, [options.onTool, options.tools, stream.values, submit]);\n\n return {\n get values() {\n return stream.values ?? ({} as StateType);\n },\n\n error: stream.error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n\n get interrupts(): Interrupt<InterruptType>[] {\n if (\n stream.values != null &&\n \"__interrupt__\" in stream.values &&\n Array.isArray(stream.values.__interrupt__)\n ) {\n return userFacingInterruptsFromValuesArray<InterruptType>(\n stream.values.__interrupt__ as Interrupt<InterruptType>[]\n );\n }\n\n return [];\n },\n\n get interrupt(): Interrupt<InterruptType> | undefined {\n const all = this.interrupts;\n if (all.length === 0) return undefined;\n if (all.length === 1) return all[0];\n\n // Multiple interrupts: return the array for backward compat\n return all as Interrupt<InterruptType>;\n },\n\n get messages(): Message<ToolCallType>[] {\n if (!stream.values) return [];\n return getMessages(stream.values);\n },\n\n get toolCalls() {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n getToolCalls(message) {\n if (!stream.values) return [];\n const msgs = getMessages(stream.values);\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n get subagents() {\n return stream.getSubagents();\n },\n\n get activeSubagents() {\n return stream.getActiveSubagents();\n },\n\n getSubagent(toolCallId: string) {\n return stream.getSubagent(toolCallId);\n },\n\n getSubagentsByType(type: string) {\n return stream.getSubagentsByType(type);\n },\n\n getSubagentsByMessage(messageId: string) {\n return stream.getSubagentsByMessage(messageId);\n },\n };\n}\n"],"mappings":"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"}
"use client";
require("../_virtual/_rolldown/runtime.cjs");
require("../stream/constants.cjs");
const require_messages = require("../ui/messages.cjs");

@@ -4,0 +5,0 @@ const require_headless_tools = require("../headless-tools.cjs");

@@ -1,1 +0,1 @@

{"version":3,"file":"stream.lgp.cjs","names":["getClientConfigHash","Client","MessageTupleManager","StreamManager","useControllableThreadId","getBranchContext","StreamError","findLast","onFinishRequiresThreadState","unique","filterStream","userFacingInterruptsFromValuesArray","userFacingInterruptsFromThreadTasks","getToolCallsWithResults"],"sources":["../../src/react/stream.lgp.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport {\n type RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n filterStream,\n findLast,\n onFinishRequiresThreadState,\n unique,\n} from \"../ui/utils.js\";\nimport { StreamError } from \"../ui/errors.js\";\nimport { getBranchContext } from \"../ui/branching.js\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport type {\n AnyStreamOptions,\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetConfigurableType,\n GetToolCallsType,\n RunCallbackMeta,\n MessageMetadata,\n UseStreamThread,\n} from \"../ui/types.js\";\nimport type { UseStream, SubmitOptions } from \"./types.js\";\n\nimport { Client, getClientConfigHash } from \"../client.js\";\nimport { type Message } from \"../types.messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport type { Interrupt, ThreadState } from \"../schema.js\";\nimport type {\n StreamMode,\n ToolProgress,\n ToolsStreamEvent,\n} from \"../types.stream.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport {\n userFacingInterruptsFromThreadTasks,\n userFacingInterruptsFromValuesArray,\n} from \"../ui/interrupts.js\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport type { StreamEvent } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport { flushPendingHeadlessToolInterrupts } from \"../headless-tools.js\";\n\nfunction getFetchHistoryKey(\n client: Client,\n threadId: string | undefined | null,\n limit: boolean | number\n) {\n return [getClientConfigHash(client), threadId, limit].join(\":\");\n}\n\nfunction fetchHistory<StateType extends Record<string, unknown>>(\n client: Client,\n threadId: string,\n options?: { limit?: boolean | number }\n) {\n if (options?.limit === false) {\n return client.threads.getState<StateType>(threadId).then((state) => {\n if (state.checkpoint == null) return [];\n return [state];\n });\n }\n\n const limit = typeof options?.limit === \"number\" ? options.limit : 10;\n return client.threads.getHistory<StateType>(threadId, { limit });\n}\n\nfunction useThreadHistory<StateType extends Record<string, unknown>>(\n client: Client,\n threadId: string | undefined | null,\n limit: boolean | number,\n options: {\n passthrough: boolean;\n submittingRef: RefObject<string | null>;\n onError?: (error: unknown, run?: RunCallbackMeta) => void;\n }\n): UseStreamThread<StateType> {\n const key = getFetchHistoryKey(client, threadId, limit);\n const [state, setState] = useState<{\n key: string | undefined;\n data: ThreadState<StateType>[] | undefined;\n error: unknown | undefined;\n isLoading: boolean;\n }>(() => ({\n key: undefined,\n data: undefined,\n error: undefined,\n isLoading: threadId != null,\n }));\n\n const clientRef = useRef(client);\n clientRef.current = client;\n\n const onErrorRef = useRef(options?.onError);\n onErrorRef.current = options?.onError;\n\n const fetcher = useCallback(\n (\n threadId: string | undefined | null,\n limit: boolean | number\n ): Promise<ThreadState<StateType>[]> => {\n // If only passthrough is enabled, don't fetch history\n if (options.passthrough) return Promise.resolve([]);\n\n const client = clientRef.current;\n const key = getFetchHistoryKey(client, threadId, limit);\n\n if (threadId != null) {\n setState((state) => {\n if (state.key === key) return { ...state, isLoading: true };\n return { key, data: undefined, error: undefined, isLoading: true };\n });\n return fetchHistory<StateType>(client, threadId, { limit }).then(\n (data) => {\n setState((state) => {\n if (state.key !== key) return state;\n return { key, data, error: undefined, isLoading: false };\n });\n return data;\n },\n (error) => {\n setState((state) => {\n if (state.key !== key) return state;\n return { key, data: state.data, error, isLoading: false };\n });\n onErrorRef.current?.(error);\n return Promise.reject(error);\n }\n );\n }\n\n setState({ key, data: undefined, error: undefined, isLoading: false });\n return Promise.resolve([]);\n },\n [options.passthrough]\n );\n\n useEffect(() => {\n // Skip if a stream is already in progress, no need to fetch history\n if (\n options.submittingRef.current != null &&\n options.submittingRef.current === threadId\n ) {\n return;\n }\n\n void fetcher(threadId, limit);\n // The `threadId` and `limit` arguments are already present in `key`\n // Thus we don't need to include them in the dependency array\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fetcher, key]);\n\n return {\n data: state.data,\n error: state.error,\n isLoading: state.isLoading,\n mutate: (mutateId?: string) => fetcher(mutateId ?? threadId, limit),\n };\n}\n\nexport function useStreamLGP<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(options: AnyStreamOptions<StateType, Bag>): UseStream<StateType, Bag> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n type InterruptType = GetInterruptType<Bag>;\n type ConfigurableType = GetConfigurableType<Bag>;\n type ToolCallType = GetToolCallsType<StateType>;\n\n const reconnectOnMountRef = useRef(options.reconnectOnMount);\n const runMetadataStorage = useMemo(() => {\n if (typeof window === \"undefined\") return null;\n const storage = reconnectOnMountRef.current;\n if (storage === true) return window.sessionStorage;\n if (typeof storage === \"function\") return storage();\n return null;\n }, []);\n\n const client = useMemo(\n () =>\n options.client ??\n new Client({\n apiUrl: options.apiUrl,\n apiKey: options.apiKey,\n callerOptions: options.callerOptions,\n defaultHeaders: options.defaultHeaders,\n }),\n [\n options.client,\n options.apiKey,\n options.apiUrl,\n options.callerOptions,\n options.defaultHeaders,\n ]\n );\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const trackStreamModeRef = useRef<Exclude<StreamMode, \"messages\">[]>([]);\n\n const trackStreamMode = useCallback(\n (...mode: Exclude<StreamMode, \"messages\">[]) => {\n const ref = trackStreamModeRef.current;\n for (const m of mode) {\n if (!ref.includes(m)) ref.push(m);\n }\n },\n []\n );\n\n const hasUpdateListener = options.onUpdateEvent != null;\n const hasCustomListener = options.onCustomEvent != null;\n const hasLangChainListener = options.onLangChainEvent != null;\n const hasDebugListener = options.onDebugEvent != null;\n const hasCheckpointListener = options.onCheckpointEvent != null;\n const hasTaskListener = options.onTaskEvent != null;\n const hasToolListener = options.onToolEvent != null;\n\n const callbackStreamMode = useMemo(() => {\n const modes: Exclude<StreamMode, \"messages\">[] = [];\n if (hasUpdateListener) modes.push(\"updates\");\n if (hasCustomListener) modes.push(\"custom\");\n if (hasLangChainListener) modes.push(\"events\");\n if (hasDebugListener) modes.push(\"debug\");\n if (hasCheckpointListener) modes.push(\"checkpoints\");\n if (hasTaskListener) modes.push(\"tasks\");\n if (hasToolListener) modes.push(\"tools\");\n return modes;\n }, [\n hasUpdateListener,\n hasCustomListener,\n hasLangChainListener,\n hasDebugListener,\n hasCheckpointListener,\n hasTaskListener,\n hasToolListener,\n ]);\n\n const threadIdRef = useRef<string | null>(threadId);\n const threadIdStreamingRef = useRef<string | null>(null);\n\n // Cancel the stream if thread ID has changed\n useEffect(() => {\n if (threadIdRef.current !== threadId) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n }, [threadId, stream]);\n\n const switchThread = useCallback(\n (newThreadId: string | null) => {\n if (newThreadId !== threadIdRef.current) {\n threadIdRef.current = newThreadId;\n stream.clear();\n onThreadId(newThreadId as string);\n }\n },\n [stream, onThreadId]\n );\n\n const historyLimit =\n typeof options.fetchStateHistory === \"object\" &&\n options.fetchStateHistory != null\n ? (options.fetchStateHistory.limit ?? false)\n : (options.fetchStateHistory ?? false);\n\n const builtInHistory = useThreadHistory<StateType>(\n client,\n threadId,\n historyLimit,\n {\n passthrough: options.thread != null,\n submittingRef: threadIdStreamingRef,\n onError: options.onError,\n }\n );\n const history = options.thread ?? builtInHistory;\n\n const getMessages = (value: StateType): Message[] => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n const setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return { ...current, [messagesKey]: messages };\n };\n\n const [branch, setBranch] = useState<string>(\"\");\n const branchContext = getBranchContext(branch, history.data ?? undefined);\n\n const [toolProgressMap, setToolProgressMap] = useState<\n Map<string, ToolProgress>\n >(new Map());\n\n const handleToolEvent = useCallback((data: ToolsStreamEvent[\"data\"]) => {\n setToolProgressMap((prev) => {\n const next = new Map(prev);\n const key = data.toolCallId ?? data.name;\n const existing = next.get(key);\n\n switch (data.event) {\n case \"on_tool_start\": {\n next.set(key, {\n toolCallId: data.toolCallId,\n name: data.name,\n state: \"starting\",\n input: data.input,\n });\n break;\n }\n case \"on_tool_event\": {\n if (existing) {\n next.set(key, { ...existing, state: \"running\", data: data.data });\n }\n break;\n }\n case \"on_tool_end\": {\n if (existing) {\n next.set(key, {\n ...existing,\n state: \"completed\",\n result: data.output,\n });\n }\n break;\n }\n case \"on_tool_error\": {\n if (existing) {\n next.set(key, { ...existing, state: \"error\", error: data.error });\n }\n break;\n }\n default: {\n throw new Error(\n `Unexpected tool event: ${(data as { event: string }).event}`\n );\n }\n }\n\n return next;\n });\n }, []);\n\n const historyValues =\n branchContext.threadHead?.values ??\n options.initialValues ??\n ({} as StateType);\n\n // Reconstruct subagents from history when:\n // 1. History is loaded (not loading, has data)\n // 2. No active stream is running\n // 3. Subagent filtering is enabled (otherwise subagents aren't tracked)\n // This ensures subagent visualization persists after page refresh or stream completion\n const historyMessages = getMessages(historyValues);\n const shouldReconstructSubagents =\n options.filterSubagentMessages &&\n !stream.isLoading &&\n !history.isLoading &&\n historyMessages.length > 0;\n\n useEffect(() => {\n if (shouldReconstructSubagents) {\n // skipIfPopulated: true ensures we don't overwrite subagents from active streaming\n stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });\n // Fetch internal messages for each subagent from their subgraph checkpoints.\n // These messages are not in the main thread state but are persisted in the\n // checkpointer under a subgraph-specific checkpoint_ns (e.g. tools:call_abc123).\n if (historyLimit !== false && threadId) {\n const controller = new AbortController();\n void stream.fetchSubagentHistory(client.threads, threadId, {\n messagesKey: options.messagesKey ?? \"messages\",\n historyLimit:\n typeof historyLimit === \"number\" ? historyLimit : undefined,\n signal: controller.signal,\n });\n return () => controller.abort();\n }\n }\n\n // We intentionally only run this when shouldReconstructSubagents changes\n // to avoid unnecessary reconstructions during streaming\n return undefined;\n }, [shouldReconstructSubagents, historyMessages.length]);\n\n const historyError = (() => {\n const error = branchContext.threadHead?.tasks?.at(-1)?.error;\n if (error == null) return undefined;\n try {\n const parsed = JSON.parse(error) as unknown;\n if (StreamError.isStructuredError(parsed)) return new StreamError(parsed);\n return parsed;\n } catch {\n // do nothing\n }\n return error;\n })();\n\n const messageMetadata = (() => {\n const alreadyShown = new Set<string>();\n return getMessages(historyValues).map(\n (message, idx): Omit<MessageMetadata<StateType>, \"streamMetadata\"> => {\n const messageId = message.id ?? idx;\n\n // Find the first checkpoint where the message was seen\n const firstSeenState = findLast(\n history.data ?? [],\n (state) =>\n state.values != null &&\n getMessages(state.values)\n .map((m, idx) => m.id ?? idx)\n .includes(messageId)\n );\n\n const checkpointId = firstSeenState?.checkpoint?.checkpoint_id;\n let branch =\n checkpointId != null\n ? branchContext.branchByCheckpoint[checkpointId]\n : undefined;\n if (!branch?.branch?.length) branch = undefined;\n\n // serialize branches\n const optionsShown = branch?.branchOptions?.flat(2).join(\",\");\n if (optionsShown) {\n if (alreadyShown.has(optionsShown)) branch = undefined;\n alreadyShown.add(optionsShown);\n }\n\n return {\n messageId: messageId.toString(),\n firstSeenState,\n\n branch: branch?.branch,\n branchOptions: branch?.branchOptions,\n };\n }\n );\n })();\n\n const stop = () =>\n stream.stop(historyValues, {\n onStop: (args) => {\n if (runMetadataStorage && threadId) {\n const runId = runMetadataStorage.getItem(`lg:stream:${threadId}`);\n if (runId) void client.runs.cancel(threadId, runId);\n runMetadataStorage.removeItem(`lg:stream:${threadId}`);\n }\n\n options.onStop?.(args);\n },\n });\n\n // --- TRANSPORT ---\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: SubmitOptions<StateType, ConfigurableType>\n ) => {\n setToolProgressMap(new Map());\n\n // Unbranch things\n const checkpointId = submitOptions?.checkpoint?.checkpoint_id;\n setBranch(\n checkpointId != null\n ? (branchContext.branchByCheckpoint[checkpointId]?.branch ?? \"\")\n : \"\"\n );\n\n // When `fetchStateHistory` is requested, thus we assume that branching\n // is enabled. We then need to include the implicit branch.\n const includeImplicitBranch =\n historyLimit === true || typeof historyLimit === \"number\";\n\n const shouldRefetch =\n includeImplicitBranch || onFinishRequiresThreadState(options.onFinish);\n\n let callbackMeta: RunCallbackMeta | undefined;\n let rejoinKey: `lg:stream:${string}` | undefined;\n let usableThreadId = threadId;\n\n const shouldAbortPrevious =\n (submitOptions?.multitaskStrategy === \"interrupt\" ||\n submitOptions?.multitaskStrategy === \"rollback\") &&\n stream.isLoading;\n\n await stream.start(\n async (signal: AbortSignal) => {\n stream.setStreamValues((values) => {\n const prev = { ...historyValues, ...values };\n if (submitOptions?.optimisticValues != null) {\n return {\n ...prev,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(prev)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...prev };\n });\n\n if (!usableThreadId) {\n const thread = await client.threads.create({\n threadId: submitOptions?.threadId,\n metadata: submitOptions?.metadata,\n signal,\n });\n\n usableThreadId = thread.thread_id;\n\n // Pre-emptively update the thread ID before\n // stream cancellation is kicked off and thread\n // is being refetched\n threadIdRef.current = usableThreadId;\n threadIdStreamingRef.current = usableThreadId;\n\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n threadIdStreamingRef.current = usableThreadId;\n\n const streamMode = unique([\n ...(submitOptions?.streamMode ?? []),\n ...trackStreamModeRef.current,\n ...callbackStreamMode,\n ]);\n\n let checkpoint =\n submitOptions?.checkpoint ??\n (includeImplicitBranch\n ? branchContext.threadHead?.checkpoint\n : undefined) ??\n undefined;\n\n // Avoid specifying a checkpoint if user explicitly set it to null\n if (submitOptions?.checkpoint === null) checkpoint = undefined;\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n if (checkpoint != null) delete checkpoint.thread_id;\n const streamResumable =\n submitOptions?.streamResumable ?? !!runMetadataStorage;\n\n return client.runs.stream(usableThreadId, options.assistantId, {\n input: values as Record<string, unknown>,\n config: submitOptions?.config,\n context: submitOptions?.context,\n command: submitOptions?.command,\n\n interruptBefore: submitOptions?.interruptBefore,\n interruptAfter: submitOptions?.interruptAfter,\n metadata: submitOptions?.metadata,\n multitaskStrategy: submitOptions?.multitaskStrategy,\n onCompletion: submitOptions?.onCompletion,\n onDisconnect:\n submitOptions?.onDisconnect ??\n (streamResumable ? \"continue\" : \"cancel\"),\n\n signal,\n\n checkpoint,\n streamMode,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n streamResumable,\n durability: submitOptions?.durability,\n onRunCreated(params) {\n callbackMeta = {\n run_id: params.run_id,\n thread_id: params.thread_id ?? usableThreadId!,\n };\n\n if (runMetadataStorage) {\n rejoinKey = `lg:stream:${usableThreadId}`;\n runMetadataStorage.setItem(rejoinKey, callbackMeta.run_id);\n }\n\n options.onCreated?.(callbackMeta);\n },\n }) as AsyncGenerator<\n EventStreamEvent<StateType, UpdateType, CustomType>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: historyValues,\n callbacks: {\n ...options,\n onToolEvent: (data, opts) => {\n handleToolEvent(data);\n options.onToolEvent?.(data, opts);\n },\n },\n\n async onSuccess() {\n if (rejoinKey) runMetadataStorage?.removeItem(rejoinKey);\n\n if (shouldRefetch) {\n const newHistory = await history.mutate(usableThreadId!);\n const lastHead = newHistory?.at(0);\n if (lastHead) {\n // We now have the latest update from /history\n // Thus we can clear the local stream state\n options.onFinish?.(lastHead, callbackMeta);\n return null;\n }\n } else if (\n options.onFinish != null &&\n !onFinishRequiresThreadState(options.onFinish)\n ) {\n options.onFinish(\n undefined as unknown as ThreadState<StateType>,\n callbackMeta\n );\n }\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n onFinish() {\n threadIdStreamingRef.current = null;\n },\n },\n { abortPrevious: shouldAbortPrevious }\n );\n };\n\n const joinStream = async (\n runId: string,\n lastEventId?: string,\n joinOptions?: {\n streamMode?: StreamMode | StreamMode[];\n filter?: (event: {\n id?: string;\n event: StreamEvent;\n data: unknown;\n }) => boolean;\n }\n ) => {\n setToolProgressMap(new Map());\n\n // eslint-disable-next-line no-param-reassign\n lastEventId ??= \"-1\";\n if (!threadId) return;\n\n const callbackMeta: RunCallbackMeta = {\n thread_id: threadId,\n run_id: runId,\n };\n\n const includeImplicitBranchJoin =\n historyLimit === true || typeof historyLimit === \"number\";\n const shouldRefetchJoin =\n includeImplicitBranchJoin ||\n onFinishRequiresThreadState(options.onFinish);\n\n await stream.start(\n async (signal: AbortSignal) => {\n threadIdStreamingRef.current = threadId;\n const stream = client.runs.joinStream(threadId, runId, {\n signal,\n lastEventId,\n streamMode: joinOptions?.streamMode,\n }) as AsyncGenerator<\n EventStreamEvent<StateType, UpdateType, CustomType>\n >;\n\n return joinOptions?.filter != null\n ? filterStream(stream, joinOptions.filter)\n : stream;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: historyValues,\n callbacks: {\n ...options,\n onToolEvent: (data, opts) => {\n handleToolEvent(data);\n options.onToolEvent?.(data, opts);\n },\n },\n async onSuccess() {\n runMetadataStorage?.removeItem(`lg:stream:${threadId}`);\n if (!shouldRefetchJoin) {\n if (\n options.onFinish != null &&\n !onFinishRequiresThreadState(options.onFinish)\n ) {\n options.onFinish(\n undefined as unknown as ThreadState<StateType>,\n callbackMeta\n );\n }\n return;\n }\n const newHistory = await history.mutate(threadId);\n const lastHead = newHistory?.at(0);\n if (lastHead) options.onFinish?.(lastHead, callbackMeta);\n },\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n onFinish() {\n threadIdStreamingRef.current = null;\n },\n }\n );\n };\n\n const reconnectKey = useMemo(() => {\n if (!runMetadataStorage || stream.isLoading) return undefined;\n if (typeof window === \"undefined\") return undefined;\n const runId = runMetadataStorage?.getItem(`lg:stream:${threadId}`);\n if (!runId) return undefined;\n return { runId, threadId };\n }, [runMetadataStorage, stream.isLoading, threadId]);\n\n const shouldReconnect = !!runMetadataStorage;\n const reconnectRef = useRef({ threadId, shouldReconnect });\n\n const joinStreamRef = useRef<typeof joinStream>(joinStream);\n joinStreamRef.current = joinStream;\n\n useEffect(() => {\n // reset shouldReconnect when switching threads\n if (reconnectRef.current.threadId !== threadId) {\n reconnectRef.current = { threadId, shouldReconnect };\n }\n }, [threadId, shouldReconnect]);\n\n useEffect(() => {\n if (reconnectKey && reconnectRef.current.shouldReconnect) {\n reconnectRef.current.shouldReconnect = false;\n void joinStreamRef.current?.(reconnectKey.runId);\n }\n }, [reconnectKey]);\n\n const error = stream.error ?? historyError ?? history.error;\n const values = stream.values ?? historyValues;\n\n const handledToolsRef = useRef<Set<string>>(new Set());\n useEffect(() => {\n handledToolsRef.current.clear();\n }, [threadId]);\n\n useEffect(() => {\n flushPendingHeadlessToolInterrupts(\n values as Record<string, unknown>,\n options.tools,\n handledToolsRef.current,\n {\n onTool: options.onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n submit(null, {\n multitaskStrategy: \"interrupt\",\n command,\n }),\n }\n );\n }, [options.onTool, options.tools, submit, values]);\n\n const streamHandle: UseStream<StateType, Bag> = {\n get values() {\n trackStreamMode(\"values\");\n return values;\n },\n\n client,\n assistantId: options.assistantId,\n\n error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n switchThread,\n\n joinStream,\n\n branch,\n setBranch,\n\n get history() {\n if (historyLimit === false) {\n throw new Error(\n \"`fetchStateHistory` must be set to `true` to use `history`\"\n );\n }\n\n return branchContext.flatHistory;\n },\n\n isThreadLoading: history.isLoading && history.data == null,\n\n get experimental_branchTree() {\n if (historyLimit === false) {\n throw new Error(\n \"`fetchStateHistory` must be set to `true` to use `experimental_branchTree`\"\n );\n }\n\n return branchContext.branchTree;\n },\n\n get interrupts(): Interrupt<InterruptType>[] {\n if (\n values != null &&\n \"__interrupt__\" in values &&\n Array.isArray(values.__interrupt__)\n ) {\n return userFacingInterruptsFromValuesArray<InterruptType>(\n values.__interrupt__ as Interrupt<InterruptType>[]\n );\n }\n\n // If we're deferring to old interrupt detection logic, don't show the interrupt if the stream is loading\n if (stream.isLoading) return [];\n\n // Collect interrupts from ALL tasks (not just the last one)\n const allTasks = branchContext.threadHead?.tasks ?? [];\n const allInterrupts = allTasks.flatMap((t) => t.interrupts ?? []);\n\n const taskInterrupts = userFacingInterruptsFromThreadTasks<InterruptType>(\n allInterrupts as Interrupt<InterruptType>[]\n );\n if (taskInterrupts != null) return taskInterrupts;\n\n // check if there's a next task present (breakpoint-style interrupt)\n const next = branchContext.threadHead?.next ?? [];\n if (!next.length || error != null) return [];\n return [{ when: \"breakpoint\" }];\n },\n\n get interrupt() {\n const all = this.interrupts;\n if (all.length === 0) return undefined;\n if (all.length === 1) return all[0];\n\n // Multiple interrupts: return the array for backward compat\n return all as Interrupt<InterruptType>;\n },\n\n get messages(): Message<ToolCallType>[] {\n trackStreamMode(\"messages-tuple\", \"values\");\n return getMessages(values);\n },\n\n get toolCalls() {\n trackStreamMode(\"messages-tuple\", \"values\");\n const msgs = getMessages(values) as Message<ToolCallType>[];\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n get toolProgress(): ToolProgress[] {\n trackStreamMode(\"tools\");\n return Array.from(toolProgressMap.values());\n },\n\n getToolCalls(message: Message<ToolCallType>) {\n trackStreamMode(\"messages-tuple\", \"values\");\n const msgs = getMessages(values) as Message<ToolCallType>[];\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n getMessagesMetadata(\n message: Message<ToolCallType>,\n index?: number\n ): MessageMetadata<StateType> | undefined {\n trackStreamMode(\"values\");\n\n const streamMetadata = messageManager.get(message.id)?.metadata;\n const historyMetadata = messageMetadata?.find(\n (m) => m.messageId === (message.id ?? index)\n );\n\n if (streamMetadata != null || historyMetadata != null) {\n return {\n ...historyMetadata,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n\n return undefined;\n },\n\n get subagents() {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagents();\n },\n\n get activeSubagents() {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getActiveSubagents();\n },\n\n getSubagent(toolCallId: string) {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagent(toolCallId);\n },\n\n getSubagentsByType(type: string) {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagentsByType(type);\n },\n\n getSubagentsByMessage(messageId: string) {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagentsByMessage(messageId);\n },\n };\n\n // Avoid eager getter evaluation during object spread/rest destructuring.\n // These accessors are opt-in and should only run when explicitly read.\n const nonEnumerableAccessors = [\n \"history\",\n \"experimental_branchTree\",\n \"toolProgress\",\n \"subagents\",\n \"activeSubagents\",\n ] as const;\n for (const key of nonEnumerableAccessors) {\n const descriptor = Object.getOwnPropertyDescriptor(streamHandle, key);\n if (descriptor?.get) {\n Object.defineProperty(streamHandle, key, {\n ...descriptor,\n enumerable: false,\n });\n }\n }\n\n return streamHandle;\n}\n"],"mappings":"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"}
{"version":3,"file":"stream.lgp.cjs","names":["getClientConfigHash","Client","MessageTupleManager","StreamManager","useControllableThreadId","getBranchContext","StreamError","findLast","onFinishRequiresThreadState","unique","filterStream","userFacingInterruptsFromValuesArray","userFacingInterruptsFromThreadTasks","getToolCallsWithResults"],"sources":["../../src/react/stream.lgp.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport {\n type RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n filterStream,\n findLast,\n onFinishRequiresThreadState,\n unique,\n} from \"../ui/utils.js\";\nimport { StreamError } from \"../ui/errors.js\";\nimport { getBranchContext } from \"../ui/branching.js\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport type {\n AnyStreamOptions,\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetConfigurableType,\n GetToolCallsType,\n RunCallbackMeta,\n MessageMetadata,\n UseStreamThread,\n} from \"../ui/types.js\";\nimport type { UseStream, SubmitOptions } from \"./types.js\";\n\nimport { Client, getClientConfigHash } from \"../client.js\";\nimport { DEFAULT_MESSAGES_KEY } from \"../stream/constants.js\";\nimport { type Message } from \"../types.messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport type { Interrupt, ThreadState } from \"../schema.js\";\nimport type {\n StreamMode,\n ToolProgress,\n ToolsStreamEvent,\n} from \"../types.stream.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport {\n userFacingInterruptsFromThreadTasks,\n userFacingInterruptsFromValuesArray,\n} from \"../ui/interrupts.js\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport type { StreamEvent } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport { flushPendingHeadlessToolInterrupts } from \"../headless-tools.js\";\n\nfunction getFetchHistoryKey(\n client: Client,\n threadId: string | undefined | null,\n limit: boolean | number\n) {\n return [getClientConfigHash(client), threadId, limit].join(\":\");\n}\n\nfunction fetchHistory<StateType extends Record<string, unknown>>(\n client: Client,\n threadId: string,\n options?: { limit?: boolean | number }\n) {\n if (options?.limit === false) {\n return client.threads.getState<StateType>(threadId).then((state) => {\n if (state.checkpoint == null) return [];\n return [state];\n });\n }\n\n const limit = typeof options?.limit === \"number\" ? options.limit : 10;\n return client.threads.getHistory<StateType>(threadId, { limit });\n}\n\nfunction useThreadHistory<StateType extends Record<string, unknown>>(\n client: Client,\n threadId: string | undefined | null,\n limit: boolean | number,\n options: {\n passthrough: boolean;\n submittingRef: RefObject<string | null>;\n onError?: (error: unknown, run?: RunCallbackMeta) => void;\n }\n): UseStreamThread<StateType> {\n const key = getFetchHistoryKey(client, threadId, limit);\n const [state, setState] = useState<{\n key: string | undefined;\n data: ThreadState<StateType>[] | undefined;\n error: unknown | undefined;\n isLoading: boolean;\n }>(() => ({\n key: undefined,\n data: undefined,\n error: undefined,\n isLoading: threadId != null,\n }));\n\n const clientRef = useRef(client);\n clientRef.current = client;\n\n const onErrorRef = useRef(options?.onError);\n onErrorRef.current = options?.onError;\n\n const fetcher = useCallback(\n (\n threadId: string | undefined | null,\n limit: boolean | number\n ): Promise<ThreadState<StateType>[]> => {\n // If only passthrough is enabled, don't fetch history\n if (options.passthrough) return Promise.resolve([]);\n\n const client = clientRef.current;\n const key = getFetchHistoryKey(client, threadId, limit);\n\n if (threadId != null) {\n setState((state) => {\n if (state.key === key) return { ...state, isLoading: true };\n return { key, data: undefined, error: undefined, isLoading: true };\n });\n return fetchHistory<StateType>(client, threadId, { limit }).then(\n (data) => {\n setState((state) => {\n if (state.key !== key) return state;\n return { key, data, error: undefined, isLoading: false };\n });\n return data;\n },\n (error) => {\n setState((state) => {\n if (state.key !== key) return state;\n return { key, data: state.data, error, isLoading: false };\n });\n onErrorRef.current?.(error);\n return Promise.reject(error);\n }\n );\n }\n\n setState({ key, data: undefined, error: undefined, isLoading: false });\n return Promise.resolve([]);\n },\n [options.passthrough]\n );\n\n useEffect(() => {\n // Skip if a stream is already in progress, no need to fetch history\n if (\n options.submittingRef.current != null &&\n options.submittingRef.current === threadId\n ) {\n return;\n }\n\n void fetcher(threadId, limit);\n // The `threadId` and `limit` arguments are already present in `key`\n // Thus we don't need to include them in the dependency array\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fetcher, key]);\n\n return {\n data: state.data,\n error: state.error,\n isLoading: state.isLoading,\n mutate: (mutateId?: string) => fetcher(mutateId ?? threadId, limit),\n };\n}\n\nexport function useStreamLGP<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(options: AnyStreamOptions<StateType, Bag>): UseStream<StateType, Bag> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n type InterruptType = GetInterruptType<Bag>;\n type ConfigurableType = GetConfigurableType<Bag>;\n type ToolCallType = GetToolCallsType<StateType>;\n\n const reconnectOnMountRef = useRef(options.reconnectOnMount);\n const runMetadataStorage = useMemo(() => {\n if (typeof window === \"undefined\") return null;\n const storage = reconnectOnMountRef.current;\n if (storage === true) return window.sessionStorage;\n if (typeof storage === \"function\") return storage();\n return null;\n }, []);\n\n const client = useMemo(\n () =>\n options.client ??\n new Client({\n apiUrl: options.apiUrl,\n apiKey: options.apiKey,\n callerOptions: options.callerOptions,\n defaultHeaders: options.defaultHeaders,\n }),\n [\n options.client,\n options.apiKey,\n options.apiUrl,\n options.callerOptions,\n options.defaultHeaders,\n ]\n );\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const trackStreamModeRef = useRef<Exclude<StreamMode, \"messages\">[]>([]);\n\n const trackStreamMode = useCallback(\n (...mode: Exclude<StreamMode, \"messages\">[]) => {\n const ref = trackStreamModeRef.current;\n for (const m of mode) {\n if (!ref.includes(m)) ref.push(m);\n }\n },\n []\n );\n\n const hasUpdateListener = options.onUpdateEvent != null;\n const hasCustomListener = options.onCustomEvent != null;\n const hasLangChainListener = options.onLangChainEvent != null;\n const hasDebugListener = options.onDebugEvent != null;\n const hasCheckpointListener = options.onCheckpointEvent != null;\n const hasTaskListener = options.onTaskEvent != null;\n const hasToolListener = options.onToolEvent != null;\n\n const callbackStreamMode = useMemo(() => {\n const modes: Exclude<StreamMode, \"messages\">[] = [];\n if (hasUpdateListener) modes.push(\"updates\");\n if (hasCustomListener) modes.push(\"custom\");\n if (hasLangChainListener) modes.push(\"events\");\n if (hasDebugListener) modes.push(\"debug\");\n if (hasCheckpointListener) modes.push(\"checkpoints\");\n if (hasTaskListener) modes.push(\"tasks\");\n if (hasToolListener) modes.push(\"tools\");\n return modes;\n }, [\n hasUpdateListener,\n hasCustomListener,\n hasLangChainListener,\n hasDebugListener,\n hasCheckpointListener,\n hasTaskListener,\n hasToolListener,\n ]);\n\n const threadIdRef = useRef<string | null>(threadId);\n const threadIdStreamingRef = useRef<string | null>(null);\n\n // Cancel the stream if thread ID has changed\n useEffect(() => {\n if (threadIdRef.current !== threadId) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n }, [threadId, stream]);\n\n const switchThread = useCallback(\n (newThreadId: string | null) => {\n if (newThreadId !== threadIdRef.current) {\n threadIdRef.current = newThreadId;\n stream.clear();\n onThreadId(newThreadId as string);\n }\n },\n [stream, onThreadId]\n );\n\n const historyLimit =\n typeof options.fetchStateHistory === \"object\" &&\n options.fetchStateHistory != null\n ? (options.fetchStateHistory.limit ?? false)\n : (options.fetchStateHistory ?? false);\n\n const builtInHistory = useThreadHistory<StateType>(\n client,\n threadId,\n historyLimit,\n {\n passthrough: options.thread != null,\n submittingRef: threadIdStreamingRef,\n onError: options.onError,\n }\n );\n const history = options.thread ?? builtInHistory;\n\n const getMessages = (value: StateType): Message[] => {\n const messagesKey = options.messagesKey ?? DEFAULT_MESSAGES_KEY;\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n const setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = options.messagesKey ?? DEFAULT_MESSAGES_KEY;\n return { ...current, [messagesKey]: messages };\n };\n\n const [branch, setBranch] = useState<string>(\"\");\n const branchContext = getBranchContext(branch, history.data ?? undefined);\n\n const [toolProgressMap, setToolProgressMap] = useState<\n Map<string, ToolProgress>\n >(new Map());\n\n const handleToolEvent = useCallback((data: ToolsStreamEvent[\"data\"]) => {\n setToolProgressMap((prev) => {\n const next = new Map(prev);\n const key = data.toolCallId ?? data.name;\n const existing = next.get(key);\n\n switch (data.event) {\n case \"on_tool_start\": {\n next.set(key, {\n toolCallId: data.toolCallId,\n name: data.name,\n state: \"starting\",\n input: data.input,\n });\n break;\n }\n case \"on_tool_event\": {\n if (existing) {\n next.set(key, { ...existing, state: \"running\", data: data.data });\n }\n break;\n }\n case \"on_tool_end\": {\n if (existing) {\n next.set(key, {\n ...existing,\n state: \"completed\",\n result: data.output,\n });\n }\n break;\n }\n case \"on_tool_error\": {\n if (existing) {\n next.set(key, { ...existing, state: \"error\", error: data.error });\n }\n break;\n }\n default: {\n throw new Error(\n `Unexpected tool event: ${(data as { event: string }).event}`\n );\n }\n }\n\n return next;\n });\n }, []);\n\n const historyValues =\n branchContext.threadHead?.values ??\n options.initialValues ??\n ({} as StateType);\n\n // Reconstruct subagents from history when:\n // 1. History is loaded (not loading, has data)\n // 2. No active stream is running\n // 3. Subagent filtering is enabled (otherwise subagents aren't tracked)\n // This ensures subagent visualization persists after page refresh or stream completion\n const historyMessages = getMessages(historyValues);\n const shouldReconstructSubagents =\n options.filterSubagentMessages &&\n !stream.isLoading &&\n !history.isLoading &&\n historyMessages.length > 0;\n\n useEffect(() => {\n if (shouldReconstructSubagents) {\n // skipIfPopulated: true ensures we don't overwrite subagents from active streaming\n stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });\n // Fetch internal messages for each subagent from their subgraph checkpoints.\n // These messages are not in the main thread state but are persisted in the\n // checkpointer under a subgraph-specific checkpoint_ns (e.g. tools:call_abc123).\n if (historyLimit !== false && threadId) {\n const controller = new AbortController();\n void stream.fetchSubagentHistory(client.threads, threadId, {\n messagesKey: options.messagesKey ?? DEFAULT_MESSAGES_KEY,\n historyLimit:\n typeof historyLimit === \"number\" ? historyLimit : undefined,\n signal: controller.signal,\n });\n return () => controller.abort();\n }\n }\n\n // We intentionally only run this when shouldReconstructSubagents changes\n // to avoid unnecessary reconstructions during streaming\n return undefined;\n }, [shouldReconstructSubagents, historyMessages.length]);\n\n const historyError = (() => {\n const error = branchContext.threadHead?.tasks?.at(-1)?.error;\n if (error == null) return undefined;\n try {\n const parsed = JSON.parse(error) as unknown;\n if (StreamError.isStructuredError(parsed)) return new StreamError(parsed);\n return parsed;\n } catch {\n // do nothing\n }\n return error;\n })();\n\n const messageMetadata = (() => {\n const alreadyShown = new Set<string>();\n return getMessages(historyValues).map(\n (message, idx): Omit<MessageMetadata<StateType>, \"streamMetadata\"> => {\n const messageId = message.id ?? idx;\n\n // Find the first checkpoint where the message was seen\n const firstSeenState = findLast(\n history.data ?? [],\n (state) =>\n state.values != null &&\n getMessages(state.values)\n .map((m, idx) => m.id ?? idx)\n .includes(messageId)\n );\n\n const checkpointId = firstSeenState?.checkpoint?.checkpoint_id;\n let branch =\n checkpointId != null\n ? branchContext.branchByCheckpoint[checkpointId]\n : undefined;\n if (!branch?.branch?.length) branch = undefined;\n\n // serialize branches\n const optionsShown = branch?.branchOptions?.flat(2).join(\",\");\n if (optionsShown) {\n if (alreadyShown.has(optionsShown)) branch = undefined;\n alreadyShown.add(optionsShown);\n }\n\n return {\n messageId: messageId.toString(),\n firstSeenState,\n\n branch: branch?.branch,\n branchOptions: branch?.branchOptions,\n };\n }\n );\n })();\n\n const stop = () =>\n stream.stop(historyValues, {\n onStop: (args) => {\n if (runMetadataStorage && threadId) {\n const runId = runMetadataStorage.getItem(`lg:stream:${threadId}`);\n if (runId) void client.runs.cancel(threadId, runId);\n runMetadataStorage.removeItem(`lg:stream:${threadId}`);\n }\n\n options.onStop?.(args);\n },\n });\n\n // --- TRANSPORT ---\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: SubmitOptions<StateType, ConfigurableType>\n ) => {\n setToolProgressMap(new Map());\n\n // Unbranch things\n const checkpointId = submitOptions?.checkpoint?.checkpoint_id;\n setBranch(\n checkpointId != null\n ? (branchContext.branchByCheckpoint[checkpointId]?.branch ?? \"\")\n : \"\"\n );\n\n // When `fetchStateHistory` is requested, thus we assume that branching\n // is enabled. We then need to include the implicit branch.\n const includeImplicitBranch =\n historyLimit === true || typeof historyLimit === \"number\";\n\n const shouldRefetch =\n includeImplicitBranch || onFinishRequiresThreadState(options.onFinish);\n\n let callbackMeta: RunCallbackMeta | undefined;\n let rejoinKey: `lg:stream:${string}` | undefined;\n let usableThreadId = threadId;\n\n const shouldAbortPrevious =\n (submitOptions?.multitaskStrategy === \"interrupt\" ||\n submitOptions?.multitaskStrategy === \"rollback\") &&\n stream.isLoading;\n\n await stream.start(\n async (signal: AbortSignal) => {\n stream.setStreamValues((values) => {\n const prev = { ...historyValues, ...values };\n if (submitOptions?.optimisticValues != null) {\n return {\n ...prev,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(prev)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...prev };\n });\n\n if (!usableThreadId) {\n const thread = await client.threads.create({\n threadId: submitOptions?.threadId,\n metadata: submitOptions?.metadata,\n signal,\n });\n\n usableThreadId = thread.thread_id;\n\n // Pre-emptively update the thread ID before\n // stream cancellation is kicked off and thread\n // is being refetched\n threadIdRef.current = usableThreadId;\n threadIdStreamingRef.current = usableThreadId;\n\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n threadIdStreamingRef.current = usableThreadId;\n\n const streamMode = unique([\n ...(submitOptions?.streamMode ?? []),\n ...trackStreamModeRef.current,\n ...callbackStreamMode,\n ]);\n\n let checkpoint =\n submitOptions?.checkpoint ??\n (includeImplicitBranch\n ? branchContext.threadHead?.checkpoint\n : undefined) ??\n undefined;\n\n // Avoid specifying a checkpoint if user explicitly set it to null\n if (submitOptions?.checkpoint === null) checkpoint = undefined;\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n if (checkpoint != null) delete checkpoint.thread_id;\n const streamResumable =\n submitOptions?.streamResumable ?? !!runMetadataStorage;\n\n return client.runs.stream(usableThreadId, options.assistantId, {\n input: values as Record<string, unknown>,\n config: submitOptions?.config,\n context: submitOptions?.context,\n command: submitOptions?.command,\n\n interruptBefore: submitOptions?.interruptBefore,\n interruptAfter: submitOptions?.interruptAfter,\n metadata: submitOptions?.metadata,\n multitaskStrategy: submitOptions?.multitaskStrategy,\n onCompletion: submitOptions?.onCompletion,\n onDisconnect:\n submitOptions?.onDisconnect ??\n (streamResumable ? \"continue\" : \"cancel\"),\n\n signal,\n\n checkpoint,\n streamMode,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n streamResumable,\n durability: submitOptions?.durability,\n onRunCreated(params) {\n callbackMeta = {\n run_id: params.run_id,\n thread_id: params.thread_id ?? usableThreadId!,\n };\n\n if (runMetadataStorage) {\n rejoinKey = `lg:stream:${usableThreadId}`;\n runMetadataStorage.setItem(rejoinKey, callbackMeta.run_id);\n }\n\n options.onCreated?.(callbackMeta);\n },\n }) as AsyncGenerator<\n EventStreamEvent<StateType, UpdateType, CustomType>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: historyValues,\n callbacks: {\n ...options,\n onToolEvent: (data, opts) => {\n handleToolEvent(data);\n options.onToolEvent?.(data, opts);\n },\n },\n\n async onSuccess() {\n if (rejoinKey) runMetadataStorage?.removeItem(rejoinKey);\n\n if (shouldRefetch) {\n const newHistory = await history.mutate(usableThreadId!);\n const lastHead = newHistory?.at(0);\n if (lastHead) {\n // We now have the latest update from /history\n // Thus we can clear the local stream state\n options.onFinish?.(lastHead, callbackMeta);\n return null;\n }\n } else if (\n options.onFinish != null &&\n !onFinishRequiresThreadState(options.onFinish)\n ) {\n options.onFinish(\n undefined as unknown as ThreadState<StateType>,\n callbackMeta\n );\n }\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n onFinish() {\n threadIdStreamingRef.current = null;\n },\n },\n { abortPrevious: shouldAbortPrevious }\n );\n };\n\n const joinStream = async (\n runId: string,\n lastEventId?: string,\n joinOptions?: {\n streamMode?: StreamMode | StreamMode[];\n filter?: (event: {\n id?: string;\n event: StreamEvent;\n data: unknown;\n }) => boolean;\n }\n ) => {\n setToolProgressMap(new Map());\n\n // eslint-disable-next-line no-param-reassign\n lastEventId ??= \"-1\";\n if (!threadId) return;\n\n const callbackMeta: RunCallbackMeta = {\n thread_id: threadId,\n run_id: runId,\n };\n\n const includeImplicitBranchJoin =\n historyLimit === true || typeof historyLimit === \"number\";\n const shouldRefetchJoin =\n includeImplicitBranchJoin ||\n onFinishRequiresThreadState(options.onFinish);\n\n await stream.start(\n async (signal: AbortSignal) => {\n threadIdStreamingRef.current = threadId;\n const stream = client.runs.joinStream(threadId, runId, {\n signal,\n lastEventId,\n streamMode: joinOptions?.streamMode,\n }) as AsyncGenerator<\n EventStreamEvent<StateType, UpdateType, CustomType>\n >;\n\n return joinOptions?.filter != null\n ? filterStream(stream, joinOptions.filter)\n : stream;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: historyValues,\n callbacks: {\n ...options,\n onToolEvent: (data, opts) => {\n handleToolEvent(data);\n options.onToolEvent?.(data, opts);\n },\n },\n async onSuccess() {\n runMetadataStorage?.removeItem(`lg:stream:${threadId}`);\n if (!shouldRefetchJoin) {\n if (\n options.onFinish != null &&\n !onFinishRequiresThreadState(options.onFinish)\n ) {\n options.onFinish(\n undefined as unknown as ThreadState<StateType>,\n callbackMeta\n );\n }\n return;\n }\n const newHistory = await history.mutate(threadId);\n const lastHead = newHistory?.at(0);\n if (lastHead) options.onFinish?.(lastHead, callbackMeta);\n },\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n onFinish() {\n threadIdStreamingRef.current = null;\n },\n }\n );\n };\n\n const reconnectKey = useMemo(() => {\n if (!runMetadataStorage || stream.isLoading) return undefined;\n if (typeof window === \"undefined\") return undefined;\n const runId = runMetadataStorage?.getItem(`lg:stream:${threadId}`);\n if (!runId) return undefined;\n return { runId, threadId };\n }, [runMetadataStorage, stream.isLoading, threadId]);\n\n const shouldReconnect = !!runMetadataStorage;\n const reconnectRef = useRef({ threadId, shouldReconnect });\n\n const joinStreamRef = useRef<typeof joinStream>(joinStream);\n joinStreamRef.current = joinStream;\n\n useEffect(() => {\n // reset shouldReconnect when switching threads\n if (reconnectRef.current.threadId !== threadId) {\n reconnectRef.current = { threadId, shouldReconnect };\n }\n }, [threadId, shouldReconnect]);\n\n useEffect(() => {\n if (reconnectKey && reconnectRef.current.shouldReconnect) {\n reconnectRef.current.shouldReconnect = false;\n void joinStreamRef.current?.(reconnectKey.runId);\n }\n }, [reconnectKey]);\n\n const error = stream.error ?? historyError ?? history.error;\n const values = stream.values ?? historyValues;\n\n const handledToolsRef = useRef<Set<string>>(new Set());\n useEffect(() => {\n handledToolsRef.current.clear();\n }, [threadId]);\n\n useEffect(() => {\n flushPendingHeadlessToolInterrupts(\n values as Record<string, unknown>,\n options.tools,\n handledToolsRef.current,\n {\n onTool: options.onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n submit(null, {\n multitaskStrategy: \"interrupt\",\n command,\n }),\n }\n );\n }, [options.onTool, options.tools, submit, values]);\n\n const streamHandle: UseStream<StateType, Bag> = {\n get values() {\n trackStreamMode(\"values\");\n return values;\n },\n\n client,\n assistantId: options.assistantId,\n\n error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n switchThread,\n\n joinStream,\n\n branch,\n setBranch,\n\n get history() {\n if (historyLimit === false) {\n throw new Error(\n \"`fetchStateHistory` must be set to `true` to use `history`\"\n );\n }\n\n return branchContext.flatHistory;\n },\n\n isThreadLoading: history.isLoading && history.data == null,\n\n get experimental_branchTree() {\n if (historyLimit === false) {\n throw new Error(\n \"`fetchStateHistory` must be set to `true` to use `experimental_branchTree`\"\n );\n }\n\n return branchContext.branchTree;\n },\n\n get interrupts(): Interrupt<InterruptType>[] {\n if (\n values != null &&\n \"__interrupt__\" in values &&\n Array.isArray(values.__interrupt__)\n ) {\n return userFacingInterruptsFromValuesArray<InterruptType>(\n values.__interrupt__ as Interrupt<InterruptType>[]\n );\n }\n\n // If we're deferring to old interrupt detection logic, don't show the interrupt if the stream is loading\n if (stream.isLoading) return [];\n\n // Collect interrupts from ALL tasks (not just the last one)\n const allTasks = branchContext.threadHead?.tasks ?? [];\n const allInterrupts = allTasks.flatMap((t) => t.interrupts ?? []);\n\n const taskInterrupts = userFacingInterruptsFromThreadTasks<InterruptType>(\n allInterrupts as Interrupt<InterruptType>[]\n );\n if (taskInterrupts != null) return taskInterrupts;\n\n // check if there's a next task present (breakpoint-style interrupt)\n const next = branchContext.threadHead?.next ?? [];\n if (!next.length || error != null) return [];\n return [{ when: \"breakpoint\" }];\n },\n\n get interrupt() {\n const all = this.interrupts;\n if (all.length === 0) return undefined;\n if (all.length === 1) return all[0];\n\n // Multiple interrupts: return the array for backward compat\n return all as Interrupt<InterruptType>;\n },\n\n get messages(): Message<ToolCallType>[] {\n trackStreamMode(\"messages-tuple\", \"values\");\n return getMessages(values);\n },\n\n get toolCalls() {\n trackStreamMode(\"messages-tuple\", \"values\");\n const msgs = getMessages(values) as Message<ToolCallType>[];\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n get toolProgress(): ToolProgress[] {\n trackStreamMode(\"tools\");\n return Array.from(toolProgressMap.values());\n },\n\n getToolCalls(message: Message<ToolCallType>) {\n trackStreamMode(\"messages-tuple\", \"values\");\n const msgs = getMessages(values) as Message<ToolCallType>[];\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n getMessagesMetadata(\n message: Message<ToolCallType>,\n index?: number\n ): MessageMetadata<StateType> | undefined {\n trackStreamMode(\"values\");\n\n const streamMetadata = messageManager.get(message.id)?.metadata;\n const historyMetadata = messageMetadata?.find(\n (m) => m.messageId === (message.id ?? index)\n );\n\n if (streamMetadata != null || historyMetadata != null) {\n return {\n ...historyMetadata,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n\n return undefined;\n },\n\n get subagents() {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagents();\n },\n\n get activeSubagents() {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getActiveSubagents();\n },\n\n getSubagent(toolCallId: string) {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagent(toolCallId);\n },\n\n getSubagentsByType(type: string) {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagentsByType(type);\n },\n\n getSubagentsByMessage(messageId: string) {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagentsByMessage(messageId);\n },\n };\n\n // Avoid eager getter evaluation during object spread/rest destructuring.\n // These accessors are opt-in and should only run when explicitly read.\n const nonEnumerableAccessors = [\n \"history\",\n \"experimental_branchTree\",\n \"toolProgress\",\n \"subagents\",\n \"activeSubagents\",\n ] as const;\n for (const key of nonEnumerableAccessors) {\n const descriptor = Object.getOwnPropertyDescriptor(streamHandle, key);\n if (descriptor?.get) {\n Object.defineProperty(streamHandle, key, {\n ...descriptor,\n enumerable: false,\n });\n }\n }\n\n return streamHandle;\n}\n"],"mappings":"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"}
"use client";
import "../stream/constants.js";
import { MessageTupleManager } from "../ui/messages.js";

@@ -3,0 +4,0 @@ import { flushPendingHeadlessToolInterrupts } from "../headless-tools.js";

@@ -1,1 +0,1 @@

{"version":3,"file":"stream.lgp.js","names":[],"sources":["../../src/react/stream.lgp.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport {\n type RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n filterStream,\n findLast,\n onFinishRequiresThreadState,\n unique,\n} from \"../ui/utils.js\";\nimport { StreamError } from \"../ui/errors.js\";\nimport { getBranchContext } from \"../ui/branching.js\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport type {\n AnyStreamOptions,\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetConfigurableType,\n GetToolCallsType,\n RunCallbackMeta,\n MessageMetadata,\n UseStreamThread,\n} from \"../ui/types.js\";\nimport type { UseStream, SubmitOptions } from \"./types.js\";\n\nimport { Client, getClientConfigHash } from \"../client.js\";\nimport { type Message } from \"../types.messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport type { Interrupt, ThreadState } from \"../schema.js\";\nimport type {\n StreamMode,\n ToolProgress,\n ToolsStreamEvent,\n} from \"../types.stream.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport {\n userFacingInterruptsFromThreadTasks,\n userFacingInterruptsFromValuesArray,\n} from \"../ui/interrupts.js\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport type { StreamEvent } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport { flushPendingHeadlessToolInterrupts } from \"../headless-tools.js\";\n\nfunction getFetchHistoryKey(\n client: Client,\n threadId: string | undefined | null,\n limit: boolean | number\n) {\n return [getClientConfigHash(client), threadId, limit].join(\":\");\n}\n\nfunction fetchHistory<StateType extends Record<string, unknown>>(\n client: Client,\n threadId: string,\n options?: { limit?: boolean | number }\n) {\n if (options?.limit === false) {\n return client.threads.getState<StateType>(threadId).then((state) => {\n if (state.checkpoint == null) return [];\n return [state];\n });\n }\n\n const limit = typeof options?.limit === \"number\" ? options.limit : 10;\n return client.threads.getHistory<StateType>(threadId, { limit });\n}\n\nfunction useThreadHistory<StateType extends Record<string, unknown>>(\n client: Client,\n threadId: string | undefined | null,\n limit: boolean | number,\n options: {\n passthrough: boolean;\n submittingRef: RefObject<string | null>;\n onError?: (error: unknown, run?: RunCallbackMeta) => void;\n }\n): UseStreamThread<StateType> {\n const key = getFetchHistoryKey(client, threadId, limit);\n const [state, setState] = useState<{\n key: string | undefined;\n data: ThreadState<StateType>[] | undefined;\n error: unknown | undefined;\n isLoading: boolean;\n }>(() => ({\n key: undefined,\n data: undefined,\n error: undefined,\n isLoading: threadId != null,\n }));\n\n const clientRef = useRef(client);\n clientRef.current = client;\n\n const onErrorRef = useRef(options?.onError);\n onErrorRef.current = options?.onError;\n\n const fetcher = useCallback(\n (\n threadId: string | undefined | null,\n limit: boolean | number\n ): Promise<ThreadState<StateType>[]> => {\n // If only passthrough is enabled, don't fetch history\n if (options.passthrough) return Promise.resolve([]);\n\n const client = clientRef.current;\n const key = getFetchHistoryKey(client, threadId, limit);\n\n if (threadId != null) {\n setState((state) => {\n if (state.key === key) return { ...state, isLoading: true };\n return { key, data: undefined, error: undefined, isLoading: true };\n });\n return fetchHistory<StateType>(client, threadId, { limit }).then(\n (data) => {\n setState((state) => {\n if (state.key !== key) return state;\n return { key, data, error: undefined, isLoading: false };\n });\n return data;\n },\n (error) => {\n setState((state) => {\n if (state.key !== key) return state;\n return { key, data: state.data, error, isLoading: false };\n });\n onErrorRef.current?.(error);\n return Promise.reject(error);\n }\n );\n }\n\n setState({ key, data: undefined, error: undefined, isLoading: false });\n return Promise.resolve([]);\n },\n [options.passthrough]\n );\n\n useEffect(() => {\n // Skip if a stream is already in progress, no need to fetch history\n if (\n options.submittingRef.current != null &&\n options.submittingRef.current === threadId\n ) {\n return;\n }\n\n void fetcher(threadId, limit);\n // The `threadId` and `limit` arguments are already present in `key`\n // Thus we don't need to include them in the dependency array\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fetcher, key]);\n\n return {\n data: state.data,\n error: state.error,\n isLoading: state.isLoading,\n mutate: (mutateId?: string) => fetcher(mutateId ?? threadId, limit),\n };\n}\n\nexport function useStreamLGP<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(options: AnyStreamOptions<StateType, Bag>): UseStream<StateType, Bag> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n type InterruptType = GetInterruptType<Bag>;\n type ConfigurableType = GetConfigurableType<Bag>;\n type ToolCallType = GetToolCallsType<StateType>;\n\n const reconnectOnMountRef = useRef(options.reconnectOnMount);\n const runMetadataStorage = useMemo(() => {\n if (typeof window === \"undefined\") return null;\n const storage = reconnectOnMountRef.current;\n if (storage === true) return window.sessionStorage;\n if (typeof storage === \"function\") return storage();\n return null;\n }, []);\n\n const client = useMemo(\n () =>\n options.client ??\n new Client({\n apiUrl: options.apiUrl,\n apiKey: options.apiKey,\n callerOptions: options.callerOptions,\n defaultHeaders: options.defaultHeaders,\n }),\n [\n options.client,\n options.apiKey,\n options.apiUrl,\n options.callerOptions,\n options.defaultHeaders,\n ]\n );\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const trackStreamModeRef = useRef<Exclude<StreamMode, \"messages\">[]>([]);\n\n const trackStreamMode = useCallback(\n (...mode: Exclude<StreamMode, \"messages\">[]) => {\n const ref = trackStreamModeRef.current;\n for (const m of mode) {\n if (!ref.includes(m)) ref.push(m);\n }\n },\n []\n );\n\n const hasUpdateListener = options.onUpdateEvent != null;\n const hasCustomListener = options.onCustomEvent != null;\n const hasLangChainListener = options.onLangChainEvent != null;\n const hasDebugListener = options.onDebugEvent != null;\n const hasCheckpointListener = options.onCheckpointEvent != null;\n const hasTaskListener = options.onTaskEvent != null;\n const hasToolListener = options.onToolEvent != null;\n\n const callbackStreamMode = useMemo(() => {\n const modes: Exclude<StreamMode, \"messages\">[] = [];\n if (hasUpdateListener) modes.push(\"updates\");\n if (hasCustomListener) modes.push(\"custom\");\n if (hasLangChainListener) modes.push(\"events\");\n if (hasDebugListener) modes.push(\"debug\");\n if (hasCheckpointListener) modes.push(\"checkpoints\");\n if (hasTaskListener) modes.push(\"tasks\");\n if (hasToolListener) modes.push(\"tools\");\n return modes;\n }, [\n hasUpdateListener,\n hasCustomListener,\n hasLangChainListener,\n hasDebugListener,\n hasCheckpointListener,\n hasTaskListener,\n hasToolListener,\n ]);\n\n const threadIdRef = useRef<string | null>(threadId);\n const threadIdStreamingRef = useRef<string | null>(null);\n\n // Cancel the stream if thread ID has changed\n useEffect(() => {\n if (threadIdRef.current !== threadId) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n }, [threadId, stream]);\n\n const switchThread = useCallback(\n (newThreadId: string | null) => {\n if (newThreadId !== threadIdRef.current) {\n threadIdRef.current = newThreadId;\n stream.clear();\n onThreadId(newThreadId as string);\n }\n },\n [stream, onThreadId]\n );\n\n const historyLimit =\n typeof options.fetchStateHistory === \"object\" &&\n options.fetchStateHistory != null\n ? (options.fetchStateHistory.limit ?? false)\n : (options.fetchStateHistory ?? false);\n\n const builtInHistory = useThreadHistory<StateType>(\n client,\n threadId,\n historyLimit,\n {\n passthrough: options.thread != null,\n submittingRef: threadIdStreamingRef,\n onError: options.onError,\n }\n );\n const history = options.thread ?? builtInHistory;\n\n const getMessages = (value: StateType): Message[] => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n const setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = options.messagesKey ?? \"messages\";\n return { ...current, [messagesKey]: messages };\n };\n\n const [branch, setBranch] = useState<string>(\"\");\n const branchContext = getBranchContext(branch, history.data ?? undefined);\n\n const [toolProgressMap, setToolProgressMap] = useState<\n Map<string, ToolProgress>\n >(new Map());\n\n const handleToolEvent = useCallback((data: ToolsStreamEvent[\"data\"]) => {\n setToolProgressMap((prev) => {\n const next = new Map(prev);\n const key = data.toolCallId ?? data.name;\n const existing = next.get(key);\n\n switch (data.event) {\n case \"on_tool_start\": {\n next.set(key, {\n toolCallId: data.toolCallId,\n name: data.name,\n state: \"starting\",\n input: data.input,\n });\n break;\n }\n case \"on_tool_event\": {\n if (existing) {\n next.set(key, { ...existing, state: \"running\", data: data.data });\n }\n break;\n }\n case \"on_tool_end\": {\n if (existing) {\n next.set(key, {\n ...existing,\n state: \"completed\",\n result: data.output,\n });\n }\n break;\n }\n case \"on_tool_error\": {\n if (existing) {\n next.set(key, { ...existing, state: \"error\", error: data.error });\n }\n break;\n }\n default: {\n throw new Error(\n `Unexpected tool event: ${(data as { event: string }).event}`\n );\n }\n }\n\n return next;\n });\n }, []);\n\n const historyValues =\n branchContext.threadHead?.values ??\n options.initialValues ??\n ({} as StateType);\n\n // Reconstruct subagents from history when:\n // 1. History is loaded (not loading, has data)\n // 2. No active stream is running\n // 3. Subagent filtering is enabled (otherwise subagents aren't tracked)\n // This ensures subagent visualization persists after page refresh or stream completion\n const historyMessages = getMessages(historyValues);\n const shouldReconstructSubagents =\n options.filterSubagentMessages &&\n !stream.isLoading &&\n !history.isLoading &&\n historyMessages.length > 0;\n\n useEffect(() => {\n if (shouldReconstructSubagents) {\n // skipIfPopulated: true ensures we don't overwrite subagents from active streaming\n stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });\n // Fetch internal messages for each subagent from their subgraph checkpoints.\n // These messages are not in the main thread state but are persisted in the\n // checkpointer under a subgraph-specific checkpoint_ns (e.g. tools:call_abc123).\n if (historyLimit !== false && threadId) {\n const controller = new AbortController();\n void stream.fetchSubagentHistory(client.threads, threadId, {\n messagesKey: options.messagesKey ?? \"messages\",\n historyLimit:\n typeof historyLimit === \"number\" ? historyLimit : undefined,\n signal: controller.signal,\n });\n return () => controller.abort();\n }\n }\n\n // We intentionally only run this when shouldReconstructSubagents changes\n // to avoid unnecessary reconstructions during streaming\n return undefined;\n }, [shouldReconstructSubagents, historyMessages.length]);\n\n const historyError = (() => {\n const error = branchContext.threadHead?.tasks?.at(-1)?.error;\n if (error == null) return undefined;\n try {\n const parsed = JSON.parse(error) as unknown;\n if (StreamError.isStructuredError(parsed)) return new StreamError(parsed);\n return parsed;\n } catch {\n // do nothing\n }\n return error;\n })();\n\n const messageMetadata = (() => {\n const alreadyShown = new Set<string>();\n return getMessages(historyValues).map(\n (message, idx): Omit<MessageMetadata<StateType>, \"streamMetadata\"> => {\n const messageId = message.id ?? idx;\n\n // Find the first checkpoint where the message was seen\n const firstSeenState = findLast(\n history.data ?? [],\n (state) =>\n state.values != null &&\n getMessages(state.values)\n .map((m, idx) => m.id ?? idx)\n .includes(messageId)\n );\n\n const checkpointId = firstSeenState?.checkpoint?.checkpoint_id;\n let branch =\n checkpointId != null\n ? branchContext.branchByCheckpoint[checkpointId]\n : undefined;\n if (!branch?.branch?.length) branch = undefined;\n\n // serialize branches\n const optionsShown = branch?.branchOptions?.flat(2).join(\",\");\n if (optionsShown) {\n if (alreadyShown.has(optionsShown)) branch = undefined;\n alreadyShown.add(optionsShown);\n }\n\n return {\n messageId: messageId.toString(),\n firstSeenState,\n\n branch: branch?.branch,\n branchOptions: branch?.branchOptions,\n };\n }\n );\n })();\n\n const stop = () =>\n stream.stop(historyValues, {\n onStop: (args) => {\n if (runMetadataStorage && threadId) {\n const runId = runMetadataStorage.getItem(`lg:stream:${threadId}`);\n if (runId) void client.runs.cancel(threadId, runId);\n runMetadataStorage.removeItem(`lg:stream:${threadId}`);\n }\n\n options.onStop?.(args);\n },\n });\n\n // --- TRANSPORT ---\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: SubmitOptions<StateType, ConfigurableType>\n ) => {\n setToolProgressMap(new Map());\n\n // Unbranch things\n const checkpointId = submitOptions?.checkpoint?.checkpoint_id;\n setBranch(\n checkpointId != null\n ? (branchContext.branchByCheckpoint[checkpointId]?.branch ?? \"\")\n : \"\"\n );\n\n // When `fetchStateHistory` is requested, thus we assume that branching\n // is enabled. We then need to include the implicit branch.\n const includeImplicitBranch =\n historyLimit === true || typeof historyLimit === \"number\";\n\n const shouldRefetch =\n includeImplicitBranch || onFinishRequiresThreadState(options.onFinish);\n\n let callbackMeta: RunCallbackMeta | undefined;\n let rejoinKey: `lg:stream:${string}` | undefined;\n let usableThreadId = threadId;\n\n const shouldAbortPrevious =\n (submitOptions?.multitaskStrategy === \"interrupt\" ||\n submitOptions?.multitaskStrategy === \"rollback\") &&\n stream.isLoading;\n\n await stream.start(\n async (signal: AbortSignal) => {\n stream.setStreamValues((values) => {\n const prev = { ...historyValues, ...values };\n if (submitOptions?.optimisticValues != null) {\n return {\n ...prev,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(prev)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...prev };\n });\n\n if (!usableThreadId) {\n const thread = await client.threads.create({\n threadId: submitOptions?.threadId,\n metadata: submitOptions?.metadata,\n signal,\n });\n\n usableThreadId = thread.thread_id;\n\n // Pre-emptively update the thread ID before\n // stream cancellation is kicked off and thread\n // is being refetched\n threadIdRef.current = usableThreadId;\n threadIdStreamingRef.current = usableThreadId;\n\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n threadIdStreamingRef.current = usableThreadId;\n\n const streamMode = unique([\n ...(submitOptions?.streamMode ?? []),\n ...trackStreamModeRef.current,\n ...callbackStreamMode,\n ]);\n\n let checkpoint =\n submitOptions?.checkpoint ??\n (includeImplicitBranch\n ? branchContext.threadHead?.checkpoint\n : undefined) ??\n undefined;\n\n // Avoid specifying a checkpoint if user explicitly set it to null\n if (submitOptions?.checkpoint === null) checkpoint = undefined;\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n if (checkpoint != null) delete checkpoint.thread_id;\n const streamResumable =\n submitOptions?.streamResumable ?? !!runMetadataStorage;\n\n return client.runs.stream(usableThreadId, options.assistantId, {\n input: values as Record<string, unknown>,\n config: submitOptions?.config,\n context: submitOptions?.context,\n command: submitOptions?.command,\n\n interruptBefore: submitOptions?.interruptBefore,\n interruptAfter: submitOptions?.interruptAfter,\n metadata: submitOptions?.metadata,\n multitaskStrategy: submitOptions?.multitaskStrategy,\n onCompletion: submitOptions?.onCompletion,\n onDisconnect:\n submitOptions?.onDisconnect ??\n (streamResumable ? \"continue\" : \"cancel\"),\n\n signal,\n\n checkpoint,\n streamMode,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n streamResumable,\n durability: submitOptions?.durability,\n onRunCreated(params) {\n callbackMeta = {\n run_id: params.run_id,\n thread_id: params.thread_id ?? usableThreadId!,\n };\n\n if (runMetadataStorage) {\n rejoinKey = `lg:stream:${usableThreadId}`;\n runMetadataStorage.setItem(rejoinKey, callbackMeta.run_id);\n }\n\n options.onCreated?.(callbackMeta);\n },\n }) as AsyncGenerator<\n EventStreamEvent<StateType, UpdateType, CustomType>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: historyValues,\n callbacks: {\n ...options,\n onToolEvent: (data, opts) => {\n handleToolEvent(data);\n options.onToolEvent?.(data, opts);\n },\n },\n\n async onSuccess() {\n if (rejoinKey) runMetadataStorage?.removeItem(rejoinKey);\n\n if (shouldRefetch) {\n const newHistory = await history.mutate(usableThreadId!);\n const lastHead = newHistory?.at(0);\n if (lastHead) {\n // We now have the latest update from /history\n // Thus we can clear the local stream state\n options.onFinish?.(lastHead, callbackMeta);\n return null;\n }\n } else if (\n options.onFinish != null &&\n !onFinishRequiresThreadState(options.onFinish)\n ) {\n options.onFinish(\n undefined as unknown as ThreadState<StateType>,\n callbackMeta\n );\n }\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n onFinish() {\n threadIdStreamingRef.current = null;\n },\n },\n { abortPrevious: shouldAbortPrevious }\n );\n };\n\n const joinStream = async (\n runId: string,\n lastEventId?: string,\n joinOptions?: {\n streamMode?: StreamMode | StreamMode[];\n filter?: (event: {\n id?: string;\n event: StreamEvent;\n data: unknown;\n }) => boolean;\n }\n ) => {\n setToolProgressMap(new Map());\n\n // eslint-disable-next-line no-param-reassign\n lastEventId ??= \"-1\";\n if (!threadId) return;\n\n const callbackMeta: RunCallbackMeta = {\n thread_id: threadId,\n run_id: runId,\n };\n\n const includeImplicitBranchJoin =\n historyLimit === true || typeof historyLimit === \"number\";\n const shouldRefetchJoin =\n includeImplicitBranchJoin ||\n onFinishRequiresThreadState(options.onFinish);\n\n await stream.start(\n async (signal: AbortSignal) => {\n threadIdStreamingRef.current = threadId;\n const stream = client.runs.joinStream(threadId, runId, {\n signal,\n lastEventId,\n streamMode: joinOptions?.streamMode,\n }) as AsyncGenerator<\n EventStreamEvent<StateType, UpdateType, CustomType>\n >;\n\n return joinOptions?.filter != null\n ? filterStream(stream, joinOptions.filter)\n : stream;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: historyValues,\n callbacks: {\n ...options,\n onToolEvent: (data, opts) => {\n handleToolEvent(data);\n options.onToolEvent?.(data, opts);\n },\n },\n async onSuccess() {\n runMetadataStorage?.removeItem(`lg:stream:${threadId}`);\n if (!shouldRefetchJoin) {\n if (\n options.onFinish != null &&\n !onFinishRequiresThreadState(options.onFinish)\n ) {\n options.onFinish(\n undefined as unknown as ThreadState<StateType>,\n callbackMeta\n );\n }\n return;\n }\n const newHistory = await history.mutate(threadId);\n const lastHead = newHistory?.at(0);\n if (lastHead) options.onFinish?.(lastHead, callbackMeta);\n },\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n onFinish() {\n threadIdStreamingRef.current = null;\n },\n }\n );\n };\n\n const reconnectKey = useMemo(() => {\n if (!runMetadataStorage || stream.isLoading) return undefined;\n if (typeof window === \"undefined\") return undefined;\n const runId = runMetadataStorage?.getItem(`lg:stream:${threadId}`);\n if (!runId) return undefined;\n return { runId, threadId };\n }, [runMetadataStorage, stream.isLoading, threadId]);\n\n const shouldReconnect = !!runMetadataStorage;\n const reconnectRef = useRef({ threadId, shouldReconnect });\n\n const joinStreamRef = useRef<typeof joinStream>(joinStream);\n joinStreamRef.current = joinStream;\n\n useEffect(() => {\n // reset shouldReconnect when switching threads\n if (reconnectRef.current.threadId !== threadId) {\n reconnectRef.current = { threadId, shouldReconnect };\n }\n }, [threadId, shouldReconnect]);\n\n useEffect(() => {\n if (reconnectKey && reconnectRef.current.shouldReconnect) {\n reconnectRef.current.shouldReconnect = false;\n void joinStreamRef.current?.(reconnectKey.runId);\n }\n }, [reconnectKey]);\n\n const error = stream.error ?? historyError ?? history.error;\n const values = stream.values ?? historyValues;\n\n const handledToolsRef = useRef<Set<string>>(new Set());\n useEffect(() => {\n handledToolsRef.current.clear();\n }, [threadId]);\n\n useEffect(() => {\n flushPendingHeadlessToolInterrupts(\n values as Record<string, unknown>,\n options.tools,\n handledToolsRef.current,\n {\n onTool: options.onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n submit(null, {\n multitaskStrategy: \"interrupt\",\n command,\n }),\n }\n );\n }, [options.onTool, options.tools, submit, values]);\n\n const streamHandle: UseStream<StateType, Bag> = {\n get values() {\n trackStreamMode(\"values\");\n return values;\n },\n\n client,\n assistantId: options.assistantId,\n\n error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n switchThread,\n\n joinStream,\n\n branch,\n setBranch,\n\n get history() {\n if (historyLimit === false) {\n throw new Error(\n \"`fetchStateHistory` must be set to `true` to use `history`\"\n );\n }\n\n return branchContext.flatHistory;\n },\n\n isThreadLoading: history.isLoading && history.data == null,\n\n get experimental_branchTree() {\n if (historyLimit === false) {\n throw new Error(\n \"`fetchStateHistory` must be set to `true` to use `experimental_branchTree`\"\n );\n }\n\n return branchContext.branchTree;\n },\n\n get interrupts(): Interrupt<InterruptType>[] {\n if (\n values != null &&\n \"__interrupt__\" in values &&\n Array.isArray(values.__interrupt__)\n ) {\n return userFacingInterruptsFromValuesArray<InterruptType>(\n values.__interrupt__ as Interrupt<InterruptType>[]\n );\n }\n\n // If we're deferring to old interrupt detection logic, don't show the interrupt if the stream is loading\n if (stream.isLoading) return [];\n\n // Collect interrupts from ALL tasks (not just the last one)\n const allTasks = branchContext.threadHead?.tasks ?? [];\n const allInterrupts = allTasks.flatMap((t) => t.interrupts ?? []);\n\n const taskInterrupts = userFacingInterruptsFromThreadTasks<InterruptType>(\n allInterrupts as Interrupt<InterruptType>[]\n );\n if (taskInterrupts != null) return taskInterrupts;\n\n // check if there's a next task present (breakpoint-style interrupt)\n const next = branchContext.threadHead?.next ?? [];\n if (!next.length || error != null) return [];\n return [{ when: \"breakpoint\" }];\n },\n\n get interrupt() {\n const all = this.interrupts;\n if (all.length === 0) return undefined;\n if (all.length === 1) return all[0];\n\n // Multiple interrupts: return the array for backward compat\n return all as Interrupt<InterruptType>;\n },\n\n get messages(): Message<ToolCallType>[] {\n trackStreamMode(\"messages-tuple\", \"values\");\n return getMessages(values);\n },\n\n get toolCalls() {\n trackStreamMode(\"messages-tuple\", \"values\");\n const msgs = getMessages(values) as Message<ToolCallType>[];\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n get toolProgress(): ToolProgress[] {\n trackStreamMode(\"tools\");\n return Array.from(toolProgressMap.values());\n },\n\n getToolCalls(message: Message<ToolCallType>) {\n trackStreamMode(\"messages-tuple\", \"values\");\n const msgs = getMessages(values) as Message<ToolCallType>[];\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n getMessagesMetadata(\n message: Message<ToolCallType>,\n index?: number\n ): MessageMetadata<StateType> | undefined {\n trackStreamMode(\"values\");\n\n const streamMetadata = messageManager.get(message.id)?.metadata;\n const historyMetadata = messageMetadata?.find(\n (m) => m.messageId === (message.id ?? index)\n );\n\n if (streamMetadata != null || historyMetadata != null) {\n return {\n ...historyMetadata,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n\n return undefined;\n },\n\n get subagents() {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagents();\n },\n\n get activeSubagents() {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getActiveSubagents();\n },\n\n getSubagent(toolCallId: string) {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagent(toolCallId);\n },\n\n getSubagentsByType(type: string) {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagentsByType(type);\n },\n\n getSubagentsByMessage(messageId: string) {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagentsByMessage(messageId);\n },\n };\n\n // Avoid eager getter evaluation during object spread/rest destructuring.\n // These accessors are opt-in and should only run when explicitly read.\n const nonEnumerableAccessors = [\n \"history\",\n \"experimental_branchTree\",\n \"toolProgress\",\n \"subagents\",\n \"activeSubagents\",\n ] as const;\n for (const key of nonEnumerableAccessors) {\n const descriptor = Object.getOwnPropertyDescriptor(streamHandle, key);\n if (descriptor?.get) {\n Object.defineProperty(streamHandle, key, {\n ...descriptor,\n enumerable: false,\n });\n }\n }\n\n return streamHandle;\n}\n"],"mappings":";;;;;;;;;;;;;;AAsDA,SAAS,mBACP,QACA,UACA,OACA;AACA,QAAO;EAAC,oBAAoB,OAAO;EAAE;EAAU;EAAM,CAAC,KAAK,IAAI;;AAGjE,SAAS,aACP,QACA,UACA,SACA;AACA,KAAI,SAAS,UAAU,MACrB,QAAO,OAAO,QAAQ,SAAoB,SAAS,CAAC,MAAM,UAAU;AAClE,MAAI,MAAM,cAAc,KAAM,QAAO,EAAE;AACvC,SAAO,CAAC,MAAM;GACd;CAGJ,MAAM,QAAQ,OAAO,SAAS,UAAU,WAAW,QAAQ,QAAQ;AACnE,QAAO,OAAO,QAAQ,WAAsB,UAAU,EAAE,OAAO,CAAC;;AAGlE,SAAS,iBACP,QACA,UACA,OACA,SAK4B;CAC5B,MAAM,MAAM,mBAAmB,QAAQ,UAAU,MAAM;CACvD,MAAM,CAAC,OAAO,YAAY,gBAKhB;EACR,KAAK,KAAA;EACL,MAAM,KAAA;EACN,OAAO,KAAA;EACP,WAAW,YAAY;EACxB,EAAE;CAEH,MAAM,YAAY,OAAO,OAAO;AAChC,WAAU,UAAU;CAEpB,MAAM,aAAa,OAAO,SAAS,QAAQ;AAC3C,YAAW,UAAU,SAAS;CAE9B,MAAM,UAAU,aAEZ,UACA,UACsC;AAEtC,MAAI,QAAQ,YAAa,QAAO,QAAQ,QAAQ,EAAE,CAAC;EAEnD,MAAM,SAAS,UAAU;EACzB,MAAM,MAAM,mBAAmB,QAAQ,UAAU,MAAM;AAEvD,MAAI,YAAY,MAAM;AACpB,aAAU,UAAU;AAClB,QAAI,MAAM,QAAQ,IAAK,QAAO;KAAE,GAAG;KAAO,WAAW;KAAM;AAC3D,WAAO;KAAE;KAAK,MAAM,KAAA;KAAW,OAAO,KAAA;KAAW,WAAW;KAAM;KAClE;AACF,UAAO,aAAwB,QAAQ,UAAU,EAAE,OAAO,CAAC,CAAC,MACzD,SAAS;AACR,cAAU,UAAU;AAClB,SAAI,MAAM,QAAQ,IAAK,QAAO;AAC9B,YAAO;MAAE;MAAK;MAAM,OAAO,KAAA;MAAW,WAAW;MAAO;MACxD;AACF,WAAO;OAER,UAAU;AACT,cAAU,UAAU;AAClB,SAAI,MAAM,QAAQ,IAAK,QAAO;AAC9B,YAAO;MAAE;MAAK,MAAM,MAAM;MAAM;MAAO,WAAW;MAAO;MACzD;AACF,eAAW,UAAU,MAAM;AAC3B,WAAO,QAAQ,OAAO,MAAM;KAE/B;;AAGH,WAAS;GAAE;GAAK,MAAM,KAAA;GAAW,OAAO,KAAA;GAAW,WAAW;GAAO,CAAC;AACtE,SAAO,QAAQ,QAAQ,EAAE,CAAC;IAE5B,CAAC,QAAQ,YAAY,CACtB;AAED,iBAAgB;AAEd,MACE,QAAQ,cAAc,WAAW,QACjC,QAAQ,cAAc,YAAY,SAElC;AAGG,UAAQ,UAAU,MAAM;IAI5B,CAAC,SAAS,IAAI,CAAC;AAElB,QAAO;EACL,MAAM,MAAM;EACZ,OAAO,MAAM;EACb,WAAW,MAAM;EACjB,SAAS,aAAsB,QAAQ,YAAY,UAAU,MAAM;EACpE;;AAGH,SAAgB,aAGd,SAAsE;CAOtE,MAAM,sBAAsB,OAAO,QAAQ,iBAAiB;CAC5D,MAAM,qBAAqB,cAAc;AACvC,MAAI,OAAO,WAAW,YAAa,QAAO;EAC1C,MAAM,UAAU,oBAAoB;AACpC,MAAI,YAAY,KAAM,QAAO,OAAO;AACpC,MAAI,OAAO,YAAY,WAAY,QAAO,SAAS;AACnD,SAAO;IACN,EAAE,CAAC;CAEN,MAAM,SAAS,cAEX,QAAQ,UACR,IAAI,OAAO;EACT,QAAQ,QAAQ;EAChB,QAAQ,QAAQ;EAChB,eAAe,QAAQ;EACvB,gBAAgB,QAAQ;EACzB,CAAC,EACJ;EACE,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACR,QAAQ;EACT,CACF;CAED,MAAM,CAAC,kBAAkB,eAAe,IAAI,qBAAqB,CAAC;CAClE,MAAM,CAAC,UAAU,eAEb,IAAI,cAA8B,gBAAgB;EAChD,UAAU,QAAQ,YAAY;EAC9B,mBAAmB,QAAQ;EAC3B,wBAAwB,QAAQ;EACjC,CAAC,CACL;AAED,sBACE,OAAO,WACP,OAAO,aACP,OAAO,YACR;CAED,MAAM,CAAC,UAAU,cAAc,wBAAwB,QAAQ;CAC/D,MAAM,qBAAqB,OAA0C,EAAE,CAAC;CAExE,MAAM,kBAAkB,aACrB,GAAG,SAA4C;EAC9C,MAAM,MAAM,mBAAmB;AAC/B,OAAK,MAAM,KAAK,KACd,KAAI,CAAC,IAAI,SAAS,EAAE,CAAE,KAAI,KAAK,EAAE;IAGrC,EAAE,CACH;CAED,MAAM,oBAAoB,QAAQ,iBAAiB;CACnD,MAAM,oBAAoB,QAAQ,iBAAiB;CACnD,MAAM,uBAAuB,QAAQ,oBAAoB;CACzD,MAAM,mBAAmB,QAAQ,gBAAgB;CACjD,MAAM,wBAAwB,QAAQ,qBAAqB;CAC3D,MAAM,kBAAkB,QAAQ,eAAe;CAC/C,MAAM,kBAAkB,QAAQ,eAAe;CAE/C,MAAM,qBAAqB,cAAc;EACvC,MAAM,QAA2C,EAAE;AACnD,MAAI,kBAAmB,OAAM,KAAK,UAAU;AAC5C,MAAI,kBAAmB,OAAM,KAAK,SAAS;AAC3C,MAAI,qBAAsB,OAAM,KAAK,SAAS;AAC9C,MAAI,iBAAkB,OAAM,KAAK,QAAQ;AACzC,MAAI,sBAAuB,OAAM,KAAK,cAAc;AACpD,MAAI,gBAAiB,OAAM,KAAK,QAAQ;AACxC,MAAI,gBAAiB,OAAM,KAAK,QAAQ;AACxC,SAAO;IACN;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,cAAc,OAAsB,SAAS;CACnD,MAAM,uBAAuB,OAAsB,KAAK;AAGxD,iBAAgB;AACd,MAAI,YAAY,YAAY,UAAU;AACpC,eAAY,UAAU;AACtB,UAAO,OAAO;;IAEf,CAAC,UAAU,OAAO,CAAC;CAEtB,MAAM,eAAe,aAClB,gBAA+B;AAC9B,MAAI,gBAAgB,YAAY,SAAS;AACvC,eAAY,UAAU;AACtB,UAAO,OAAO;AACd,cAAW,YAAsB;;IAGrC,CAAC,QAAQ,WAAW,CACrB;CAED,MAAM,eACJ,OAAO,QAAQ,sBAAsB,YACrC,QAAQ,qBAAqB,OACxB,QAAQ,kBAAkB,SAAS,QACnC,QAAQ,qBAAqB;CAEpC,MAAM,iBAAiB,iBACrB,QACA,UACA,cACA;EACE,aAAa,QAAQ,UAAU;EAC/B,eAAe;EACf,SAAS,QAAQ;EAClB,CACF;CACD,MAAM,UAAU,QAAQ,UAAU;CAElC,MAAM,eAAe,UAAgC;EACnD,MAAM,cAAc,QAAQ,eAAe;AAC3C,SAAO,MAAM,QAAQ,MAAM,aAAa,GACnC,MAAM,eACP,EAAE;;CAGR,MAAM,eAAe,SAAoB,aAAmC;EAC1E,MAAM,cAAc,QAAQ,eAAe;AAC3C,SAAO;GAAE,GAAG;IAAU,cAAc;GAAU;;CAGhD,MAAM,CAAC,QAAQ,aAAa,SAAiB,GAAG;CAChD,MAAM,gBAAgB,iBAAiB,QAAQ,QAAQ,QAAQ,KAAA,EAAU;CAEzE,MAAM,CAAC,iBAAiB,sBAAsB,yBAE5C,IAAI,KAAK,CAAC;CAEZ,MAAM,kBAAkB,aAAa,SAAmC;AACtE,sBAAoB,SAAS;GAC3B,MAAM,OAAO,IAAI,IAAI,KAAK;GAC1B,MAAM,MAAM,KAAK,cAAc,KAAK;GACpC,MAAM,WAAW,KAAK,IAAI,IAAI;AAE9B,WAAQ,KAAK,OAAb;IACE,KAAK;AACH,UAAK,IAAI,KAAK;MACZ,YAAY,KAAK;MACjB,MAAM,KAAK;MACX,OAAO;MACP,OAAO,KAAK;MACb,CAAC;AACF;IAEF,KAAK;AACH,SAAI,SACF,MAAK,IAAI,KAAK;MAAE,GAAG;MAAU,OAAO;MAAW,MAAM,KAAK;MAAM,CAAC;AAEnE;IAEF,KAAK;AACH,SAAI,SACF,MAAK,IAAI,KAAK;MACZ,GAAG;MACH,OAAO;MACP,QAAQ,KAAK;MACd,CAAC;AAEJ;IAEF,KAAK;AACH,SAAI,SACF,MAAK,IAAI,KAAK;MAAE,GAAG;MAAU,OAAO;MAAS,OAAO,KAAK;MAAO,CAAC;AAEnE;IAEF,QACE,OAAM,IAAI,MACR,0BAA2B,KAA2B,QACvD;;AAIL,UAAO;IACP;IACD,EAAE,CAAC;CAEN,MAAM,gBACJ,cAAc,YAAY,UAC1B,QAAQ,iBACP,EAAE;CAOL,MAAM,kBAAkB,YAAY,cAAc;CAClD,MAAM,6BACJ,QAAQ,0BACR,CAAC,OAAO,aACR,CAAC,QAAQ,aACT,gBAAgB,SAAS;AAE3B,iBAAgB;AACd,MAAI,4BAA4B;AAE9B,UAAO,qBAAqB,iBAAiB,EAAE,iBAAiB,MAAM,CAAC;AAIvE,OAAI,iBAAiB,SAAS,UAAU;IACtC,MAAM,aAAa,IAAI,iBAAiB;AACnC,WAAO,qBAAqB,OAAO,SAAS,UAAU;KACzD,aAAa,QAAQ,eAAe;KACpC,cACE,OAAO,iBAAiB,WAAW,eAAe,KAAA;KACpD,QAAQ,WAAW;KACpB,CAAC;AACF,iBAAa,WAAW,OAAO;;;IAOlC,CAAC,4BAA4B,gBAAgB,OAAO,CAAC;CAExD,MAAM,sBAAsB;EAC1B,MAAM,QAAQ,cAAc,YAAY,OAAO,GAAG,GAAG,EAAE;AACvD,MAAI,SAAS,KAAM,QAAO,KAAA;AAC1B,MAAI;GACF,MAAM,SAAS,KAAK,MAAM,MAAM;AAChC,OAAI,YAAY,kBAAkB,OAAO,CAAE,QAAO,IAAI,YAAY,OAAO;AACzE,UAAO;UACD;AAGR,SAAO;KACL;CAEJ,MAAM,yBAAyB;EAC7B,MAAM,+BAAe,IAAI,KAAa;AACtC,SAAO,YAAY,cAAc,CAAC,KAC/B,SAAS,QAA4D;GACpE,MAAM,YAAY,QAAQ,MAAM;GAGhC,MAAM,iBAAiB,SACrB,QAAQ,QAAQ,EAAE,GACjB,UACC,MAAM,UAAU,QAChB,YAAY,MAAM,OAAO,CACtB,KAAK,GAAG,QAAQ,EAAE,MAAM,IAAI,CAC5B,SAAS,UAAU,CACzB;GAED,MAAM,eAAe,gBAAgB,YAAY;GACjD,IAAI,SACF,gBAAgB,OACZ,cAAc,mBAAmB,gBACjC,KAAA;AACN,OAAI,CAAC,QAAQ,QAAQ,OAAQ,UAAS,KAAA;GAGtC,MAAM,eAAe,QAAQ,eAAe,KAAK,EAAE,CAAC,KAAK,IAAI;AAC7D,OAAI,cAAc;AAChB,QAAI,aAAa,IAAI,aAAa,CAAE,UAAS,KAAA;AAC7C,iBAAa,IAAI,aAAa;;AAGhC,UAAO;IACL,WAAW,UAAU,UAAU;IAC/B;IAEA,QAAQ,QAAQ;IAChB,eAAe,QAAQ;IACxB;IAEJ;KACC;CAEJ,MAAM,aACJ,OAAO,KAAK,eAAe,EACzB,SAAS,SAAS;AAChB,MAAI,sBAAsB,UAAU;GAClC,MAAM,QAAQ,mBAAmB,QAAQ,aAAa,WAAW;AACjE,OAAI,MAAY,QAAO,KAAK,OAAO,UAAU,MAAM;AACnD,sBAAmB,WAAW,aAAa,WAAW;;AAGxD,UAAQ,SAAS,KAAK;IAEzB,CAAC;CAGJ,MAAM,SAAS,OACb,QACA,kBACG;AACH,qCAAmB,IAAI,KAAK,CAAC;EAG7B,MAAM,eAAe,eAAe,YAAY;AAChD,YACE,gBAAgB,OACX,cAAc,mBAAmB,eAAe,UAAU,KAC3D,GACL;EAID,MAAM,wBACJ,iBAAiB,QAAQ,OAAO,iBAAiB;EAEnD,MAAM,gBACJ,yBAAyB,4BAA4B,QAAQ,SAAS;EAExE,IAAI;EACJ,IAAI;EACJ,IAAI,iBAAiB;EAErB,MAAM,uBACH,eAAe,sBAAsB,eACpC,eAAe,sBAAsB,eACvC,OAAO;AAET,QAAM,OAAO,MACX,OAAO,WAAwB;AAC7B,UAAO,iBAAiB,WAAW;IACjC,MAAM,OAAO;KAAE,GAAG;KAAe,GAAG;KAAQ;AAC5C,QAAI,eAAe,oBAAoB,KACrC,QAAO;KACL,GAAG;KACH,GAAI,OAAO,cAAc,qBAAqB,aAC1C,cAAc,iBAAiB,KAAK,GACpC,cAAc;KACnB;AAGH,WAAO,EAAE,GAAG,MAAM;KAClB;AAEF,OAAI,CAAC,gBAAgB;AAOnB,sBANe,MAAM,OAAO,QAAQ,OAAO;KACzC,UAAU,eAAe;KACzB,UAAU,eAAe;KACzB;KACD,CAAC,EAEsB;AAKxB,gBAAY,UAAU;AACtB,yBAAqB,UAAU;AAE/B,eAAW,eAAe;;AAG5B,OAAI,CAAC,eACH,OAAM,IAAI,MAAM,oCAAoC;AAGtD,wBAAqB,UAAU;GAE/B,MAAM,aAAa,OAAO;IACxB,GAAI,eAAe,cAAc,EAAE;IACnC,GAAG,mBAAmB;IACtB,GAAG;IACJ,CAAC;GAEF,IAAI,aACF,eAAe,eACd,wBACG,cAAc,YAAY,aAC1B,KAAA,MACJ,KAAA;AAGF,OAAI,eAAe,eAAe,KAAM,cAAa,KAAA;AAIrD,OAAI,cAAc,KAAM,QAAO,WAAW;GAC1C,MAAM,kBACJ,eAAe,mBAAmB,CAAC,CAAC;AAEtC,UAAO,OAAO,KAAK,OAAO,gBAAgB,QAAQ,aAAa;IAC7D,OAAO;IACP,QAAQ,eAAe;IACvB,SAAS,eAAe;IACxB,SAAS,eAAe;IAExB,iBAAiB,eAAe;IAChC,gBAAgB,eAAe;IAC/B,UAAU,eAAe;IACzB,mBAAmB,eAAe;IAClC,cAAc,eAAe;IAC7B,cACE,eAAe,iBACd,kBAAkB,aAAa;IAElC;IAEA;IACA;IACA,iBAAiB,eAAe;IAChC;IACA,YAAY,eAAe;IAC3B,aAAa,QAAQ;AACnB,oBAAe;MACb,QAAQ,OAAO;MACf,WAAW,OAAO,aAAa;MAChC;AAED,SAAI,oBAAoB;AACtB,kBAAY,aAAa;AACzB,yBAAmB,QAAQ,WAAW,aAAa,OAAO;;AAG5D,aAAQ,YAAY,aAAa;;IAEpC,CAAC;KAIJ;GACE;GACA;GAEA,eAAe;GACf,WAAW;IACT,GAAG;IACH,cAAc,MAAM,SAAS;AAC3B,qBAAgB,KAAK;AACrB,aAAQ,cAAc,MAAM,KAAK;;IAEpC;GAED,MAAM,YAAY;AAChB,QAAI,UAAW,qBAAoB,WAAW,UAAU;AAExD,QAAI,eAAe;KAEjB,MAAM,YADa,MAAM,QAAQ,OAAO,eAAgB,GAC3B,GAAG,EAAE;AAClC,SAAI,UAAU;AAGZ,cAAQ,WAAW,UAAU,aAAa;AAC1C,aAAO;;eAGT,QAAQ,YAAY,QACpB,CAAC,4BAA4B,QAAQ,SAAS,CAE9C,SAAQ,SACN,KAAA,GACA,aACD;;GAKL,QAAQ,OAAO;AACb,YAAQ,UAAU,OAAO,aAAa;;GAExC,WAAW;AACT,yBAAqB,UAAU;;GAElC,EACD,EAAE,eAAe,qBAAqB,CACvC;;CAGH,MAAM,aAAa,OACjB,OACA,aACA,gBAQG;AACH,qCAAmB,IAAI,KAAK,CAAC;AAG7B,kBAAgB;AAChB,MAAI,CAAC,SAAU;EAEf,MAAM,eAAgC;GACpC,WAAW;GACX,QAAQ;GACT;EAID,MAAM,oBADJ,iBAAiB,QAAQ,OAAO,iBAAiB,YAGjD,4BAA4B,QAAQ,SAAS;AAE/C,QAAM,OAAO,MACX,OAAO,WAAwB;AAC7B,wBAAqB,UAAU;GAC/B,MAAM,SAAS,OAAO,KAAK,WAAW,UAAU,OAAO;IACrD;IACA;IACA,YAAY,aAAa;IAC1B,CAAC;AAIF,UAAO,aAAa,UAAU,OAC1B,aAAa,QAAQ,YAAY,OAAO,GACxC;KAEN;GACE;GACA;GAEA,eAAe;GACf,WAAW;IACT,GAAG;IACH,cAAc,MAAM,SAAS;AAC3B,qBAAgB,KAAK;AACrB,aAAQ,cAAc,MAAM,KAAK;;IAEpC;GACD,MAAM,YAAY;AAChB,wBAAoB,WAAW,aAAa,WAAW;AACvD,QAAI,CAAC,mBAAmB;AACtB,SACE,QAAQ,YAAY,QACpB,CAAC,4BAA4B,QAAQ,SAAS,CAE9C,SAAQ,SACN,KAAA,GACA,aACD;AAEH;;IAGF,MAAM,YADa,MAAM,QAAQ,OAAO,SAAS,GACpB,GAAG,EAAE;AAClC,QAAI,SAAU,SAAQ,WAAW,UAAU,aAAa;;GAE1D,QAAQ,OAAO;AACb,YAAQ,UAAU,OAAO,aAAa;;GAExC,WAAW;AACT,yBAAqB,UAAU;;GAElC,CACF;;CAGH,MAAM,eAAe,cAAc;AACjC,MAAI,CAAC,sBAAsB,OAAO,UAAW,QAAO,KAAA;AACpD,MAAI,OAAO,WAAW,YAAa,QAAO,KAAA;EAC1C,MAAM,QAAQ,oBAAoB,QAAQ,aAAa,WAAW;AAClE,MAAI,CAAC,MAAO,QAAO,KAAA;AACnB,SAAO;GAAE;GAAO;GAAU;IACzB;EAAC;EAAoB,OAAO;EAAW;EAAS,CAAC;CAEpD,MAAM,kBAAkB,CAAC,CAAC;CAC1B,MAAM,eAAe,OAAO;EAAE;EAAU;EAAiB,CAAC;CAE1D,MAAM,gBAAgB,OAA0B,WAAW;AAC3D,eAAc,UAAU;AAExB,iBAAgB;AAEd,MAAI,aAAa,QAAQ,aAAa,SACpC,cAAa,UAAU;GAAE;GAAU;GAAiB;IAErD,CAAC,UAAU,gBAAgB,CAAC;AAE/B,iBAAgB;AACd,MAAI,gBAAgB,aAAa,QAAQ,iBAAiB;AACxD,gBAAa,QAAQ,kBAAkB;AAClC,iBAAc,UAAU,aAAa,MAAM;;IAEjD,CAAC,aAAa,CAAC;CAElB,MAAM,QAAQ,OAAO,SAAS,gBAAgB,QAAQ;CACtD,MAAM,SAAS,OAAO,UAAU;CAEhC,MAAM,kBAAkB,uBAAoB,IAAI,KAAK,CAAC;AACtD,iBAAgB;AACd,kBAAgB,QAAQ,OAAO;IAC9B,CAAC,SAAS,CAAC;AAEd,iBAAgB;AACd,qCACE,QACA,QAAQ,OACR,gBAAgB,SAChB;GACE,QAAQ,QAAQ;GAChB,QAAQ,QAAQ;AACT,YAAQ,SAAS,CAAC,KAAK,IAAI;;GAElC,eAAe,YACb,OAAO,MAAM;IACX,mBAAmB;IACnB;IACD,CAAC;GACL,CACF;IACA;EAAC,QAAQ;EAAQ,QAAQ;EAAO;EAAQ;EAAO,CAAC;CAEnD,MAAM,eAA0C;EAC9C,IAAI,SAAS;AACX,mBAAgB,SAAS;AACzB,UAAO;;EAGT;EACA,aAAa,QAAQ;EAErB;EACA,WAAW,OAAO;EAElB;EACA;EACA;EAEA;EAEA;EACA;EAEA,IAAI,UAAU;AACZ,OAAI,iBAAiB,MACnB,OAAM,IAAI,MACR,6DACD;AAGH,UAAO,cAAc;;EAGvB,iBAAiB,QAAQ,aAAa,QAAQ,QAAQ;EAEtD,IAAI,0BAA0B;AAC5B,OAAI,iBAAiB,MACnB,OAAM,IAAI,MACR,6EACD;AAGH,UAAO,cAAc;;EAGvB,IAAI,aAAyC;AAC3C,OACE,UAAU,QACV,mBAAmB,UACnB,MAAM,QAAQ,OAAO,cAAc,CAEnC,QAAO,oCACL,OAAO,cACR;AAIH,OAAI,OAAO,UAAW,QAAO,EAAE;GAM/B,MAAM,iBAAiB,qCAHN,cAAc,YAAY,SAAS,EAAE,EACvB,SAAS,MAAM,EAAE,cAAc,EAAE,CAAC,CAIhE;AACD,OAAI,kBAAkB,KAAM,QAAO;AAInC,OAAI,EADS,cAAc,YAAY,QAAQ,EAAE,EACvC,UAAU,SAAS,KAAM,QAAO,EAAE;AAC5C,UAAO,CAAC,EAAE,MAAM,cAAc,CAAC;;EAGjC,IAAI,YAAY;GACd,MAAM,MAAM,KAAK;AACjB,OAAI,IAAI,WAAW,EAAG,QAAO,KAAA;AAC7B,OAAI,IAAI,WAAW,EAAG,QAAO,IAAI;AAGjC,UAAO;;EAGT,IAAI,WAAoC;AACtC,mBAAgB,kBAAkB,SAAS;AAC3C,UAAO,YAAY,OAAO;;EAG5B,IAAI,YAAY;AACd,mBAAgB,kBAAkB,SAAS;AAE3C,UAAO,wBADM,YAAY,OAAO,CACkB;;EAGpD,IAAI,eAA+B;AACjC,mBAAgB,QAAQ;AACxB,UAAO,MAAM,KAAK,gBAAgB,QAAQ,CAAC;;EAG7C,aAAa,SAAgC;AAC3C,mBAAgB,kBAAkB,SAAS;AAG3C,UADqB,wBADR,YAAY,OAAO,CACgC,CAC5C,QAAQ,OAAO,GAAG,UAAU,OAAO,QAAQ,GAAG;;EAGpE,oBACE,SACA,OACwC;AACxC,mBAAgB,SAAS;GAEzB,MAAM,iBAAiB,eAAe,IAAI,QAAQ,GAAG,EAAE;GACvD,MAAM,kBAAkB,iBAAiB,MACtC,MAAM,EAAE,eAAe,QAAQ,MAAM,OACvC;AAED,OAAI,kBAAkB,QAAQ,mBAAmB,KAC/C,QAAO;IACL,GAAG;IACH;IACD;;EAML,IAAI,YAAY;AACd,mBAAgB,WAAW,iBAAiB;AAC5C,UAAO,OAAO,cAAc;;EAG9B,IAAI,kBAAkB;AACpB,mBAAgB,WAAW,iBAAiB;AAC5C,UAAO,OAAO,oBAAoB;;EAGpC,YAAY,YAAoB;AAC9B,mBAAgB,WAAW,iBAAiB;AAC5C,UAAO,OAAO,YAAY,WAAW;;EAGvC,mBAAmB,MAAc;AAC/B,mBAAgB,WAAW,iBAAiB;AAC5C,UAAO,OAAO,mBAAmB,KAAK;;EAGxC,sBAAsB,WAAmB;AACvC,mBAAgB,WAAW,iBAAiB;AAC5C,UAAO,OAAO,sBAAsB,UAAU;;EAEjD;AAWD,MAAK,MAAM,OAPoB;EAC7B;EACA;EACA;EACA;EACA;EACD,EACyC;EACxC,MAAM,aAAa,OAAO,yBAAyB,cAAc,IAAI;AACrE,MAAI,YAAY,IACd,QAAO,eAAe,cAAc,KAAK;GACvC,GAAG;GACH,YAAY;GACb,CAAC;;AAIN,QAAO"}
{"version":3,"file":"stream.lgp.js","names":[],"sources":["../../src/react/stream.lgp.tsx"],"sourcesContent":["/* __LC_ALLOW_ENTRYPOINT_SIDE_EFFECTS__ */\n\n\"use client\";\n\nimport {\n type RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n filterStream,\n findLast,\n onFinishRequiresThreadState,\n unique,\n} from \"../ui/utils.js\";\nimport { StreamError } from \"../ui/errors.js\";\nimport { getBranchContext } from \"../ui/branching.js\";\nimport { EventStreamEvent, StreamManager } from \"../ui/manager.js\";\nimport type {\n AnyStreamOptions,\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetConfigurableType,\n GetToolCallsType,\n RunCallbackMeta,\n MessageMetadata,\n UseStreamThread,\n} from \"../ui/types.js\";\nimport type { UseStream, SubmitOptions } from \"./types.js\";\n\nimport { Client, getClientConfigHash } from \"../client.js\";\nimport { DEFAULT_MESSAGES_KEY } from \"../stream/constants.js\";\nimport { type Message } from \"../types.messages.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport type { Interrupt, ThreadState } from \"../schema.js\";\nimport type {\n StreamMode,\n ToolProgress,\n ToolsStreamEvent,\n} from \"../types.stream.js\";\nimport { MessageTupleManager } from \"../ui/messages.js\";\nimport {\n userFacingInterruptsFromThreadTasks,\n userFacingInterruptsFromValuesArray,\n} from \"../ui/interrupts.js\";\nimport { useControllableThreadId } from \"./thread.js\";\nimport type { StreamEvent } from \"../types.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport { flushPendingHeadlessToolInterrupts } from \"../headless-tools.js\";\n\nfunction getFetchHistoryKey(\n client: Client,\n threadId: string | undefined | null,\n limit: boolean | number\n) {\n return [getClientConfigHash(client), threadId, limit].join(\":\");\n}\n\nfunction fetchHistory<StateType extends Record<string, unknown>>(\n client: Client,\n threadId: string,\n options?: { limit?: boolean | number }\n) {\n if (options?.limit === false) {\n return client.threads.getState<StateType>(threadId).then((state) => {\n if (state.checkpoint == null) return [];\n return [state];\n });\n }\n\n const limit = typeof options?.limit === \"number\" ? options.limit : 10;\n return client.threads.getHistory<StateType>(threadId, { limit });\n}\n\nfunction useThreadHistory<StateType extends Record<string, unknown>>(\n client: Client,\n threadId: string | undefined | null,\n limit: boolean | number,\n options: {\n passthrough: boolean;\n submittingRef: RefObject<string | null>;\n onError?: (error: unknown, run?: RunCallbackMeta) => void;\n }\n): UseStreamThread<StateType> {\n const key = getFetchHistoryKey(client, threadId, limit);\n const [state, setState] = useState<{\n key: string | undefined;\n data: ThreadState<StateType>[] | undefined;\n error: unknown | undefined;\n isLoading: boolean;\n }>(() => ({\n key: undefined,\n data: undefined,\n error: undefined,\n isLoading: threadId != null,\n }));\n\n const clientRef = useRef(client);\n clientRef.current = client;\n\n const onErrorRef = useRef(options?.onError);\n onErrorRef.current = options?.onError;\n\n const fetcher = useCallback(\n (\n threadId: string | undefined | null,\n limit: boolean | number\n ): Promise<ThreadState<StateType>[]> => {\n // If only passthrough is enabled, don't fetch history\n if (options.passthrough) return Promise.resolve([]);\n\n const client = clientRef.current;\n const key = getFetchHistoryKey(client, threadId, limit);\n\n if (threadId != null) {\n setState((state) => {\n if (state.key === key) return { ...state, isLoading: true };\n return { key, data: undefined, error: undefined, isLoading: true };\n });\n return fetchHistory<StateType>(client, threadId, { limit }).then(\n (data) => {\n setState((state) => {\n if (state.key !== key) return state;\n return { key, data, error: undefined, isLoading: false };\n });\n return data;\n },\n (error) => {\n setState((state) => {\n if (state.key !== key) return state;\n return { key, data: state.data, error, isLoading: false };\n });\n onErrorRef.current?.(error);\n return Promise.reject(error);\n }\n );\n }\n\n setState({ key, data: undefined, error: undefined, isLoading: false });\n return Promise.resolve([]);\n },\n [options.passthrough]\n );\n\n useEffect(() => {\n // Skip if a stream is already in progress, no need to fetch history\n if (\n options.submittingRef.current != null &&\n options.submittingRef.current === threadId\n ) {\n return;\n }\n\n void fetcher(threadId, limit);\n // The `threadId` and `limit` arguments are already present in `key`\n // Thus we don't need to include them in the dependency array\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fetcher, key]);\n\n return {\n data: state.data,\n error: state.error,\n isLoading: state.isLoading,\n mutate: (mutateId?: string) => fetcher(mutateId ?? threadId, limit),\n };\n}\n\nexport function useStreamLGP<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n>(options: AnyStreamOptions<StateType, Bag>): UseStream<StateType, Bag> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n type InterruptType = GetInterruptType<Bag>;\n type ConfigurableType = GetConfigurableType<Bag>;\n type ToolCallType = GetToolCallsType<StateType>;\n\n const reconnectOnMountRef = useRef(options.reconnectOnMount);\n const runMetadataStorage = useMemo(() => {\n if (typeof window === \"undefined\") return null;\n const storage = reconnectOnMountRef.current;\n if (storage === true) return window.sessionStorage;\n if (typeof storage === \"function\") return storage();\n return null;\n }, []);\n\n const client = useMemo(\n () =>\n options.client ??\n new Client({\n apiUrl: options.apiUrl,\n apiKey: options.apiKey,\n callerOptions: options.callerOptions,\n defaultHeaders: options.defaultHeaders,\n }),\n [\n options.client,\n options.apiKey,\n options.apiUrl,\n options.callerOptions,\n options.defaultHeaders,\n ]\n );\n\n const [messageManager] = useState(() => new MessageTupleManager());\n const [stream] = useState(\n () =>\n new StreamManager<StateType, Bag>(messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n })\n );\n\n useSyncExternalStore(\n stream.subscribe,\n stream.getSnapshot,\n stream.getSnapshot\n );\n\n const [threadId, onThreadId] = useControllableThreadId(options);\n const trackStreamModeRef = useRef<Exclude<StreamMode, \"messages\">[]>([]);\n\n const trackStreamMode = useCallback(\n (...mode: Exclude<StreamMode, \"messages\">[]) => {\n const ref = trackStreamModeRef.current;\n for (const m of mode) {\n if (!ref.includes(m)) ref.push(m);\n }\n },\n []\n );\n\n const hasUpdateListener = options.onUpdateEvent != null;\n const hasCustomListener = options.onCustomEvent != null;\n const hasLangChainListener = options.onLangChainEvent != null;\n const hasDebugListener = options.onDebugEvent != null;\n const hasCheckpointListener = options.onCheckpointEvent != null;\n const hasTaskListener = options.onTaskEvent != null;\n const hasToolListener = options.onToolEvent != null;\n\n const callbackStreamMode = useMemo(() => {\n const modes: Exclude<StreamMode, \"messages\">[] = [];\n if (hasUpdateListener) modes.push(\"updates\");\n if (hasCustomListener) modes.push(\"custom\");\n if (hasLangChainListener) modes.push(\"events\");\n if (hasDebugListener) modes.push(\"debug\");\n if (hasCheckpointListener) modes.push(\"checkpoints\");\n if (hasTaskListener) modes.push(\"tasks\");\n if (hasToolListener) modes.push(\"tools\");\n return modes;\n }, [\n hasUpdateListener,\n hasCustomListener,\n hasLangChainListener,\n hasDebugListener,\n hasCheckpointListener,\n hasTaskListener,\n hasToolListener,\n ]);\n\n const threadIdRef = useRef<string | null>(threadId);\n const threadIdStreamingRef = useRef<string | null>(null);\n\n // Cancel the stream if thread ID has changed\n useEffect(() => {\n if (threadIdRef.current !== threadId) {\n threadIdRef.current = threadId;\n stream.clear();\n }\n }, [threadId, stream]);\n\n const switchThread = useCallback(\n (newThreadId: string | null) => {\n if (newThreadId !== threadIdRef.current) {\n threadIdRef.current = newThreadId;\n stream.clear();\n onThreadId(newThreadId as string);\n }\n },\n [stream, onThreadId]\n );\n\n const historyLimit =\n typeof options.fetchStateHistory === \"object\" &&\n options.fetchStateHistory != null\n ? (options.fetchStateHistory.limit ?? false)\n : (options.fetchStateHistory ?? false);\n\n const builtInHistory = useThreadHistory<StateType>(\n client,\n threadId,\n historyLimit,\n {\n passthrough: options.thread != null,\n submittingRef: threadIdStreamingRef,\n onError: options.onError,\n }\n );\n const history = options.thread ?? builtInHistory;\n\n const getMessages = (value: StateType): Message[] => {\n const messagesKey = options.messagesKey ?? DEFAULT_MESSAGES_KEY;\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n const setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = options.messagesKey ?? DEFAULT_MESSAGES_KEY;\n return { ...current, [messagesKey]: messages };\n };\n\n const [branch, setBranch] = useState<string>(\"\");\n const branchContext = getBranchContext(branch, history.data ?? undefined);\n\n const [toolProgressMap, setToolProgressMap] = useState<\n Map<string, ToolProgress>\n >(new Map());\n\n const handleToolEvent = useCallback((data: ToolsStreamEvent[\"data\"]) => {\n setToolProgressMap((prev) => {\n const next = new Map(prev);\n const key = data.toolCallId ?? data.name;\n const existing = next.get(key);\n\n switch (data.event) {\n case \"on_tool_start\": {\n next.set(key, {\n toolCallId: data.toolCallId,\n name: data.name,\n state: \"starting\",\n input: data.input,\n });\n break;\n }\n case \"on_tool_event\": {\n if (existing) {\n next.set(key, { ...existing, state: \"running\", data: data.data });\n }\n break;\n }\n case \"on_tool_end\": {\n if (existing) {\n next.set(key, {\n ...existing,\n state: \"completed\",\n result: data.output,\n });\n }\n break;\n }\n case \"on_tool_error\": {\n if (existing) {\n next.set(key, { ...existing, state: \"error\", error: data.error });\n }\n break;\n }\n default: {\n throw new Error(\n `Unexpected tool event: ${(data as { event: string }).event}`\n );\n }\n }\n\n return next;\n });\n }, []);\n\n const historyValues =\n branchContext.threadHead?.values ??\n options.initialValues ??\n ({} as StateType);\n\n // Reconstruct subagents from history when:\n // 1. History is loaded (not loading, has data)\n // 2. No active stream is running\n // 3. Subagent filtering is enabled (otherwise subagents aren't tracked)\n // This ensures subagent visualization persists after page refresh or stream completion\n const historyMessages = getMessages(historyValues);\n const shouldReconstructSubagents =\n options.filterSubagentMessages &&\n !stream.isLoading &&\n !history.isLoading &&\n historyMessages.length > 0;\n\n useEffect(() => {\n if (shouldReconstructSubagents) {\n // skipIfPopulated: true ensures we don't overwrite subagents from active streaming\n stream.reconstructSubagents(historyMessages, { skipIfPopulated: true });\n // Fetch internal messages for each subagent from their subgraph checkpoints.\n // These messages are not in the main thread state but are persisted in the\n // checkpointer under a subgraph-specific checkpoint_ns (e.g. tools:call_abc123).\n if (historyLimit !== false && threadId) {\n const controller = new AbortController();\n void stream.fetchSubagentHistory(client.threads, threadId, {\n messagesKey: options.messagesKey ?? DEFAULT_MESSAGES_KEY,\n historyLimit:\n typeof historyLimit === \"number\" ? historyLimit : undefined,\n signal: controller.signal,\n });\n return () => controller.abort();\n }\n }\n\n // We intentionally only run this when shouldReconstructSubagents changes\n // to avoid unnecessary reconstructions during streaming\n return undefined;\n }, [shouldReconstructSubagents, historyMessages.length]);\n\n const historyError = (() => {\n const error = branchContext.threadHead?.tasks?.at(-1)?.error;\n if (error == null) return undefined;\n try {\n const parsed = JSON.parse(error) as unknown;\n if (StreamError.isStructuredError(parsed)) return new StreamError(parsed);\n return parsed;\n } catch {\n // do nothing\n }\n return error;\n })();\n\n const messageMetadata = (() => {\n const alreadyShown = new Set<string>();\n return getMessages(historyValues).map(\n (message, idx): Omit<MessageMetadata<StateType>, \"streamMetadata\"> => {\n const messageId = message.id ?? idx;\n\n // Find the first checkpoint where the message was seen\n const firstSeenState = findLast(\n history.data ?? [],\n (state) =>\n state.values != null &&\n getMessages(state.values)\n .map((m, idx) => m.id ?? idx)\n .includes(messageId)\n );\n\n const checkpointId = firstSeenState?.checkpoint?.checkpoint_id;\n let branch =\n checkpointId != null\n ? branchContext.branchByCheckpoint[checkpointId]\n : undefined;\n if (!branch?.branch?.length) branch = undefined;\n\n // serialize branches\n const optionsShown = branch?.branchOptions?.flat(2).join(\",\");\n if (optionsShown) {\n if (alreadyShown.has(optionsShown)) branch = undefined;\n alreadyShown.add(optionsShown);\n }\n\n return {\n messageId: messageId.toString(),\n firstSeenState,\n\n branch: branch?.branch,\n branchOptions: branch?.branchOptions,\n };\n }\n );\n })();\n\n const stop = () =>\n stream.stop(historyValues, {\n onStop: (args) => {\n if (runMetadataStorage && threadId) {\n const runId = runMetadataStorage.getItem(`lg:stream:${threadId}`);\n if (runId) void client.runs.cancel(threadId, runId);\n runMetadataStorage.removeItem(`lg:stream:${threadId}`);\n }\n\n options.onStop?.(args);\n },\n });\n\n // --- TRANSPORT ---\n const submit = async (\n values: UpdateType | null | undefined,\n submitOptions?: SubmitOptions<StateType, ConfigurableType>\n ) => {\n setToolProgressMap(new Map());\n\n // Unbranch things\n const checkpointId = submitOptions?.checkpoint?.checkpoint_id;\n setBranch(\n checkpointId != null\n ? (branchContext.branchByCheckpoint[checkpointId]?.branch ?? \"\")\n : \"\"\n );\n\n // When `fetchStateHistory` is requested, thus we assume that branching\n // is enabled. We then need to include the implicit branch.\n const includeImplicitBranch =\n historyLimit === true || typeof historyLimit === \"number\";\n\n const shouldRefetch =\n includeImplicitBranch || onFinishRequiresThreadState(options.onFinish);\n\n let callbackMeta: RunCallbackMeta | undefined;\n let rejoinKey: `lg:stream:${string}` | undefined;\n let usableThreadId = threadId;\n\n const shouldAbortPrevious =\n (submitOptions?.multitaskStrategy === \"interrupt\" ||\n submitOptions?.multitaskStrategy === \"rollback\") &&\n stream.isLoading;\n\n await stream.start(\n async (signal: AbortSignal) => {\n stream.setStreamValues((values) => {\n const prev = { ...historyValues, ...values };\n if (submitOptions?.optimisticValues != null) {\n return {\n ...prev,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(prev)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...prev };\n });\n\n if (!usableThreadId) {\n const thread = await client.threads.create({\n threadId: submitOptions?.threadId,\n metadata: submitOptions?.metadata,\n signal,\n });\n\n usableThreadId = thread.thread_id;\n\n // Pre-emptively update the thread ID before\n // stream cancellation is kicked off and thread\n // is being refetched\n threadIdRef.current = usableThreadId;\n threadIdStreamingRef.current = usableThreadId;\n\n onThreadId(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n threadIdStreamingRef.current = usableThreadId;\n\n const streamMode = unique([\n ...(submitOptions?.streamMode ?? []),\n ...trackStreamModeRef.current,\n ...callbackStreamMode,\n ]);\n\n let checkpoint =\n submitOptions?.checkpoint ??\n (includeImplicitBranch\n ? branchContext.threadHead?.checkpoint\n : undefined) ??\n undefined;\n\n // Avoid specifying a checkpoint if user explicitly set it to null\n if (submitOptions?.checkpoint === null) checkpoint = undefined;\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n if (checkpoint != null) delete checkpoint.thread_id;\n const streamResumable =\n submitOptions?.streamResumable ?? !!runMetadataStorage;\n\n return client.runs.stream(usableThreadId, options.assistantId, {\n input: values as Record<string, unknown>,\n config: submitOptions?.config,\n context: submitOptions?.context,\n command: submitOptions?.command,\n\n interruptBefore: submitOptions?.interruptBefore,\n interruptAfter: submitOptions?.interruptAfter,\n metadata: submitOptions?.metadata,\n multitaskStrategy: submitOptions?.multitaskStrategy,\n onCompletion: submitOptions?.onCompletion,\n onDisconnect:\n submitOptions?.onDisconnect ??\n (streamResumable ? \"continue\" : \"cancel\"),\n\n signal,\n\n checkpoint,\n streamMode,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n streamResumable,\n durability: submitOptions?.durability,\n onRunCreated(params) {\n callbackMeta = {\n run_id: params.run_id,\n thread_id: params.thread_id ?? usableThreadId!,\n };\n\n if (runMetadataStorage) {\n rejoinKey = `lg:stream:${usableThreadId}`;\n runMetadataStorage.setItem(rejoinKey, callbackMeta.run_id);\n }\n\n options.onCreated?.(callbackMeta);\n },\n }) as AsyncGenerator<\n EventStreamEvent<StateType, UpdateType, CustomType>\n >;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: historyValues,\n callbacks: {\n ...options,\n onToolEvent: (data, opts) => {\n handleToolEvent(data);\n options.onToolEvent?.(data, opts);\n },\n },\n\n async onSuccess() {\n if (rejoinKey) runMetadataStorage?.removeItem(rejoinKey);\n\n if (shouldRefetch) {\n const newHistory = await history.mutate(usableThreadId!);\n const lastHead = newHistory?.at(0);\n if (lastHead) {\n // We now have the latest update from /history\n // Thus we can clear the local stream state\n options.onFinish?.(lastHead, callbackMeta);\n return null;\n }\n } else if (\n options.onFinish != null &&\n !onFinishRequiresThreadState(options.onFinish)\n ) {\n options.onFinish(\n undefined as unknown as ThreadState<StateType>,\n callbackMeta\n );\n }\n\n return undefined;\n },\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n onFinish() {\n threadIdStreamingRef.current = null;\n },\n },\n { abortPrevious: shouldAbortPrevious }\n );\n };\n\n const joinStream = async (\n runId: string,\n lastEventId?: string,\n joinOptions?: {\n streamMode?: StreamMode | StreamMode[];\n filter?: (event: {\n id?: string;\n event: StreamEvent;\n data: unknown;\n }) => boolean;\n }\n ) => {\n setToolProgressMap(new Map());\n\n // eslint-disable-next-line no-param-reassign\n lastEventId ??= \"-1\";\n if (!threadId) return;\n\n const callbackMeta: RunCallbackMeta = {\n thread_id: threadId,\n run_id: runId,\n };\n\n const includeImplicitBranchJoin =\n historyLimit === true || typeof historyLimit === \"number\";\n const shouldRefetchJoin =\n includeImplicitBranchJoin ||\n onFinishRequiresThreadState(options.onFinish);\n\n await stream.start(\n async (signal: AbortSignal) => {\n threadIdStreamingRef.current = threadId;\n const stream = client.runs.joinStream(threadId, runId, {\n signal,\n lastEventId,\n streamMode: joinOptions?.streamMode,\n }) as AsyncGenerator<\n EventStreamEvent<StateType, UpdateType, CustomType>\n >;\n\n return joinOptions?.filter != null\n ? filterStream(stream, joinOptions.filter)\n : stream;\n },\n {\n getMessages,\n setMessages,\n\n initialValues: historyValues,\n callbacks: {\n ...options,\n onToolEvent: (data, opts) => {\n handleToolEvent(data);\n options.onToolEvent?.(data, opts);\n },\n },\n async onSuccess() {\n runMetadataStorage?.removeItem(`lg:stream:${threadId}`);\n if (!shouldRefetchJoin) {\n if (\n options.onFinish != null &&\n !onFinishRequiresThreadState(options.onFinish)\n ) {\n options.onFinish(\n undefined as unknown as ThreadState<StateType>,\n callbackMeta\n );\n }\n return;\n }\n const newHistory = await history.mutate(threadId);\n const lastHead = newHistory?.at(0);\n if (lastHead) options.onFinish?.(lastHead, callbackMeta);\n },\n onError(error) {\n options.onError?.(error, callbackMeta);\n },\n onFinish() {\n threadIdStreamingRef.current = null;\n },\n }\n );\n };\n\n const reconnectKey = useMemo(() => {\n if (!runMetadataStorage || stream.isLoading) return undefined;\n if (typeof window === \"undefined\") return undefined;\n const runId = runMetadataStorage?.getItem(`lg:stream:${threadId}`);\n if (!runId) return undefined;\n return { runId, threadId };\n }, [runMetadataStorage, stream.isLoading, threadId]);\n\n const shouldReconnect = !!runMetadataStorage;\n const reconnectRef = useRef({ threadId, shouldReconnect });\n\n const joinStreamRef = useRef<typeof joinStream>(joinStream);\n joinStreamRef.current = joinStream;\n\n useEffect(() => {\n // reset shouldReconnect when switching threads\n if (reconnectRef.current.threadId !== threadId) {\n reconnectRef.current = { threadId, shouldReconnect };\n }\n }, [threadId, shouldReconnect]);\n\n useEffect(() => {\n if (reconnectKey && reconnectRef.current.shouldReconnect) {\n reconnectRef.current.shouldReconnect = false;\n void joinStreamRef.current?.(reconnectKey.runId);\n }\n }, [reconnectKey]);\n\n const error = stream.error ?? historyError ?? history.error;\n const values = stream.values ?? historyValues;\n\n const handledToolsRef = useRef<Set<string>>(new Set());\n useEffect(() => {\n handledToolsRef.current.clear();\n }, [threadId]);\n\n useEffect(() => {\n flushPendingHeadlessToolInterrupts(\n values as Record<string, unknown>,\n options.tools,\n handledToolsRef.current,\n {\n onTool: options.onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n submit(null, {\n multitaskStrategy: \"interrupt\",\n command,\n }),\n }\n );\n }, [options.onTool, options.tools, submit, values]);\n\n const streamHandle: UseStream<StateType, Bag> = {\n get values() {\n trackStreamMode(\"values\");\n return values;\n },\n\n client,\n assistantId: options.assistantId,\n\n error,\n isLoading: stream.isLoading,\n\n stop,\n submit,\n switchThread,\n\n joinStream,\n\n branch,\n setBranch,\n\n get history() {\n if (historyLimit === false) {\n throw new Error(\n \"`fetchStateHistory` must be set to `true` to use `history`\"\n );\n }\n\n return branchContext.flatHistory;\n },\n\n isThreadLoading: history.isLoading && history.data == null,\n\n get experimental_branchTree() {\n if (historyLimit === false) {\n throw new Error(\n \"`fetchStateHistory` must be set to `true` to use `experimental_branchTree`\"\n );\n }\n\n return branchContext.branchTree;\n },\n\n get interrupts(): Interrupt<InterruptType>[] {\n if (\n values != null &&\n \"__interrupt__\" in values &&\n Array.isArray(values.__interrupt__)\n ) {\n return userFacingInterruptsFromValuesArray<InterruptType>(\n values.__interrupt__ as Interrupt<InterruptType>[]\n );\n }\n\n // If we're deferring to old interrupt detection logic, don't show the interrupt if the stream is loading\n if (stream.isLoading) return [];\n\n // Collect interrupts from ALL tasks (not just the last one)\n const allTasks = branchContext.threadHead?.tasks ?? [];\n const allInterrupts = allTasks.flatMap((t) => t.interrupts ?? []);\n\n const taskInterrupts = userFacingInterruptsFromThreadTasks<InterruptType>(\n allInterrupts as Interrupt<InterruptType>[]\n );\n if (taskInterrupts != null) return taskInterrupts;\n\n // check if there's a next task present (breakpoint-style interrupt)\n const next = branchContext.threadHead?.next ?? [];\n if (!next.length || error != null) return [];\n return [{ when: \"breakpoint\" }];\n },\n\n get interrupt() {\n const all = this.interrupts;\n if (all.length === 0) return undefined;\n if (all.length === 1) return all[0];\n\n // Multiple interrupts: return the array for backward compat\n return all as Interrupt<InterruptType>;\n },\n\n get messages(): Message<ToolCallType>[] {\n trackStreamMode(\"messages-tuple\", \"values\");\n return getMessages(values);\n },\n\n get toolCalls() {\n trackStreamMode(\"messages-tuple\", \"values\");\n const msgs = getMessages(values) as Message<ToolCallType>[];\n return getToolCallsWithResults<ToolCallType>(msgs);\n },\n\n get toolProgress(): ToolProgress[] {\n trackStreamMode(\"tools\");\n return Array.from(toolProgressMap.values());\n },\n\n getToolCalls(message: Message<ToolCallType>) {\n trackStreamMode(\"messages-tuple\", \"values\");\n const msgs = getMessages(values) as Message<ToolCallType>[];\n const allToolCalls = getToolCallsWithResults<ToolCallType>(msgs);\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n },\n\n getMessagesMetadata(\n message: Message<ToolCallType>,\n index?: number\n ): MessageMetadata<StateType> | undefined {\n trackStreamMode(\"values\");\n\n const streamMetadata = messageManager.get(message.id)?.metadata;\n const historyMetadata = messageMetadata?.find(\n (m) => m.messageId === (message.id ?? index)\n );\n\n if (streamMetadata != null || historyMetadata != null) {\n return {\n ...historyMetadata,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n\n return undefined;\n },\n\n get subagents() {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagents();\n },\n\n get activeSubagents() {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getActiveSubagents();\n },\n\n getSubagent(toolCallId: string) {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagent(toolCallId);\n },\n\n getSubagentsByType(type: string) {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagentsByType(type);\n },\n\n getSubagentsByMessage(messageId: string) {\n trackStreamMode(\"updates\", \"messages-tuple\");\n return stream.getSubagentsByMessage(messageId);\n },\n };\n\n // Avoid eager getter evaluation during object spread/rest destructuring.\n // These accessors are opt-in and should only run when explicitly read.\n const nonEnumerableAccessors = [\n \"history\",\n \"experimental_branchTree\",\n \"toolProgress\",\n \"subagents\",\n \"activeSubagents\",\n ] as const;\n for (const key of nonEnumerableAccessors) {\n const descriptor = Object.getOwnPropertyDescriptor(streamHandle, key);\n if (descriptor?.get) {\n Object.defineProperty(streamHandle, key, {\n ...descriptor,\n enumerable: false,\n });\n }\n }\n\n return streamHandle;\n}\n"],"mappings":"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"}

@@ -8,5 +8,11 @@ //#region src/stream/constants.ts

const NAMESPACE_SEPARATOR = "\0";
/**
* Default state / values key that holds the message array for stream
* controllers and UI bindings.
*/
const DEFAULT_MESSAGES_KEY = "messages";
//#endregion
exports.DEFAULT_MESSAGES_KEY = DEFAULT_MESSAGES_KEY;
exports.NAMESPACE_SEPARATOR = NAMESPACE_SEPARATOR;
//# sourceMappingURL=constants.cjs.map

@@ -1,1 +0,1 @@

{"version":3,"file":"constants.cjs","names":[],"sources":["../../src/stream/constants.ts"],"sourcesContent":["/**\n * Separator used to create stable string keys from namespace tuples.\n * The null character cannot collide with protocol namespace segments,\n * which are printable identifiers.\n */\nexport const NAMESPACE_SEPARATOR = \"\\u0000\";\n"],"mappings":";;;;;;AAKA,MAAa,sBAAsB"}
{"version":3,"file":"constants.cjs","names":[],"sources":["../../src/stream/constants.ts"],"sourcesContent":["/**\n * Separator used to create stable string keys from namespace tuples.\n * The null character cannot collide with protocol namespace segments,\n * which are printable identifiers.\n */\nexport const NAMESPACE_SEPARATOR = \"\\u0000\";\n\n/**\n * Default state / values key that holds the message array for stream\n * controllers and UI bindings.\n */\nexport const DEFAULT_MESSAGES_KEY = \"messages\";\n"],"mappings":";;;;;;AAKA,MAAa,sBAAsB;;;;;AAMnC,MAAa,uBAAuB"}

@@ -8,4 +8,9 @@ //#region src/stream/constants.d.ts

declare const NAMESPACE_SEPARATOR = "\0";
/**
* Default state / values key that holds the message array for stream
* controllers and UI bindings.
*/
declare const DEFAULT_MESSAGES_KEY = "messages";
//#endregion
export { NAMESPACE_SEPARATOR };
export { DEFAULT_MESSAGES_KEY, NAMESPACE_SEPARATOR };
//# sourceMappingURL=constants.d.cts.map

@@ -1,1 +0,1 @@

{"version":3,"file":"constants.d.cts","names":[],"sources":["../../src/stream/constants.ts"],"mappings":";;AAKA;;;;cAAa,mBAAA"}
{"version":3,"file":"constants.d.cts","names":[],"sources":["../../src/stream/constants.ts"],"mappings":";;AAKA;;;;cAAa,mBAAA;AAMb;;;;AAAA,cAAa,oBAAA"}

@@ -8,4 +8,9 @@ //#region src/stream/constants.d.ts

declare const NAMESPACE_SEPARATOR = "\0";
/**
* Default state / values key that holds the message array for stream
* controllers and UI bindings.
*/
declare const DEFAULT_MESSAGES_KEY = "messages";
//#endregion
export { NAMESPACE_SEPARATOR };
export { DEFAULT_MESSAGES_KEY, NAMESPACE_SEPARATOR };
//# sourceMappingURL=constants.d.ts.map

@@ -1,1 +0,1 @@

{"version":3,"file":"constants.d.ts","names":[],"sources":["../../src/stream/constants.ts"],"mappings":";;AAKA;;;;cAAa,mBAAA"}
{"version":3,"file":"constants.d.ts","names":[],"sources":["../../src/stream/constants.ts"],"mappings":";;AAKA;;;;cAAa,mBAAA;AAMb;;;;AAAA,cAAa,oBAAA"}

@@ -8,5 +8,10 @@ //#region src/stream/constants.ts

const NAMESPACE_SEPARATOR = "\0";
/**
* Default state / values key that holds the message array for stream
* controllers and UI bindings.
*/
const DEFAULT_MESSAGES_KEY = "messages";
//#endregion
export { NAMESPACE_SEPARATOR };
export { DEFAULT_MESSAGES_KEY, NAMESPACE_SEPARATOR };
//# sourceMappingURL=constants.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"constants.js","names":[],"sources":["../../src/stream/constants.ts"],"sourcesContent":["/**\n * Separator used to create stable string keys from namespace tuples.\n * The null character cannot collide with protocol namespace segments,\n * which are printable identifiers.\n */\nexport const NAMESPACE_SEPARATOR = \"\\u0000\";\n"],"mappings":";;;;;;AAKA,MAAa,sBAAsB"}
{"version":3,"file":"constants.js","names":[],"sources":["../../src/stream/constants.ts"],"sourcesContent":["/**\n * Separator used to create stable string keys from namespace tuples.\n * The null character cannot collide with protocol namespace segments,\n * which are printable identifiers.\n */\nexport const NAMESPACE_SEPARATOR = \"\\u0000\";\n\n/**\n * Default state / values key that holds the message array for stream\n * controllers and UI bindings.\n */\nexport const DEFAULT_MESSAGES_KEY = \"messages\";\n"],"mappings":";;;;;;AAKA,MAAa,sBAAsB;;;;;AAMnC,MAAa,uBAAuB"}

@@ -0,3 +1,3 @@

const require_constants = require("../constants.cjs");
const require_message_coercion = require("../message-coercion.cjs");
require("../constants.cjs");
const require_namespace = require("../namespace.cjs");

@@ -81,3 +81,3 @@ //#region src/stream/discovery/namespace-from-history.ts

*/
function mapSubagentNamespaces(history, toolCallIds, messagesKey = "messages") {
function mapSubagentNamespaces(history, toolCallIds, messagesKey = require_constants.DEFAULT_MESSAGES_KEY) {
const out = /* @__PURE__ */ new Map();

@@ -84,0 +84,0 @@ const targets = new Set(toolCallIds);

@@ -1,1 +0,1 @@

{"version":3,"file":"namespace-from-history.cjs","names":["normalizeAIMessageToolCalls","namespaceKey"],"sources":["../../../src/stream/discovery/namespace-from-history.ts"],"sourcesContent":["/**\n * Reconstruct discovery namespaces from checkpoint history.\n *\n * On reconnect the always-on SSE replay eventually re-derives every\n * subagent execution namespace and every subgraph host, but that costs\n * a full depth-1 replay. This module derives the same information from\n * a single bounded `getHistory()` read so the controller can promote\n * namespaces immediately on `hydrate()` (subgraph hosts + subagent\n * execution namespaces) and lazily for a single opened subagent.\n *\n * The logic mirrors the live discovery state machines so a\n * history-derived namespace and an SSE-derived one cannot disagree:\n * - subagent mapping ports {@link ../../ui/manager} `fetchSubagentHistory`\n * (direct task-result mapping, then positional Send-index fallback);\n * - subgraph host detection ports the strict-prefix promotion rule in\n * {@link ./subgraphs}.\n */\nimport type { Client } from \"../../client/index.js\";\nimport type {\n Checkpoint,\n Config,\n Metadata,\n ThreadState,\n} from \"../../schema.js\";\nimport { NAMESPACE_SEPARATOR } from \"../constants.js\";\nimport { namespaceKey } from \"../namespace.js\";\nimport { normalizeAIMessageToolCalls } from \"../message-coercion.js\";\n\ntype AnyCheckpoint = ThreadState<Record<string, unknown>>;\n\ninterface HistoryTask {\n id?: unknown;\n name?: unknown;\n path?: unknown;\n result?: { messages?: unknown[] };\n checkpoint?: { checkpoint_ns?: unknown } | null;\n}\n\nfunction getTasks(checkpoint: AnyCheckpoint): HistoryTask[] {\n const tasks = (checkpoint as { tasks?: unknown }).tasks;\n return Array.isArray(tasks) ? (tasks as HistoryTask[]) : [];\n}\n\n/**\n * Phase 1 (preferred): map a `task` tool-call id directly to its\n * execution namespace via the task's result `ToolMessage`. Unambiguous\n * — works even when a step mixes subagent and non-subagent tool calls.\n *\n * The subgraph checkpoint_ns is `task.name + \":\" + task.id` (mirrors\n * pregel's `taskCheckpointNamespace`), so we derive it from name+id\n * rather than the always-null completed-task checkpoint.\n */\nexport function collectDirectTaskMappings(\n tasks: HistoryTask[],\n targets: Set<string>,\n out: Map<string, string>\n): void {\n for (const task of tasks) {\n if (\n !Array.isArray(task.path) ||\n task.path[0] !== \"__pregel_push\" ||\n typeof task.id !== \"string\" ||\n typeof task.name !== \"string\"\n ) {\n continue;\n }\n const resultMessages = task.result?.messages;\n if (!Array.isArray(resultMessages)) continue;\n for (const msg of resultMessages) {\n const m = msg as Record<string, unknown>;\n const id = m.tool_call_id;\n if (\n m.type === \"tool\" &&\n typeof id === \"string\" &&\n targets.has(id) &&\n !out.has(id)\n ) {\n out.set(id, `${task.name}:${task.id}`);\n }\n }\n }\n}\n\n/**\n * Phase 2 (fallback): align still-pending push tasks to the triggering\n * AI message's tool calls by Send index (`path[1]`), where `path[1]`\n * indexes into the *full* `tool_calls` array. Only push tasks whose\n * targeted call is a subagent `task` are mapped, so a sibling\n * non-subagent tool call in the same message can't capture a subagent's\n * namespace. Applied only to ids Phase 1 could not resolve so a correct\n * direct mapping is never overwritten by a positional guess.\n */\nexport function collectPositionalTaskMappings(\n checkpoint: AnyCheckpoint,\n targets: Set<string>,\n out: Map<string, string>,\n messagesKey: string\n): void {\n const pushTasks = getTasks(checkpoint).filter(\n (t) =>\n Array.isArray(t.path) &&\n t.path[0] === \"__pregel_push\" &&\n typeof t.path[1] === \"number\" &&\n typeof t.id === \"string\" &&\n typeof t.name === \"string\"\n );\n if (pushTasks.length === 0) return;\n\n const msgs = (checkpoint.values as Record<string, unknown> | undefined)?.[\n messagesKey\n ];\n if (!Array.isArray(msgs)) return;\n\n let toolCalls: Array<{ id?: string; name?: string }> | undefined;\n for (let i = msgs.length - 1; i >= 0; i -= 1) {\n const m = msgs[i] as Record<string, unknown>;\n if (m.type !== \"ai\") continue;\n const normalized = normalizeAIMessageToolCalls(\n m as unknown as Parameters<typeof normalizeAIMessageToolCalls>[0]\n ) as Record<string, unknown>;\n const normalizedToolCalls = normalized.tool_calls;\n if (\n Array.isArray(normalizedToolCalls) &&\n (normalizedToolCalls as Array<{ name?: string }>).some(\n (tc) => tc.name === \"task\"\n )\n ) {\n toolCalls = normalizedToolCalls as Array<{\n id?: string;\n name?: string;\n }>;\n break;\n }\n }\n if (toolCalls == null) return;\n\n // `path[1]` is the Send index into the *full* `tool_calls` array, not the\n // subagent-only subset. Resolve each push task against that array and map\n // it only when the targeted call is itself a `task`, so a sibling\n // non-subagent tool call cannot capture a subagent's namespace.\n for (const task of pushTasks) {\n const index = (task.path as unknown[])[1] as number;\n const tc = toolCalls[index];\n if (\n tc?.name === \"task\" &&\n tc.id != null &&\n typeof task.id === \"string\" &&\n typeof task.name === \"string\" &&\n targets.has(tc.id) &&\n !out.has(tc.id)\n ) {\n out.set(tc.id, `${task.name}:${task.id}`);\n }\n }\n}\n\n/** Build a `getHistory` `before` cursor from a history entry. */\nfunction beforeCursor(entry: AnyCheckpoint): Config | undefined {\n const checkpointId = entry.checkpoint?.checkpoint_id;\n if (typeof checkpointId !== \"string\") return undefined;\n return { configurable: { checkpoint_id: checkpointId } };\n}\n\nfunction applyCollectors(\n history: AnyCheckpoint[],\n targets: Set<string>,\n out: Map<string, string>,\n messagesKey: string\n): void {\n for (const checkpoint of history) {\n collectDirectTaskMappings(getTasks(checkpoint), targets, out);\n }\n const stillUnmapped = () => [...targets].some((id) => !out.has(id));\n if (stillUnmapped()) {\n for (const checkpoint of history) {\n if (!stillUnmapped()) break;\n collectPositionalTaskMappings(checkpoint, targets, out, messagesKey);\n }\n }\n}\n\n/**\n * Synchronous subagent namespace mapping over an already-fetched\n * history page. Used by {@link resolveSubagentNamespaces} and by the\n * controller's hydrate-time bulk seed (which shares a single\n * `getHistory` page with subgraph host detection).\n */\nexport function mapSubagentNamespaces(\n history: AnyCheckpoint[],\n toolCallIds: string[],\n messagesKey = \"messages\"\n): Map<string, string> {\n const out = new Map<string, string>();\n const targets = new Set(toolCallIds);\n if (targets.size === 0) return out;\n applyCollectors(history, targets, out, messagesKey);\n return out;\n}\n\n/**\n * Resolve execution namespaces for the given subagent `task` tool-call\n * ids from checkpoint history.\n *\n * Bounded and O(1) in calls: one `getHistory` page, plus at most one\n * `before`-cursor fallback page when the first leaves ids unresolved.\n * Never fans out per id.\n *\n * @returns Map of `toolCallId` → single execution namespace segment\n * (e.g. `tools:<uuid>`). Unresolved ids are omitted.\n */\nexport async function resolveSubagentNamespaces<TStateType>(\n client: Client<TStateType>,\n threadId: string,\n toolCallIds: string[],\n opts?: { limit?: number; messagesKey?: string; signal?: AbortSignal }\n): Promise<Map<string, string>> {\n const out = new Map<string, string>();\n const targets = new Set(toolCallIds);\n if (targets.size === 0) return out;\n\n const limit = opts?.limit ?? 20;\n const messagesKey = opts?.messagesKey ?? \"messages\";\n const signal = opts?.signal;\n\n const page1 = await getHistoryPage(client, threadId, { limit, signal });\n applyCollectors(page1, targets, out, messagesKey);\n\n const unresolved = [...targets].filter((id) => !out.has(id));\n if (unresolved.length > 0 && page1.length > 0) {\n const before = beforeCursor(page1[page1.length - 1]);\n if (before != null) {\n const page2 = await getHistoryPage(client, threadId, {\n limit,\n before,\n signal,\n });\n applyCollectors(page2, targets, out, messagesKey);\n }\n }\n\n return out;\n}\n\n/**\n * Fetch one bounded history page typed as plain records, sidestepping\n * the client's `TStateType` generic so the discovery collectors (which\n * read raw `values`/`tasks`) get a stable {@link AnyCheckpoint} shape.\n */\nexport function getHistoryPage<TStateType>(\n client: Client<TStateType>,\n threadId: string,\n options: {\n limit?: number;\n before?: Config;\n checkpoint?: Partial<Omit<Checkpoint, \"thread_id\">>;\n metadata?: Metadata;\n signal?: AbortSignal;\n }\n): Promise<AnyCheckpoint[]> {\n return client.threads.getHistory<Record<string, unknown>>(threadId, options);\n}\n\nexport interface SubgraphHost {\n namespace: string[];\n status: \"running\" | \"complete\" | \"error\";\n}\n\nfunction checkpointNsToSegments(checkpointNs: unknown): string[] {\n if (typeof checkpointNs !== \"string\" || checkpointNs.length === 0) return [];\n return checkpointNs.split(\"|\").filter((segment) => segment.length > 0);\n}\n\nfunction isInternalSegment(segment: string): boolean {\n return segment.startsWith(\"tools:\") || segment.startsWith(\"task:\");\n}\n\n/**\n * Identify subgraph host namespaces from checkpoint history, mirroring the\n * promotion rule of the live {@link ./subgraphs} `SubgraphDiscovery`: a\n * namespace is a host iff it is a *strict ancestor* of a deeper namespace,\n * and inner function-node leaves are never promoted on their own.\n *\n * Two host signals are derived from the checkpoint namespaces observed in\n * history (`state` + `task` `checkpoint_ns`):\n *\n * - **Interior hosts** — every strict ancestor of an observed namespace.\n * Each segment of a nested `checkpoint_ns` wraps a deeper one, so the\n * parent is always a subgraph (this also recovers a host whose own\n * checkpoint fell outside the fetched page).\n * - **Top-level hosts** — every depth-1 observed namespace. A top-level\n * subgraph is always a host, including the values-only shape supported\n * by `SubgraphDiscovery.#onValuesEvent`, where the host (e.g.\n * `research:<uuid>`) appears with no deeper `research:<uuid>|...` key.\n * The old strict-prefix rule dropped those, so reconnecting waited for\n * SSE replay instead of hydrating the card immediately.\n *\n * A *deeper* observed namespace's own deepest segment is NOT promoted\n * unless it is itself an ancestor of something deeper — otherwise a plain\n * inner node (e.g. `worker:<uuid>|inner:<uuid>`) would surface as a\n * spurious subgraph card that was never present during live streaming.\n *\n * Tool/subagent namespaces (`tools:` / `task:`) are excluded — those are\n * owned by {@link ./subagents}. A namespace nested under a subgraph (e.g.\n * `research:<uuid>|tools:<uuid>`) still promotes its non-internal\n * `research:<uuid>` ancestor.\n */\nexport function collectSubgraphHostNamespaces(\n history: AnyCheckpoint[]\n): SubgraphHost[] {\n // Directly observed namespace tuples (state + task checkpoint_ns), with\n // NO prefix synthesis — host promotion is derived below so that a deeper\n // namespace's leaf segment is not mistaken for a host.\n const observed = new Map<string, string[]>();\n const record = (segments: string[]) => {\n if (segments.length === 0) return;\n observed.set(namespaceKey(segments), segments);\n };\n for (const state of history) {\n record(checkpointNsToSegments(state.checkpoint?.checkpoint_ns));\n for (const task of getTasks(state)) {\n record(checkpointNsToSegments(task.checkpoint?.checkpoint_ns));\n }\n }\n\n // Pending namespaces of the newest checkpoint → still running.\n const pending = new Set<string>();\n if (history.length > 0) {\n for (const task of getTasks(history[0])) {\n const segments = checkpointNsToSegments(task.checkpoint?.checkpoint_ns);\n if (segments.length > 0) pending.add(namespaceKey(segments));\n }\n }\n\n // Host candidates = strict ancestors of observed (interior) + depth-1\n // observed (top-level). Insertion order: shallow ancestors first so the\n // emitted host list keeps parents ahead of children.\n const candidates = new Map<string, string[]>();\n for (const segments of observed.values()) {\n for (let depth = 1; depth < segments.length; depth += 1) {\n const slice = segments.slice(0, depth);\n candidates.set(namespaceKey(slice), slice);\n }\n if (segments.length === 1) {\n candidates.set(namespaceKey(segments), segments);\n }\n }\n\n const hosts: SubgraphHost[] = [];\n for (const [key, segments] of candidates) {\n if (segments.some(isInternalSegment)) continue;\n const prefix = key + NAMESPACE_SEPARATOR;\n const running =\n pending.has(key) || [...pending].some((p) => p.startsWith(prefix));\n hosts.push({\n namespace: segments,\n status: running ? \"running\" : \"complete\",\n });\n }\n return hosts;\n}\n"],"mappings":"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"}
{"version":3,"file":"namespace-from-history.cjs","names":["normalizeAIMessageToolCalls","DEFAULT_MESSAGES_KEY","namespaceKey"],"sources":["../../../src/stream/discovery/namespace-from-history.ts"],"sourcesContent":["/**\n * Reconstruct discovery namespaces from checkpoint history.\n *\n * On reconnect the always-on SSE replay eventually re-derives every\n * subagent execution namespace and every subgraph host, but that costs\n * a full depth-1 replay. This module derives the same information from\n * a single bounded `getHistory()` read so the controller can promote\n * namespaces immediately on `hydrate()` (subgraph hosts + subagent\n * execution namespaces) and lazily for a single opened subagent.\n *\n * The logic mirrors the live discovery state machines so a\n * history-derived namespace and an SSE-derived one cannot disagree:\n * - subagent mapping ports {@link ../../ui/manager} `fetchSubagentHistory`\n * (direct task-result mapping, then positional Send-index fallback);\n * - subgraph host detection ports the strict-prefix promotion rule in\n * {@link ./subgraphs}.\n */\nimport type { Client } from \"../../client/index.js\";\nimport type {\n Checkpoint,\n Config,\n Metadata,\n ThreadState,\n} from \"../../schema.js\";\nimport { NAMESPACE_SEPARATOR, DEFAULT_MESSAGES_KEY } from \"../constants.js\";\nimport { namespaceKey } from \"../namespace.js\";\nimport { normalizeAIMessageToolCalls } from \"../message-coercion.js\";\n\ntype AnyCheckpoint = ThreadState<Record<string, unknown>>;\n\ninterface HistoryTask {\n id?: unknown;\n name?: unknown;\n path?: unknown;\n result?: { messages?: unknown[] };\n checkpoint?: { checkpoint_ns?: unknown } | null;\n}\n\nfunction getTasks(checkpoint: AnyCheckpoint): HistoryTask[] {\n const tasks = (checkpoint as { tasks?: unknown }).tasks;\n return Array.isArray(tasks) ? (tasks as HistoryTask[]) : [];\n}\n\n/**\n * Phase 1 (preferred): map a `task` tool-call id directly to its\n * execution namespace via the task's result `ToolMessage`. Unambiguous\n * — works even when a step mixes subagent and non-subagent tool calls.\n *\n * The subgraph checkpoint_ns is `task.name + \":\" + task.id` (mirrors\n * pregel's `taskCheckpointNamespace`), so we derive it from name+id\n * rather than the always-null completed-task checkpoint.\n */\nexport function collectDirectTaskMappings(\n tasks: HistoryTask[],\n targets: Set<string>,\n out: Map<string, string>\n): void {\n for (const task of tasks) {\n if (\n !Array.isArray(task.path) ||\n task.path[0] !== \"__pregel_push\" ||\n typeof task.id !== \"string\" ||\n typeof task.name !== \"string\"\n ) {\n continue;\n }\n const resultMessages = task.result?.messages;\n if (!Array.isArray(resultMessages)) continue;\n for (const msg of resultMessages) {\n const m = msg as Record<string, unknown>;\n const id = m.tool_call_id;\n if (\n m.type === \"tool\" &&\n typeof id === \"string\" &&\n targets.has(id) &&\n !out.has(id)\n ) {\n out.set(id, `${task.name}:${task.id}`);\n }\n }\n }\n}\n\n/**\n * Phase 2 (fallback): align still-pending push tasks to the triggering\n * AI message's tool calls by Send index (`path[1]`), where `path[1]`\n * indexes into the *full* `tool_calls` array. Only push tasks whose\n * targeted call is a subagent `task` are mapped, so a sibling\n * non-subagent tool call in the same message can't capture a subagent's\n * namespace. Applied only to ids Phase 1 could not resolve so a correct\n * direct mapping is never overwritten by a positional guess.\n */\nexport function collectPositionalTaskMappings(\n checkpoint: AnyCheckpoint,\n targets: Set<string>,\n out: Map<string, string>,\n messagesKey: string\n): void {\n const pushTasks = getTasks(checkpoint).filter(\n (t) =>\n Array.isArray(t.path) &&\n t.path[0] === \"__pregel_push\" &&\n typeof t.path[1] === \"number\" &&\n typeof t.id === \"string\" &&\n typeof t.name === \"string\"\n );\n if (pushTasks.length === 0) return;\n\n const msgs = (checkpoint.values as Record<string, unknown> | undefined)?.[\n messagesKey\n ];\n if (!Array.isArray(msgs)) return;\n\n let toolCalls: Array<{ id?: string; name?: string }> | undefined;\n for (let i = msgs.length - 1; i >= 0; i -= 1) {\n const m = msgs[i] as Record<string, unknown>;\n if (m.type !== \"ai\") continue;\n const normalized = normalizeAIMessageToolCalls(\n m as unknown as Parameters<typeof normalizeAIMessageToolCalls>[0]\n ) as Record<string, unknown>;\n const normalizedToolCalls = normalized.tool_calls;\n if (\n Array.isArray(normalizedToolCalls) &&\n (normalizedToolCalls as Array<{ name?: string }>).some(\n (tc) => tc.name === \"task\"\n )\n ) {\n toolCalls = normalizedToolCalls as Array<{\n id?: string;\n name?: string;\n }>;\n break;\n }\n }\n if (toolCalls == null) return;\n\n // `path[1]` is the Send index into the *full* `tool_calls` array, not the\n // subagent-only subset. Resolve each push task against that array and map\n // it only when the targeted call is itself a `task`, so a sibling\n // non-subagent tool call cannot capture a subagent's namespace.\n for (const task of pushTasks) {\n const index = (task.path as unknown[])[1] as number;\n const tc = toolCalls[index];\n if (\n tc?.name === \"task\" &&\n tc.id != null &&\n typeof task.id === \"string\" &&\n typeof task.name === \"string\" &&\n targets.has(tc.id) &&\n !out.has(tc.id)\n ) {\n out.set(tc.id, `${task.name}:${task.id}`);\n }\n }\n}\n\n/** Build a `getHistory` `before` cursor from a history entry. */\nfunction beforeCursor(entry: AnyCheckpoint): Config | undefined {\n const checkpointId = entry.checkpoint?.checkpoint_id;\n if (typeof checkpointId !== \"string\") return undefined;\n return { configurable: { checkpoint_id: checkpointId } };\n}\n\nfunction applyCollectors(\n history: AnyCheckpoint[],\n targets: Set<string>,\n out: Map<string, string>,\n messagesKey: string\n): void {\n for (const checkpoint of history) {\n collectDirectTaskMappings(getTasks(checkpoint), targets, out);\n }\n const stillUnmapped = () => [...targets].some((id) => !out.has(id));\n if (stillUnmapped()) {\n for (const checkpoint of history) {\n if (!stillUnmapped()) break;\n collectPositionalTaskMappings(checkpoint, targets, out, messagesKey);\n }\n }\n}\n\n/**\n * Synchronous subagent namespace mapping over an already-fetched\n * history page. Used by {@link resolveSubagentNamespaces} and by the\n * controller's hydrate-time bulk seed (which shares a single\n * `getHistory` page with subgraph host detection).\n */\nexport function mapSubagentNamespaces(\n history: AnyCheckpoint[],\n toolCallIds: string[],\n messagesKey = DEFAULT_MESSAGES_KEY\n): Map<string, string> {\n const out = new Map<string, string>();\n const targets = new Set(toolCallIds);\n if (targets.size === 0) return out;\n applyCollectors(history, targets, out, messagesKey);\n return out;\n}\n\n/**\n * Resolve execution namespaces for the given subagent `task` tool-call\n * ids from checkpoint history.\n *\n * Bounded and O(1) in calls: one `getHistory` page, plus at most one\n * `before`-cursor fallback page when the first leaves ids unresolved.\n * Never fans out per id.\n *\n * @returns Map of `toolCallId` → single execution namespace segment\n * (e.g. `tools:<uuid>`). Unresolved ids are omitted.\n */\nexport async function resolveSubagentNamespaces<TStateType>(\n client: Client<TStateType>,\n threadId: string,\n toolCallIds: string[],\n opts?: { limit?: number; messagesKey?: string; signal?: AbortSignal }\n): Promise<Map<string, string>> {\n const out = new Map<string, string>();\n const targets = new Set(toolCallIds);\n if (targets.size === 0) return out;\n\n const limit = opts?.limit ?? 20;\n const messagesKey = opts?.messagesKey ?? DEFAULT_MESSAGES_KEY;\n const signal = opts?.signal;\n\n const page1 = await getHistoryPage(client, threadId, { limit, signal });\n applyCollectors(page1, targets, out, messagesKey);\n\n const unresolved = [...targets].filter((id) => !out.has(id));\n if (unresolved.length > 0 && page1.length > 0) {\n const before = beforeCursor(page1[page1.length - 1]);\n if (before != null) {\n const page2 = await getHistoryPage(client, threadId, {\n limit,\n before,\n signal,\n });\n applyCollectors(page2, targets, out, messagesKey);\n }\n }\n\n return out;\n}\n\n/**\n * Fetch one bounded history page typed as plain records, sidestepping\n * the client's `TStateType` generic so the discovery collectors (which\n * read raw `values`/`tasks`) get a stable {@link AnyCheckpoint} shape.\n */\nexport function getHistoryPage<TStateType>(\n client: Client<TStateType>,\n threadId: string,\n options: {\n limit?: number;\n before?: Config;\n checkpoint?: Partial<Omit<Checkpoint, \"thread_id\">>;\n metadata?: Metadata;\n signal?: AbortSignal;\n }\n): Promise<AnyCheckpoint[]> {\n return client.threads.getHistory<Record<string, unknown>>(threadId, options);\n}\n\nexport interface SubgraphHost {\n namespace: string[];\n status: \"running\" | \"complete\" | \"error\";\n}\n\nfunction checkpointNsToSegments(checkpointNs: unknown): string[] {\n if (typeof checkpointNs !== \"string\" || checkpointNs.length === 0) return [];\n return checkpointNs.split(\"|\").filter((segment) => segment.length > 0);\n}\n\nfunction isInternalSegment(segment: string): boolean {\n return segment.startsWith(\"tools:\") || segment.startsWith(\"task:\");\n}\n\n/**\n * Identify subgraph host namespaces from checkpoint history, mirroring the\n * promotion rule of the live {@link ./subgraphs} `SubgraphDiscovery`: a\n * namespace is a host iff it is a *strict ancestor* of a deeper namespace,\n * and inner function-node leaves are never promoted on their own.\n *\n * Two host signals are derived from the checkpoint namespaces observed in\n * history (`state` + `task` `checkpoint_ns`):\n *\n * - **Interior hosts** — every strict ancestor of an observed namespace.\n * Each segment of a nested `checkpoint_ns` wraps a deeper one, so the\n * parent is always a subgraph (this also recovers a host whose own\n * checkpoint fell outside the fetched page).\n * - **Top-level hosts** — every depth-1 observed namespace. A top-level\n * subgraph is always a host, including the values-only shape supported\n * by `SubgraphDiscovery.#onValuesEvent`, where the host (e.g.\n * `research:<uuid>`) appears with no deeper `research:<uuid>|...` key.\n * The old strict-prefix rule dropped those, so reconnecting waited for\n * SSE replay instead of hydrating the card immediately.\n *\n * A *deeper* observed namespace's own deepest segment is NOT promoted\n * unless it is itself an ancestor of something deeper — otherwise a plain\n * inner node (e.g. `worker:<uuid>|inner:<uuid>`) would surface as a\n * spurious subgraph card that was never present during live streaming.\n *\n * Tool/subagent namespaces (`tools:` / `task:`) are excluded — those are\n * owned by {@link ./subagents}. A namespace nested under a subgraph (e.g.\n * `research:<uuid>|tools:<uuid>`) still promotes its non-internal\n * `research:<uuid>` ancestor.\n */\nexport function collectSubgraphHostNamespaces(\n history: AnyCheckpoint[]\n): SubgraphHost[] {\n // Directly observed namespace tuples (state + task checkpoint_ns), with\n // NO prefix synthesis — host promotion is derived below so that a deeper\n // namespace's leaf segment is not mistaken for a host.\n const observed = new Map<string, string[]>();\n const record = (segments: string[]) => {\n if (segments.length === 0) return;\n observed.set(namespaceKey(segments), segments);\n };\n for (const state of history) {\n record(checkpointNsToSegments(state.checkpoint?.checkpoint_ns));\n for (const task of getTasks(state)) {\n record(checkpointNsToSegments(task.checkpoint?.checkpoint_ns));\n }\n }\n\n // Pending namespaces of the newest checkpoint → still running.\n const pending = new Set<string>();\n if (history.length > 0) {\n for (const task of getTasks(history[0])) {\n const segments = checkpointNsToSegments(task.checkpoint?.checkpoint_ns);\n if (segments.length > 0) pending.add(namespaceKey(segments));\n }\n }\n\n // Host candidates = strict ancestors of observed (interior) + depth-1\n // observed (top-level). Insertion order: shallow ancestors first so the\n // emitted host list keeps parents ahead of children.\n const candidates = new Map<string, string[]>();\n for (const segments of observed.values()) {\n for (let depth = 1; depth < segments.length; depth += 1) {\n const slice = segments.slice(0, depth);\n candidates.set(namespaceKey(slice), slice);\n }\n if (segments.length === 1) {\n candidates.set(namespaceKey(segments), segments);\n }\n }\n\n const hosts: SubgraphHost[] = [];\n for (const [key, segments] of candidates) {\n if (segments.some(isInternalSegment)) continue;\n const prefix = key + NAMESPACE_SEPARATOR;\n const running =\n pending.has(key) || [...pending].some((p) => p.startsWith(prefix));\n hosts.push({\n namespace: segments,\n status: running ? \"running\" : \"complete\",\n });\n }\n return hosts;\n}\n"],"mappings":"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"}

@@ -0,3 +1,3 @@

import { DEFAULT_MESSAGES_KEY } from "../constants.js";
import { normalizeAIMessageToolCalls } from "../message-coercion.js";
import "../constants.js";
import { namespaceKey } from "../namespace.js";

@@ -81,3 +81,3 @@ //#region src/stream/discovery/namespace-from-history.ts

*/
function mapSubagentNamespaces(history, toolCallIds, messagesKey = "messages") {
function mapSubagentNamespaces(history, toolCallIds, messagesKey = DEFAULT_MESSAGES_KEY) {
const out = /* @__PURE__ */ new Map();

@@ -84,0 +84,0 @@ const targets = new Set(toolCallIds);

@@ -1,1 +0,1 @@

{"version":3,"file":"namespace-from-history.js","names":[],"sources":["../../../src/stream/discovery/namespace-from-history.ts"],"sourcesContent":["/**\n * Reconstruct discovery namespaces from checkpoint history.\n *\n * On reconnect the always-on SSE replay eventually re-derives every\n * subagent execution namespace and every subgraph host, but that costs\n * a full depth-1 replay. This module derives the same information from\n * a single bounded `getHistory()` read so the controller can promote\n * namespaces immediately on `hydrate()` (subgraph hosts + subagent\n * execution namespaces) and lazily for a single opened subagent.\n *\n * The logic mirrors the live discovery state machines so a\n * history-derived namespace and an SSE-derived one cannot disagree:\n * - subagent mapping ports {@link ../../ui/manager} `fetchSubagentHistory`\n * (direct task-result mapping, then positional Send-index fallback);\n * - subgraph host detection ports the strict-prefix promotion rule in\n * {@link ./subgraphs}.\n */\nimport type { Client } from \"../../client/index.js\";\nimport type {\n Checkpoint,\n Config,\n Metadata,\n ThreadState,\n} from \"../../schema.js\";\nimport { NAMESPACE_SEPARATOR } from \"../constants.js\";\nimport { namespaceKey } from \"../namespace.js\";\nimport { normalizeAIMessageToolCalls } from \"../message-coercion.js\";\n\ntype AnyCheckpoint = ThreadState<Record<string, unknown>>;\n\ninterface HistoryTask {\n id?: unknown;\n name?: unknown;\n path?: unknown;\n result?: { messages?: unknown[] };\n checkpoint?: { checkpoint_ns?: unknown } | null;\n}\n\nfunction getTasks(checkpoint: AnyCheckpoint): HistoryTask[] {\n const tasks = (checkpoint as { tasks?: unknown }).tasks;\n return Array.isArray(tasks) ? (tasks as HistoryTask[]) : [];\n}\n\n/**\n * Phase 1 (preferred): map a `task` tool-call id directly to its\n * execution namespace via the task's result `ToolMessage`. Unambiguous\n * — works even when a step mixes subagent and non-subagent tool calls.\n *\n * The subgraph checkpoint_ns is `task.name + \":\" + task.id` (mirrors\n * pregel's `taskCheckpointNamespace`), so we derive it from name+id\n * rather than the always-null completed-task checkpoint.\n */\nexport function collectDirectTaskMappings(\n tasks: HistoryTask[],\n targets: Set<string>,\n out: Map<string, string>\n): void {\n for (const task of tasks) {\n if (\n !Array.isArray(task.path) ||\n task.path[0] !== \"__pregel_push\" ||\n typeof task.id !== \"string\" ||\n typeof task.name !== \"string\"\n ) {\n continue;\n }\n const resultMessages = task.result?.messages;\n if (!Array.isArray(resultMessages)) continue;\n for (const msg of resultMessages) {\n const m = msg as Record<string, unknown>;\n const id = m.tool_call_id;\n if (\n m.type === \"tool\" &&\n typeof id === \"string\" &&\n targets.has(id) &&\n !out.has(id)\n ) {\n out.set(id, `${task.name}:${task.id}`);\n }\n }\n }\n}\n\n/**\n * Phase 2 (fallback): align still-pending push tasks to the triggering\n * AI message's tool calls by Send index (`path[1]`), where `path[1]`\n * indexes into the *full* `tool_calls` array. Only push tasks whose\n * targeted call is a subagent `task` are mapped, so a sibling\n * non-subagent tool call in the same message can't capture a subagent's\n * namespace. Applied only to ids Phase 1 could not resolve so a correct\n * direct mapping is never overwritten by a positional guess.\n */\nexport function collectPositionalTaskMappings(\n checkpoint: AnyCheckpoint,\n targets: Set<string>,\n out: Map<string, string>,\n messagesKey: string\n): void {\n const pushTasks = getTasks(checkpoint).filter(\n (t) =>\n Array.isArray(t.path) &&\n t.path[0] === \"__pregel_push\" &&\n typeof t.path[1] === \"number\" &&\n typeof t.id === \"string\" &&\n typeof t.name === \"string\"\n );\n if (pushTasks.length === 0) return;\n\n const msgs = (checkpoint.values as Record<string, unknown> | undefined)?.[\n messagesKey\n ];\n if (!Array.isArray(msgs)) return;\n\n let toolCalls: Array<{ id?: string; name?: string }> | undefined;\n for (let i = msgs.length - 1; i >= 0; i -= 1) {\n const m = msgs[i] as Record<string, unknown>;\n if (m.type !== \"ai\") continue;\n const normalized = normalizeAIMessageToolCalls(\n m as unknown as Parameters<typeof normalizeAIMessageToolCalls>[0]\n ) as Record<string, unknown>;\n const normalizedToolCalls = normalized.tool_calls;\n if (\n Array.isArray(normalizedToolCalls) &&\n (normalizedToolCalls as Array<{ name?: string }>).some(\n (tc) => tc.name === \"task\"\n )\n ) {\n toolCalls = normalizedToolCalls as Array<{\n id?: string;\n name?: string;\n }>;\n break;\n }\n }\n if (toolCalls == null) return;\n\n // `path[1]` is the Send index into the *full* `tool_calls` array, not the\n // subagent-only subset. Resolve each push task against that array and map\n // it only when the targeted call is itself a `task`, so a sibling\n // non-subagent tool call cannot capture a subagent's namespace.\n for (const task of pushTasks) {\n const index = (task.path as unknown[])[1] as number;\n const tc = toolCalls[index];\n if (\n tc?.name === \"task\" &&\n tc.id != null &&\n typeof task.id === \"string\" &&\n typeof task.name === \"string\" &&\n targets.has(tc.id) &&\n !out.has(tc.id)\n ) {\n out.set(tc.id, `${task.name}:${task.id}`);\n }\n }\n}\n\n/** Build a `getHistory` `before` cursor from a history entry. */\nfunction beforeCursor(entry: AnyCheckpoint): Config | undefined {\n const checkpointId = entry.checkpoint?.checkpoint_id;\n if (typeof checkpointId !== \"string\") return undefined;\n return { configurable: { checkpoint_id: checkpointId } };\n}\n\nfunction applyCollectors(\n history: AnyCheckpoint[],\n targets: Set<string>,\n out: Map<string, string>,\n messagesKey: string\n): void {\n for (const checkpoint of history) {\n collectDirectTaskMappings(getTasks(checkpoint), targets, out);\n }\n const stillUnmapped = () => [...targets].some((id) => !out.has(id));\n if (stillUnmapped()) {\n for (const checkpoint of history) {\n if (!stillUnmapped()) break;\n collectPositionalTaskMappings(checkpoint, targets, out, messagesKey);\n }\n }\n}\n\n/**\n * Synchronous subagent namespace mapping over an already-fetched\n * history page. Used by {@link resolveSubagentNamespaces} and by the\n * controller's hydrate-time bulk seed (which shares a single\n * `getHistory` page with subgraph host detection).\n */\nexport function mapSubagentNamespaces(\n history: AnyCheckpoint[],\n toolCallIds: string[],\n messagesKey = \"messages\"\n): Map<string, string> {\n const out = new Map<string, string>();\n const targets = new Set(toolCallIds);\n if (targets.size === 0) return out;\n applyCollectors(history, targets, out, messagesKey);\n return out;\n}\n\n/**\n * Resolve execution namespaces for the given subagent `task` tool-call\n * ids from checkpoint history.\n *\n * Bounded and O(1) in calls: one `getHistory` page, plus at most one\n * `before`-cursor fallback page when the first leaves ids unresolved.\n * Never fans out per id.\n *\n * @returns Map of `toolCallId` → single execution namespace segment\n * (e.g. `tools:<uuid>`). Unresolved ids are omitted.\n */\nexport async function resolveSubagentNamespaces<TStateType>(\n client: Client<TStateType>,\n threadId: string,\n toolCallIds: string[],\n opts?: { limit?: number; messagesKey?: string; signal?: AbortSignal }\n): Promise<Map<string, string>> {\n const out = new Map<string, string>();\n const targets = new Set(toolCallIds);\n if (targets.size === 0) return out;\n\n const limit = opts?.limit ?? 20;\n const messagesKey = opts?.messagesKey ?? \"messages\";\n const signal = opts?.signal;\n\n const page1 = await getHistoryPage(client, threadId, { limit, signal });\n applyCollectors(page1, targets, out, messagesKey);\n\n const unresolved = [...targets].filter((id) => !out.has(id));\n if (unresolved.length > 0 && page1.length > 0) {\n const before = beforeCursor(page1[page1.length - 1]);\n if (before != null) {\n const page2 = await getHistoryPage(client, threadId, {\n limit,\n before,\n signal,\n });\n applyCollectors(page2, targets, out, messagesKey);\n }\n }\n\n return out;\n}\n\n/**\n * Fetch one bounded history page typed as plain records, sidestepping\n * the client's `TStateType` generic so the discovery collectors (which\n * read raw `values`/`tasks`) get a stable {@link AnyCheckpoint} shape.\n */\nexport function getHistoryPage<TStateType>(\n client: Client<TStateType>,\n threadId: string,\n options: {\n limit?: number;\n before?: Config;\n checkpoint?: Partial<Omit<Checkpoint, \"thread_id\">>;\n metadata?: Metadata;\n signal?: AbortSignal;\n }\n): Promise<AnyCheckpoint[]> {\n return client.threads.getHistory<Record<string, unknown>>(threadId, options);\n}\n\nexport interface SubgraphHost {\n namespace: string[];\n status: \"running\" | \"complete\" | \"error\";\n}\n\nfunction checkpointNsToSegments(checkpointNs: unknown): string[] {\n if (typeof checkpointNs !== \"string\" || checkpointNs.length === 0) return [];\n return checkpointNs.split(\"|\").filter((segment) => segment.length > 0);\n}\n\nfunction isInternalSegment(segment: string): boolean {\n return segment.startsWith(\"tools:\") || segment.startsWith(\"task:\");\n}\n\n/**\n * Identify subgraph host namespaces from checkpoint history, mirroring the\n * promotion rule of the live {@link ./subgraphs} `SubgraphDiscovery`: a\n * namespace is a host iff it is a *strict ancestor* of a deeper namespace,\n * and inner function-node leaves are never promoted on their own.\n *\n * Two host signals are derived from the checkpoint namespaces observed in\n * history (`state` + `task` `checkpoint_ns`):\n *\n * - **Interior hosts** — every strict ancestor of an observed namespace.\n * Each segment of a nested `checkpoint_ns` wraps a deeper one, so the\n * parent is always a subgraph (this also recovers a host whose own\n * checkpoint fell outside the fetched page).\n * - **Top-level hosts** — every depth-1 observed namespace. A top-level\n * subgraph is always a host, including the values-only shape supported\n * by `SubgraphDiscovery.#onValuesEvent`, where the host (e.g.\n * `research:<uuid>`) appears with no deeper `research:<uuid>|...` key.\n * The old strict-prefix rule dropped those, so reconnecting waited for\n * SSE replay instead of hydrating the card immediately.\n *\n * A *deeper* observed namespace's own deepest segment is NOT promoted\n * unless it is itself an ancestor of something deeper — otherwise a plain\n * inner node (e.g. `worker:<uuid>|inner:<uuid>`) would surface as a\n * spurious subgraph card that was never present during live streaming.\n *\n * Tool/subagent namespaces (`tools:` / `task:`) are excluded — those are\n * owned by {@link ./subagents}. A namespace nested under a subgraph (e.g.\n * `research:<uuid>|tools:<uuid>`) still promotes its non-internal\n * `research:<uuid>` ancestor.\n */\nexport function collectSubgraphHostNamespaces(\n history: AnyCheckpoint[]\n): SubgraphHost[] {\n // Directly observed namespace tuples (state + task checkpoint_ns), with\n // NO prefix synthesis — host promotion is derived below so that a deeper\n // namespace's leaf segment is not mistaken for a host.\n const observed = new Map<string, string[]>();\n const record = (segments: string[]) => {\n if (segments.length === 0) return;\n observed.set(namespaceKey(segments), segments);\n };\n for (const state of history) {\n record(checkpointNsToSegments(state.checkpoint?.checkpoint_ns));\n for (const task of getTasks(state)) {\n record(checkpointNsToSegments(task.checkpoint?.checkpoint_ns));\n }\n }\n\n // Pending namespaces of the newest checkpoint → still running.\n const pending = new Set<string>();\n if (history.length > 0) {\n for (const task of getTasks(history[0])) {\n const segments = checkpointNsToSegments(task.checkpoint?.checkpoint_ns);\n if (segments.length > 0) pending.add(namespaceKey(segments));\n }\n }\n\n // Host candidates = strict ancestors of observed (interior) + depth-1\n // observed (top-level). Insertion order: shallow ancestors first so the\n // emitted host list keeps parents ahead of children.\n const candidates = new Map<string, string[]>();\n for (const segments of observed.values()) {\n for (let depth = 1; depth < segments.length; depth += 1) {\n const slice = segments.slice(0, depth);\n candidates.set(namespaceKey(slice), slice);\n }\n if (segments.length === 1) {\n candidates.set(namespaceKey(segments), segments);\n }\n }\n\n const hosts: SubgraphHost[] = [];\n for (const [key, segments] of candidates) {\n if (segments.some(isInternalSegment)) continue;\n const prefix = key + NAMESPACE_SEPARATOR;\n const running =\n pending.has(key) || [...pending].some((p) => p.startsWith(prefix));\n hosts.push({\n namespace: segments,\n status: running ? \"running\" : \"complete\",\n });\n }\n return hosts;\n}\n"],"mappings":"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"}
{"version":3,"file":"namespace-from-history.js","names":[],"sources":["../../../src/stream/discovery/namespace-from-history.ts"],"sourcesContent":["/**\n * Reconstruct discovery namespaces from checkpoint history.\n *\n * On reconnect the always-on SSE replay eventually re-derives every\n * subagent execution namespace and every subgraph host, but that costs\n * a full depth-1 replay. This module derives the same information from\n * a single bounded `getHistory()` read so the controller can promote\n * namespaces immediately on `hydrate()` (subgraph hosts + subagent\n * execution namespaces) and lazily for a single opened subagent.\n *\n * The logic mirrors the live discovery state machines so a\n * history-derived namespace and an SSE-derived one cannot disagree:\n * - subagent mapping ports {@link ../../ui/manager} `fetchSubagentHistory`\n * (direct task-result mapping, then positional Send-index fallback);\n * - subgraph host detection ports the strict-prefix promotion rule in\n * {@link ./subgraphs}.\n */\nimport type { Client } from \"../../client/index.js\";\nimport type {\n Checkpoint,\n Config,\n Metadata,\n ThreadState,\n} from \"../../schema.js\";\nimport { NAMESPACE_SEPARATOR, DEFAULT_MESSAGES_KEY } from \"../constants.js\";\nimport { namespaceKey } from \"../namespace.js\";\nimport { normalizeAIMessageToolCalls } from \"../message-coercion.js\";\n\ntype AnyCheckpoint = ThreadState<Record<string, unknown>>;\n\ninterface HistoryTask {\n id?: unknown;\n name?: unknown;\n path?: unknown;\n result?: { messages?: unknown[] };\n checkpoint?: { checkpoint_ns?: unknown } | null;\n}\n\nfunction getTasks(checkpoint: AnyCheckpoint): HistoryTask[] {\n const tasks = (checkpoint as { tasks?: unknown }).tasks;\n return Array.isArray(tasks) ? (tasks as HistoryTask[]) : [];\n}\n\n/**\n * Phase 1 (preferred): map a `task` tool-call id directly to its\n * execution namespace via the task's result `ToolMessage`. Unambiguous\n * — works even when a step mixes subagent and non-subagent tool calls.\n *\n * The subgraph checkpoint_ns is `task.name + \":\" + task.id` (mirrors\n * pregel's `taskCheckpointNamespace`), so we derive it from name+id\n * rather than the always-null completed-task checkpoint.\n */\nexport function collectDirectTaskMappings(\n tasks: HistoryTask[],\n targets: Set<string>,\n out: Map<string, string>\n): void {\n for (const task of tasks) {\n if (\n !Array.isArray(task.path) ||\n task.path[0] !== \"__pregel_push\" ||\n typeof task.id !== \"string\" ||\n typeof task.name !== \"string\"\n ) {\n continue;\n }\n const resultMessages = task.result?.messages;\n if (!Array.isArray(resultMessages)) continue;\n for (const msg of resultMessages) {\n const m = msg as Record<string, unknown>;\n const id = m.tool_call_id;\n if (\n m.type === \"tool\" &&\n typeof id === \"string\" &&\n targets.has(id) &&\n !out.has(id)\n ) {\n out.set(id, `${task.name}:${task.id}`);\n }\n }\n }\n}\n\n/**\n * Phase 2 (fallback): align still-pending push tasks to the triggering\n * AI message's tool calls by Send index (`path[1]`), where `path[1]`\n * indexes into the *full* `tool_calls` array. Only push tasks whose\n * targeted call is a subagent `task` are mapped, so a sibling\n * non-subagent tool call in the same message can't capture a subagent's\n * namespace. Applied only to ids Phase 1 could not resolve so a correct\n * direct mapping is never overwritten by a positional guess.\n */\nexport function collectPositionalTaskMappings(\n checkpoint: AnyCheckpoint,\n targets: Set<string>,\n out: Map<string, string>,\n messagesKey: string\n): void {\n const pushTasks = getTasks(checkpoint).filter(\n (t) =>\n Array.isArray(t.path) &&\n t.path[0] === \"__pregel_push\" &&\n typeof t.path[1] === \"number\" &&\n typeof t.id === \"string\" &&\n typeof t.name === \"string\"\n );\n if (pushTasks.length === 0) return;\n\n const msgs = (checkpoint.values as Record<string, unknown> | undefined)?.[\n messagesKey\n ];\n if (!Array.isArray(msgs)) return;\n\n let toolCalls: Array<{ id?: string; name?: string }> | undefined;\n for (let i = msgs.length - 1; i >= 0; i -= 1) {\n const m = msgs[i] as Record<string, unknown>;\n if (m.type !== \"ai\") continue;\n const normalized = normalizeAIMessageToolCalls(\n m as unknown as Parameters<typeof normalizeAIMessageToolCalls>[0]\n ) as Record<string, unknown>;\n const normalizedToolCalls = normalized.tool_calls;\n if (\n Array.isArray(normalizedToolCalls) &&\n (normalizedToolCalls as Array<{ name?: string }>).some(\n (tc) => tc.name === \"task\"\n )\n ) {\n toolCalls = normalizedToolCalls as Array<{\n id?: string;\n name?: string;\n }>;\n break;\n }\n }\n if (toolCalls == null) return;\n\n // `path[1]` is the Send index into the *full* `tool_calls` array, not the\n // subagent-only subset. Resolve each push task against that array and map\n // it only when the targeted call is itself a `task`, so a sibling\n // non-subagent tool call cannot capture a subagent's namespace.\n for (const task of pushTasks) {\n const index = (task.path as unknown[])[1] as number;\n const tc = toolCalls[index];\n if (\n tc?.name === \"task\" &&\n tc.id != null &&\n typeof task.id === \"string\" &&\n typeof task.name === \"string\" &&\n targets.has(tc.id) &&\n !out.has(tc.id)\n ) {\n out.set(tc.id, `${task.name}:${task.id}`);\n }\n }\n}\n\n/** Build a `getHistory` `before` cursor from a history entry. */\nfunction beforeCursor(entry: AnyCheckpoint): Config | undefined {\n const checkpointId = entry.checkpoint?.checkpoint_id;\n if (typeof checkpointId !== \"string\") return undefined;\n return { configurable: { checkpoint_id: checkpointId } };\n}\n\nfunction applyCollectors(\n history: AnyCheckpoint[],\n targets: Set<string>,\n out: Map<string, string>,\n messagesKey: string\n): void {\n for (const checkpoint of history) {\n collectDirectTaskMappings(getTasks(checkpoint), targets, out);\n }\n const stillUnmapped = () => [...targets].some((id) => !out.has(id));\n if (stillUnmapped()) {\n for (const checkpoint of history) {\n if (!stillUnmapped()) break;\n collectPositionalTaskMappings(checkpoint, targets, out, messagesKey);\n }\n }\n}\n\n/**\n * Synchronous subagent namespace mapping over an already-fetched\n * history page. Used by {@link resolveSubagentNamespaces} and by the\n * controller's hydrate-time bulk seed (which shares a single\n * `getHistory` page with subgraph host detection).\n */\nexport function mapSubagentNamespaces(\n history: AnyCheckpoint[],\n toolCallIds: string[],\n messagesKey = DEFAULT_MESSAGES_KEY\n): Map<string, string> {\n const out = new Map<string, string>();\n const targets = new Set(toolCallIds);\n if (targets.size === 0) return out;\n applyCollectors(history, targets, out, messagesKey);\n return out;\n}\n\n/**\n * Resolve execution namespaces for the given subagent `task` tool-call\n * ids from checkpoint history.\n *\n * Bounded and O(1) in calls: one `getHistory` page, plus at most one\n * `before`-cursor fallback page when the first leaves ids unresolved.\n * Never fans out per id.\n *\n * @returns Map of `toolCallId` → single execution namespace segment\n * (e.g. `tools:<uuid>`). Unresolved ids are omitted.\n */\nexport async function resolveSubagentNamespaces<TStateType>(\n client: Client<TStateType>,\n threadId: string,\n toolCallIds: string[],\n opts?: { limit?: number; messagesKey?: string; signal?: AbortSignal }\n): Promise<Map<string, string>> {\n const out = new Map<string, string>();\n const targets = new Set(toolCallIds);\n if (targets.size === 0) return out;\n\n const limit = opts?.limit ?? 20;\n const messagesKey = opts?.messagesKey ?? DEFAULT_MESSAGES_KEY;\n const signal = opts?.signal;\n\n const page1 = await getHistoryPage(client, threadId, { limit, signal });\n applyCollectors(page1, targets, out, messagesKey);\n\n const unresolved = [...targets].filter((id) => !out.has(id));\n if (unresolved.length > 0 && page1.length > 0) {\n const before = beforeCursor(page1[page1.length - 1]);\n if (before != null) {\n const page2 = await getHistoryPage(client, threadId, {\n limit,\n before,\n signal,\n });\n applyCollectors(page2, targets, out, messagesKey);\n }\n }\n\n return out;\n}\n\n/**\n * Fetch one bounded history page typed as plain records, sidestepping\n * the client's `TStateType` generic so the discovery collectors (which\n * read raw `values`/`tasks`) get a stable {@link AnyCheckpoint} shape.\n */\nexport function getHistoryPage<TStateType>(\n client: Client<TStateType>,\n threadId: string,\n options: {\n limit?: number;\n before?: Config;\n checkpoint?: Partial<Omit<Checkpoint, \"thread_id\">>;\n metadata?: Metadata;\n signal?: AbortSignal;\n }\n): Promise<AnyCheckpoint[]> {\n return client.threads.getHistory<Record<string, unknown>>(threadId, options);\n}\n\nexport interface SubgraphHost {\n namespace: string[];\n status: \"running\" | \"complete\" | \"error\";\n}\n\nfunction checkpointNsToSegments(checkpointNs: unknown): string[] {\n if (typeof checkpointNs !== \"string\" || checkpointNs.length === 0) return [];\n return checkpointNs.split(\"|\").filter((segment) => segment.length > 0);\n}\n\nfunction isInternalSegment(segment: string): boolean {\n return segment.startsWith(\"tools:\") || segment.startsWith(\"task:\");\n}\n\n/**\n * Identify subgraph host namespaces from checkpoint history, mirroring the\n * promotion rule of the live {@link ./subgraphs} `SubgraphDiscovery`: a\n * namespace is a host iff it is a *strict ancestor* of a deeper namespace,\n * and inner function-node leaves are never promoted on their own.\n *\n * Two host signals are derived from the checkpoint namespaces observed in\n * history (`state` + `task` `checkpoint_ns`):\n *\n * - **Interior hosts** — every strict ancestor of an observed namespace.\n * Each segment of a nested `checkpoint_ns` wraps a deeper one, so the\n * parent is always a subgraph (this also recovers a host whose own\n * checkpoint fell outside the fetched page).\n * - **Top-level hosts** — every depth-1 observed namespace. A top-level\n * subgraph is always a host, including the values-only shape supported\n * by `SubgraphDiscovery.#onValuesEvent`, where the host (e.g.\n * `research:<uuid>`) appears with no deeper `research:<uuid>|...` key.\n * The old strict-prefix rule dropped those, so reconnecting waited for\n * SSE replay instead of hydrating the card immediately.\n *\n * A *deeper* observed namespace's own deepest segment is NOT promoted\n * unless it is itself an ancestor of something deeper — otherwise a plain\n * inner node (e.g. `worker:<uuid>|inner:<uuid>`) would surface as a\n * spurious subgraph card that was never present during live streaming.\n *\n * Tool/subagent namespaces (`tools:` / `task:`) are excluded — those are\n * owned by {@link ./subagents}. A namespace nested under a subgraph (e.g.\n * `research:<uuid>|tools:<uuid>`) still promotes its non-internal\n * `research:<uuid>` ancestor.\n */\nexport function collectSubgraphHostNamespaces(\n history: AnyCheckpoint[]\n): SubgraphHost[] {\n // Directly observed namespace tuples (state + task checkpoint_ns), with\n // NO prefix synthesis — host promotion is derived below so that a deeper\n // namespace's leaf segment is not mistaken for a host.\n const observed = new Map<string, string[]>();\n const record = (segments: string[]) => {\n if (segments.length === 0) return;\n observed.set(namespaceKey(segments), segments);\n };\n for (const state of history) {\n record(checkpointNsToSegments(state.checkpoint?.checkpoint_ns));\n for (const task of getTasks(state)) {\n record(checkpointNsToSegments(task.checkpoint?.checkpoint_ns));\n }\n }\n\n // Pending namespaces of the newest checkpoint → still running.\n const pending = new Set<string>();\n if (history.length > 0) {\n for (const task of getTasks(history[0])) {\n const segments = checkpointNsToSegments(task.checkpoint?.checkpoint_ns);\n if (segments.length > 0) pending.add(namespaceKey(segments));\n }\n }\n\n // Host candidates = strict ancestors of observed (interior) + depth-1\n // observed (top-level). Insertion order: shallow ancestors first so the\n // emitted host list keeps parents ahead of children.\n const candidates = new Map<string, string[]>();\n for (const segments of observed.values()) {\n for (let depth = 1; depth < segments.length; depth += 1) {\n const slice = segments.slice(0, depth);\n candidates.set(namespaceKey(slice), slice);\n }\n if (segments.length === 1) {\n candidates.set(namespaceKey(segments), segments);\n }\n }\n\n const hosts: SubgraphHost[] = [];\n for (const [key, segments] of candidates) {\n if (segments.some(isInternalSegment)) continue;\n const prefix = key + NAMESPACE_SEPARATOR;\n const running =\n pending.has(key) || [...pending].some((p) => p.startsWith(prefix));\n hosts.push({\n namespace: segments,\n status: running ? \"running\" : \"complete\",\n });\n }\n return hosts;\n}\n"],"mappings":"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"}
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_constants = require("./constants.cjs");
const require_tools = require("../client/stream/handles/tools.cjs");
const require_media = require("../client/stream/media.cjs");
const require_constants = require("./constants.cjs");
const require_store = require("./store.cjs");

@@ -21,2 +21,3 @@ const require_channel_registry = require("./channel-registry.cjs");

exports.ChannelRegistry = require_channel_registry.ChannelRegistry;
exports.DEFAULT_MESSAGES_KEY = require_constants.DEFAULT_MESSAGES_KEY;
exports.MediaAssembler = require_media.MediaAssembler;

@@ -23,0 +24,0 @@ exports.MediaAssemblyError = require_media.MediaAssemblyError;

@@ -9,2 +9,3 @@ import { DefaultToolCall, InferToolOutput, ToolCallFromTool } from "../types.messages.cjs";

import { StoreListener, StreamStore } from "./store.cjs";
import { DEFAULT_MESSAGES_KEY, NAMESPACE_SEPARATOR } from "./constants.cjs";
import { AcquiredProjection, AgentServerOptions, CustomAdapterOptions, ProjectionRuntime, ProjectionSpec, RootEventBus, RootSnapshot, RunCompletedInfo, RunExecutionInfo, RunExecutionReason, StreamControllerOptions, StreamRespondAllOptions, StreamRespondOptions, StreamStopOptions, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, Target, UseStreamCommonOptions, UseStreamOptions } from "./types.cjs";

@@ -25,4 +26,3 @@ import { ChannelRegistry } from "./channel-registry.cjs";

import { AssembledToMessageInput, ExtendedMessageRole, assembledMessageToBaseMessage, assembledToBaseMessage } from "./assembled-to-message.cjs";
import { NAMESPACE_SEPARATOR } from "./constants.cjs";
import { Channel, Event } from "@langchain/protocol";
export { type AcquiredProjection, type AgentServerAdapter, type AgentServerOptions, type AgentTypeConfigLike, type AnyMediaHandle, type AssembledToMessageInput, type AssembledToolCall, type AssembledToolCallFromTool, type AudioMedia, type Channel, type ChannelEffectOptions, type ChannelProjectionOptions, ChannelRegistry, type CompiledSubAgentLike, type CustomAdapterOptions, type DeepAgentTypeConfigLike, type DefaultSubagentStates, type DefaultToolCall, type Event, type ExtendedMessageRole, type ExtractAgentConfig, type ExtractDeepAgentConfig, type ExtractSubAgentMiddleware, type FileMedia, type ImageMedia, type InferAgentToolCalls, type InferBag, type InferDeepAgentSubagents, type InferNodeNames, type InferStateType, type InferSubagentByName, type InferSubagentNames, type InferSubagentState, type InferSubagentStates, type InferToolCalls, type InferToolOutput, type IsAgentLike, type IsDeepAgentLike, MediaAssembler, type MediaAssemblerCallbacks, type MediaAssemblerOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MediaProjectionOptions, type MessageMetadata, type MessageMetadataMap, NAMESPACE_SEPARATOR, type ProjectionRuntime, type ProjectionSpec, ROOT_PUMP_CHANNELS, type RootEventBus, type RootSnapshot, type RunCompletedInfo, type RunExecutionInfo, type RunExecutionReason, type StoreListener, StreamController, type StreamControllerOptions, type StreamRespondAllOptions, type StreamRespondOptions, type StreamStopOptions, StreamStore, type StreamSubmitOptions, type SubAgentLike, SubagentDiscovery, type SubagentDiscoverySnapshot, type SubagentMap, type SubagentStateMap, type SubagentToolCall, type SubgraphByNodeMap, SubgraphDiscovery, type SubgraphDiscoverySnapshot, type SubgraphMap, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type Target, type ToolCallFromTool, type ToolCallStatus, type TransportAdapter, type UseStreamCommonOptions, type UseStreamOptions, type VideoMedia, type WidenUpdateMessages, acquireChannelEffect, assembledMessageToBaseMessage, assembledToBaseMessage, audioProjection, channelProjection, extensionProjection, filesProjection, imagesProjection, messagesProjection, parseToolOutput, parseToolPayload, toolCallsProjection, valuesProjection, videoProjection };
export { type AcquiredProjection, type AgentServerAdapter, type AgentServerOptions, type AgentTypeConfigLike, type AnyMediaHandle, type AssembledToMessageInput, type AssembledToolCall, type AssembledToolCallFromTool, type AudioMedia, type Channel, type ChannelEffectOptions, type ChannelProjectionOptions, ChannelRegistry, type CompiledSubAgentLike, type CustomAdapterOptions, DEFAULT_MESSAGES_KEY, type DeepAgentTypeConfigLike, type DefaultSubagentStates, type DefaultToolCall, type Event, type ExtendedMessageRole, type ExtractAgentConfig, type ExtractDeepAgentConfig, type ExtractSubAgentMiddleware, type FileMedia, type ImageMedia, type InferAgentToolCalls, type InferBag, type InferDeepAgentSubagents, type InferNodeNames, type InferStateType, type InferSubagentByName, type InferSubagentNames, type InferSubagentState, type InferSubagentStates, type InferToolCalls, type InferToolOutput, type IsAgentLike, type IsDeepAgentLike, MediaAssembler, type MediaAssemblerCallbacks, type MediaAssemblerOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MediaProjectionOptions, type MessageMetadata, type MessageMetadataMap, NAMESPACE_SEPARATOR, type ProjectionRuntime, type ProjectionSpec, ROOT_PUMP_CHANNELS, type RootEventBus, type RootSnapshot, type RunCompletedInfo, type RunExecutionInfo, type RunExecutionReason, type StoreListener, StreamController, type StreamControllerOptions, type StreamRespondAllOptions, type StreamRespondOptions, type StreamStopOptions, StreamStore, type StreamSubmitOptions, type SubAgentLike, SubagentDiscovery, type SubagentDiscoverySnapshot, type SubagentMap, type SubagentStateMap, type SubagentToolCall, type SubgraphByNodeMap, SubgraphDiscovery, type SubgraphDiscoverySnapshot, type SubgraphMap, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type Target, type ToolCallFromTool, type ToolCallStatus, type TransportAdapter, type UseStreamCommonOptions, type UseStreamOptions, type VideoMedia, type WidenUpdateMessages, acquireChannelEffect, assembledMessageToBaseMessage, assembledToBaseMessage, audioProjection, channelProjection, extensionProjection, filesProjection, imagesProjection, messagesProjection, parseToolOutput, parseToolPayload, toolCallsProjection, valuesProjection, videoProjection };

@@ -9,2 +9,3 @@ import { DefaultToolCall, InferToolOutput, ToolCallFromTool } from "../types.messages.js";

import { StoreListener, StreamStore } from "./store.js";
import { DEFAULT_MESSAGES_KEY, NAMESPACE_SEPARATOR } from "./constants.js";
import { AcquiredProjection, AgentServerOptions, CustomAdapterOptions, ProjectionRuntime, ProjectionSpec, RootEventBus, RootSnapshot, RunCompletedInfo, RunExecutionInfo, RunExecutionReason, StreamControllerOptions, StreamRespondAllOptions, StreamRespondOptions, StreamStopOptions, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, Target, UseStreamCommonOptions, UseStreamOptions } from "./types.js";

@@ -25,4 +26,3 @@ import { ChannelRegistry } from "./channel-registry.js";

import { AssembledToMessageInput, ExtendedMessageRole, assembledMessageToBaseMessage, assembledToBaseMessage } from "./assembled-to-message.js";
import { NAMESPACE_SEPARATOR } from "./constants.js";
import { Channel, Event } from "@langchain/protocol";
export { type AcquiredProjection, type AgentServerAdapter, type AgentServerOptions, type AgentTypeConfigLike, type AnyMediaHandle, type AssembledToMessageInput, type AssembledToolCall, type AssembledToolCallFromTool, type AudioMedia, type Channel, type ChannelEffectOptions, type ChannelProjectionOptions, ChannelRegistry, type CompiledSubAgentLike, type CustomAdapterOptions, type DeepAgentTypeConfigLike, type DefaultSubagentStates, type DefaultToolCall, type Event, type ExtendedMessageRole, type ExtractAgentConfig, type ExtractDeepAgentConfig, type ExtractSubAgentMiddleware, type FileMedia, type ImageMedia, type InferAgentToolCalls, type InferBag, type InferDeepAgentSubagents, type InferNodeNames, type InferStateType, type InferSubagentByName, type InferSubagentNames, type InferSubagentState, type InferSubagentStates, type InferToolCalls, type InferToolOutput, type IsAgentLike, type IsDeepAgentLike, MediaAssembler, type MediaAssemblerCallbacks, type MediaAssemblerOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MediaProjectionOptions, type MessageMetadata, type MessageMetadataMap, NAMESPACE_SEPARATOR, type ProjectionRuntime, type ProjectionSpec, ROOT_PUMP_CHANNELS, type RootEventBus, type RootSnapshot, type RunCompletedInfo, type RunExecutionInfo, type RunExecutionReason, type StoreListener, StreamController, type StreamControllerOptions, type StreamRespondAllOptions, type StreamRespondOptions, type StreamStopOptions, StreamStore, type StreamSubmitOptions, type SubAgentLike, SubagentDiscovery, type SubagentDiscoverySnapshot, type SubagentMap, type SubagentStateMap, type SubagentToolCall, type SubgraphByNodeMap, SubgraphDiscovery, type SubgraphDiscoverySnapshot, type SubgraphMap, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type Target, type ToolCallFromTool, type ToolCallStatus, type TransportAdapter, type UseStreamCommonOptions, type UseStreamOptions, type VideoMedia, type WidenUpdateMessages, acquireChannelEffect, assembledMessageToBaseMessage, assembledToBaseMessage, audioProjection, channelProjection, extensionProjection, filesProjection, imagesProjection, messagesProjection, parseToolOutput, parseToolPayload, toolCallsProjection, valuesProjection, videoProjection };
export { type AcquiredProjection, type AgentServerAdapter, type AgentServerOptions, type AgentTypeConfigLike, type AnyMediaHandle, type AssembledToMessageInput, type AssembledToolCall, type AssembledToolCallFromTool, type AudioMedia, type Channel, type ChannelEffectOptions, type ChannelProjectionOptions, ChannelRegistry, type CompiledSubAgentLike, type CustomAdapterOptions, DEFAULT_MESSAGES_KEY, type DeepAgentTypeConfigLike, type DefaultSubagentStates, type DefaultToolCall, type Event, type ExtendedMessageRole, type ExtractAgentConfig, type ExtractDeepAgentConfig, type ExtractSubAgentMiddleware, type FileMedia, type ImageMedia, type InferAgentToolCalls, type InferBag, type InferDeepAgentSubagents, type InferNodeNames, type InferStateType, type InferSubagentByName, type InferSubagentNames, type InferSubagentState, type InferSubagentStates, type InferToolCalls, type InferToolOutput, type IsAgentLike, type IsDeepAgentLike, MediaAssembler, type MediaAssemblerCallbacks, type MediaAssemblerOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MediaProjectionOptions, type MessageMetadata, type MessageMetadataMap, NAMESPACE_SEPARATOR, type ProjectionRuntime, type ProjectionSpec, ROOT_PUMP_CHANNELS, type RootEventBus, type RootSnapshot, type RunCompletedInfo, type RunExecutionInfo, type RunExecutionReason, type StoreListener, StreamController, type StreamControllerOptions, type StreamRespondAllOptions, type StreamRespondOptions, type StreamStopOptions, StreamStore, type StreamSubmitOptions, type SubAgentLike, SubagentDiscovery, type SubagentDiscoverySnapshot, type SubagentMap, type SubagentStateMap, type SubagentToolCall, type SubgraphByNodeMap, SubgraphDiscovery, type SubgraphDiscoverySnapshot, type SubgraphMap, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type Target, type ToolCallFromTool, type ToolCallStatus, type TransportAdapter, type UseStreamCommonOptions, type UseStreamOptions, type VideoMedia, type WidenUpdateMessages, acquireChannelEffect, assembledMessageToBaseMessage, assembledToBaseMessage, audioProjection, channelProjection, extensionProjection, filesProjection, imagesProjection, messagesProjection, parseToolOutput, parseToolPayload, toolCallsProjection, valuesProjection, videoProjection };

@@ -0,4 +1,4 @@

import { DEFAULT_MESSAGES_KEY, NAMESPACE_SEPARATOR } from "./constants.js";
import { parseToolOutput, parseToolPayload } from "../client/stream/handles/tools.js";
import { MediaAssembler, MediaAssemblyError } from "../client/stream/media.js";
import { NAMESPACE_SEPARATOR } from "./constants.js";
import { StreamStore } from "./store.js";

@@ -19,2 +19,2 @@ import { ChannelRegistry } from "./channel-registry.js";

import "./projections/index.js";
export { ChannelRegistry, MediaAssembler, MediaAssemblyError, NAMESPACE_SEPARATOR, ROOT_PUMP_CHANNELS, StreamController, StreamStore, SubagentDiscovery, SubgraphDiscovery, acquireChannelEffect, assembledMessageToBaseMessage, assembledToBaseMessage, audioProjection, channelProjection, extensionProjection, filesProjection, imagesProjection, messagesProjection, parseToolOutput, parseToolPayload, toolCallsProjection, valuesProjection, videoProjection };
export { ChannelRegistry, DEFAULT_MESSAGES_KEY, MediaAssembler, MediaAssemblyError, NAMESPACE_SEPARATOR, ROOT_PUMP_CHANNELS, StreamController, StreamStore, SubagentDiscovery, SubgraphDiscovery, acquireChannelEffect, assembledMessageToBaseMessage, assembledToBaseMessage, audioProjection, channelProjection, extensionProjection, filesProjection, imagesProjection, messagesProjection, parseToolOutput, parseToolPayload, toolCallsProjection, valuesProjection, videoProjection };

@@ -0,1 +1,2 @@

const require_constants = require("../constants.cjs");
const require_message_coercion = require("../message-coercion.cjs");

@@ -5,3 +6,3 @@ const require_namespace = require("../namespace.cjs");

//#region src/stream/projections/values.ts
function valuesProjection(namespace, messagesKey = "messages") {
function valuesProjection(namespace, messagesKey = require_constants.DEFAULT_MESSAGES_KEY) {
const ns = [...namespace];

@@ -8,0 +9,0 @@ return {

@@ -1,1 +0,1 @@

{"version":3,"file":"values.cjs","names":["namespaceKey","isRootNamespace","openProjectionSubscription","ensureMessageInstances"],"sources":["../../../src/stream/projections/values.ts"],"sourcesContent":["/**\n * Namespace-scoped `values` projection.\n *\n * Opens `thread.subscribe({ channels: [\"values\"], namespaces: [ns] })`\n * and stores the most-recent `values.data` payload. Mirrors\n * {@link ThreadStream.values} but scoped to an arbitrary namespace so\n * subgraphs and subagents can expose their own state.\n *\n * When the state payload carries a `messages` array of serialized\n * messages, those are coerced to `BaseMessage` class instances so the\n * surface shape matches the root snapshot.\n */\nimport type { ValuesEvent } from \"@langchain/protocol\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport {\n ensureMessageInstances,\n tryCoerceMessageLikeToMessage,\n} from \"../message-coercion.js\";\nimport type { Message } from \"../../types.messages.js\";\nimport type { ProjectionSpec, ProjectionRuntime } from \"../types.js\";\nimport { isRootNamespace, namespaceKey } from \"../namespace.js\";\nimport { openProjectionSubscription } from \"./runtime.js\";\n\nexport function valuesProjection<T = unknown>(\n namespace: readonly string[],\n messagesKey: string = \"messages\"\n): ProjectionSpec<T | undefined> {\n const ns = [...namespace];\n const key = `values|${messagesKey}|${namespaceKey(ns)}`;\n\n return {\n key,\n namespace: ns,\n initial: undefined,\n open({ thread, store, rootBus }): ProjectionRuntime {\n const applyValuesEvent = (event: ValuesEvent): void => {\n const coerced = coerceMessagesInState(event.params.data, messagesKey);\n store.setValue(coerced as T);\n };\n\n // See `messagesProjection` — root-scoped projections attach to\n // the controller's root bus instead of opening a duplicate\n // server subscription.\n const rootShortCircuit =\n isRootNamespace(ns) && rootBus.channels.includes(\"values\");\n\n if (rootShortCircuit) {\n const unsubscribe = rootBus.subscribe((event) => {\n if (event.method !== \"values\") return;\n if (!isRootNamespace(event.params.namespace)) return;\n applyValuesEvent(event as ValuesEvent);\n });\n return {\n dispose() {\n unsubscribe();\n },\n };\n }\n\n return openProjectionSubscription({\n thread,\n channels: [\"values\"],\n namespace: ns,\n onEvent(event) {\n if (event.method !== \"values\") return;\n applyValuesEvent(event as ValuesEvent);\n },\n });\n },\n };\n}\n\nfunction coerceMessagesInState(value: unknown, messagesKey: string): unknown {\n if (value == null || typeof value !== \"object\" || Array.isArray(value)) {\n return value;\n }\n const state = value as Record<string, unknown>;\n const maybeMessages = state[messagesKey];\n if (!Array.isArray(maybeMessages) || maybeMessages.length === 0) {\n return value;\n }\n // Fast path: array already contains class instances.\n const hasPlain = maybeMessages.some(\n (m) => m != null && typeof (m as BaseMessage).getType !== \"function\"\n );\n if (!hasPlain) return value;\n return {\n ...state,\n [messagesKey]: ensureMessageInstances(\n maybeMessages as (Message | BaseMessage)[]\n ),\n };\n}\n\nexport { tryCoerceMessageLikeToMessage };\n"],"mappings":";;;;AAuBA,SAAgB,iBACd,WACA,cAAsB,YACS;CAC/B,MAAM,KAAK,CAAC,GAAG,UAAU;AAGzB,QAAO;EACL,KAHU,UAAU,YAAY,GAAGA,kBAAAA,aAAa,GAAG;EAInD,WAAW;EACX,SAAS,KAAA;EACT,KAAK,EAAE,QAAQ,OAAO,WAA8B;GAClD,MAAM,oBAAoB,UAA6B;IACrD,MAAM,UAAU,sBAAsB,MAAM,OAAO,MAAM,YAAY;AACrE,UAAM,SAAS,QAAa;;AAS9B,OAFEC,kBAAAA,gBAAgB,GAAG,IAAI,QAAQ,SAAS,SAAS,SAAS,EAEtC;IACpB,MAAM,cAAc,QAAQ,WAAW,UAAU;AAC/C,SAAI,MAAM,WAAW,SAAU;AAC/B,SAAI,CAACA,kBAAAA,gBAAgB,MAAM,OAAO,UAAU,CAAE;AAC9C,sBAAiB,MAAqB;MACtC;AACF,WAAO,EACL,UAAU;AACR,kBAAa;OAEhB;;AAGH,UAAOC,gBAAAA,2BAA2B;IAChC;IACA,UAAU,CAAC,SAAS;IACpB,WAAW;IACX,QAAQ,OAAO;AACb,SAAI,MAAM,WAAW,SAAU;AAC/B,sBAAiB,MAAqB;;IAEzC,CAAC;;EAEL;;AAGH,SAAS,sBAAsB,OAAgB,aAA8B;AAC3E,KAAI,SAAS,QAAQ,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CACpE,QAAO;CAET,MAAM,QAAQ;CACd,MAAM,gBAAgB,MAAM;AAC5B,KAAI,CAAC,MAAM,QAAQ,cAAc,IAAI,cAAc,WAAW,EAC5D,QAAO;AAMT,KAAI,CAHa,cAAc,MAC5B,MAAM,KAAK,QAAQ,OAAQ,EAAkB,YAAY,WAC3D,CACc,QAAO;AACtB,QAAO;EACL,GAAG;GACF,cAAcC,yBAAAA,uBACb,cACD;EACF"}
{"version":3,"file":"values.cjs","names":["DEFAULT_MESSAGES_KEY","namespaceKey","isRootNamespace","openProjectionSubscription","ensureMessageInstances"],"sources":["../../../src/stream/projections/values.ts"],"sourcesContent":["/**\n * Namespace-scoped `values` projection.\n *\n * Opens `thread.subscribe({ channels: [\"values\"], namespaces: [ns] })`\n * and stores the most-recent `values.data` payload. Mirrors\n * {@link ThreadStream.values} but scoped to an arbitrary namespace so\n * subgraphs and subagents can expose their own state.\n *\n * When the state payload carries a `messages` array of serialized\n * messages, those are coerced to `BaseMessage` class instances so the\n * surface shape matches the root snapshot.\n */\nimport type { ValuesEvent } from \"@langchain/protocol\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport {\n ensureMessageInstances,\n tryCoerceMessageLikeToMessage,\n} from \"../message-coercion.js\";\nimport type { Message } from \"../../types.messages.js\";\nimport type { ProjectionSpec, ProjectionRuntime } from \"../types.js\";\nimport { DEFAULT_MESSAGES_KEY } from \"../constants.js\";\nimport { isRootNamespace, namespaceKey } from \"../namespace.js\";\nimport { openProjectionSubscription } from \"./runtime.js\";\n\nexport function valuesProjection<T = unknown>(\n namespace: readonly string[],\n messagesKey: string = DEFAULT_MESSAGES_KEY\n): ProjectionSpec<T | undefined> {\n const ns = [...namespace];\n const key = `values|${messagesKey}|${namespaceKey(ns)}`;\n\n return {\n key,\n namespace: ns,\n initial: undefined,\n open({ thread, store, rootBus }): ProjectionRuntime {\n const applyValuesEvent = (event: ValuesEvent): void => {\n const coerced = coerceMessagesInState(event.params.data, messagesKey);\n store.setValue(coerced as T);\n };\n\n // See `messagesProjection` — root-scoped projections attach to\n // the controller's root bus instead of opening a duplicate\n // server subscription.\n const rootShortCircuit =\n isRootNamespace(ns) && rootBus.channels.includes(\"values\");\n\n if (rootShortCircuit) {\n const unsubscribe = rootBus.subscribe((event) => {\n if (event.method !== \"values\") return;\n if (!isRootNamespace(event.params.namespace)) return;\n applyValuesEvent(event as ValuesEvent);\n });\n return {\n dispose() {\n unsubscribe();\n },\n };\n }\n\n return openProjectionSubscription({\n thread,\n channels: [\"values\"],\n namespace: ns,\n onEvent(event) {\n if (event.method !== \"values\") return;\n applyValuesEvent(event as ValuesEvent);\n },\n });\n },\n };\n}\n\nfunction coerceMessagesInState(value: unknown, messagesKey: string): unknown {\n if (value == null || typeof value !== \"object\" || Array.isArray(value)) {\n return value;\n }\n const state = value as Record<string, unknown>;\n const maybeMessages = state[messagesKey];\n if (!Array.isArray(maybeMessages) || maybeMessages.length === 0) {\n return value;\n }\n // Fast path: array already contains class instances.\n const hasPlain = maybeMessages.some(\n (m) => m != null && typeof (m as BaseMessage).getType !== \"function\"\n );\n if (!hasPlain) return value;\n return {\n ...state,\n [messagesKey]: ensureMessageInstances(\n maybeMessages as (Message | BaseMessage)[]\n ),\n };\n}\n\nexport { tryCoerceMessageLikeToMessage };\n"],"mappings":";;;;;AAwBA,SAAgB,iBACd,WACA,cAAsBA,kBAAAA,sBACS;CAC/B,MAAM,KAAK,CAAC,GAAG,UAAU;AAGzB,QAAO;EACL,KAHU,UAAU,YAAY,GAAGC,kBAAAA,aAAa,GAAG;EAInD,WAAW;EACX,SAAS,KAAA;EACT,KAAK,EAAE,QAAQ,OAAO,WAA8B;GAClD,MAAM,oBAAoB,UAA6B;IACrD,MAAM,UAAU,sBAAsB,MAAM,OAAO,MAAM,YAAY;AACrE,UAAM,SAAS,QAAa;;AAS9B,OAFEC,kBAAAA,gBAAgB,GAAG,IAAI,QAAQ,SAAS,SAAS,SAAS,EAEtC;IACpB,MAAM,cAAc,QAAQ,WAAW,UAAU;AAC/C,SAAI,MAAM,WAAW,SAAU;AAC/B,SAAI,CAACA,kBAAAA,gBAAgB,MAAM,OAAO,UAAU,CAAE;AAC9C,sBAAiB,MAAqB;MACtC;AACF,WAAO,EACL,UAAU;AACR,kBAAa;OAEhB;;AAGH,UAAOC,gBAAAA,2BAA2B;IAChC;IACA,UAAU,CAAC,SAAS;IACpB,WAAW;IACX,QAAQ,OAAO;AACb,SAAI,MAAM,WAAW,SAAU;AAC/B,sBAAiB,MAAqB;;IAEzC,CAAC;;EAEL;;AAGH,SAAS,sBAAsB,OAAgB,aAA8B;AAC3E,KAAI,SAAS,QAAQ,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CACpE,QAAO;CAET,MAAM,QAAQ;CACd,MAAM,gBAAgB,MAAM;AAC5B,KAAI,CAAC,MAAM,QAAQ,cAAc,IAAI,cAAc,WAAW,EAC5D,QAAO;AAMT,KAAI,CAHa,cAAc,MAC5B,MAAM,KAAK,QAAQ,OAAQ,EAAkB,YAAY,WAC3D,CACc,QAAO;AACtB,QAAO;EACL,GAAG;GACF,cAAcC,yBAAAA,uBACb,cACD;EACF"}

@@ -1,1 +0,1 @@

{"version":3,"file":"values.d.cts","names":[],"sources":["../../../src/stream/projections/values.ts"],"mappings":";;;iBAuBgB,gBAAA,aAAA,CACd,SAAA,qBACA,WAAA,YACC,cAAA,CAAe,CAAA"}
{"version":3,"file":"values.d.cts","names":[],"sources":["../../../src/stream/projections/values.ts"],"mappings":";;;iBAwBgB,gBAAA,aAAA,CACd,SAAA,qBACA,WAAA,YACC,cAAA,CAAe,CAAA"}

@@ -1,1 +0,1 @@

{"version":3,"file":"values.d.ts","names":[],"sources":["../../../src/stream/projections/values.ts"],"mappings":";;iBAuBgB,gBAAA,aAAA,CACd,SAAA,qBACA,WAAA,YACC,cAAA,CAAe,CAAA"}
{"version":3,"file":"values.d.ts","names":[],"sources":["../../../src/stream/projections/values.ts"],"mappings":";;iBAwBgB,gBAAA,aAAA,CACd,SAAA,qBACA,WAAA,YACC,cAAA,CAAe,CAAA"}

@@ -0,1 +1,2 @@

import { DEFAULT_MESSAGES_KEY } from "../constants.js";
import { ensureMessageInstances } from "../message-coercion.js";

@@ -5,3 +6,3 @@ import { isRootNamespace, namespaceKey } from "../namespace.js";

//#region src/stream/projections/values.ts
function valuesProjection(namespace, messagesKey = "messages") {
function valuesProjection(namespace, messagesKey = DEFAULT_MESSAGES_KEY) {
const ns = [...namespace];

@@ -8,0 +9,0 @@ return {

@@ -1,1 +0,1 @@

{"version":3,"file":"values.js","names":[],"sources":["../../../src/stream/projections/values.ts"],"sourcesContent":["/**\n * Namespace-scoped `values` projection.\n *\n * Opens `thread.subscribe({ channels: [\"values\"], namespaces: [ns] })`\n * and stores the most-recent `values.data` payload. Mirrors\n * {@link ThreadStream.values} but scoped to an arbitrary namespace so\n * subgraphs and subagents can expose their own state.\n *\n * When the state payload carries a `messages` array of serialized\n * messages, those are coerced to `BaseMessage` class instances so the\n * surface shape matches the root snapshot.\n */\nimport type { ValuesEvent } from \"@langchain/protocol\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport {\n ensureMessageInstances,\n tryCoerceMessageLikeToMessage,\n} from \"../message-coercion.js\";\nimport type { Message } from \"../../types.messages.js\";\nimport type { ProjectionSpec, ProjectionRuntime } from \"../types.js\";\nimport { isRootNamespace, namespaceKey } from \"../namespace.js\";\nimport { openProjectionSubscription } from \"./runtime.js\";\n\nexport function valuesProjection<T = unknown>(\n namespace: readonly string[],\n messagesKey: string = \"messages\"\n): ProjectionSpec<T | undefined> {\n const ns = [...namespace];\n const key = `values|${messagesKey}|${namespaceKey(ns)}`;\n\n return {\n key,\n namespace: ns,\n initial: undefined,\n open({ thread, store, rootBus }): ProjectionRuntime {\n const applyValuesEvent = (event: ValuesEvent): void => {\n const coerced = coerceMessagesInState(event.params.data, messagesKey);\n store.setValue(coerced as T);\n };\n\n // See `messagesProjection` — root-scoped projections attach to\n // the controller's root bus instead of opening a duplicate\n // server subscription.\n const rootShortCircuit =\n isRootNamespace(ns) && rootBus.channels.includes(\"values\");\n\n if (rootShortCircuit) {\n const unsubscribe = rootBus.subscribe((event) => {\n if (event.method !== \"values\") return;\n if (!isRootNamespace(event.params.namespace)) return;\n applyValuesEvent(event as ValuesEvent);\n });\n return {\n dispose() {\n unsubscribe();\n },\n };\n }\n\n return openProjectionSubscription({\n thread,\n channels: [\"values\"],\n namespace: ns,\n onEvent(event) {\n if (event.method !== \"values\") return;\n applyValuesEvent(event as ValuesEvent);\n },\n });\n },\n };\n}\n\nfunction coerceMessagesInState(value: unknown, messagesKey: string): unknown {\n if (value == null || typeof value !== \"object\" || Array.isArray(value)) {\n return value;\n }\n const state = value as Record<string, unknown>;\n const maybeMessages = state[messagesKey];\n if (!Array.isArray(maybeMessages) || maybeMessages.length === 0) {\n return value;\n }\n // Fast path: array already contains class instances.\n const hasPlain = maybeMessages.some(\n (m) => m != null && typeof (m as BaseMessage).getType !== \"function\"\n );\n if (!hasPlain) return value;\n return {\n ...state,\n [messagesKey]: ensureMessageInstances(\n maybeMessages as (Message | BaseMessage)[]\n ),\n };\n}\n\nexport { tryCoerceMessageLikeToMessage };\n"],"mappings":";;;;AAuBA,SAAgB,iBACd,WACA,cAAsB,YACS;CAC/B,MAAM,KAAK,CAAC,GAAG,UAAU;AAGzB,QAAO;EACL,KAHU,UAAU,YAAY,GAAG,aAAa,GAAG;EAInD,WAAW;EACX,SAAS,KAAA;EACT,KAAK,EAAE,QAAQ,OAAO,WAA8B;GAClD,MAAM,oBAAoB,UAA6B;IACrD,MAAM,UAAU,sBAAsB,MAAM,OAAO,MAAM,YAAY;AACrE,UAAM,SAAS,QAAa;;AAS9B,OAFE,gBAAgB,GAAG,IAAI,QAAQ,SAAS,SAAS,SAAS,EAEtC;IACpB,MAAM,cAAc,QAAQ,WAAW,UAAU;AAC/C,SAAI,MAAM,WAAW,SAAU;AAC/B,SAAI,CAAC,gBAAgB,MAAM,OAAO,UAAU,CAAE;AAC9C,sBAAiB,MAAqB;MACtC;AACF,WAAO,EACL,UAAU;AACR,kBAAa;OAEhB;;AAGH,UAAO,2BAA2B;IAChC;IACA,UAAU,CAAC,SAAS;IACpB,WAAW;IACX,QAAQ,OAAO;AACb,SAAI,MAAM,WAAW,SAAU;AAC/B,sBAAiB,MAAqB;;IAEzC,CAAC;;EAEL;;AAGH,SAAS,sBAAsB,OAAgB,aAA8B;AAC3E,KAAI,SAAS,QAAQ,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CACpE,QAAO;CAET,MAAM,QAAQ;CACd,MAAM,gBAAgB,MAAM;AAC5B,KAAI,CAAC,MAAM,QAAQ,cAAc,IAAI,cAAc,WAAW,EAC5D,QAAO;AAMT,KAAI,CAHa,cAAc,MAC5B,MAAM,KAAK,QAAQ,OAAQ,EAAkB,YAAY,WAC3D,CACc,QAAO;AACtB,QAAO;EACL,GAAG;GACF,cAAc,uBACb,cACD;EACF"}
{"version":3,"file":"values.js","names":[],"sources":["../../../src/stream/projections/values.ts"],"sourcesContent":["/**\n * Namespace-scoped `values` projection.\n *\n * Opens `thread.subscribe({ channels: [\"values\"], namespaces: [ns] })`\n * and stores the most-recent `values.data` payload. Mirrors\n * {@link ThreadStream.values} but scoped to an arbitrary namespace so\n * subgraphs and subagents can expose their own state.\n *\n * When the state payload carries a `messages` array of serialized\n * messages, those are coerced to `BaseMessage` class instances so the\n * surface shape matches the root snapshot.\n */\nimport type { ValuesEvent } from \"@langchain/protocol\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport {\n ensureMessageInstances,\n tryCoerceMessageLikeToMessage,\n} from \"../message-coercion.js\";\nimport type { Message } from \"../../types.messages.js\";\nimport type { ProjectionSpec, ProjectionRuntime } from \"../types.js\";\nimport { DEFAULT_MESSAGES_KEY } from \"../constants.js\";\nimport { isRootNamespace, namespaceKey } from \"../namespace.js\";\nimport { openProjectionSubscription } from \"./runtime.js\";\n\nexport function valuesProjection<T = unknown>(\n namespace: readonly string[],\n messagesKey: string = DEFAULT_MESSAGES_KEY\n): ProjectionSpec<T | undefined> {\n const ns = [...namespace];\n const key = `values|${messagesKey}|${namespaceKey(ns)}`;\n\n return {\n key,\n namespace: ns,\n initial: undefined,\n open({ thread, store, rootBus }): ProjectionRuntime {\n const applyValuesEvent = (event: ValuesEvent): void => {\n const coerced = coerceMessagesInState(event.params.data, messagesKey);\n store.setValue(coerced as T);\n };\n\n // See `messagesProjection` — root-scoped projections attach to\n // the controller's root bus instead of opening a duplicate\n // server subscription.\n const rootShortCircuit =\n isRootNamespace(ns) && rootBus.channels.includes(\"values\");\n\n if (rootShortCircuit) {\n const unsubscribe = rootBus.subscribe((event) => {\n if (event.method !== \"values\") return;\n if (!isRootNamespace(event.params.namespace)) return;\n applyValuesEvent(event as ValuesEvent);\n });\n return {\n dispose() {\n unsubscribe();\n },\n };\n }\n\n return openProjectionSubscription({\n thread,\n channels: [\"values\"],\n namespace: ns,\n onEvent(event) {\n if (event.method !== \"values\") return;\n applyValuesEvent(event as ValuesEvent);\n },\n });\n },\n };\n}\n\nfunction coerceMessagesInState(value: unknown, messagesKey: string): unknown {\n if (value == null || typeof value !== \"object\" || Array.isArray(value)) {\n return value;\n }\n const state = value as Record<string, unknown>;\n const maybeMessages = state[messagesKey];\n if (!Array.isArray(maybeMessages) || maybeMessages.length === 0) {\n return value;\n }\n // Fast path: array already contains class instances.\n const hasPlain = maybeMessages.some(\n (m) => m != null && typeof (m as BaseMessage).getType !== \"function\"\n );\n if (!hasPlain) return value;\n return {\n ...state,\n [messagesKey]: ensureMessageInstances(\n maybeMessages as (Message | BaseMessage)[]\n ),\n };\n}\n\nexport { tryCoerceMessageLikeToMessage };\n"],"mappings":";;;;;AAwBA,SAAgB,iBACd,WACA,cAAsB,sBACS;CAC/B,MAAM,KAAK,CAAC,GAAG,UAAU;AAGzB,QAAO;EACL,KAHU,UAAU,YAAY,GAAG,aAAa,GAAG;EAInD,WAAW;EACX,SAAS,KAAA;EACT,KAAK,EAAE,QAAQ,OAAO,WAA8B;GAClD,MAAM,oBAAoB,UAA6B;IACrD,MAAM,UAAU,sBAAsB,MAAM,OAAO,MAAM,YAAY;AACrE,UAAM,SAAS,QAAa;;AAS9B,OAFE,gBAAgB,GAAG,IAAI,QAAQ,SAAS,SAAS,SAAS,EAEtC;IACpB,MAAM,cAAc,QAAQ,WAAW,UAAU;AAC/C,SAAI,MAAM,WAAW,SAAU;AAC/B,SAAI,CAAC,gBAAgB,MAAM,OAAO,UAAU,CAAE;AAC9C,sBAAiB,MAAqB;MACtC;AACF,WAAO,EACL,UAAU;AACR,kBAAa;OAEhB;;AAGH,UAAO,2BAA2B;IAChC;IACA,UAAU,CAAC,SAAS;IACpB,WAAW;IACX,QAAQ,OAAO;AACb,SAAI,MAAM,WAAW,SAAU;AAC/B,sBAAiB,MAAqB;;IAEzC,CAAC;;EAEL;;AAGH,SAAS,sBAAsB,OAAgB,aAA8B;AAC3E,KAAI,SAAS,QAAQ,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CACpE,QAAO;CAET,MAAM,QAAQ;CACd,MAAM,gBAAgB,MAAM;AAC5B,KAAI,CAAC,MAAM,QAAQ,cAAc,IAAI,cAAc,WAAW,EAC5D,QAAO;AAMT,KAAI,CAHa,cAAc,MAC5B,MAAM,KAAK,QAAQ,OAAQ,EAAkB,YAAY,WAC3D,CACc,QAAO;AACtB,QAAO;EACL,GAAG;GACF,cAAc,uBACb,cACD;EACF"}

@@ -10,2 +10,3 @@ import { Interrupt } from "../schema.cjs";

import { StreamStore } from "./store.cjs";
import { DEFAULT_MESSAGES_KEY } from "./constants.cjs";
import { Channel, Event as Event$1, Goto } from "@langchain/protocol";

@@ -127,3 +128,3 @@ import { BaseMessage as BaseMessage$1 } from "@langchain/core/messages";

initialValues?: StateType;
/** State key holding the message array. Defaults to `"messages"`. */
/** State key holding the message array. Defaults to {@link DEFAULT_MESSAGES_KEY}. */
messagesKey?: string;

@@ -178,2 +179,18 @@ /** Headless tool implementations; auto-resumes matching interrupts. */

webSocketFactory?: (url: string) => WebSocket;
/**
* Built-in transports only: max reconnect attempts after an unexpected
* disconnect. Defaults to {@link DEFAULT_MAX_RECONNECT_ATTEMPTS}.
* Independent of whether {@link fetch} is set.
*/
maxReconnectAttempts?: number;
/**
* Built-in SSE transport only: idle-reconnect policy. Defaults to
* {@link DEFAULT_IDLE_RECONNECT}.
* Pass `0` to disable.
*/
streamIdleReconnect?: ThreadStreamOptions["streamIdleReconnect"];
/** Built-in transports only: delay before each reconnect attempt. */
reconnectDelayMs?: ThreadStreamOptions["reconnectDelayMs"];
/** Built-in transports only: invoked before each reconnect attempt. */
onReconnect?: ThreadStreamOptions["onReconnect"];
}

@@ -204,2 +221,6 @@ /**

webSocketFactory?: never;
maxReconnectAttempts?: never;
streamIdleReconnect?: never;
reconnectDelayMs?: never;
onReconnect?: never;
}

@@ -286,2 +307,19 @@ /**

webSocketFactory?: (url: string) => WebSocket;
/**
* Built-in transports only: max reconnect attempts after an unexpected
* disconnect. Defaults to {@link DEFAULT_MAX_RECONNECT_ATTEMPTS}.
* Independent of whether {@link fetch} is set — auth shims keep reconnect
* enabled. Pass `0` to disable.
*/
maxReconnectAttempts?: number;
/**
* Built-in SSE transport only: idle-reconnect policy. Defaults to
* {@link DEFAULT_IDLE_RECONNECT}.
* Pass `0` to disable. See {@link ThreadStreamOptions.streamIdleReconnect}.
*/
streamIdleReconnect?: ThreadStreamOptions["streamIdleReconnect"];
/** Built-in transports only: delay before each reconnect attempt. */
reconnectDelayMs?: ThreadStreamOptions["reconnectDelayMs"];
/** Built-in transports only: invoked before each reconnect attempt. */
onReconnect?: ThreadStreamOptions["onReconnect"];
/** Called when a thread id is first produced (new-thread submits). */

@@ -303,3 +341,3 @@ onThreadId?: (threadId: string) => void;

initialValues?: StateType;
/** Key inside `values` that holds the message array. Defaults to `"messages"`. */
/** Key inside `values` that holds the message array. Defaults to {@link DEFAULT_MESSAGES_KEY}. */
messagesKey?: string;

@@ -306,0 +344,0 @@ /**

@@ -1,1 +0,1 @@

{"version":3,"file":"types.d.cts","names":[],"sources":["../../src/stream/types.ts"],"mappings":"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"}
{"version":3,"file":"types.d.cts","names":[],"sources":["../../src/stream/types.ts"],"mappings":"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"}

@@ -10,2 +10,3 @@ import { Interrupt } from "../schema.js";

import { StreamStore } from "./store.js";
import { DEFAULT_MESSAGES_KEY } from "./constants.js";
import { BaseMessage as BaseMessage$1 } from "@langchain/core/messages";

@@ -127,3 +128,3 @@ import { Channel, Event as Event$1, Goto } from "@langchain/protocol";

initialValues?: StateType;
/** State key holding the message array. Defaults to `"messages"`. */
/** State key holding the message array. Defaults to {@link DEFAULT_MESSAGES_KEY}. */
messagesKey?: string;

@@ -178,2 +179,18 @@ /** Headless tool implementations; auto-resumes matching interrupts. */

webSocketFactory?: (url: string) => WebSocket;
/**
* Built-in transports only: max reconnect attempts after an unexpected
* disconnect. Defaults to {@link DEFAULT_MAX_RECONNECT_ATTEMPTS}.
* Independent of whether {@link fetch} is set.
*/
maxReconnectAttempts?: number;
/**
* Built-in SSE transport only: idle-reconnect policy. Defaults to
* {@link DEFAULT_IDLE_RECONNECT}.
* Pass `0` to disable.
*/
streamIdleReconnect?: ThreadStreamOptions["streamIdleReconnect"];
/** Built-in transports only: delay before each reconnect attempt. */
reconnectDelayMs?: ThreadStreamOptions["reconnectDelayMs"];
/** Built-in transports only: invoked before each reconnect attempt. */
onReconnect?: ThreadStreamOptions["onReconnect"];
}

@@ -204,2 +221,6 @@ /**

webSocketFactory?: never;
maxReconnectAttempts?: never;
streamIdleReconnect?: never;
reconnectDelayMs?: never;
onReconnect?: never;
}

@@ -286,2 +307,19 @@ /**

webSocketFactory?: (url: string) => WebSocket;
/**
* Built-in transports only: max reconnect attempts after an unexpected
* disconnect. Defaults to {@link DEFAULT_MAX_RECONNECT_ATTEMPTS}.
* Independent of whether {@link fetch} is set — auth shims keep reconnect
* enabled. Pass `0` to disable.
*/
maxReconnectAttempts?: number;
/**
* Built-in SSE transport only: idle-reconnect policy. Defaults to
* {@link DEFAULT_IDLE_RECONNECT}.
* Pass `0` to disable. See {@link ThreadStreamOptions.streamIdleReconnect}.
*/
streamIdleReconnect?: ThreadStreamOptions["streamIdleReconnect"];
/** Built-in transports only: delay before each reconnect attempt. */
reconnectDelayMs?: ThreadStreamOptions["reconnectDelayMs"];
/** Built-in transports only: invoked before each reconnect attempt. */
onReconnect?: ThreadStreamOptions["onReconnect"];
/** Called when a thread id is first produced (new-thread submits). */

@@ -303,3 +341,3 @@ onThreadId?: (threadId: string) => void;

initialValues?: StateType;
/** Key inside `values` that holds the message array. Defaults to `"messages"`. */
/** Key inside `values` that holds the message array. Defaults to {@link DEFAULT_MESSAGES_KEY}. */
messagesKey?: string;

@@ -306,0 +344,0 @@ /**

@@ -1,1 +0,1 @@

{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/stream/types.ts"],"mappings":"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"}
{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/stream/types.ts"],"mappings":"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"}

@@ -228,4 +228,8 @@ import { Checkpoint, Config, Metadata } from "./schema.cjs";

schedule?: string;
endTime?: string;
/**
* ISO 8601 timestamp after which the cron stops scheduling runs.
* Pass `null` to clear a previously set end time; omit to leave it unchanged.
*/
endTime?: string | null;
/**
* IANA timezone string for interpreting the schedule (e.g. "America/New_York").

@@ -232,0 +236,0 @@ */

@@ -1,1 +0,1 @@

{"version":3,"file":"types.d.cts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;KAKY,iBAAA;AAAA,KACA,kBAAA;AAAA,KACA,oBAAA;AAAA,KACA,cAAA;AAAA,KACA,UAAA;AAAA,KACA,cAAA;AAAA,KACA,WAAA;AAAA,UAYK,IAAA;EACf,IAAA;EACA,KAAA;AAAA;AAAA,UAGe,OAAA;EArBL;;;EAyBV,MAAA,GAAS,MAAA;EAzBqB;AAChC;;EA6BE,MAAA;EA7BwB;;AAC1B;;;EAmCE,IAAA,GAAO,IAAA,GAAO,IAAA;AAAA;AAAA,UAGC,iBAAA;EArCS;;;EAyCxB,KAAA,GAAQ,MAAA;EAxCE;;;EA6CV,QAAA,GAAW,QAAA;EA7CU;AAYvB;;EAsCE,MAAA,GAAS,MAAA;EArCT;;AAIF;;EAuCE,OAAA;EAnCS;;;EAwCT,YAAA;EA5BkB;;;EAiClB,UAAA,GAAa,IAAA,CAAK,UAAA;EAjClB;;;;EAuCA,gBAAA;EApCe;;;;;;;EA6Cf,UAAA,GAAa,UAAA;EAAA;;;EAKb,eAAA;EA2Ce;;;EAtCf,cAAA;EAiEkC;;;;;;;;;;EArDlC,iBAAA,GAAoB,iBAAA;EArCF;;;EA0ClB,MAAA,GAAS,eAAA;EAtBT;;;;;;EA8BA,YAAA,GAAe,oBAAA;EAAA;;;EAKf,OAAA;EAcA;;;;;;EANA,YAAA,GAAe,cAAA;EAqBC;;;;EAfhB,YAAA;EAwBe;;;EAnBf,WAAA;EAoBiC;;;EAfjC,OAAA,GAAU,OAAA;EAiBF;;;EAZR,YAAA,IAAgB,MAAA;IAAU,MAAA;IAAgB,SAAA;EAAA;EAYlC;;;;EANR,gBAAA,GAAmB,eAAA;AAAA;AAAA,UAGJ,iBAAA,qBACK,UAAA,GAAa,UAAA,qDAEzB,iBAAA;EAmCc;;;EA/BtB,UAAA,GAAa,WAAA;EAwCE;;;EAnCf,eAAA,GAAkB,UAAA;EAuCc;;;;EAjChC,eAAA;EA6ByC;;;;;;;;;;AAwB3C;;;;;;;;EAjCE,mBAAA,GAAsB,iBAAA;EA8DtB;;;AAGF;EA3DE,YAAA;AAAA;AAAA,UAGe,iBAAA,SAA0B,iBAAA;EAoET;;;EAhEhC,UAAA,GAAa,UAAA,GAAa,KAAA,CAAM,UAAA;EAoD2B;;;EA/C3D,eAAA;EAsDA;;;;EAhDA,eAAA;EA0DA;;;;EApDA,YAAA;AAAA;AAAA,UAGe,kBAAA,SAA2B,iBAAA;EAkEX;;;;EA7D/B,QAAA;;;;;EAMA,QAAA;;;;;;;EAQA,cAAA;;;;EAKA,OAAA;;;;EAKA,OAAA;AAAA;AAAA,UAGe,kBAAA,SAA2B,iBAAA;EAC1C,QAAA;EACA,OAAA;;;;EAKA,QAAA;;;;EAKA,UAAA,GAAa,UAAA,GAAa,KAAA,CAAM,UAAA;;;;EAKhC,eAAA;;;;EAKA,eAAA;;;;;;;EAQA,cAAA;EACA,OAAA;AAAA;AAAA,UAGe,eAAA,SAAwB,iBAAA;;;;EAIvC,UAAA;AAAA"}
{"version":3,"file":"types.d.cts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;KAKY,iBAAA;AAAA,KACA,kBAAA;AAAA,KACA,oBAAA;AAAA,KACA,cAAA;AAAA,KACA,UAAA;AAAA,KACA,cAAA;AAAA,KACA,WAAA;AAAA,UAYK,IAAA;EACf,IAAA;EACA,KAAA;AAAA;AAAA,UAGe,OAAA;EArBL;;;EAyBV,MAAA,GAAS,MAAA;EAzBqB;AAChC;;EA6BE,MAAA;EA7BwB;;AAC1B;;;EAmCE,IAAA,GAAO,IAAA,GAAO,IAAA;AAAA;AAAA,UAGC,iBAAA;EArCS;;;EAyCxB,KAAA,GAAQ,MAAA;EAxCE;;;EA6CV,QAAA,GAAW,QAAA;EA7CU;AAYvB;;EAsCE,MAAA,GAAS,MAAA;EArCT;;AAIF;;EAuCE,OAAA;EAnCS;;;EAwCT,YAAA;EA5BkB;;;EAiClB,UAAA,GAAa,IAAA,CAAK,UAAA;EAjClB;;;;EAuCA,gBAAA;EApCe;;;;;;;EA6Cf,UAAA,GAAa,UAAA;EAAA;;;EAKb,eAAA;EA2Ce;;;EAtCf,cAAA;EAiEkC;;;;;;;;;;EArDlC,iBAAA,GAAoB,iBAAA;EArCF;;;EA0ClB,MAAA,GAAS,eAAA;EAtBT;;;;;;EA8BA,YAAA,GAAe,oBAAA;EAAA;;;EAKf,OAAA;EAcA;;;;;;EANA,YAAA,GAAe,cAAA;EAqBC;;;;EAfhB,YAAA;EAwBe;;;EAnBf,WAAA;EAoBiC;;;EAfjC,OAAA,GAAU,OAAA;EAiBF;;;EAZR,YAAA,IAAgB,MAAA;IAAU,MAAA;IAAgB,SAAA;EAAA;EAYlC;;;;EANR,gBAAA,GAAmB,eAAA;AAAA;AAAA,UAGJ,iBAAA,qBACK,UAAA,GAAa,UAAA,qDAEzB,iBAAA;EAmCc;;;EA/BtB,UAAA,GAAa,WAAA;EAwCE;;;EAnCf,eAAA,GAAkB,UAAA;EAuCc;;;;EAjChC,eAAA;EA6ByC;;;;;;;;;;AAwB3C;;;;;;;;EAjCE,mBAAA,GAAsB,iBAAA;EA8DtB;;;AAGF;EA3DE,YAAA;AAAA;AAAA,UAGe,iBAAA,SAA0B,iBAAA;EAwET;;;EApEhC,UAAA,GAAa,UAAA,GAAa,KAAA,CAAM,UAAA;EAoD2B;;;EA/C3D,eAAA;EA0DA;;;;EApDA,eAAA;EA8DA;;;;EAxDA,YAAA;AAAA;AAAA,UAGe,kBAAA,SAA2B,iBAAA;EAsEX;;;;EAjE/B,QAAA;;;;;EAMA,QAAA;;;;;;;EAQA,cAAA;;;;EAKA,OAAA;;;;EAKA,OAAA;AAAA;AAAA,UAGe,kBAAA,SAA2B,iBAAA;EAC1C,QAAA;;;;;EAKA,OAAA;;;;EAKA,QAAA;;;;EAKA,UAAA,GAAa,UAAA,GAAa,KAAA,CAAM,UAAA;;;;EAKhC,eAAA;;;;EAKA,eAAA;;;;;;;EAQA,cAAA;EACA,OAAA;AAAA;AAAA,UAGe,eAAA,SAAwB,iBAAA;;;;EAIvC,UAAA;AAAA"}

@@ -228,4 +228,8 @@ import { Checkpoint, Config, Metadata } from "./schema.js";

schedule?: string;
endTime?: string;
/**
* ISO 8601 timestamp after which the cron stops scheduling runs.
* Pass `null` to clear a previously set end time; omit to leave it unchanged.
*/
endTime?: string | null;
/**
* IANA timezone string for interpreting the schedule (e.g. "America/New_York").

@@ -232,0 +236,0 @@ */

@@ -1,1 +0,1 @@

{"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;KAKY,iBAAA;AAAA,KACA,kBAAA;AAAA,KACA,oBAAA;AAAA,KACA,cAAA;AAAA,KACA,UAAA;AAAA,KACA,cAAA;AAAA,KACA,WAAA;AAAA,UAYK,IAAA;EACf,IAAA;EACA,KAAA;AAAA;AAAA,UAGe,OAAA;EArBL;;;EAyBV,MAAA,GAAS,MAAA;EAzBqB;AAChC;;EA6BE,MAAA;EA7BwB;;AAC1B;;;EAmCE,IAAA,GAAO,IAAA,GAAO,IAAA;AAAA;AAAA,UAGC,iBAAA;EArCS;;;EAyCxB,KAAA,GAAQ,MAAA;EAxCE;;;EA6CV,QAAA,GAAW,QAAA;EA7CU;AAYvB;;EAsCE,MAAA,GAAS,MAAA;EArCT;;AAIF;;EAuCE,OAAA;EAnCS;;;EAwCT,YAAA;EA5BkB;;;EAiClB,UAAA,GAAa,IAAA,CAAK,UAAA;EAjClB;;;;EAuCA,gBAAA;EApCe;;;;;;;EA6Cf,UAAA,GAAa,UAAA;EAAA;;;EAKb,eAAA;EA2Ce;;;EAtCf,cAAA;EAiEkC;;;;;;;;;;EArDlC,iBAAA,GAAoB,iBAAA;EArCF;;;EA0ClB,MAAA,GAAS,eAAA;EAtBT;;;;;;EA8BA,YAAA,GAAe,oBAAA;EAAA;;;EAKf,OAAA;EAcA;;;;;;EANA,YAAA,GAAe,cAAA;EAqBC;;;;EAfhB,YAAA;EAwBe;;;EAnBf,WAAA;EAoBiC;;;EAfjC,OAAA,GAAU,OAAA;EAiBF;;;EAZR,YAAA,IAAgB,MAAA;IAAU,MAAA;IAAgB,SAAA;EAAA;EAYlC;;;;EANR,gBAAA,GAAmB,eAAA;AAAA;AAAA,UAGJ,iBAAA,qBACK,UAAA,GAAa,UAAA,qDAEzB,iBAAA;EAmCc;;;EA/BtB,UAAA,GAAa,WAAA;EAwCE;;;EAnCf,eAAA,GAAkB,UAAA;EAuCc;;;;EAjChC,eAAA;EA6ByC;;;;;;;;;;AAwB3C;;;;;;;;EAjCE,mBAAA,GAAsB,iBAAA;EA8DtB;;;AAGF;EA3DE,YAAA;AAAA;AAAA,UAGe,iBAAA,SAA0B,iBAAA;EAoET;;;EAhEhC,UAAA,GAAa,UAAA,GAAa,KAAA,CAAM,UAAA;EAoD2B;;;EA/C3D,eAAA;EAsDA;;;;EAhDA,eAAA;EA0DA;;;;EApDA,YAAA;AAAA;AAAA,UAGe,kBAAA,SAA2B,iBAAA;EAkEX;;;;EA7D/B,QAAA;;;;;EAMA,QAAA;;;;;;;EAQA,cAAA;;;;EAKA,OAAA;;;;EAKA,OAAA;AAAA;AAAA,UAGe,kBAAA,SAA2B,iBAAA;EAC1C,QAAA;EACA,OAAA;;;;EAKA,QAAA;;;;EAKA,UAAA,GAAa,UAAA,GAAa,KAAA,CAAM,UAAA;;;;EAKhC,eAAA;;;;EAKA,eAAA;;;;;;;EAQA,cAAA;EACA,OAAA;AAAA;AAAA,UAGe,eAAA,SAAwB,iBAAA;;;;EAIvC,UAAA;AAAA"}
{"version":3,"file":"types.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;KAKY,iBAAA;AAAA,KACA,kBAAA;AAAA,KACA,oBAAA;AAAA,KACA,cAAA;AAAA,KACA,UAAA;AAAA,KACA,cAAA;AAAA,KACA,WAAA;AAAA,UAYK,IAAA;EACf,IAAA;EACA,KAAA;AAAA;AAAA,UAGe,OAAA;EArBL;;;EAyBV,MAAA,GAAS,MAAA;EAzBqB;AAChC;;EA6BE,MAAA;EA7BwB;;AAC1B;;;EAmCE,IAAA,GAAO,IAAA,GAAO,IAAA;AAAA;AAAA,UAGC,iBAAA;EArCS;;;EAyCxB,KAAA,GAAQ,MAAA;EAxCE;;;EA6CV,QAAA,GAAW,QAAA;EA7CU;AAYvB;;EAsCE,MAAA,GAAS,MAAA;EArCT;;AAIF;;EAuCE,OAAA;EAnCS;;;EAwCT,YAAA;EA5BkB;;;EAiClB,UAAA,GAAa,IAAA,CAAK,UAAA;EAjClB;;;;EAuCA,gBAAA;EApCe;;;;;;;EA6Cf,UAAA,GAAa,UAAA;EAAA;;;EAKb,eAAA;EA2Ce;;;EAtCf,cAAA;EAiEkC;;;;;;;;;;EArDlC,iBAAA,GAAoB,iBAAA;EArCF;;;EA0ClB,MAAA,GAAS,eAAA;EAtBT;;;;;;EA8BA,YAAA,GAAe,oBAAA;EAAA;;;EAKf,OAAA;EAcA;;;;;;EANA,YAAA,GAAe,cAAA;EAqBC;;;;EAfhB,YAAA;EAwBe;;;EAnBf,WAAA;EAoBiC;;;EAfjC,OAAA,GAAU,OAAA;EAiBF;;;EAZR,YAAA,IAAgB,MAAA;IAAU,MAAA;IAAgB,SAAA;EAAA;EAYlC;;;;EANR,gBAAA,GAAmB,eAAA;AAAA;AAAA,UAGJ,iBAAA,qBACK,UAAA,GAAa,UAAA,qDAEzB,iBAAA;EAmCc;;;EA/BtB,UAAA,GAAa,WAAA;EAwCE;;;EAnCf,eAAA,GAAkB,UAAA;EAuCc;;;;EAjChC,eAAA;EA6ByC;;;;;;;;;;AAwB3C;;;;;;;;EAjCE,mBAAA,GAAsB,iBAAA;EA8DtB;;;AAGF;EA3DE,YAAA;AAAA;AAAA,UAGe,iBAAA,SAA0B,iBAAA;EAwET;;;EApEhC,UAAA,GAAa,UAAA,GAAa,KAAA,CAAM,UAAA;EAoD2B;;;EA/C3D,eAAA;EA0DA;;;;EApDA,eAAA;EA8DA;;;;EAxDA,YAAA;AAAA;AAAA,UAGe,kBAAA,SAA2B,iBAAA;EAsEX;;;;EAjE/B,QAAA;;;;;EAMA,QAAA;;;;;;;EAQA,cAAA;;;;EAKA,OAAA;;;;EAKA,OAAA;AAAA;AAAA,UAGe,kBAAA,SAA2B,iBAAA;EAC1C,QAAA;;;;;EAKA,OAAA;;;;EAKA,QAAA;;;;EAKA,UAAA,GAAa,UAAA,GAAa,KAAA,CAAM,UAAA;;;;EAKhC,eAAA;;;;EAKA,eAAA;;;;;;;EAQA,cAAA;EACA,OAAA;AAAA;AAAA,UAGe,eAAA,SAAwB,iBAAA;;;;EAIvC,UAAA;AAAA"}

@@ -0,1 +1,2 @@

require("../stream/constants.cjs");
const require_messages = require("./messages.cjs");

@@ -2,0 +3,0 @@ const require_errors = require("./errors.cjs");

@@ -1,1 +0,1 @@

{"version":3,"file":"manager.cjs","names":["toMessageDict","SubagentManager","StreamError","isSubagentNamespace","extractToolCallIdFromNamespace"],"sources":["../../src/ui/manager.ts"],"sourcesContent":["import type { BaseMessage } from \"@langchain/core/messages\";\n\nimport type {\n CheckpointsStreamEvent,\n CustomStreamEvent,\n DebugStreamEvent,\n ErrorStreamEvent,\n EventsStreamEvent,\n FeedbackStreamEvent,\n MessagesTupleStreamEvent,\n MetadataStreamEvent,\n TasksStreamEvent,\n ToolsStreamEvent,\n UpdatesStreamEvent,\n ValuesStreamEvent,\n} from \"../types.stream.js\";\nimport { MessageTupleManager, toMessageDict } from \"./messages.js\";\nimport { StreamError } from \"./errors.js\";\nimport type { Message } from \"../types.messages.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport {\n SubagentManager,\n extractToolCallIdFromNamespace,\n isSubagentNamespace,\n} from \"./subagents.js\";\nimport type { SubagentStreamInterface } from \"./types.js\";\n\n/**\n * Special ID used by LangGraph's messagesStateReducer to signal\n * that all messages should be removed from the state.\n */\nexport const REMOVE_ALL_MESSAGES = \"__remove_all__\";\n\ntype GetUpdateType<\n Bag extends BagTemplate,\n StateType extends Record<string, unknown>,\n> = Bag extends { UpdateType: unknown }\n ? Bag[\"UpdateType\"]\n : Partial<StateType>;\n\ntype GetCustomEventType<Bag extends BagTemplate> = Bag extends {\n CustomEventType: unknown;\n}\n ? Bag[\"CustomEventType\"]\n : unknown;\n\ntype EventStreamMap<StateType, UpdateType, CustomType> = {\n values: ValuesStreamEvent<StateType>;\n updates: UpdatesStreamEvent<UpdateType>;\n custom: CustomStreamEvent<CustomType>;\n debug: DebugStreamEvent;\n messages: MessagesTupleStreamEvent;\n events: EventsStreamEvent;\n metadata: MetadataStreamEvent;\n checkpoints: CheckpointsStreamEvent<StateType>;\n tasks: TasksStreamEvent<StateType, UpdateType>;\n error: ErrorStreamEvent;\n feedback: FeedbackStreamEvent;\n tools: ToolsStreamEvent;\n};\n\nexport type EventStreamEvent<StateType, UpdateType, CustomType> =\n EventStreamMap<StateType, UpdateType, CustomType>[keyof EventStreamMap<\n StateType,\n UpdateType,\n CustomType\n >];\n\ninterface StreamManagerEventCallbacks<\n StateType extends Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n> {\n onUpdateEvent?: (\n data: UpdatesStreamEvent<GetUpdateType<Bag, StateType>>[\"data\"],\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n onCustomEvent?: (\n data: GetCustomEventType<Bag>,\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n onMetadataEvent?: (data: MetadataStreamEvent[\"data\"]) => void;\n onLangChainEvent?: (data: EventsStreamEvent[\"data\"]) => void;\n onDebugEvent?: (\n data: DebugStreamEvent[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onCheckpointEvent?: (\n data: CheckpointsStreamEvent<StateType>[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onTaskEvent?: (\n data: TasksStreamEvent<StateType, GetUpdateType<Bag, StateType>>[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onToolEvent?: (\n data: ToolsStreamEvent[\"data\"],\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n}\n\n/**\n * Options for StreamManager constructor.\n */\nexport interface StreamManagerOptions {\n /**\n * Throttle the stream updates.\n * If a number is provided, updates are throttled to the given milliseconds.\n * If `true`, updates are batched in a single macrotask.\n * If `false`, updates are not throttled.\n */\n throttle: number | boolean;\n\n /**\n * Tool names that indicate subagent invocation.\n *\n * When an AI message contains tool calls with these names, they are\n * automatically tracked as subagent executions. This enables the\n * `subagents`, `activeSubagents`, `getSubagent()`, and `getSubagentsByType()`\n * properties on the stream.\n *\n * @default [\"task\"]\n *\n * @example\n * ```typescript\n * // Track both \"task\" and \"delegate\" as subagent tools\n * subagentToolNames: [\"task\", \"delegate\", \"spawn_agent\"]\n * ```\n */\n subagentToolNames?: string[];\n\n /**\n * Filter out messages from subagent streams in the main messages array.\n *\n * When enabled, messages from subagraph executions (those with a `tools:` namespace)\n * are excluded from `stream.messages`. Instead, these messages are tracked\n * per-subagent and accessible via `stream.subagents.get(id).messages`.\n *\n * This is useful for deep agent architectures where you want to display\n * the main conversation separately from subagent activity.\n *\n * @default false\n *\n * @example\n * ```typescript\n * const stream = useStream({\n * assistantId: \"my-agent\",\n * filterSubagentMessages: true,\n * });\n *\n * // Main thread messages only (no subagent messages)\n * stream.messages\n *\n * // Access subagent messages individually\n * stream.subagents.get(\"call_xyz\").messages\n * ```\n */\n filterSubagentMessages?: boolean;\n\n /**\n * Converts a @langchain/core BaseMessage to the desired output format.\n *\n * Defaults to `toMessageDict` which produces plain Message objects.\n * Framework SDKs pass `toMessageClass` (identity) to keep class instances.\n */\n toMessage?: (chunk: BaseMessage) => Message | BaseMessage;\n}\n\nexport class StreamManager<\n StateType extends Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n> {\n private abortRef = new AbortController();\n\n private messages: MessageTupleManager;\n\n private subagentManager: SubagentManager;\n\n private listeners = new Set<() => void>();\n\n private throttle: number | boolean;\n\n private filterSubagentMessages: boolean;\n\n private toMessage: (chunk: BaseMessage) => Message | BaseMessage;\n\n private queue: Promise<unknown> = Promise.resolve();\n\n private queueSize: number = 0;\n\n private state: {\n isLoading: boolean;\n values: [values: StateType, kind: \"stream\" | \"stop\"] | null;\n error: unknown;\n /** Version counter to force React re-renders on subagent changes */\n version: number;\n };\n\n constructor(messages: MessageTupleManager, options: StreamManagerOptions) {\n this.messages = messages;\n this.state = {\n isLoading: false,\n values: null,\n error: undefined,\n version: 0,\n };\n this.throttle = options.throttle;\n this.filterSubagentMessages = options.filterSubagentMessages ?? false;\n this.toMessage = options.toMessage ?? toMessageDict;\n this.subagentManager = new SubagentManager({\n subagentToolNames: options.subagentToolNames,\n onSubagentChange: () => this.bumpVersion(),\n toMessage: this.toMessage,\n });\n }\n\n /**\n * Increment version counter to trigger React re-renders.\n * Called when subagent state changes.\n */\n private bumpVersion = () => {\n this.state = { ...this.state, version: this.state.version + 1 };\n this.notifyListeners();\n };\n\n /**\n * Get all subagents as a Map.\n */\n getSubagents(): Map<string, SubagentStreamInterface> {\n return this.subagentManager.getSubagents();\n }\n\n /**\n * Get all currently running subagents.\n */\n getActiveSubagents(): SubagentStreamInterface[] {\n return this.subagentManager.getActiveSubagents();\n }\n\n /**\n * Get a specific subagent by tool call ID.\n */\n getSubagent(toolCallId: string): SubagentStreamInterface | undefined {\n return this.subagentManager.getSubagent(toolCallId);\n }\n\n /**\n * Get all subagents of a specific type.\n */\n getSubagentsByType(type: string): SubagentStreamInterface[] {\n return this.subagentManager.getSubagentsByType(type);\n }\n\n /**\n * Get all subagents triggered by a specific AI message.\n */\n getSubagentsByMessage(messageId: string): SubagentStreamInterface[] {\n return this.subagentManager.getSubagentsByMessage(messageId);\n }\n\n /**\n * Reconstruct subagent state from historical messages.\n *\n * This method should be called when loading thread history to restore\n * subagent visualization after:\n * - Page refresh (when stream has already completed)\n * - Loading thread history\n * - Navigating between threads\n *\n * @param messages - Array of messages from thread history\n * @param options - Optional configuration\n * @param options.skipIfPopulated - If true, skip reconstruction if subagents already exist\n */\n reconstructSubagents(\n messages: Message[],\n options?: { skipIfPopulated?: boolean }\n ): void {\n this.subagentManager.reconstructFromMessages(messages, options);\n }\n\n /**\n * Fetch and restore internal messages for reconstructed subagents from their\n * subgraph checkpoints. Should be called after `reconstructSubagents` to\n * restore the full subagent conversation after a page refresh.\n *\n * Subagent messages are persisted in the LangGraph checkpointer under a\n * subgraph-specific `checkpoint_ns` (e.g. `tools:<uuid>`). This method\n * discovers the correct namespace by inspecting the main thread's intermediate\n * history checkpoints, where each pending task's `checkpoint.checkpoint_ns`\n * identifies the subgraph. Tasks are matched to tool calls by their Send index\n * (`task.path[1]`), which corresponds to the order of tool calls in the AI\n * message — no deepagent-specific metadata required.\n *\n * @param threads - Client with a `getHistory` method (e.g. `client.threads`)\n * @param threadId - The parent thread ID\n * @param options - Optional configuration\n * @param options.messagesKey - Key in state values containing messages (default: \"messages\")\n * @param options.signal - AbortSignal to cancel in-flight requests on effect cleanup\n */\n async fetchSubagentHistory(\n threads: {\n getHistory<V extends Record<string, unknown>>(\n threadId: string,\n options?: {\n limit?: number;\n checkpoint?: { checkpoint_ns?: string };\n signal?: AbortSignal;\n }\n ): Promise<\n Array<{\n values: V;\n tasks?: Array<{\n id: string;\n name: string;\n path?: unknown[];\n checkpoint?: { checkpoint_ns?: string } | null;\n }>;\n }>\n >;\n },\n threadId: string,\n options?: {\n messagesKey?: string;\n historyLimit?: number;\n signal?: AbortSignal;\n }\n ): Promise<void> {\n const messagesKey = options?.messagesKey ?? \"messages\";\n const signal = options?.signal;\n\n /**\n * Bail immediately if already cancelled (React Strict Mode cleanup)\n */\n if (signal?.aborted) {\n return;\n }\n\n /**\n * Only fetch for subagents that have no messages (reconstructed from history)\n */\n const toFetch = [...this.subagentManager.getSubagents().entries()].filter(\n ([, s]) => s.messages.length === 0\n );\n\n /**\n * Bail immediately if there are no subagents to fetch\n */\n if (toFetch.length === 0) {\n return;\n }\n\n /**\n * Step 1: Discover subgraph namespaces from intermediate history\n *\n * When LangGraph dispatches parallel tool calls (v2 mode), each is a\n * separate Send task with a unique UUID-based checkpoint_ns. The intermediate\n * history checkpoints record these as `tasks[i]` where:\n * - `tasks[i].checkpoint.checkpoint_ns` = \"tools:<uuid>\" for each subgraph\n * - `tasks[i].path = [\"__pregel_push\", sendIndex]` matches tool_calls order\n *\n * By matching task Send index → tool_call position in the AI message we can\n * derive the subgraph namespace for every tool call without any external\n * metadata on the ToolMessage itself.\n */\n const toolCallIdToNamespace = new Map<string, string>();\n\n try {\n /**\n * Fetch enough history to include the intermediate checkpoint where\n * tool-call tasks were pending (typically within the last 10 checkpoints).\n */\n const mainHistory = await threads.getHistory<Record<string, unknown>>(\n threadId,\n { limit: options?.historyLimit ?? 20, signal }\n );\n\n /**\n * Phase 1: Direct mapping across ALL checkpoints (preferred).\n *\n * When a completed checkpoint contains task results, each task.result\n * has a ToolMessage whose tool_call_id directly and unambiguously maps\n * the task to the LLM tool call that triggered it. This is more robust\n * than positional alignment: it works even when a step mixes subagent\n * tool calls with other tool calls, and requires no assumptions about\n * the ordering of tasks vs tool_calls.\n *\n * We collect these direct mappings across the entire history before\n * attempting any positional fallback. Otherwise a more recent checkpoint\n * whose task is still pending (e.g. an interrupted run) could produce a\n * positional guess and stop the scan before reaching the older checkpoint\n * that actually holds the correct, completed mapping.\n *\n * LangGraph v2 dispatches each parallel tool call as a separate PUSH\n * task (\"__pregel_push\"). The subgraph checkpoint_ns is constructed as\n * `task.name + \":\" + task.id`, mirroring algo.ts:\n * taskCheckpointNamespace = checkpointNamespace + \":\" + taskId\n * where checkpointNamespace = task.name for root-level tasks.\n *\n * task.checkpoint is always null for completed tasks, so we derive the\n * namespace from task.name + task.id rather than task.checkpoint.checkpoint_ns.\n */\n for (const checkpoint of mainHistory) {\n const { tasks } = checkpoint;\n if (!tasks || tasks.length === 0) {\n continue;\n }\n\n for (const task of tasks) {\n if (\n !Array.isArray(task.path) ||\n task.path[0] !== \"__pregel_push\" ||\n typeof task.id !== \"string\" ||\n typeof task.name !== \"string\"\n ) {\n continue;\n }\n\n /**\n * Read tool_call_id directly from the task's result ToolMessage.\n */\n const resultMessages = (\n task as unknown as { result?: { messages?: unknown[] } }\n ).result?.messages;\n\n if (!Array.isArray(resultMessages)) {\n continue;\n }\n\n for (const msg of resultMessages) {\n const m = msg as Record<string, unknown>;\n if (\n m.type === \"tool\" &&\n typeof m.tool_call_id === \"string\" &&\n toFetch.some(([id]) => id === m.tool_call_id) &&\n !toolCallIdToNamespace.has(m.tool_call_id)\n ) {\n toolCallIdToNamespace.set(\n m.tool_call_id,\n `${task.name}:${task.id}`\n );\n }\n }\n }\n }\n\n /**\n * Phase 2: Positional fallback, applied ONLY to tool calls that Phase 1\n * could not resolve.\n *\n * This covers checkpoints whose task results are not yet populated (tasks\n * still pending — the live or just-interrupted case). We align push tasks\n * to the subagent tool calls of the triggering AI message by Send index\n * (task.path[1]). Restricting this to still-unmapped tool calls guarantees\n * a correct direct mapping from Phase 1 is never overwritten by a guess.\n */\n const hasUnmappedToolCalls = () =>\n toFetch.some(([id]) => !toolCallIdToNamespace.has(id));\n\n if (hasUnmappedToolCalls()) {\n for (const checkpoint of mainHistory) {\n if (!hasUnmappedToolCalls()) break;\n\n const { tasks } = checkpoint;\n if (!tasks || tasks.length === 0) {\n continue;\n }\n\n const pushTasks = tasks.filter(\n (t) =>\n Array.isArray(t.path) &&\n t.path[0] === \"__pregel_push\" &&\n typeof t.path[1] === \"number\" &&\n typeof t.id === \"string\" &&\n typeof t.name === \"string\"\n );\n if (pushTasks.length === 0) continue;\n\n /**\n * Find the AI message with subagent tool calls to align by Send index.\n */\n const msgs = checkpoint.values[messagesKey];\n if (!Array.isArray(msgs)) continue;\n\n let aiMessage: Record<string, unknown> | undefined;\n for (let i = msgs.length - 1; i >= 0; i -= 1) {\n const m = msgs[i] as Record<string, unknown>;\n if (\n m.type === \"ai\" &&\n Array.isArray(m.tool_calls) &&\n m.tool_calls.length > 0 &&\n (m.tool_calls as Array<{ name: string }>).some((tc) =>\n this.subagentManager.isSubagentToolCall(tc.name)\n )\n ) {\n aiMessage = m;\n break;\n }\n }\n if (!aiMessage) {\n continue;\n }\n\n /**\n * Only consider subagent tool calls from the AI message — not all tool\n * calls. This ensures regular tool calls (searchWeb, queryDatabase, etc.)\n * are never mistaken for subagents even when they appear in the same step.\n */\n const subagentToolCalls = (\n aiMessage.tool_calls as Array<{ id?: string; name: string }>\n ).filter((tc) => this.subagentManager.isSubagentToolCall(tc.name));\n\n if (subagentToolCalls.length === 0) {\n continue;\n }\n\n /**\n * Sort push tasks by Send index (path[1]) to align with tool_calls order\n */\n const sorted = [...pushTasks].sort((a, b) => {\n const ai = Array.isArray(a.path) ? (a.path[1] as number) : 0;\n const bi = Array.isArray(b.path) ? (b.path[1] as number) : 0;\n return ai - bi;\n });\n\n for (\n let i = 0;\n i < sorted.length && i < subagentToolCalls.length;\n i += 1\n ) {\n const tc = subagentToolCalls[i];\n const task = sorted[i];\n if (\n tc?.id &&\n task.id &&\n task.name &&\n toFetch.some(([id]) => id === tc.id) &&\n !toolCallIdToNamespace.has(tc.id)\n ) {\n toolCallIdToNamespace.set(tc.id, `${task.name}:${task.id}`);\n }\n }\n }\n }\n } catch {\n /**\n * Non-fatal: fall back to subagent.namespace below\n */\n }\n\n /**\n * Step 2: Fetch each subagent's conversation from its subgraph checkpoint\n */\n await Promise.all(\n toFetch.map(async ([toolCallId, subagent]) => {\n /**\n * Priority order for the subgraph checkpoint_ns:\n * 1. Derived from main thread's intermediate task list (preferred, no coupling)\n * 2. Already on the subagent's namespace (e.g. populated during streaming)\n * 3. Skip — we cannot reliably identify the namespace\n */\n const checkpointNs =\n toolCallIdToNamespace.get(toolCallId) ??\n (subagent.namespace.length > 0\n ? subagent.namespace.join(\"|\")\n : undefined);\n\n if (!checkpointNs) return;\n\n try {\n const history = await threads.getHistory<Record<string, unknown>>(\n threadId,\n {\n checkpoint: { checkpoint_ns: checkpointNs },\n limit: 1,\n signal,\n }\n );\n\n /**\n * If the HTTP request was cancelled mid-flight the getHistory call\n * would have thrown an AbortError (caught below). If we reach here the\n * fetch completed successfully, so always process the result.\n */\n const latestState = history[0];\n if (!latestState?.values) return;\n\n const messages = latestState.values[messagesKey];\n if (!Array.isArray(messages) || messages.length === 0) return;\n\n /**\n * Normalize messages: promote tool_calls from additional_kwargs to top\n * level when the checkpointer serialized them in the legacy format.\n */\n const normalizedMessages = messages.map((msg) => {\n const m = msg as Record<string, unknown>;\n if (\n m.type === \"ai\" &&\n (!m.tool_calls || (m.tool_calls as unknown[]).length === 0)\n ) {\n const ak = m.additional_kwargs as\n | Record<string, unknown>\n | undefined;\n const legacy = ak?.tool_calls;\n if (Array.isArray(legacy) && legacy.length > 0) {\n return { ...m, tool_calls: legacy };\n }\n }\n return m;\n });\n\n this.subagentManager.updateSubagentFromSubgraphState(\n toolCallId,\n normalizedMessages as Message[],\n latestState.values\n );\n } catch {\n /**\n * Ignore AbortError and other transient errors\n */\n }\n })\n );\n }\n\n /**\n * Check if any subagents are currently tracked.\n */\n hasSubagents(): boolean {\n return this.subagentManager.hasSubagents();\n }\n\n private setState = (newState: Partial<typeof this.state>) => {\n this.state = { ...this.state, ...newState };\n this.notifyListeners();\n };\n\n private notifyListeners = () => {\n this.listeners.forEach((listener) => listener());\n };\n\n subscribe = (listener: () => void): (() => void) => {\n if (this.throttle === false) {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n const timeoutMs = this.throttle === true ? 0 : this.throttle;\n let timeoutId: NodeJS.Timeout | number | undefined;\n\n const throttledListener = () => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n clearTimeout(timeoutId);\n listener();\n }, timeoutMs);\n };\n\n this.listeners.add(throttledListener);\n return () => {\n clearTimeout(timeoutId);\n this.listeners.delete(throttledListener);\n };\n };\n\n getSnapshot = () => this.state;\n\n get isLoading() {\n return this.state.isLoading;\n }\n\n get values() {\n return this.state.values?.[0] ?? null;\n }\n\n get error() {\n return this.state.error;\n }\n\n setStreamValues = (\n values:\n | (StateType | null)\n | ((prev: StateType | null, kind: \"stream\" | \"stop\") => StateType | null),\n kind: \"stream\" | \"stop\" = \"stream\"\n ) => {\n if (typeof values === \"function\") {\n const [prevValues, prevKind] = this.state.values ?? [null, \"stream\"];\n const nextValues = values(prevValues, prevKind);\n this.setState({ values: nextValues != null ? [nextValues, kind] : null });\n } else {\n const nextValues = values != null ? [values, kind] : null;\n this.setState({ values: nextValues as [StateType, \"stream\" | \"stop\"] });\n }\n };\n\n private getMutateFn = (kind: \"stream\" | \"stop\", historyValues: StateType) => {\n return (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => {\n const stateValues = (this.state.values ?? [null, \"stream\"])[0];\n const prev = {\n ...historyValues,\n ...stateValues,\n };\n const next = typeof update === \"function\" ? update(prev) : update;\n this.setStreamValues({ ...prev, ...next }, kind);\n };\n };\n\n private matchEventType = <\n T extends keyof EventStreamMap<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >,\n >(\n expected: T,\n actual: EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[\"event\"],\n _data: EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[\"data\"]\n ): _data is EventStreamMap<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[T][\"data\"] => {\n return expected === actual || actual.startsWith(`${expected}|`);\n };\n\n protected enqueue = async (\n action: (\n signal: AbortSignal\n ) => Promise<\n AsyncGenerator<\n EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >\n >\n >,\n options: {\n getMessages: (values: StateType) => Message[];\n\n setMessages: (current: StateType, messages: Message[]) => StateType;\n\n initialValues: StateType;\n\n callbacks: StreamManagerEventCallbacks<StateType, Bag>;\n\n onSuccess: () =>\n | StateType\n | null\n | undefined\n | void\n | Promise<StateType | null | undefined | void>;\n\n onError: (error: unknown) => void | Promise<void>;\n\n onFinish?: () => void;\n }\n ) => {\n try {\n this.queueSize = Math.max(0, this.queueSize - 1);\n this.setState({ isLoading: true, error: undefined });\n this.abortRef = new AbortController();\n\n const run = await action(this.abortRef.signal);\n let clearedPreviousInterrupts = false;\n\n let streamError: StreamError | undefined;\n for await (const { event, data } of run) {\n if (event === \"error\") {\n streamError = new StreamError(data);\n break;\n }\n\n const namespace = event.includes(\"|\")\n ? event.split(\"|\").slice(1)\n : undefined;\n\n const mutate = this.getMutateFn(\"stream\", options.initialValues);\n\n if (event === \"metadata\") options.callbacks.onMetadataEvent?.(data);\n if (event === \"events\") options.callbacks.onLangChainEvent?.(data);\n\n if (this.matchEventType(\"updates\", event, data)) {\n options.callbacks.onUpdateEvent?.(data, { namespace, mutate });\n\n // Track subagent streaming updates from subgraph namespaces\n // Mark the subagent as running when we receive updates\n // The actual message content is handled via addMessageToSubagent\n if (namespace && isSubagentNamespace(namespace)) {\n const namespaceId = extractToolCallIdFromNamespace(namespace);\n if (namespaceId && this.filterSubagentMessages) {\n this.subagentManager.markRunningFromNamespace(\n namespaceId,\n namespace\n );\n }\n }\n\n // Also register subagents from main agent updates (tool_calls in messages)\n // AND process tool results to complete subagents\n // This is needed because tool_calls often appear complete in updates\n // before they appear in the messages stream\n if (!namespace || !isSubagentNamespace(namespace)) {\n const updateData = data as Record<string, unknown>;\n for (const nodeData of Object.values(updateData)) {\n if (\n nodeData &&\n typeof nodeData === \"object\" &&\n \"messages\" in nodeData\n ) {\n const { messages } = nodeData as { messages: unknown[] };\n if (Array.isArray(messages)) {\n for (const msg of messages) {\n if (!msg || typeof msg !== \"object\") continue;\n const msgObj = msg as Record<string, unknown>;\n\n // Register subagents from AI messages with tool_calls\n if (\n msgObj.type === \"ai\" &&\n \"tool_calls\" in msgObj &&\n Array.isArray(msgObj.tool_calls)\n ) {\n this.subagentManager.registerFromToolCalls(\n msgObj.tool_calls as Array<{\n id?: string;\n name: string;\n args: Record<string, unknown> | string;\n }>,\n msgObj.id as string | undefined\n );\n }\n\n // Complete subagents from tool messages (task results)\n if (\n msgObj.type === \"tool\" &&\n \"tool_call_id\" in msgObj &&\n typeof msgObj.tool_call_id === \"string\"\n ) {\n const content =\n typeof msgObj.content === \"string\"\n ? msgObj.content\n : JSON.stringify(msgObj.content);\n const status =\n \"status\" in msgObj && msgObj.status === \"error\"\n ? \"error\"\n : \"success\";\n this.subagentManager.processToolMessage(\n msgObj.tool_call_id,\n content,\n status\n );\n }\n }\n }\n }\n }\n }\n }\n\n if (this.matchEventType(\"custom\", event, data)) {\n options.callbacks.onCustomEvent?.(data, { namespace, mutate });\n }\n\n if (this.matchEventType(\"checkpoints\", event, data)) {\n options.callbacks.onCheckpointEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"tasks\", event, data)) {\n options.callbacks.onTaskEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"debug\", event, data)) {\n options.callbacks.onDebugEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"tools\", event, data)) {\n options.callbacks.onToolEvent?.(data, { namespace, mutate });\n }\n\n // Handle values events - use startsWith to match both \"values\" and \"values|tools:xxx\"\n if (event === \"values\" || event.startsWith(\"values|\")) {\n // Check if this is a subgraph values event (for namespace mapping and values)\n if (namespace && isSubagentNamespace(namespace)) {\n const namespaceId = extractToolCallIdFromNamespace(namespace);\n if (namespaceId && this.filterSubagentMessages) {\n const valuesData = data as Record<string, unknown>;\n\n // Try to establish namespace mapping from the initial human message\n const messages = valuesData.messages as unknown[];\n if (Array.isArray(messages) && messages.length > 0) {\n const firstMsg = messages[0] as Record<string, unknown>;\n if (\n firstMsg?.type === \"human\" &&\n typeof firstMsg?.content === \"string\"\n ) {\n this.subagentManager.matchSubgraphToSubagent(\n namespaceId,\n firstMsg.content\n );\n }\n }\n\n // Update the subagent's values with the full state\n this.subagentManager.updateSubagentValues(\n namespaceId,\n valuesData\n );\n }\n } else {\n if (!clearedPreviousInterrupts) {\n // Clear stale __interrupt__ from the previous run once the new\n // stream starts delivering main values. This avoids carrying\n // resumed interrupts forward while still preserving the previous\n // interrupt state if the new stream fails before any values\n // arrive.\n this.setStreamValues((prev) => {\n if (prev && \"__interrupt__\" in prev) {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { __interrupt__, ...rest } = prev;\n return rest as StateType;\n }\n return prev;\n });\n clearedPreviousInterrupts = true;\n }\n\n if (data && typeof data === \"object\" && \"__interrupt__\" in data) {\n // When parallel branches each raise an interrupt, the backend\n // may stream separate values events per branch. We accumulate\n // the __interrupt__ arrays so none are lost, but still honor an\n // explicit empty array as \"clear interrupts\".\n const interruptData = data as Partial<StateType> & {\n __interrupt__?: Array<{ id?: string }>;\n };\n this.setStreamValues((prev) => {\n const prevInterrupts = (\n prev as\n | (StateType & { __interrupt__?: Array<{ id?: string }> })\n | null\n )?.__interrupt__;\n\n let interrupts = interruptData.__interrupt__;\n if (Array.isArray(interrupts)) {\n if (interrupts.length === 0) {\n interrupts = [];\n } else if (Array.isArray(prevInterrupts)) {\n const mergedInterrupts = [...prevInterrupts];\n const existingIds = new Set(\n prevInterrupts.map((i) => i.id).filter((id) => id != null)\n );\n for (const interrupt of interrupts) {\n if (interrupt.id != null) {\n if (existingIds.has(interrupt.id)) continue;\n existingIds.add(interrupt.id);\n }\n mergedInterrupts.push(interrupt);\n }\n interrupts = mergedInterrupts;\n }\n }\n\n return {\n ...prev,\n __interrupt__: interrupts,\n } as unknown as StateType;\n });\n } else {\n // Non-interrupt values events must not wipe accumulated\n // __interrupt__ state. Preserve it when the incoming data\n // does not carry its own __interrupt__ field.\n this.setStreamValues((prev) => {\n if (\n prev &&\n \"__interrupt__\" in prev &&\n Array.isArray((prev as Record<string, unknown>).__interrupt__)\n ) {\n return {\n ...(data as StateType),\n __interrupt__: (prev as Record<string, unknown>)\n .__interrupt__,\n } as StateType;\n }\n return data as StateType;\n });\n }\n }\n }\n\n if (this.matchEventType(\"messages\", event, data)) {\n const [serialized, metadata] = data;\n\n // Check if this message is from a subagent namespace\n const eventCheckpointNs =\n namespace && isSubagentNamespace(namespace) ? namespace : undefined;\n const rawCheckpointNs =\n (metadata?.langgraph_checkpoint_ns as string | undefined) ||\n (metadata?.checkpoint_ns as string | undefined);\n const checkpointNs: string[] | undefined =\n eventCheckpointNs ??\n (typeof rawCheckpointNs === \"string\"\n ? rawCheckpointNs.split(\"|\")\n : undefined);\n const isFromSubagent = isSubagentNamespace(checkpointNs);\n const toolCallId = isFromSubagent\n ? extractToolCallIdFromNamespace(checkpointNs)\n : undefined;\n\n // If filtering is enabled and this is a subagent message,\n // add it to the subagent's messages instead of the main stream\n if (this.filterSubagentMessages && isFromSubagent && toolCallId) {\n // Add to subagent's message list\n this.subagentManager.addMessageToSubagent(\n toolCallId,\n serialized,\n metadata\n );\n continue;\n }\n\n const messageId = this.messages.add(serialized, metadata);\n if (!messageId) {\n console.warn(\n \"Failed to add message to manager, no message ID found\"\n );\n continue;\n }\n\n this.setStreamValues((streamValues) => {\n const values = {\n ...options.initialValues,\n ...streamValues,\n };\n\n // Assumption: we're concatenating the message\n let messages = options.getMessages(values).slice();\n const { chunk, index } =\n this.messages.get(messageId, messages.length) ?? {};\n\n if (!chunk || index == null) return values;\n if (chunk.getType() === \"remove\") {\n // Check for special REMOVE_ALL_MESSAGES sentinel\n if (chunk.id === REMOVE_ALL_MESSAGES) {\n // Clear all messages when __remove_all__ is received\n messages = [];\n } else {\n messages.splice(index, 1);\n }\n } else {\n const msgDict = this.toMessage(chunk) as Message;\n messages[index] = msgDict;\n\n // Track subagents from AI messages with tool calls (main agent only)\n if (\n !isFromSubagent &&\n msgDict.type === \"ai\" &&\n \"tool_calls\" in msgDict &&\n Array.isArray(msgDict.tool_calls)\n ) {\n this.subagentManager.registerFromToolCalls(\n msgDict.tool_calls,\n msgDict.id as string | undefined\n );\n }\n\n // Complete subagents when tool messages arrive (main agent only)\n if (\n !isFromSubagent &&\n msgDict.type === \"tool\" &&\n \"tool_call_id\" in msgDict\n ) {\n const tcId = msgDict.tool_call_id as string;\n const content =\n typeof msgDict.content === \"string\"\n ? msgDict.content\n : JSON.stringify(msgDict.content);\n const status =\n \"status\" in msgDict && msgDict.status === \"error\"\n ? \"error\"\n : \"success\";\n this.subagentManager.processToolMessage(tcId, content, status);\n }\n }\n\n return options.setMessages(values, messages);\n });\n }\n }\n\n if (streamError != null) throw streamError;\n\n // Skip onSuccess when the stream was aborted (e.g., by multitask interrupt).\n // This avoids unnecessary HTTP calls (like history fetching) that would\n // delay the next queued stream from starting.\n if (!this.abortRef.signal.aborted) {\n const values = await options.onSuccess?.();\n if (typeof values !== \"undefined\" && this.queueSize === 0) {\n this.setStreamValues(values);\n }\n }\n } catch (error) {\n if (\n !(\n error instanceof Error && // eslint-disable-line no-instanceof/no-instanceof\n (error.name === \"AbortError\" || error.name === \"TimeoutError\")\n )\n ) {\n console.error(error);\n this.setState({ error });\n await options.onError?.(error);\n }\n } finally {\n this.setState({ isLoading: false });\n this.abortRef = new AbortController();\n options.onFinish?.();\n }\n };\n\n start = async (\n action: (\n signal: AbortSignal\n ) => Promise<\n AsyncGenerator<\n EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >\n >\n >,\n options: {\n getMessages: (values: StateType) => Message[];\n\n setMessages: (current: StateType, messages: Message[]) => StateType;\n\n initialValues: StateType;\n\n callbacks: StreamManagerEventCallbacks<StateType, Bag>;\n\n onSuccess: () =>\n | StateType\n | null\n | undefined\n | void\n | Promise<StateType | null | undefined | void>;\n\n onError: (error: unknown) => void | Promise<void>;\n\n onFinish?: () => void;\n },\n startOptions?: {\n /**\n * If true, abort any currently running stream before starting this one.\n * Used for multitask_strategy: \"interrupt\" and \"rollback\" to unblock\n * the queue so the new run request can proceed immediately.\n */\n abortPrevious?: boolean;\n }\n ): Promise<void> => {\n if (startOptions?.abortPrevious) {\n this.abortRef.abort();\n }\n this.queueSize += 1;\n const queued = this.queue.then(() => this.enqueue(action, options));\n this.queue = queued;\n await queued;\n };\n\n stop = async (\n historyValues: StateType,\n options: {\n onStop?: (options: {\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }) => void;\n }\n ): Promise<void> => {\n this.abortRef.abort();\n this.abortRef = new AbortController();\n\n options.onStop?.({ mutate: this.getMutateFn(\"stop\", historyValues) });\n };\n\n clear = () => {\n // Cancel any running streams\n this.abortRef.abort();\n this.abortRef = new AbortController();\n\n // Set the stream state to null\n this.setState({ error: undefined, values: null, isLoading: false });\n\n // Clear any pending messages\n this.messages.clear();\n\n // Clear subagent state\n this.subagentManager.clear();\n };\n}\n"],"mappings":"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"}
{"version":3,"file":"manager.cjs","names":["toMessageDict","SubagentManager","StreamError","isSubagentNamespace","extractToolCallIdFromNamespace"],"sources":["../../src/ui/manager.ts"],"sourcesContent":["import type { BaseMessage } from \"@langchain/core/messages\";\n\nimport { DEFAULT_MESSAGES_KEY } from \"../stream/constants.js\";\nimport type {\n CheckpointsStreamEvent,\n CustomStreamEvent,\n DebugStreamEvent,\n ErrorStreamEvent,\n EventsStreamEvent,\n FeedbackStreamEvent,\n MessagesTupleStreamEvent,\n MetadataStreamEvent,\n TasksStreamEvent,\n ToolsStreamEvent,\n UpdatesStreamEvent,\n ValuesStreamEvent,\n} from \"../types.stream.js\";\nimport { MessageTupleManager, toMessageDict } from \"./messages.js\";\nimport { StreamError } from \"./errors.js\";\nimport type { Message } from \"../types.messages.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport {\n SubagentManager,\n extractToolCallIdFromNamespace,\n isSubagentNamespace,\n} from \"./subagents.js\";\nimport type { SubagentStreamInterface } from \"./types.js\";\n\n/**\n * Special ID used by LangGraph's messagesStateReducer to signal\n * that all messages should be removed from the state.\n */\nexport const REMOVE_ALL_MESSAGES = \"__remove_all__\";\n\ntype GetUpdateType<\n Bag extends BagTemplate,\n StateType extends Record<string, unknown>,\n> = Bag extends { UpdateType: unknown }\n ? Bag[\"UpdateType\"]\n : Partial<StateType>;\n\ntype GetCustomEventType<Bag extends BagTemplate> = Bag extends {\n CustomEventType: unknown;\n}\n ? Bag[\"CustomEventType\"]\n : unknown;\n\ntype EventStreamMap<StateType, UpdateType, CustomType> = {\n values: ValuesStreamEvent<StateType>;\n updates: UpdatesStreamEvent<UpdateType>;\n custom: CustomStreamEvent<CustomType>;\n debug: DebugStreamEvent;\n messages: MessagesTupleStreamEvent;\n events: EventsStreamEvent;\n metadata: MetadataStreamEvent;\n checkpoints: CheckpointsStreamEvent<StateType>;\n tasks: TasksStreamEvent<StateType, UpdateType>;\n error: ErrorStreamEvent;\n feedback: FeedbackStreamEvent;\n tools: ToolsStreamEvent;\n};\n\nexport type EventStreamEvent<StateType, UpdateType, CustomType> =\n EventStreamMap<StateType, UpdateType, CustomType>[keyof EventStreamMap<\n StateType,\n UpdateType,\n CustomType\n >];\n\ninterface StreamManagerEventCallbacks<\n StateType extends Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n> {\n onUpdateEvent?: (\n data: UpdatesStreamEvent<GetUpdateType<Bag, StateType>>[\"data\"],\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n onCustomEvent?: (\n data: GetCustomEventType<Bag>,\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n onMetadataEvent?: (data: MetadataStreamEvent[\"data\"]) => void;\n onLangChainEvent?: (data: EventsStreamEvent[\"data\"]) => void;\n onDebugEvent?: (\n data: DebugStreamEvent[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onCheckpointEvent?: (\n data: CheckpointsStreamEvent<StateType>[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onTaskEvent?: (\n data: TasksStreamEvent<StateType, GetUpdateType<Bag, StateType>>[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onToolEvent?: (\n data: ToolsStreamEvent[\"data\"],\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n}\n\n/**\n * Options for StreamManager constructor.\n */\nexport interface StreamManagerOptions {\n /**\n * Throttle the stream updates.\n * If a number is provided, updates are throttled to the given milliseconds.\n * If `true`, updates are batched in a single macrotask.\n * If `false`, updates are not throttled.\n */\n throttle: number | boolean;\n\n /**\n * Tool names that indicate subagent invocation.\n *\n * When an AI message contains tool calls with these names, they are\n * automatically tracked as subagent executions. This enables the\n * `subagents`, `activeSubagents`, `getSubagent()`, and `getSubagentsByType()`\n * properties on the stream.\n *\n * @default [\"task\"]\n *\n * @example\n * ```typescript\n * // Track both \"task\" and \"delegate\" as subagent tools\n * subagentToolNames: [\"task\", \"delegate\", \"spawn_agent\"]\n * ```\n */\n subagentToolNames?: string[];\n\n /**\n * Filter out messages from subagent streams in the main messages array.\n *\n * When enabled, messages from subagraph executions (those with a `tools:` namespace)\n * are excluded from `stream.messages`. Instead, these messages are tracked\n * per-subagent and accessible via `stream.subagents.get(id).messages`.\n *\n * This is useful for deep agent architectures where you want to display\n * the main conversation separately from subagent activity.\n *\n * @default false\n *\n * @example\n * ```typescript\n * const stream = useStream({\n * assistantId: \"my-agent\",\n * filterSubagentMessages: true,\n * });\n *\n * // Main thread messages only (no subagent messages)\n * stream.messages\n *\n * // Access subagent messages individually\n * stream.subagents.get(\"call_xyz\").messages\n * ```\n */\n filterSubagentMessages?: boolean;\n\n /**\n * Converts a @langchain/core BaseMessage to the desired output format.\n *\n * Defaults to `toMessageDict` which produces plain Message objects.\n * Framework SDKs pass `toMessageClass` (identity) to keep class instances.\n */\n toMessage?: (chunk: BaseMessage) => Message | BaseMessage;\n}\n\nexport class StreamManager<\n StateType extends Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n> {\n private abortRef = new AbortController();\n\n private messages: MessageTupleManager;\n\n private subagentManager: SubagentManager;\n\n private listeners = new Set<() => void>();\n\n private throttle: number | boolean;\n\n private filterSubagentMessages: boolean;\n\n private toMessage: (chunk: BaseMessage) => Message | BaseMessage;\n\n private queue: Promise<unknown> = Promise.resolve();\n\n private queueSize: number = 0;\n\n private state: {\n isLoading: boolean;\n values: [values: StateType, kind: \"stream\" | \"stop\"] | null;\n error: unknown;\n /** Version counter to force React re-renders on subagent changes */\n version: number;\n };\n\n constructor(messages: MessageTupleManager, options: StreamManagerOptions) {\n this.messages = messages;\n this.state = {\n isLoading: false,\n values: null,\n error: undefined,\n version: 0,\n };\n this.throttle = options.throttle;\n this.filterSubagentMessages = options.filterSubagentMessages ?? false;\n this.toMessage = options.toMessage ?? toMessageDict;\n this.subagentManager = new SubagentManager({\n subagentToolNames: options.subagentToolNames,\n onSubagentChange: () => this.bumpVersion(),\n toMessage: this.toMessage,\n });\n }\n\n /**\n * Increment version counter to trigger React re-renders.\n * Called when subagent state changes.\n */\n private bumpVersion = () => {\n this.state = { ...this.state, version: this.state.version + 1 };\n this.notifyListeners();\n };\n\n /**\n * Get all subagents as a Map.\n */\n getSubagents(): Map<string, SubagentStreamInterface> {\n return this.subagentManager.getSubagents();\n }\n\n /**\n * Get all currently running subagents.\n */\n getActiveSubagents(): SubagentStreamInterface[] {\n return this.subagentManager.getActiveSubagents();\n }\n\n /**\n * Get a specific subagent by tool call ID.\n */\n getSubagent(toolCallId: string): SubagentStreamInterface | undefined {\n return this.subagentManager.getSubagent(toolCallId);\n }\n\n /**\n * Get all subagents of a specific type.\n */\n getSubagentsByType(type: string): SubagentStreamInterface[] {\n return this.subagentManager.getSubagentsByType(type);\n }\n\n /**\n * Get all subagents triggered by a specific AI message.\n */\n getSubagentsByMessage(messageId: string): SubagentStreamInterface[] {\n return this.subagentManager.getSubagentsByMessage(messageId);\n }\n\n /**\n * Reconstruct subagent state from historical messages.\n *\n * This method should be called when loading thread history to restore\n * subagent visualization after:\n * - Page refresh (when stream has already completed)\n * - Loading thread history\n * - Navigating between threads\n *\n * @param messages - Array of messages from thread history\n * @param options - Optional configuration\n * @param options.skipIfPopulated - If true, skip reconstruction if subagents already exist\n */\n reconstructSubagents(\n messages: Message[],\n options?: { skipIfPopulated?: boolean }\n ): void {\n this.subagentManager.reconstructFromMessages(messages, options);\n }\n\n /**\n * Fetch and restore internal messages for reconstructed subagents from their\n * subgraph checkpoints. Should be called after `reconstructSubagents` to\n * restore the full subagent conversation after a page refresh.\n *\n * Subagent messages are persisted in the LangGraph checkpointer under a\n * subgraph-specific `checkpoint_ns` (e.g. `tools:<uuid>`). This method\n * discovers the correct namespace by inspecting the main thread's intermediate\n * history checkpoints, where each pending task's `checkpoint.checkpoint_ns`\n * identifies the subgraph. Tasks are matched to tool calls by their Send index\n * (`task.path[1]`), which corresponds to the order of tool calls in the AI\n * message — no deepagent-specific metadata required.\n *\n * @param threads - Client with a `getHistory` method (e.g. `client.threads`)\n * @param threadId - The parent thread ID\n * @param options - Optional configuration\n * @param options.messagesKey - Key in state values containing messages (default: \"messages\")\n * @param options.signal - AbortSignal to cancel in-flight requests on effect cleanup\n */\n async fetchSubagentHistory(\n threads: {\n getHistory<V extends Record<string, unknown>>(\n threadId: string,\n options?: {\n limit?: number;\n checkpoint?: { checkpoint_ns?: string };\n signal?: AbortSignal;\n }\n ): Promise<\n Array<{\n values: V;\n tasks?: Array<{\n id: string;\n name: string;\n path?: unknown[];\n checkpoint?: { checkpoint_ns?: string } | null;\n }>;\n }>\n >;\n },\n threadId: string,\n options?: {\n messagesKey?: string;\n historyLimit?: number;\n signal?: AbortSignal;\n }\n ): Promise<void> {\n const messagesKey = options?.messagesKey ?? DEFAULT_MESSAGES_KEY;\n const signal = options?.signal;\n\n /**\n * Bail immediately if already cancelled (React Strict Mode cleanup)\n */\n if (signal?.aborted) {\n return;\n }\n\n /**\n * Only fetch for subagents that have no messages (reconstructed from history)\n */\n const toFetch = [...this.subagentManager.getSubagents().entries()].filter(\n ([, s]) => s.messages.length === 0\n );\n\n /**\n * Bail immediately if there are no subagents to fetch\n */\n if (toFetch.length === 0) {\n return;\n }\n\n /**\n * Step 1: Discover subgraph namespaces from intermediate history\n *\n * When LangGraph dispatches parallel tool calls (v2 mode), each is a\n * separate Send task with a unique UUID-based checkpoint_ns. The intermediate\n * history checkpoints record these as `tasks[i]` where:\n * - `tasks[i].checkpoint.checkpoint_ns` = \"tools:<uuid>\" for each subgraph\n * - `tasks[i].path = [\"__pregel_push\", sendIndex]` matches tool_calls order\n *\n * By matching task Send index → tool_call position in the AI message we can\n * derive the subgraph namespace for every tool call without any external\n * metadata on the ToolMessage itself.\n */\n const toolCallIdToNamespace = new Map<string, string>();\n\n try {\n /**\n * Fetch enough history to include the intermediate checkpoint where\n * tool-call tasks were pending (typically within the last 10 checkpoints).\n */\n const mainHistory = await threads.getHistory<Record<string, unknown>>(\n threadId,\n { limit: options?.historyLimit ?? 20, signal }\n );\n\n /**\n * Phase 1: Direct mapping across ALL checkpoints (preferred).\n *\n * When a completed checkpoint contains task results, each task.result\n * has a ToolMessage whose tool_call_id directly and unambiguously maps\n * the task to the LLM tool call that triggered it. This is more robust\n * than positional alignment: it works even when a step mixes subagent\n * tool calls with other tool calls, and requires no assumptions about\n * the ordering of tasks vs tool_calls.\n *\n * We collect these direct mappings across the entire history before\n * attempting any positional fallback. Otherwise a more recent checkpoint\n * whose task is still pending (e.g. an interrupted run) could produce a\n * positional guess and stop the scan before reaching the older checkpoint\n * that actually holds the correct, completed mapping.\n *\n * LangGraph v2 dispatches each parallel tool call as a separate PUSH\n * task (\"__pregel_push\"). The subgraph checkpoint_ns is constructed as\n * `task.name + \":\" + task.id`, mirroring algo.ts:\n * taskCheckpointNamespace = checkpointNamespace + \":\" + taskId\n * where checkpointNamespace = task.name for root-level tasks.\n *\n * task.checkpoint is always null for completed tasks, so we derive the\n * namespace from task.name + task.id rather than task.checkpoint.checkpoint_ns.\n */\n for (const checkpoint of mainHistory) {\n const { tasks } = checkpoint;\n if (!tasks || tasks.length === 0) {\n continue;\n }\n\n for (const task of tasks) {\n if (\n !Array.isArray(task.path) ||\n task.path[0] !== \"__pregel_push\" ||\n typeof task.id !== \"string\" ||\n typeof task.name !== \"string\"\n ) {\n continue;\n }\n\n /**\n * Read tool_call_id directly from the task's result ToolMessage.\n */\n const resultMessages = (\n task as unknown as { result?: { messages?: unknown[] } }\n ).result?.messages;\n\n if (!Array.isArray(resultMessages)) {\n continue;\n }\n\n for (const msg of resultMessages) {\n const m = msg as Record<string, unknown>;\n if (\n m.type === \"tool\" &&\n typeof m.tool_call_id === \"string\" &&\n toFetch.some(([id]) => id === m.tool_call_id) &&\n !toolCallIdToNamespace.has(m.tool_call_id)\n ) {\n toolCallIdToNamespace.set(\n m.tool_call_id,\n `${task.name}:${task.id}`\n );\n }\n }\n }\n }\n\n /**\n * Phase 2: Positional fallback, applied ONLY to tool calls that Phase 1\n * could not resolve.\n *\n * This covers checkpoints whose task results are not yet populated (tasks\n * still pending — the live or just-interrupted case). We align push tasks\n * to the subagent tool calls of the triggering AI message by Send index\n * (task.path[1]). Restricting this to still-unmapped tool calls guarantees\n * a correct direct mapping from Phase 1 is never overwritten by a guess.\n */\n const hasUnmappedToolCalls = () =>\n toFetch.some(([id]) => !toolCallIdToNamespace.has(id));\n\n if (hasUnmappedToolCalls()) {\n for (const checkpoint of mainHistory) {\n if (!hasUnmappedToolCalls()) break;\n\n const { tasks } = checkpoint;\n if (!tasks || tasks.length === 0) {\n continue;\n }\n\n const pushTasks = tasks.filter(\n (t) =>\n Array.isArray(t.path) &&\n t.path[0] === \"__pregel_push\" &&\n typeof t.path[1] === \"number\" &&\n typeof t.id === \"string\" &&\n typeof t.name === \"string\"\n );\n if (pushTasks.length === 0) continue;\n\n /**\n * Find the AI message with subagent tool calls to align by Send index.\n */\n const msgs = checkpoint.values[messagesKey];\n if (!Array.isArray(msgs)) continue;\n\n let aiMessage: Record<string, unknown> | undefined;\n for (let i = msgs.length - 1; i >= 0; i -= 1) {\n const m = msgs[i] as Record<string, unknown>;\n if (\n m.type === \"ai\" &&\n Array.isArray(m.tool_calls) &&\n m.tool_calls.length > 0 &&\n (m.tool_calls as Array<{ name: string }>).some((tc) =>\n this.subagentManager.isSubagentToolCall(tc.name)\n )\n ) {\n aiMessage = m;\n break;\n }\n }\n if (!aiMessage) {\n continue;\n }\n\n /**\n * Only consider subagent tool calls from the AI message — not all tool\n * calls. This ensures regular tool calls (searchWeb, queryDatabase, etc.)\n * are never mistaken for subagents even when they appear in the same step.\n */\n const subagentToolCalls = (\n aiMessage.tool_calls as Array<{ id?: string; name: string }>\n ).filter((tc) => this.subagentManager.isSubagentToolCall(tc.name));\n\n if (subagentToolCalls.length === 0) {\n continue;\n }\n\n /**\n * Sort push tasks by Send index (path[1]) to align with tool_calls order\n */\n const sorted = [...pushTasks].sort((a, b) => {\n const ai = Array.isArray(a.path) ? (a.path[1] as number) : 0;\n const bi = Array.isArray(b.path) ? (b.path[1] as number) : 0;\n return ai - bi;\n });\n\n for (\n let i = 0;\n i < sorted.length && i < subagentToolCalls.length;\n i += 1\n ) {\n const tc = subagentToolCalls[i];\n const task = sorted[i];\n if (\n tc?.id &&\n task.id &&\n task.name &&\n toFetch.some(([id]) => id === tc.id) &&\n !toolCallIdToNamespace.has(tc.id)\n ) {\n toolCallIdToNamespace.set(tc.id, `${task.name}:${task.id}`);\n }\n }\n }\n }\n } catch {\n /**\n * Non-fatal: fall back to subagent.namespace below\n */\n }\n\n /**\n * Step 2: Fetch each subagent's conversation from its subgraph checkpoint\n */\n await Promise.all(\n toFetch.map(async ([toolCallId, subagent]) => {\n /**\n * Priority order for the subgraph checkpoint_ns:\n * 1. Derived from main thread's intermediate task list (preferred, no coupling)\n * 2. Already on the subagent's namespace (e.g. populated during streaming)\n * 3. Skip — we cannot reliably identify the namespace\n */\n const checkpointNs =\n toolCallIdToNamespace.get(toolCallId) ??\n (subagent.namespace.length > 0\n ? subagent.namespace.join(\"|\")\n : undefined);\n\n if (!checkpointNs) return;\n\n try {\n const history = await threads.getHistory<Record<string, unknown>>(\n threadId,\n {\n checkpoint: { checkpoint_ns: checkpointNs },\n limit: 1,\n signal,\n }\n );\n\n /**\n * If the HTTP request was cancelled mid-flight the getHistory call\n * would have thrown an AbortError (caught below). If we reach here the\n * fetch completed successfully, so always process the result.\n */\n const latestState = history[0];\n if (!latestState?.values) return;\n\n const messages = latestState.values[messagesKey];\n if (!Array.isArray(messages) || messages.length === 0) return;\n\n /**\n * Normalize messages: promote tool_calls from additional_kwargs to top\n * level when the checkpointer serialized them in the legacy format.\n */\n const normalizedMessages = messages.map((msg) => {\n const m = msg as Record<string, unknown>;\n if (\n m.type === \"ai\" &&\n (!m.tool_calls || (m.tool_calls as unknown[]).length === 0)\n ) {\n const ak = m.additional_kwargs as\n | Record<string, unknown>\n | undefined;\n const legacy = ak?.tool_calls;\n if (Array.isArray(legacy) && legacy.length > 0) {\n return { ...m, tool_calls: legacy };\n }\n }\n return m;\n });\n\n this.subagentManager.updateSubagentFromSubgraphState(\n toolCallId,\n normalizedMessages as Message[],\n latestState.values\n );\n } catch {\n /**\n * Ignore AbortError and other transient errors\n */\n }\n })\n );\n }\n\n /**\n * Check if any subagents are currently tracked.\n */\n hasSubagents(): boolean {\n return this.subagentManager.hasSubagents();\n }\n\n private setState = (newState: Partial<typeof this.state>) => {\n this.state = { ...this.state, ...newState };\n this.notifyListeners();\n };\n\n private notifyListeners = () => {\n this.listeners.forEach((listener) => listener());\n };\n\n subscribe = (listener: () => void): (() => void) => {\n if (this.throttle === false) {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n const timeoutMs = this.throttle === true ? 0 : this.throttle;\n let timeoutId: NodeJS.Timeout | number | undefined;\n\n const throttledListener = () => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n clearTimeout(timeoutId);\n listener();\n }, timeoutMs);\n };\n\n this.listeners.add(throttledListener);\n return () => {\n clearTimeout(timeoutId);\n this.listeners.delete(throttledListener);\n };\n };\n\n getSnapshot = () => this.state;\n\n get isLoading() {\n return this.state.isLoading;\n }\n\n get values() {\n return this.state.values?.[0] ?? null;\n }\n\n get error() {\n return this.state.error;\n }\n\n setStreamValues = (\n values:\n | (StateType | null)\n | ((prev: StateType | null, kind: \"stream\" | \"stop\") => StateType | null),\n kind: \"stream\" | \"stop\" = \"stream\"\n ) => {\n if (typeof values === \"function\") {\n const [prevValues, prevKind] = this.state.values ?? [null, \"stream\"];\n const nextValues = values(prevValues, prevKind);\n this.setState({ values: nextValues != null ? [nextValues, kind] : null });\n } else {\n const nextValues = values != null ? [values, kind] : null;\n this.setState({ values: nextValues as [StateType, \"stream\" | \"stop\"] });\n }\n };\n\n private getMutateFn = (kind: \"stream\" | \"stop\", historyValues: StateType) => {\n return (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => {\n const stateValues = (this.state.values ?? [null, \"stream\"])[0];\n const prev = {\n ...historyValues,\n ...stateValues,\n };\n const next = typeof update === \"function\" ? update(prev) : update;\n this.setStreamValues({ ...prev, ...next }, kind);\n };\n };\n\n private matchEventType = <\n T extends keyof EventStreamMap<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >,\n >(\n expected: T,\n actual: EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[\"event\"],\n _data: EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[\"data\"]\n ): _data is EventStreamMap<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[T][\"data\"] => {\n return expected === actual || actual.startsWith(`${expected}|`);\n };\n\n protected enqueue = async (\n action: (\n signal: AbortSignal\n ) => Promise<\n AsyncGenerator<\n EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >\n >\n >,\n options: {\n getMessages: (values: StateType) => Message[];\n\n setMessages: (current: StateType, messages: Message[]) => StateType;\n\n initialValues: StateType;\n\n callbacks: StreamManagerEventCallbacks<StateType, Bag>;\n\n onSuccess: () =>\n | StateType\n | null\n | undefined\n | void\n | Promise<StateType | null | undefined | void>;\n\n onError: (error: unknown) => void | Promise<void>;\n\n onFinish?: () => void;\n }\n ) => {\n try {\n this.queueSize = Math.max(0, this.queueSize - 1);\n this.setState({ isLoading: true, error: undefined });\n this.abortRef = new AbortController();\n\n const run = await action(this.abortRef.signal);\n let clearedPreviousInterrupts = false;\n\n let streamError: StreamError | undefined;\n for await (const { event, data } of run) {\n if (event === \"error\") {\n streamError = new StreamError(data);\n break;\n }\n\n const namespace = event.includes(\"|\")\n ? event.split(\"|\").slice(1)\n : undefined;\n\n const mutate = this.getMutateFn(\"stream\", options.initialValues);\n\n if (event === \"metadata\") options.callbacks.onMetadataEvent?.(data);\n if (event === \"events\") options.callbacks.onLangChainEvent?.(data);\n\n if (this.matchEventType(\"updates\", event, data)) {\n options.callbacks.onUpdateEvent?.(data, { namespace, mutate });\n\n // Track subagent streaming updates from subgraph namespaces\n // Mark the subagent as running when we receive updates\n // The actual message content is handled via addMessageToSubagent\n if (namespace && isSubagentNamespace(namespace)) {\n const namespaceId = extractToolCallIdFromNamespace(namespace);\n if (namespaceId && this.filterSubagentMessages) {\n this.subagentManager.markRunningFromNamespace(\n namespaceId,\n namespace\n );\n }\n }\n\n // Also register subagents from main agent updates (tool_calls in messages)\n // AND process tool results to complete subagents\n // This is needed because tool_calls often appear complete in updates\n // before they appear in the messages stream\n if (!namespace || !isSubagentNamespace(namespace)) {\n const updateData = data as Record<string, unknown>;\n for (const nodeData of Object.values(updateData)) {\n if (\n nodeData &&\n typeof nodeData === \"object\" &&\n \"messages\" in nodeData\n ) {\n const { messages } = nodeData as { messages: unknown[] };\n if (Array.isArray(messages)) {\n for (const msg of messages) {\n if (!msg || typeof msg !== \"object\") continue;\n const msgObj = msg as Record<string, unknown>;\n\n // Register subagents from AI messages with tool_calls\n if (\n msgObj.type === \"ai\" &&\n \"tool_calls\" in msgObj &&\n Array.isArray(msgObj.tool_calls)\n ) {\n this.subagentManager.registerFromToolCalls(\n msgObj.tool_calls as Array<{\n id?: string;\n name: string;\n args: Record<string, unknown> | string;\n }>,\n msgObj.id as string | undefined\n );\n }\n\n // Complete subagents from tool messages (task results)\n if (\n msgObj.type === \"tool\" &&\n \"tool_call_id\" in msgObj &&\n typeof msgObj.tool_call_id === \"string\"\n ) {\n const content =\n typeof msgObj.content === \"string\"\n ? msgObj.content\n : JSON.stringify(msgObj.content);\n const status =\n \"status\" in msgObj && msgObj.status === \"error\"\n ? \"error\"\n : \"success\";\n this.subagentManager.processToolMessage(\n msgObj.tool_call_id,\n content,\n status\n );\n }\n }\n }\n }\n }\n }\n }\n\n if (this.matchEventType(\"custom\", event, data)) {\n options.callbacks.onCustomEvent?.(data, { namespace, mutate });\n }\n\n if (this.matchEventType(\"checkpoints\", event, data)) {\n options.callbacks.onCheckpointEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"tasks\", event, data)) {\n options.callbacks.onTaskEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"debug\", event, data)) {\n options.callbacks.onDebugEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"tools\", event, data)) {\n options.callbacks.onToolEvent?.(data, { namespace, mutate });\n }\n\n // Handle values events - use startsWith to match both \"values\" and \"values|tools:xxx\"\n if (event === \"values\" || event.startsWith(\"values|\")) {\n // Check if this is a subgraph values event (for namespace mapping and values)\n if (namespace && isSubagentNamespace(namespace)) {\n const namespaceId = extractToolCallIdFromNamespace(namespace);\n if (namespaceId && this.filterSubagentMessages) {\n const valuesData = data as Record<string, unknown>;\n\n // Try to establish namespace mapping from the initial human message\n const messages = valuesData.messages as unknown[];\n if (Array.isArray(messages) && messages.length > 0) {\n const firstMsg = messages[0] as Record<string, unknown>;\n if (\n firstMsg?.type === \"human\" &&\n typeof firstMsg?.content === \"string\"\n ) {\n this.subagentManager.matchSubgraphToSubagent(\n namespaceId,\n firstMsg.content\n );\n }\n }\n\n // Update the subagent's values with the full state\n this.subagentManager.updateSubagentValues(\n namespaceId,\n valuesData\n );\n }\n } else {\n if (!clearedPreviousInterrupts) {\n // Clear stale __interrupt__ from the previous run once the new\n // stream starts delivering main values. This avoids carrying\n // resumed interrupts forward while still preserving the previous\n // interrupt state if the new stream fails before any values\n // arrive.\n this.setStreamValues((prev) => {\n if (prev && \"__interrupt__\" in prev) {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { __interrupt__, ...rest } = prev;\n return rest as StateType;\n }\n return prev;\n });\n clearedPreviousInterrupts = true;\n }\n\n if (data && typeof data === \"object\" && \"__interrupt__\" in data) {\n // When parallel branches each raise an interrupt, the backend\n // may stream separate values events per branch. We accumulate\n // the __interrupt__ arrays so none are lost, but still honor an\n // explicit empty array as \"clear interrupts\".\n const interruptData = data as Partial<StateType> & {\n __interrupt__?: Array<{ id?: string }>;\n };\n this.setStreamValues((prev) => {\n const prevInterrupts = (\n prev as\n | (StateType & { __interrupt__?: Array<{ id?: string }> })\n | null\n )?.__interrupt__;\n\n let interrupts = interruptData.__interrupt__;\n if (Array.isArray(interrupts)) {\n if (interrupts.length === 0) {\n interrupts = [];\n } else if (Array.isArray(prevInterrupts)) {\n const mergedInterrupts = [...prevInterrupts];\n const existingIds = new Set(\n prevInterrupts.map((i) => i.id).filter((id) => id != null)\n );\n for (const interrupt of interrupts) {\n if (interrupt.id != null) {\n if (existingIds.has(interrupt.id)) continue;\n existingIds.add(interrupt.id);\n }\n mergedInterrupts.push(interrupt);\n }\n interrupts = mergedInterrupts;\n }\n }\n\n return {\n ...prev,\n __interrupt__: interrupts,\n } as unknown as StateType;\n });\n } else {\n // Non-interrupt values events must not wipe accumulated\n // __interrupt__ state. Preserve it when the incoming data\n // does not carry its own __interrupt__ field.\n this.setStreamValues((prev) => {\n if (\n prev &&\n \"__interrupt__\" in prev &&\n Array.isArray((prev as Record<string, unknown>).__interrupt__)\n ) {\n return {\n ...(data as StateType),\n __interrupt__: (prev as Record<string, unknown>)\n .__interrupt__,\n } as StateType;\n }\n return data as StateType;\n });\n }\n }\n }\n\n if (this.matchEventType(\"messages\", event, data)) {\n const [serialized, metadata] = data;\n\n // Check if this message is from a subagent namespace\n const eventCheckpointNs =\n namespace && isSubagentNamespace(namespace) ? namespace : undefined;\n const rawCheckpointNs =\n (metadata?.langgraph_checkpoint_ns as string | undefined) ||\n (metadata?.checkpoint_ns as string | undefined);\n const checkpointNs: string[] | undefined =\n eventCheckpointNs ??\n (typeof rawCheckpointNs === \"string\"\n ? rawCheckpointNs.split(\"|\")\n : undefined);\n const isFromSubagent = isSubagentNamespace(checkpointNs);\n const toolCallId = isFromSubagent\n ? extractToolCallIdFromNamespace(checkpointNs)\n : undefined;\n\n // If filtering is enabled and this is a subagent message,\n // add it to the subagent's messages instead of the main stream\n if (this.filterSubagentMessages && isFromSubagent && toolCallId) {\n // Add to subagent's message list\n this.subagentManager.addMessageToSubagent(\n toolCallId,\n serialized,\n metadata\n );\n continue;\n }\n\n const messageId = this.messages.add(serialized, metadata);\n if (!messageId) {\n console.warn(\n \"Failed to add message to manager, no message ID found\"\n );\n continue;\n }\n\n this.setStreamValues((streamValues) => {\n const values = {\n ...options.initialValues,\n ...streamValues,\n };\n\n // Assumption: we're concatenating the message\n let messages = options.getMessages(values).slice();\n const { chunk, index } =\n this.messages.get(messageId, messages.length) ?? {};\n\n if (!chunk || index == null) return values;\n if (chunk.getType() === \"remove\") {\n // Check for special REMOVE_ALL_MESSAGES sentinel\n if (chunk.id === REMOVE_ALL_MESSAGES) {\n // Clear all messages when __remove_all__ is received\n messages = [];\n } else {\n messages.splice(index, 1);\n }\n } else {\n const msgDict = this.toMessage(chunk) as Message;\n messages[index] = msgDict;\n\n // Track subagents from AI messages with tool calls (main agent only)\n if (\n !isFromSubagent &&\n msgDict.type === \"ai\" &&\n \"tool_calls\" in msgDict &&\n Array.isArray(msgDict.tool_calls)\n ) {\n this.subagentManager.registerFromToolCalls(\n msgDict.tool_calls,\n msgDict.id as string | undefined\n );\n }\n\n // Complete subagents when tool messages arrive (main agent only)\n if (\n !isFromSubagent &&\n msgDict.type === \"tool\" &&\n \"tool_call_id\" in msgDict\n ) {\n const tcId = msgDict.tool_call_id as string;\n const content =\n typeof msgDict.content === \"string\"\n ? msgDict.content\n : JSON.stringify(msgDict.content);\n const status =\n \"status\" in msgDict && msgDict.status === \"error\"\n ? \"error\"\n : \"success\";\n this.subagentManager.processToolMessage(tcId, content, status);\n }\n }\n\n return options.setMessages(values, messages);\n });\n }\n }\n\n if (streamError != null) throw streamError;\n\n // Skip onSuccess when the stream was aborted (e.g., by multitask interrupt).\n // This avoids unnecessary HTTP calls (like history fetching) that would\n // delay the next queued stream from starting.\n if (!this.abortRef.signal.aborted) {\n const values = await options.onSuccess?.();\n if (typeof values !== \"undefined\" && this.queueSize === 0) {\n this.setStreamValues(values);\n }\n }\n } catch (error) {\n if (\n !(\n error instanceof Error && // eslint-disable-line no-instanceof/no-instanceof\n (error.name === \"AbortError\" || error.name === \"TimeoutError\")\n )\n ) {\n console.error(error);\n this.setState({ error });\n await options.onError?.(error);\n }\n } finally {\n this.setState({ isLoading: false });\n this.abortRef = new AbortController();\n options.onFinish?.();\n }\n };\n\n start = async (\n action: (\n signal: AbortSignal\n ) => Promise<\n AsyncGenerator<\n EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >\n >\n >,\n options: {\n getMessages: (values: StateType) => Message[];\n\n setMessages: (current: StateType, messages: Message[]) => StateType;\n\n initialValues: StateType;\n\n callbacks: StreamManagerEventCallbacks<StateType, Bag>;\n\n onSuccess: () =>\n | StateType\n | null\n | undefined\n | void\n | Promise<StateType | null | undefined | void>;\n\n onError: (error: unknown) => void | Promise<void>;\n\n onFinish?: () => void;\n },\n startOptions?: {\n /**\n * If true, abort any currently running stream before starting this one.\n * Used for multitask_strategy: \"interrupt\" and \"rollback\" to unblock\n * the queue so the new run request can proceed immediately.\n */\n abortPrevious?: boolean;\n }\n ): Promise<void> => {\n if (startOptions?.abortPrevious) {\n this.abortRef.abort();\n }\n this.queueSize += 1;\n const queued = this.queue.then(() => this.enqueue(action, options));\n this.queue = queued;\n await queued;\n };\n\n stop = async (\n historyValues: StateType,\n options: {\n onStop?: (options: {\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }) => void;\n }\n ): Promise<void> => {\n this.abortRef.abort();\n this.abortRef = new AbortController();\n\n options.onStop?.({ mutate: this.getMutateFn(\"stop\", historyValues) });\n };\n\n clear = () => {\n // Cancel any running streams\n this.abortRef.abort();\n this.abortRef = new AbortController();\n\n // Set the stream state to null\n this.setState({ error: undefined, values: null, isLoading: false });\n\n // Clear any pending messages\n this.messages.clear();\n\n // Clear subagent state\n this.subagentManager.clear();\n };\n}\n"],"mappings":"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"}

@@ -1,1 +0,1 @@

{"version":3,"file":"manager.d.cts","names":[],"sources":["../../src/ui/manager.ts"],"mappings":"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"}
{"version":3,"file":"manager.d.cts","names":[],"sources":["../../src/ui/manager.ts"],"mappings":"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"}

@@ -1,1 +0,1 @@

{"version":3,"file":"manager.d.ts","names":[],"sources":["../../src/ui/manager.ts"],"mappings":"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"}
{"version":3,"file":"manager.d.ts","names":[],"sources":["../../src/ui/manager.ts"],"mappings":"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"}

@@ -0,1 +1,2 @@

import "../stream/constants.js";
import { toMessageDict } from "./messages.js";

@@ -2,0 +3,0 @@ import { StreamError } from "./errors.js";

@@ -1,1 +0,1 @@

{"version":3,"file":"manager.js","names":[],"sources":["../../src/ui/manager.ts"],"sourcesContent":["import type { BaseMessage } from \"@langchain/core/messages\";\n\nimport type {\n CheckpointsStreamEvent,\n CustomStreamEvent,\n DebugStreamEvent,\n ErrorStreamEvent,\n EventsStreamEvent,\n FeedbackStreamEvent,\n MessagesTupleStreamEvent,\n MetadataStreamEvent,\n TasksStreamEvent,\n ToolsStreamEvent,\n UpdatesStreamEvent,\n ValuesStreamEvent,\n} from \"../types.stream.js\";\nimport { MessageTupleManager, toMessageDict } from \"./messages.js\";\nimport { StreamError } from \"./errors.js\";\nimport type { Message } from \"../types.messages.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport {\n SubagentManager,\n extractToolCallIdFromNamespace,\n isSubagentNamespace,\n} from \"./subagents.js\";\nimport type { SubagentStreamInterface } from \"./types.js\";\n\n/**\n * Special ID used by LangGraph's messagesStateReducer to signal\n * that all messages should be removed from the state.\n */\nexport const REMOVE_ALL_MESSAGES = \"__remove_all__\";\n\ntype GetUpdateType<\n Bag extends BagTemplate,\n StateType extends Record<string, unknown>,\n> = Bag extends { UpdateType: unknown }\n ? Bag[\"UpdateType\"]\n : Partial<StateType>;\n\ntype GetCustomEventType<Bag extends BagTemplate> = Bag extends {\n CustomEventType: unknown;\n}\n ? Bag[\"CustomEventType\"]\n : unknown;\n\ntype EventStreamMap<StateType, UpdateType, CustomType> = {\n values: ValuesStreamEvent<StateType>;\n updates: UpdatesStreamEvent<UpdateType>;\n custom: CustomStreamEvent<CustomType>;\n debug: DebugStreamEvent;\n messages: MessagesTupleStreamEvent;\n events: EventsStreamEvent;\n metadata: MetadataStreamEvent;\n checkpoints: CheckpointsStreamEvent<StateType>;\n tasks: TasksStreamEvent<StateType, UpdateType>;\n error: ErrorStreamEvent;\n feedback: FeedbackStreamEvent;\n tools: ToolsStreamEvent;\n};\n\nexport type EventStreamEvent<StateType, UpdateType, CustomType> =\n EventStreamMap<StateType, UpdateType, CustomType>[keyof EventStreamMap<\n StateType,\n UpdateType,\n CustomType\n >];\n\ninterface StreamManagerEventCallbacks<\n StateType extends Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n> {\n onUpdateEvent?: (\n data: UpdatesStreamEvent<GetUpdateType<Bag, StateType>>[\"data\"],\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n onCustomEvent?: (\n data: GetCustomEventType<Bag>,\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n onMetadataEvent?: (data: MetadataStreamEvent[\"data\"]) => void;\n onLangChainEvent?: (data: EventsStreamEvent[\"data\"]) => void;\n onDebugEvent?: (\n data: DebugStreamEvent[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onCheckpointEvent?: (\n data: CheckpointsStreamEvent<StateType>[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onTaskEvent?: (\n data: TasksStreamEvent<StateType, GetUpdateType<Bag, StateType>>[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onToolEvent?: (\n data: ToolsStreamEvent[\"data\"],\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n}\n\n/**\n * Options for StreamManager constructor.\n */\nexport interface StreamManagerOptions {\n /**\n * Throttle the stream updates.\n * If a number is provided, updates are throttled to the given milliseconds.\n * If `true`, updates are batched in a single macrotask.\n * If `false`, updates are not throttled.\n */\n throttle: number | boolean;\n\n /**\n * Tool names that indicate subagent invocation.\n *\n * When an AI message contains tool calls with these names, they are\n * automatically tracked as subagent executions. This enables the\n * `subagents`, `activeSubagents`, `getSubagent()`, and `getSubagentsByType()`\n * properties on the stream.\n *\n * @default [\"task\"]\n *\n * @example\n * ```typescript\n * // Track both \"task\" and \"delegate\" as subagent tools\n * subagentToolNames: [\"task\", \"delegate\", \"spawn_agent\"]\n * ```\n */\n subagentToolNames?: string[];\n\n /**\n * Filter out messages from subagent streams in the main messages array.\n *\n * When enabled, messages from subagraph executions (those with a `tools:` namespace)\n * are excluded from `stream.messages`. Instead, these messages are tracked\n * per-subagent and accessible via `stream.subagents.get(id).messages`.\n *\n * This is useful for deep agent architectures where you want to display\n * the main conversation separately from subagent activity.\n *\n * @default false\n *\n * @example\n * ```typescript\n * const stream = useStream({\n * assistantId: \"my-agent\",\n * filterSubagentMessages: true,\n * });\n *\n * // Main thread messages only (no subagent messages)\n * stream.messages\n *\n * // Access subagent messages individually\n * stream.subagents.get(\"call_xyz\").messages\n * ```\n */\n filterSubagentMessages?: boolean;\n\n /**\n * Converts a @langchain/core BaseMessage to the desired output format.\n *\n * Defaults to `toMessageDict` which produces plain Message objects.\n * Framework SDKs pass `toMessageClass` (identity) to keep class instances.\n */\n toMessage?: (chunk: BaseMessage) => Message | BaseMessage;\n}\n\nexport class StreamManager<\n StateType extends Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n> {\n private abortRef = new AbortController();\n\n private messages: MessageTupleManager;\n\n private subagentManager: SubagentManager;\n\n private listeners = new Set<() => void>();\n\n private throttle: number | boolean;\n\n private filterSubagentMessages: boolean;\n\n private toMessage: (chunk: BaseMessage) => Message | BaseMessage;\n\n private queue: Promise<unknown> = Promise.resolve();\n\n private queueSize: number = 0;\n\n private state: {\n isLoading: boolean;\n values: [values: StateType, kind: \"stream\" | \"stop\"] | null;\n error: unknown;\n /** Version counter to force React re-renders on subagent changes */\n version: number;\n };\n\n constructor(messages: MessageTupleManager, options: StreamManagerOptions) {\n this.messages = messages;\n this.state = {\n isLoading: false,\n values: null,\n error: undefined,\n version: 0,\n };\n this.throttle = options.throttle;\n this.filterSubagentMessages = options.filterSubagentMessages ?? false;\n this.toMessage = options.toMessage ?? toMessageDict;\n this.subagentManager = new SubagentManager({\n subagentToolNames: options.subagentToolNames,\n onSubagentChange: () => this.bumpVersion(),\n toMessage: this.toMessage,\n });\n }\n\n /**\n * Increment version counter to trigger React re-renders.\n * Called when subagent state changes.\n */\n private bumpVersion = () => {\n this.state = { ...this.state, version: this.state.version + 1 };\n this.notifyListeners();\n };\n\n /**\n * Get all subagents as a Map.\n */\n getSubagents(): Map<string, SubagentStreamInterface> {\n return this.subagentManager.getSubagents();\n }\n\n /**\n * Get all currently running subagents.\n */\n getActiveSubagents(): SubagentStreamInterface[] {\n return this.subagentManager.getActiveSubagents();\n }\n\n /**\n * Get a specific subagent by tool call ID.\n */\n getSubagent(toolCallId: string): SubagentStreamInterface | undefined {\n return this.subagentManager.getSubagent(toolCallId);\n }\n\n /**\n * Get all subagents of a specific type.\n */\n getSubagentsByType(type: string): SubagentStreamInterface[] {\n return this.subagentManager.getSubagentsByType(type);\n }\n\n /**\n * Get all subagents triggered by a specific AI message.\n */\n getSubagentsByMessage(messageId: string): SubagentStreamInterface[] {\n return this.subagentManager.getSubagentsByMessage(messageId);\n }\n\n /**\n * Reconstruct subagent state from historical messages.\n *\n * This method should be called when loading thread history to restore\n * subagent visualization after:\n * - Page refresh (when stream has already completed)\n * - Loading thread history\n * - Navigating between threads\n *\n * @param messages - Array of messages from thread history\n * @param options - Optional configuration\n * @param options.skipIfPopulated - If true, skip reconstruction if subagents already exist\n */\n reconstructSubagents(\n messages: Message[],\n options?: { skipIfPopulated?: boolean }\n ): void {\n this.subagentManager.reconstructFromMessages(messages, options);\n }\n\n /**\n * Fetch and restore internal messages for reconstructed subagents from their\n * subgraph checkpoints. Should be called after `reconstructSubagents` to\n * restore the full subagent conversation after a page refresh.\n *\n * Subagent messages are persisted in the LangGraph checkpointer under a\n * subgraph-specific `checkpoint_ns` (e.g. `tools:<uuid>`). This method\n * discovers the correct namespace by inspecting the main thread's intermediate\n * history checkpoints, where each pending task's `checkpoint.checkpoint_ns`\n * identifies the subgraph. Tasks are matched to tool calls by their Send index\n * (`task.path[1]`), which corresponds to the order of tool calls in the AI\n * message — no deepagent-specific metadata required.\n *\n * @param threads - Client with a `getHistory` method (e.g. `client.threads`)\n * @param threadId - The parent thread ID\n * @param options - Optional configuration\n * @param options.messagesKey - Key in state values containing messages (default: \"messages\")\n * @param options.signal - AbortSignal to cancel in-flight requests on effect cleanup\n */\n async fetchSubagentHistory(\n threads: {\n getHistory<V extends Record<string, unknown>>(\n threadId: string,\n options?: {\n limit?: number;\n checkpoint?: { checkpoint_ns?: string };\n signal?: AbortSignal;\n }\n ): Promise<\n Array<{\n values: V;\n tasks?: Array<{\n id: string;\n name: string;\n path?: unknown[];\n checkpoint?: { checkpoint_ns?: string } | null;\n }>;\n }>\n >;\n },\n threadId: string,\n options?: {\n messagesKey?: string;\n historyLimit?: number;\n signal?: AbortSignal;\n }\n ): Promise<void> {\n const messagesKey = options?.messagesKey ?? \"messages\";\n const signal = options?.signal;\n\n /**\n * Bail immediately if already cancelled (React Strict Mode cleanup)\n */\n if (signal?.aborted) {\n return;\n }\n\n /**\n * Only fetch for subagents that have no messages (reconstructed from history)\n */\n const toFetch = [...this.subagentManager.getSubagents().entries()].filter(\n ([, s]) => s.messages.length === 0\n );\n\n /**\n * Bail immediately if there are no subagents to fetch\n */\n if (toFetch.length === 0) {\n return;\n }\n\n /**\n * Step 1: Discover subgraph namespaces from intermediate history\n *\n * When LangGraph dispatches parallel tool calls (v2 mode), each is a\n * separate Send task with a unique UUID-based checkpoint_ns. The intermediate\n * history checkpoints record these as `tasks[i]` where:\n * - `tasks[i].checkpoint.checkpoint_ns` = \"tools:<uuid>\" for each subgraph\n * - `tasks[i].path = [\"__pregel_push\", sendIndex]` matches tool_calls order\n *\n * By matching task Send index → tool_call position in the AI message we can\n * derive the subgraph namespace for every tool call without any external\n * metadata on the ToolMessage itself.\n */\n const toolCallIdToNamespace = new Map<string, string>();\n\n try {\n /**\n * Fetch enough history to include the intermediate checkpoint where\n * tool-call tasks were pending (typically within the last 10 checkpoints).\n */\n const mainHistory = await threads.getHistory<Record<string, unknown>>(\n threadId,\n { limit: options?.historyLimit ?? 20, signal }\n );\n\n /**\n * Phase 1: Direct mapping across ALL checkpoints (preferred).\n *\n * When a completed checkpoint contains task results, each task.result\n * has a ToolMessage whose tool_call_id directly and unambiguously maps\n * the task to the LLM tool call that triggered it. This is more robust\n * than positional alignment: it works even when a step mixes subagent\n * tool calls with other tool calls, and requires no assumptions about\n * the ordering of tasks vs tool_calls.\n *\n * We collect these direct mappings across the entire history before\n * attempting any positional fallback. Otherwise a more recent checkpoint\n * whose task is still pending (e.g. an interrupted run) could produce a\n * positional guess and stop the scan before reaching the older checkpoint\n * that actually holds the correct, completed mapping.\n *\n * LangGraph v2 dispatches each parallel tool call as a separate PUSH\n * task (\"__pregel_push\"). The subgraph checkpoint_ns is constructed as\n * `task.name + \":\" + task.id`, mirroring algo.ts:\n * taskCheckpointNamespace = checkpointNamespace + \":\" + taskId\n * where checkpointNamespace = task.name for root-level tasks.\n *\n * task.checkpoint is always null for completed tasks, so we derive the\n * namespace from task.name + task.id rather than task.checkpoint.checkpoint_ns.\n */\n for (const checkpoint of mainHistory) {\n const { tasks } = checkpoint;\n if (!tasks || tasks.length === 0) {\n continue;\n }\n\n for (const task of tasks) {\n if (\n !Array.isArray(task.path) ||\n task.path[0] !== \"__pregel_push\" ||\n typeof task.id !== \"string\" ||\n typeof task.name !== \"string\"\n ) {\n continue;\n }\n\n /**\n * Read tool_call_id directly from the task's result ToolMessage.\n */\n const resultMessages = (\n task as unknown as { result?: { messages?: unknown[] } }\n ).result?.messages;\n\n if (!Array.isArray(resultMessages)) {\n continue;\n }\n\n for (const msg of resultMessages) {\n const m = msg as Record<string, unknown>;\n if (\n m.type === \"tool\" &&\n typeof m.tool_call_id === \"string\" &&\n toFetch.some(([id]) => id === m.tool_call_id) &&\n !toolCallIdToNamespace.has(m.tool_call_id)\n ) {\n toolCallIdToNamespace.set(\n m.tool_call_id,\n `${task.name}:${task.id}`\n );\n }\n }\n }\n }\n\n /**\n * Phase 2: Positional fallback, applied ONLY to tool calls that Phase 1\n * could not resolve.\n *\n * This covers checkpoints whose task results are not yet populated (tasks\n * still pending — the live or just-interrupted case). We align push tasks\n * to the subagent tool calls of the triggering AI message by Send index\n * (task.path[1]). Restricting this to still-unmapped tool calls guarantees\n * a correct direct mapping from Phase 1 is never overwritten by a guess.\n */\n const hasUnmappedToolCalls = () =>\n toFetch.some(([id]) => !toolCallIdToNamespace.has(id));\n\n if (hasUnmappedToolCalls()) {\n for (const checkpoint of mainHistory) {\n if (!hasUnmappedToolCalls()) break;\n\n const { tasks } = checkpoint;\n if (!tasks || tasks.length === 0) {\n continue;\n }\n\n const pushTasks = tasks.filter(\n (t) =>\n Array.isArray(t.path) &&\n t.path[0] === \"__pregel_push\" &&\n typeof t.path[1] === \"number\" &&\n typeof t.id === \"string\" &&\n typeof t.name === \"string\"\n );\n if (pushTasks.length === 0) continue;\n\n /**\n * Find the AI message with subagent tool calls to align by Send index.\n */\n const msgs = checkpoint.values[messagesKey];\n if (!Array.isArray(msgs)) continue;\n\n let aiMessage: Record<string, unknown> | undefined;\n for (let i = msgs.length - 1; i >= 0; i -= 1) {\n const m = msgs[i] as Record<string, unknown>;\n if (\n m.type === \"ai\" &&\n Array.isArray(m.tool_calls) &&\n m.tool_calls.length > 0 &&\n (m.tool_calls as Array<{ name: string }>).some((tc) =>\n this.subagentManager.isSubagentToolCall(tc.name)\n )\n ) {\n aiMessage = m;\n break;\n }\n }\n if (!aiMessage) {\n continue;\n }\n\n /**\n * Only consider subagent tool calls from the AI message — not all tool\n * calls. This ensures regular tool calls (searchWeb, queryDatabase, etc.)\n * are never mistaken for subagents even when they appear in the same step.\n */\n const subagentToolCalls = (\n aiMessage.tool_calls as Array<{ id?: string; name: string }>\n ).filter((tc) => this.subagentManager.isSubagentToolCall(tc.name));\n\n if (subagentToolCalls.length === 0) {\n continue;\n }\n\n /**\n * Sort push tasks by Send index (path[1]) to align with tool_calls order\n */\n const sorted = [...pushTasks].sort((a, b) => {\n const ai = Array.isArray(a.path) ? (a.path[1] as number) : 0;\n const bi = Array.isArray(b.path) ? (b.path[1] as number) : 0;\n return ai - bi;\n });\n\n for (\n let i = 0;\n i < sorted.length && i < subagentToolCalls.length;\n i += 1\n ) {\n const tc = subagentToolCalls[i];\n const task = sorted[i];\n if (\n tc?.id &&\n task.id &&\n task.name &&\n toFetch.some(([id]) => id === tc.id) &&\n !toolCallIdToNamespace.has(tc.id)\n ) {\n toolCallIdToNamespace.set(tc.id, `${task.name}:${task.id}`);\n }\n }\n }\n }\n } catch {\n /**\n * Non-fatal: fall back to subagent.namespace below\n */\n }\n\n /**\n * Step 2: Fetch each subagent's conversation from its subgraph checkpoint\n */\n await Promise.all(\n toFetch.map(async ([toolCallId, subagent]) => {\n /**\n * Priority order for the subgraph checkpoint_ns:\n * 1. Derived from main thread's intermediate task list (preferred, no coupling)\n * 2. Already on the subagent's namespace (e.g. populated during streaming)\n * 3. Skip — we cannot reliably identify the namespace\n */\n const checkpointNs =\n toolCallIdToNamespace.get(toolCallId) ??\n (subagent.namespace.length > 0\n ? subagent.namespace.join(\"|\")\n : undefined);\n\n if (!checkpointNs) return;\n\n try {\n const history = await threads.getHistory<Record<string, unknown>>(\n threadId,\n {\n checkpoint: { checkpoint_ns: checkpointNs },\n limit: 1,\n signal,\n }\n );\n\n /**\n * If the HTTP request was cancelled mid-flight the getHistory call\n * would have thrown an AbortError (caught below). If we reach here the\n * fetch completed successfully, so always process the result.\n */\n const latestState = history[0];\n if (!latestState?.values) return;\n\n const messages = latestState.values[messagesKey];\n if (!Array.isArray(messages) || messages.length === 0) return;\n\n /**\n * Normalize messages: promote tool_calls from additional_kwargs to top\n * level when the checkpointer serialized them in the legacy format.\n */\n const normalizedMessages = messages.map((msg) => {\n const m = msg as Record<string, unknown>;\n if (\n m.type === \"ai\" &&\n (!m.tool_calls || (m.tool_calls as unknown[]).length === 0)\n ) {\n const ak = m.additional_kwargs as\n | Record<string, unknown>\n | undefined;\n const legacy = ak?.tool_calls;\n if (Array.isArray(legacy) && legacy.length > 0) {\n return { ...m, tool_calls: legacy };\n }\n }\n return m;\n });\n\n this.subagentManager.updateSubagentFromSubgraphState(\n toolCallId,\n normalizedMessages as Message[],\n latestState.values\n );\n } catch {\n /**\n * Ignore AbortError and other transient errors\n */\n }\n })\n );\n }\n\n /**\n * Check if any subagents are currently tracked.\n */\n hasSubagents(): boolean {\n return this.subagentManager.hasSubagents();\n }\n\n private setState = (newState: Partial<typeof this.state>) => {\n this.state = { ...this.state, ...newState };\n this.notifyListeners();\n };\n\n private notifyListeners = () => {\n this.listeners.forEach((listener) => listener());\n };\n\n subscribe = (listener: () => void): (() => void) => {\n if (this.throttle === false) {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n const timeoutMs = this.throttle === true ? 0 : this.throttle;\n let timeoutId: NodeJS.Timeout | number | undefined;\n\n const throttledListener = () => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n clearTimeout(timeoutId);\n listener();\n }, timeoutMs);\n };\n\n this.listeners.add(throttledListener);\n return () => {\n clearTimeout(timeoutId);\n this.listeners.delete(throttledListener);\n };\n };\n\n getSnapshot = () => this.state;\n\n get isLoading() {\n return this.state.isLoading;\n }\n\n get values() {\n return this.state.values?.[0] ?? null;\n }\n\n get error() {\n return this.state.error;\n }\n\n setStreamValues = (\n values:\n | (StateType | null)\n | ((prev: StateType | null, kind: \"stream\" | \"stop\") => StateType | null),\n kind: \"stream\" | \"stop\" = \"stream\"\n ) => {\n if (typeof values === \"function\") {\n const [prevValues, prevKind] = this.state.values ?? [null, \"stream\"];\n const nextValues = values(prevValues, prevKind);\n this.setState({ values: nextValues != null ? [nextValues, kind] : null });\n } else {\n const nextValues = values != null ? [values, kind] : null;\n this.setState({ values: nextValues as [StateType, \"stream\" | \"stop\"] });\n }\n };\n\n private getMutateFn = (kind: \"stream\" | \"stop\", historyValues: StateType) => {\n return (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => {\n const stateValues = (this.state.values ?? [null, \"stream\"])[0];\n const prev = {\n ...historyValues,\n ...stateValues,\n };\n const next = typeof update === \"function\" ? update(prev) : update;\n this.setStreamValues({ ...prev, ...next }, kind);\n };\n };\n\n private matchEventType = <\n T extends keyof EventStreamMap<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >,\n >(\n expected: T,\n actual: EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[\"event\"],\n _data: EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[\"data\"]\n ): _data is EventStreamMap<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[T][\"data\"] => {\n return expected === actual || actual.startsWith(`${expected}|`);\n };\n\n protected enqueue = async (\n action: (\n signal: AbortSignal\n ) => Promise<\n AsyncGenerator<\n EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >\n >\n >,\n options: {\n getMessages: (values: StateType) => Message[];\n\n setMessages: (current: StateType, messages: Message[]) => StateType;\n\n initialValues: StateType;\n\n callbacks: StreamManagerEventCallbacks<StateType, Bag>;\n\n onSuccess: () =>\n | StateType\n | null\n | undefined\n | void\n | Promise<StateType | null | undefined | void>;\n\n onError: (error: unknown) => void | Promise<void>;\n\n onFinish?: () => void;\n }\n ) => {\n try {\n this.queueSize = Math.max(0, this.queueSize - 1);\n this.setState({ isLoading: true, error: undefined });\n this.abortRef = new AbortController();\n\n const run = await action(this.abortRef.signal);\n let clearedPreviousInterrupts = false;\n\n let streamError: StreamError | undefined;\n for await (const { event, data } of run) {\n if (event === \"error\") {\n streamError = new StreamError(data);\n break;\n }\n\n const namespace = event.includes(\"|\")\n ? event.split(\"|\").slice(1)\n : undefined;\n\n const mutate = this.getMutateFn(\"stream\", options.initialValues);\n\n if (event === \"metadata\") options.callbacks.onMetadataEvent?.(data);\n if (event === \"events\") options.callbacks.onLangChainEvent?.(data);\n\n if (this.matchEventType(\"updates\", event, data)) {\n options.callbacks.onUpdateEvent?.(data, { namespace, mutate });\n\n // Track subagent streaming updates from subgraph namespaces\n // Mark the subagent as running when we receive updates\n // The actual message content is handled via addMessageToSubagent\n if (namespace && isSubagentNamespace(namespace)) {\n const namespaceId = extractToolCallIdFromNamespace(namespace);\n if (namespaceId && this.filterSubagentMessages) {\n this.subagentManager.markRunningFromNamespace(\n namespaceId,\n namespace\n );\n }\n }\n\n // Also register subagents from main agent updates (tool_calls in messages)\n // AND process tool results to complete subagents\n // This is needed because tool_calls often appear complete in updates\n // before they appear in the messages stream\n if (!namespace || !isSubagentNamespace(namespace)) {\n const updateData = data as Record<string, unknown>;\n for (const nodeData of Object.values(updateData)) {\n if (\n nodeData &&\n typeof nodeData === \"object\" &&\n \"messages\" in nodeData\n ) {\n const { messages } = nodeData as { messages: unknown[] };\n if (Array.isArray(messages)) {\n for (const msg of messages) {\n if (!msg || typeof msg !== \"object\") continue;\n const msgObj = msg as Record<string, unknown>;\n\n // Register subagents from AI messages with tool_calls\n if (\n msgObj.type === \"ai\" &&\n \"tool_calls\" in msgObj &&\n Array.isArray(msgObj.tool_calls)\n ) {\n this.subagentManager.registerFromToolCalls(\n msgObj.tool_calls as Array<{\n id?: string;\n name: string;\n args: Record<string, unknown> | string;\n }>,\n msgObj.id as string | undefined\n );\n }\n\n // Complete subagents from tool messages (task results)\n if (\n msgObj.type === \"tool\" &&\n \"tool_call_id\" in msgObj &&\n typeof msgObj.tool_call_id === \"string\"\n ) {\n const content =\n typeof msgObj.content === \"string\"\n ? msgObj.content\n : JSON.stringify(msgObj.content);\n const status =\n \"status\" in msgObj && msgObj.status === \"error\"\n ? \"error\"\n : \"success\";\n this.subagentManager.processToolMessage(\n msgObj.tool_call_id,\n content,\n status\n );\n }\n }\n }\n }\n }\n }\n }\n\n if (this.matchEventType(\"custom\", event, data)) {\n options.callbacks.onCustomEvent?.(data, { namespace, mutate });\n }\n\n if (this.matchEventType(\"checkpoints\", event, data)) {\n options.callbacks.onCheckpointEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"tasks\", event, data)) {\n options.callbacks.onTaskEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"debug\", event, data)) {\n options.callbacks.onDebugEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"tools\", event, data)) {\n options.callbacks.onToolEvent?.(data, { namespace, mutate });\n }\n\n // Handle values events - use startsWith to match both \"values\" and \"values|tools:xxx\"\n if (event === \"values\" || event.startsWith(\"values|\")) {\n // Check if this is a subgraph values event (for namespace mapping and values)\n if (namespace && isSubagentNamespace(namespace)) {\n const namespaceId = extractToolCallIdFromNamespace(namespace);\n if (namespaceId && this.filterSubagentMessages) {\n const valuesData = data as Record<string, unknown>;\n\n // Try to establish namespace mapping from the initial human message\n const messages = valuesData.messages as unknown[];\n if (Array.isArray(messages) && messages.length > 0) {\n const firstMsg = messages[0] as Record<string, unknown>;\n if (\n firstMsg?.type === \"human\" &&\n typeof firstMsg?.content === \"string\"\n ) {\n this.subagentManager.matchSubgraphToSubagent(\n namespaceId,\n firstMsg.content\n );\n }\n }\n\n // Update the subagent's values with the full state\n this.subagentManager.updateSubagentValues(\n namespaceId,\n valuesData\n );\n }\n } else {\n if (!clearedPreviousInterrupts) {\n // Clear stale __interrupt__ from the previous run once the new\n // stream starts delivering main values. This avoids carrying\n // resumed interrupts forward while still preserving the previous\n // interrupt state if the new stream fails before any values\n // arrive.\n this.setStreamValues((prev) => {\n if (prev && \"__interrupt__\" in prev) {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { __interrupt__, ...rest } = prev;\n return rest as StateType;\n }\n return prev;\n });\n clearedPreviousInterrupts = true;\n }\n\n if (data && typeof data === \"object\" && \"__interrupt__\" in data) {\n // When parallel branches each raise an interrupt, the backend\n // may stream separate values events per branch. We accumulate\n // the __interrupt__ arrays so none are lost, but still honor an\n // explicit empty array as \"clear interrupts\".\n const interruptData = data as Partial<StateType> & {\n __interrupt__?: Array<{ id?: string }>;\n };\n this.setStreamValues((prev) => {\n const prevInterrupts = (\n prev as\n | (StateType & { __interrupt__?: Array<{ id?: string }> })\n | null\n )?.__interrupt__;\n\n let interrupts = interruptData.__interrupt__;\n if (Array.isArray(interrupts)) {\n if (interrupts.length === 0) {\n interrupts = [];\n } else if (Array.isArray(prevInterrupts)) {\n const mergedInterrupts = [...prevInterrupts];\n const existingIds = new Set(\n prevInterrupts.map((i) => i.id).filter((id) => id != null)\n );\n for (const interrupt of interrupts) {\n if (interrupt.id != null) {\n if (existingIds.has(interrupt.id)) continue;\n existingIds.add(interrupt.id);\n }\n mergedInterrupts.push(interrupt);\n }\n interrupts = mergedInterrupts;\n }\n }\n\n return {\n ...prev,\n __interrupt__: interrupts,\n } as unknown as StateType;\n });\n } else {\n // Non-interrupt values events must not wipe accumulated\n // __interrupt__ state. Preserve it when the incoming data\n // does not carry its own __interrupt__ field.\n this.setStreamValues((prev) => {\n if (\n prev &&\n \"__interrupt__\" in prev &&\n Array.isArray((prev as Record<string, unknown>).__interrupt__)\n ) {\n return {\n ...(data as StateType),\n __interrupt__: (prev as Record<string, unknown>)\n .__interrupt__,\n } as StateType;\n }\n return data as StateType;\n });\n }\n }\n }\n\n if (this.matchEventType(\"messages\", event, data)) {\n const [serialized, metadata] = data;\n\n // Check if this message is from a subagent namespace\n const eventCheckpointNs =\n namespace && isSubagentNamespace(namespace) ? namespace : undefined;\n const rawCheckpointNs =\n (metadata?.langgraph_checkpoint_ns as string | undefined) ||\n (metadata?.checkpoint_ns as string | undefined);\n const checkpointNs: string[] | undefined =\n eventCheckpointNs ??\n (typeof rawCheckpointNs === \"string\"\n ? rawCheckpointNs.split(\"|\")\n : undefined);\n const isFromSubagent = isSubagentNamespace(checkpointNs);\n const toolCallId = isFromSubagent\n ? extractToolCallIdFromNamespace(checkpointNs)\n : undefined;\n\n // If filtering is enabled and this is a subagent message,\n // add it to the subagent's messages instead of the main stream\n if (this.filterSubagentMessages && isFromSubagent && toolCallId) {\n // Add to subagent's message list\n this.subagentManager.addMessageToSubagent(\n toolCallId,\n serialized,\n metadata\n );\n continue;\n }\n\n const messageId = this.messages.add(serialized, metadata);\n if (!messageId) {\n console.warn(\n \"Failed to add message to manager, no message ID found\"\n );\n continue;\n }\n\n this.setStreamValues((streamValues) => {\n const values = {\n ...options.initialValues,\n ...streamValues,\n };\n\n // Assumption: we're concatenating the message\n let messages = options.getMessages(values).slice();\n const { chunk, index } =\n this.messages.get(messageId, messages.length) ?? {};\n\n if (!chunk || index == null) return values;\n if (chunk.getType() === \"remove\") {\n // Check for special REMOVE_ALL_MESSAGES sentinel\n if (chunk.id === REMOVE_ALL_MESSAGES) {\n // Clear all messages when __remove_all__ is received\n messages = [];\n } else {\n messages.splice(index, 1);\n }\n } else {\n const msgDict = this.toMessage(chunk) as Message;\n messages[index] = msgDict;\n\n // Track subagents from AI messages with tool calls (main agent only)\n if (\n !isFromSubagent &&\n msgDict.type === \"ai\" &&\n \"tool_calls\" in msgDict &&\n Array.isArray(msgDict.tool_calls)\n ) {\n this.subagentManager.registerFromToolCalls(\n msgDict.tool_calls,\n msgDict.id as string | undefined\n );\n }\n\n // Complete subagents when tool messages arrive (main agent only)\n if (\n !isFromSubagent &&\n msgDict.type === \"tool\" &&\n \"tool_call_id\" in msgDict\n ) {\n const tcId = msgDict.tool_call_id as string;\n const content =\n typeof msgDict.content === \"string\"\n ? msgDict.content\n : JSON.stringify(msgDict.content);\n const status =\n \"status\" in msgDict && msgDict.status === \"error\"\n ? \"error\"\n : \"success\";\n this.subagentManager.processToolMessage(tcId, content, status);\n }\n }\n\n return options.setMessages(values, messages);\n });\n }\n }\n\n if (streamError != null) throw streamError;\n\n // Skip onSuccess when the stream was aborted (e.g., by multitask interrupt).\n // This avoids unnecessary HTTP calls (like history fetching) that would\n // delay the next queued stream from starting.\n if (!this.abortRef.signal.aborted) {\n const values = await options.onSuccess?.();\n if (typeof values !== \"undefined\" && this.queueSize === 0) {\n this.setStreamValues(values);\n }\n }\n } catch (error) {\n if (\n !(\n error instanceof Error && // eslint-disable-line no-instanceof/no-instanceof\n (error.name === \"AbortError\" || error.name === \"TimeoutError\")\n )\n ) {\n console.error(error);\n this.setState({ error });\n await options.onError?.(error);\n }\n } finally {\n this.setState({ isLoading: false });\n this.abortRef = new AbortController();\n options.onFinish?.();\n }\n };\n\n start = async (\n action: (\n signal: AbortSignal\n ) => Promise<\n AsyncGenerator<\n EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >\n >\n >,\n options: {\n getMessages: (values: StateType) => Message[];\n\n setMessages: (current: StateType, messages: Message[]) => StateType;\n\n initialValues: StateType;\n\n callbacks: StreamManagerEventCallbacks<StateType, Bag>;\n\n onSuccess: () =>\n | StateType\n | null\n | undefined\n | void\n | Promise<StateType | null | undefined | void>;\n\n onError: (error: unknown) => void | Promise<void>;\n\n onFinish?: () => void;\n },\n startOptions?: {\n /**\n * If true, abort any currently running stream before starting this one.\n * Used for multitask_strategy: \"interrupt\" and \"rollback\" to unblock\n * the queue so the new run request can proceed immediately.\n */\n abortPrevious?: boolean;\n }\n ): Promise<void> => {\n if (startOptions?.abortPrevious) {\n this.abortRef.abort();\n }\n this.queueSize += 1;\n const queued = this.queue.then(() => this.enqueue(action, options));\n this.queue = queued;\n await queued;\n };\n\n stop = async (\n historyValues: StateType,\n options: {\n onStop?: (options: {\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }) => void;\n }\n ): Promise<void> => {\n this.abortRef.abort();\n this.abortRef = new AbortController();\n\n options.onStop?.({ mutate: this.getMutateFn(\"stop\", historyValues) });\n };\n\n clear = () => {\n // Cancel any running streams\n this.abortRef.abort();\n this.abortRef = new AbortController();\n\n // Set the stream state to null\n this.setState({ error: undefined, values: null, isLoading: false });\n\n // Clear any pending messages\n this.messages.clear();\n\n // Clear subagent state\n this.subagentManager.clear();\n };\n}\n"],"mappings":"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"}
{"version":3,"file":"manager.js","names":[],"sources":["../../src/ui/manager.ts"],"sourcesContent":["import type { BaseMessage } from \"@langchain/core/messages\";\n\nimport { DEFAULT_MESSAGES_KEY } from \"../stream/constants.js\";\nimport type {\n CheckpointsStreamEvent,\n CustomStreamEvent,\n DebugStreamEvent,\n ErrorStreamEvent,\n EventsStreamEvent,\n FeedbackStreamEvent,\n MessagesTupleStreamEvent,\n MetadataStreamEvent,\n TasksStreamEvent,\n ToolsStreamEvent,\n UpdatesStreamEvent,\n ValuesStreamEvent,\n} from \"../types.stream.js\";\nimport { MessageTupleManager, toMessageDict } from \"./messages.js\";\nimport { StreamError } from \"./errors.js\";\nimport type { Message } from \"../types.messages.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport {\n SubagentManager,\n extractToolCallIdFromNamespace,\n isSubagentNamespace,\n} from \"./subagents.js\";\nimport type { SubagentStreamInterface } from \"./types.js\";\n\n/**\n * Special ID used by LangGraph's messagesStateReducer to signal\n * that all messages should be removed from the state.\n */\nexport const REMOVE_ALL_MESSAGES = \"__remove_all__\";\n\ntype GetUpdateType<\n Bag extends BagTemplate,\n StateType extends Record<string, unknown>,\n> = Bag extends { UpdateType: unknown }\n ? Bag[\"UpdateType\"]\n : Partial<StateType>;\n\ntype GetCustomEventType<Bag extends BagTemplate> = Bag extends {\n CustomEventType: unknown;\n}\n ? Bag[\"CustomEventType\"]\n : unknown;\n\ntype EventStreamMap<StateType, UpdateType, CustomType> = {\n values: ValuesStreamEvent<StateType>;\n updates: UpdatesStreamEvent<UpdateType>;\n custom: CustomStreamEvent<CustomType>;\n debug: DebugStreamEvent;\n messages: MessagesTupleStreamEvent;\n events: EventsStreamEvent;\n metadata: MetadataStreamEvent;\n checkpoints: CheckpointsStreamEvent<StateType>;\n tasks: TasksStreamEvent<StateType, UpdateType>;\n error: ErrorStreamEvent;\n feedback: FeedbackStreamEvent;\n tools: ToolsStreamEvent;\n};\n\nexport type EventStreamEvent<StateType, UpdateType, CustomType> =\n EventStreamMap<StateType, UpdateType, CustomType>[keyof EventStreamMap<\n StateType,\n UpdateType,\n CustomType\n >];\n\ninterface StreamManagerEventCallbacks<\n StateType extends Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n> {\n onUpdateEvent?: (\n data: UpdatesStreamEvent<GetUpdateType<Bag, StateType>>[\"data\"],\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n onCustomEvent?: (\n data: GetCustomEventType<Bag>,\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n onMetadataEvent?: (data: MetadataStreamEvent[\"data\"]) => void;\n onLangChainEvent?: (data: EventsStreamEvent[\"data\"]) => void;\n onDebugEvent?: (\n data: DebugStreamEvent[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onCheckpointEvent?: (\n data: CheckpointsStreamEvent<StateType>[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onTaskEvent?: (\n data: TasksStreamEvent<StateType, GetUpdateType<Bag, StateType>>[\"data\"],\n options: { namespace: string[] | undefined }\n ) => void;\n onToolEvent?: (\n data: ToolsStreamEvent[\"data\"],\n options: {\n namespace: string[] | undefined;\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }\n ) => void;\n}\n\n/**\n * Options for StreamManager constructor.\n */\nexport interface StreamManagerOptions {\n /**\n * Throttle the stream updates.\n * If a number is provided, updates are throttled to the given milliseconds.\n * If `true`, updates are batched in a single macrotask.\n * If `false`, updates are not throttled.\n */\n throttle: number | boolean;\n\n /**\n * Tool names that indicate subagent invocation.\n *\n * When an AI message contains tool calls with these names, they are\n * automatically tracked as subagent executions. This enables the\n * `subagents`, `activeSubagents`, `getSubagent()`, and `getSubagentsByType()`\n * properties on the stream.\n *\n * @default [\"task\"]\n *\n * @example\n * ```typescript\n * // Track both \"task\" and \"delegate\" as subagent tools\n * subagentToolNames: [\"task\", \"delegate\", \"spawn_agent\"]\n * ```\n */\n subagentToolNames?: string[];\n\n /**\n * Filter out messages from subagent streams in the main messages array.\n *\n * When enabled, messages from subagraph executions (those with a `tools:` namespace)\n * are excluded from `stream.messages`. Instead, these messages are tracked\n * per-subagent and accessible via `stream.subagents.get(id).messages`.\n *\n * This is useful for deep agent architectures where you want to display\n * the main conversation separately from subagent activity.\n *\n * @default false\n *\n * @example\n * ```typescript\n * const stream = useStream({\n * assistantId: \"my-agent\",\n * filterSubagentMessages: true,\n * });\n *\n * // Main thread messages only (no subagent messages)\n * stream.messages\n *\n * // Access subagent messages individually\n * stream.subagents.get(\"call_xyz\").messages\n * ```\n */\n filterSubagentMessages?: boolean;\n\n /**\n * Converts a @langchain/core BaseMessage to the desired output format.\n *\n * Defaults to `toMessageDict` which produces plain Message objects.\n * Framework SDKs pass `toMessageClass` (identity) to keep class instances.\n */\n toMessage?: (chunk: BaseMessage) => Message | BaseMessage;\n}\n\nexport class StreamManager<\n StateType extends Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n> {\n private abortRef = new AbortController();\n\n private messages: MessageTupleManager;\n\n private subagentManager: SubagentManager;\n\n private listeners = new Set<() => void>();\n\n private throttle: number | boolean;\n\n private filterSubagentMessages: boolean;\n\n private toMessage: (chunk: BaseMessage) => Message | BaseMessage;\n\n private queue: Promise<unknown> = Promise.resolve();\n\n private queueSize: number = 0;\n\n private state: {\n isLoading: boolean;\n values: [values: StateType, kind: \"stream\" | \"stop\"] | null;\n error: unknown;\n /** Version counter to force React re-renders on subagent changes */\n version: number;\n };\n\n constructor(messages: MessageTupleManager, options: StreamManagerOptions) {\n this.messages = messages;\n this.state = {\n isLoading: false,\n values: null,\n error: undefined,\n version: 0,\n };\n this.throttle = options.throttle;\n this.filterSubagentMessages = options.filterSubagentMessages ?? false;\n this.toMessage = options.toMessage ?? toMessageDict;\n this.subagentManager = new SubagentManager({\n subagentToolNames: options.subagentToolNames,\n onSubagentChange: () => this.bumpVersion(),\n toMessage: this.toMessage,\n });\n }\n\n /**\n * Increment version counter to trigger React re-renders.\n * Called when subagent state changes.\n */\n private bumpVersion = () => {\n this.state = { ...this.state, version: this.state.version + 1 };\n this.notifyListeners();\n };\n\n /**\n * Get all subagents as a Map.\n */\n getSubagents(): Map<string, SubagentStreamInterface> {\n return this.subagentManager.getSubagents();\n }\n\n /**\n * Get all currently running subagents.\n */\n getActiveSubagents(): SubagentStreamInterface[] {\n return this.subagentManager.getActiveSubagents();\n }\n\n /**\n * Get a specific subagent by tool call ID.\n */\n getSubagent(toolCallId: string): SubagentStreamInterface | undefined {\n return this.subagentManager.getSubagent(toolCallId);\n }\n\n /**\n * Get all subagents of a specific type.\n */\n getSubagentsByType(type: string): SubagentStreamInterface[] {\n return this.subagentManager.getSubagentsByType(type);\n }\n\n /**\n * Get all subagents triggered by a specific AI message.\n */\n getSubagentsByMessage(messageId: string): SubagentStreamInterface[] {\n return this.subagentManager.getSubagentsByMessage(messageId);\n }\n\n /**\n * Reconstruct subagent state from historical messages.\n *\n * This method should be called when loading thread history to restore\n * subagent visualization after:\n * - Page refresh (when stream has already completed)\n * - Loading thread history\n * - Navigating between threads\n *\n * @param messages - Array of messages from thread history\n * @param options - Optional configuration\n * @param options.skipIfPopulated - If true, skip reconstruction if subagents already exist\n */\n reconstructSubagents(\n messages: Message[],\n options?: { skipIfPopulated?: boolean }\n ): void {\n this.subagentManager.reconstructFromMessages(messages, options);\n }\n\n /**\n * Fetch and restore internal messages for reconstructed subagents from their\n * subgraph checkpoints. Should be called after `reconstructSubagents` to\n * restore the full subagent conversation after a page refresh.\n *\n * Subagent messages are persisted in the LangGraph checkpointer under a\n * subgraph-specific `checkpoint_ns` (e.g. `tools:<uuid>`). This method\n * discovers the correct namespace by inspecting the main thread's intermediate\n * history checkpoints, where each pending task's `checkpoint.checkpoint_ns`\n * identifies the subgraph. Tasks are matched to tool calls by their Send index\n * (`task.path[1]`), which corresponds to the order of tool calls in the AI\n * message — no deepagent-specific metadata required.\n *\n * @param threads - Client with a `getHistory` method (e.g. `client.threads`)\n * @param threadId - The parent thread ID\n * @param options - Optional configuration\n * @param options.messagesKey - Key in state values containing messages (default: \"messages\")\n * @param options.signal - AbortSignal to cancel in-flight requests on effect cleanup\n */\n async fetchSubagentHistory(\n threads: {\n getHistory<V extends Record<string, unknown>>(\n threadId: string,\n options?: {\n limit?: number;\n checkpoint?: { checkpoint_ns?: string };\n signal?: AbortSignal;\n }\n ): Promise<\n Array<{\n values: V;\n tasks?: Array<{\n id: string;\n name: string;\n path?: unknown[];\n checkpoint?: { checkpoint_ns?: string } | null;\n }>;\n }>\n >;\n },\n threadId: string,\n options?: {\n messagesKey?: string;\n historyLimit?: number;\n signal?: AbortSignal;\n }\n ): Promise<void> {\n const messagesKey = options?.messagesKey ?? DEFAULT_MESSAGES_KEY;\n const signal = options?.signal;\n\n /**\n * Bail immediately if already cancelled (React Strict Mode cleanup)\n */\n if (signal?.aborted) {\n return;\n }\n\n /**\n * Only fetch for subagents that have no messages (reconstructed from history)\n */\n const toFetch = [...this.subagentManager.getSubagents().entries()].filter(\n ([, s]) => s.messages.length === 0\n );\n\n /**\n * Bail immediately if there are no subagents to fetch\n */\n if (toFetch.length === 0) {\n return;\n }\n\n /**\n * Step 1: Discover subgraph namespaces from intermediate history\n *\n * When LangGraph dispatches parallel tool calls (v2 mode), each is a\n * separate Send task with a unique UUID-based checkpoint_ns. The intermediate\n * history checkpoints record these as `tasks[i]` where:\n * - `tasks[i].checkpoint.checkpoint_ns` = \"tools:<uuid>\" for each subgraph\n * - `tasks[i].path = [\"__pregel_push\", sendIndex]` matches tool_calls order\n *\n * By matching task Send index → tool_call position in the AI message we can\n * derive the subgraph namespace for every tool call without any external\n * metadata on the ToolMessage itself.\n */\n const toolCallIdToNamespace = new Map<string, string>();\n\n try {\n /**\n * Fetch enough history to include the intermediate checkpoint where\n * tool-call tasks were pending (typically within the last 10 checkpoints).\n */\n const mainHistory = await threads.getHistory<Record<string, unknown>>(\n threadId,\n { limit: options?.historyLimit ?? 20, signal }\n );\n\n /**\n * Phase 1: Direct mapping across ALL checkpoints (preferred).\n *\n * When a completed checkpoint contains task results, each task.result\n * has a ToolMessage whose tool_call_id directly and unambiguously maps\n * the task to the LLM tool call that triggered it. This is more robust\n * than positional alignment: it works even when a step mixes subagent\n * tool calls with other tool calls, and requires no assumptions about\n * the ordering of tasks vs tool_calls.\n *\n * We collect these direct mappings across the entire history before\n * attempting any positional fallback. Otherwise a more recent checkpoint\n * whose task is still pending (e.g. an interrupted run) could produce a\n * positional guess and stop the scan before reaching the older checkpoint\n * that actually holds the correct, completed mapping.\n *\n * LangGraph v2 dispatches each parallel tool call as a separate PUSH\n * task (\"__pregel_push\"). The subgraph checkpoint_ns is constructed as\n * `task.name + \":\" + task.id`, mirroring algo.ts:\n * taskCheckpointNamespace = checkpointNamespace + \":\" + taskId\n * where checkpointNamespace = task.name for root-level tasks.\n *\n * task.checkpoint is always null for completed tasks, so we derive the\n * namespace from task.name + task.id rather than task.checkpoint.checkpoint_ns.\n */\n for (const checkpoint of mainHistory) {\n const { tasks } = checkpoint;\n if (!tasks || tasks.length === 0) {\n continue;\n }\n\n for (const task of tasks) {\n if (\n !Array.isArray(task.path) ||\n task.path[0] !== \"__pregel_push\" ||\n typeof task.id !== \"string\" ||\n typeof task.name !== \"string\"\n ) {\n continue;\n }\n\n /**\n * Read tool_call_id directly from the task's result ToolMessage.\n */\n const resultMessages = (\n task as unknown as { result?: { messages?: unknown[] } }\n ).result?.messages;\n\n if (!Array.isArray(resultMessages)) {\n continue;\n }\n\n for (const msg of resultMessages) {\n const m = msg as Record<string, unknown>;\n if (\n m.type === \"tool\" &&\n typeof m.tool_call_id === \"string\" &&\n toFetch.some(([id]) => id === m.tool_call_id) &&\n !toolCallIdToNamespace.has(m.tool_call_id)\n ) {\n toolCallIdToNamespace.set(\n m.tool_call_id,\n `${task.name}:${task.id}`\n );\n }\n }\n }\n }\n\n /**\n * Phase 2: Positional fallback, applied ONLY to tool calls that Phase 1\n * could not resolve.\n *\n * This covers checkpoints whose task results are not yet populated (tasks\n * still pending — the live or just-interrupted case). We align push tasks\n * to the subagent tool calls of the triggering AI message by Send index\n * (task.path[1]). Restricting this to still-unmapped tool calls guarantees\n * a correct direct mapping from Phase 1 is never overwritten by a guess.\n */\n const hasUnmappedToolCalls = () =>\n toFetch.some(([id]) => !toolCallIdToNamespace.has(id));\n\n if (hasUnmappedToolCalls()) {\n for (const checkpoint of mainHistory) {\n if (!hasUnmappedToolCalls()) break;\n\n const { tasks } = checkpoint;\n if (!tasks || tasks.length === 0) {\n continue;\n }\n\n const pushTasks = tasks.filter(\n (t) =>\n Array.isArray(t.path) &&\n t.path[0] === \"__pregel_push\" &&\n typeof t.path[1] === \"number\" &&\n typeof t.id === \"string\" &&\n typeof t.name === \"string\"\n );\n if (pushTasks.length === 0) continue;\n\n /**\n * Find the AI message with subagent tool calls to align by Send index.\n */\n const msgs = checkpoint.values[messagesKey];\n if (!Array.isArray(msgs)) continue;\n\n let aiMessage: Record<string, unknown> | undefined;\n for (let i = msgs.length - 1; i >= 0; i -= 1) {\n const m = msgs[i] as Record<string, unknown>;\n if (\n m.type === \"ai\" &&\n Array.isArray(m.tool_calls) &&\n m.tool_calls.length > 0 &&\n (m.tool_calls as Array<{ name: string }>).some((tc) =>\n this.subagentManager.isSubagentToolCall(tc.name)\n )\n ) {\n aiMessage = m;\n break;\n }\n }\n if (!aiMessage) {\n continue;\n }\n\n /**\n * Only consider subagent tool calls from the AI message — not all tool\n * calls. This ensures regular tool calls (searchWeb, queryDatabase, etc.)\n * are never mistaken for subagents even when they appear in the same step.\n */\n const subagentToolCalls = (\n aiMessage.tool_calls as Array<{ id?: string; name: string }>\n ).filter((tc) => this.subagentManager.isSubagentToolCall(tc.name));\n\n if (subagentToolCalls.length === 0) {\n continue;\n }\n\n /**\n * Sort push tasks by Send index (path[1]) to align with tool_calls order\n */\n const sorted = [...pushTasks].sort((a, b) => {\n const ai = Array.isArray(a.path) ? (a.path[1] as number) : 0;\n const bi = Array.isArray(b.path) ? (b.path[1] as number) : 0;\n return ai - bi;\n });\n\n for (\n let i = 0;\n i < sorted.length && i < subagentToolCalls.length;\n i += 1\n ) {\n const tc = subagentToolCalls[i];\n const task = sorted[i];\n if (\n tc?.id &&\n task.id &&\n task.name &&\n toFetch.some(([id]) => id === tc.id) &&\n !toolCallIdToNamespace.has(tc.id)\n ) {\n toolCallIdToNamespace.set(tc.id, `${task.name}:${task.id}`);\n }\n }\n }\n }\n } catch {\n /**\n * Non-fatal: fall back to subagent.namespace below\n */\n }\n\n /**\n * Step 2: Fetch each subagent's conversation from its subgraph checkpoint\n */\n await Promise.all(\n toFetch.map(async ([toolCallId, subagent]) => {\n /**\n * Priority order for the subgraph checkpoint_ns:\n * 1. Derived from main thread's intermediate task list (preferred, no coupling)\n * 2. Already on the subagent's namespace (e.g. populated during streaming)\n * 3. Skip — we cannot reliably identify the namespace\n */\n const checkpointNs =\n toolCallIdToNamespace.get(toolCallId) ??\n (subagent.namespace.length > 0\n ? subagent.namespace.join(\"|\")\n : undefined);\n\n if (!checkpointNs) return;\n\n try {\n const history = await threads.getHistory<Record<string, unknown>>(\n threadId,\n {\n checkpoint: { checkpoint_ns: checkpointNs },\n limit: 1,\n signal,\n }\n );\n\n /**\n * If the HTTP request was cancelled mid-flight the getHistory call\n * would have thrown an AbortError (caught below). If we reach here the\n * fetch completed successfully, so always process the result.\n */\n const latestState = history[0];\n if (!latestState?.values) return;\n\n const messages = latestState.values[messagesKey];\n if (!Array.isArray(messages) || messages.length === 0) return;\n\n /**\n * Normalize messages: promote tool_calls from additional_kwargs to top\n * level when the checkpointer serialized them in the legacy format.\n */\n const normalizedMessages = messages.map((msg) => {\n const m = msg as Record<string, unknown>;\n if (\n m.type === \"ai\" &&\n (!m.tool_calls || (m.tool_calls as unknown[]).length === 0)\n ) {\n const ak = m.additional_kwargs as\n | Record<string, unknown>\n | undefined;\n const legacy = ak?.tool_calls;\n if (Array.isArray(legacy) && legacy.length > 0) {\n return { ...m, tool_calls: legacy };\n }\n }\n return m;\n });\n\n this.subagentManager.updateSubagentFromSubgraphState(\n toolCallId,\n normalizedMessages as Message[],\n latestState.values\n );\n } catch {\n /**\n * Ignore AbortError and other transient errors\n */\n }\n })\n );\n }\n\n /**\n * Check if any subagents are currently tracked.\n */\n hasSubagents(): boolean {\n return this.subagentManager.hasSubagents();\n }\n\n private setState = (newState: Partial<typeof this.state>) => {\n this.state = { ...this.state, ...newState };\n this.notifyListeners();\n };\n\n private notifyListeners = () => {\n this.listeners.forEach((listener) => listener());\n };\n\n subscribe = (listener: () => void): (() => void) => {\n if (this.throttle === false) {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n const timeoutMs = this.throttle === true ? 0 : this.throttle;\n let timeoutId: NodeJS.Timeout | number | undefined;\n\n const throttledListener = () => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => {\n clearTimeout(timeoutId);\n listener();\n }, timeoutMs);\n };\n\n this.listeners.add(throttledListener);\n return () => {\n clearTimeout(timeoutId);\n this.listeners.delete(throttledListener);\n };\n };\n\n getSnapshot = () => this.state;\n\n get isLoading() {\n return this.state.isLoading;\n }\n\n get values() {\n return this.state.values?.[0] ?? null;\n }\n\n get error() {\n return this.state.error;\n }\n\n setStreamValues = (\n values:\n | (StateType | null)\n | ((prev: StateType | null, kind: \"stream\" | \"stop\") => StateType | null),\n kind: \"stream\" | \"stop\" = \"stream\"\n ) => {\n if (typeof values === \"function\") {\n const [prevValues, prevKind] = this.state.values ?? [null, \"stream\"];\n const nextValues = values(prevValues, prevKind);\n this.setState({ values: nextValues != null ? [nextValues, kind] : null });\n } else {\n const nextValues = values != null ? [values, kind] : null;\n this.setState({ values: nextValues as [StateType, \"stream\" | \"stop\"] });\n }\n };\n\n private getMutateFn = (kind: \"stream\" | \"stop\", historyValues: StateType) => {\n return (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => {\n const stateValues = (this.state.values ?? [null, \"stream\"])[0];\n const prev = {\n ...historyValues,\n ...stateValues,\n };\n const next = typeof update === \"function\" ? update(prev) : update;\n this.setStreamValues({ ...prev, ...next }, kind);\n };\n };\n\n private matchEventType = <\n T extends keyof EventStreamMap<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >,\n >(\n expected: T,\n actual: EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[\"event\"],\n _data: EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[\"data\"]\n ): _data is EventStreamMap<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >[T][\"data\"] => {\n return expected === actual || actual.startsWith(`${expected}|`);\n };\n\n protected enqueue = async (\n action: (\n signal: AbortSignal\n ) => Promise<\n AsyncGenerator<\n EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >\n >\n >,\n options: {\n getMessages: (values: StateType) => Message[];\n\n setMessages: (current: StateType, messages: Message[]) => StateType;\n\n initialValues: StateType;\n\n callbacks: StreamManagerEventCallbacks<StateType, Bag>;\n\n onSuccess: () =>\n | StateType\n | null\n | undefined\n | void\n | Promise<StateType | null | undefined | void>;\n\n onError: (error: unknown) => void | Promise<void>;\n\n onFinish?: () => void;\n }\n ) => {\n try {\n this.queueSize = Math.max(0, this.queueSize - 1);\n this.setState({ isLoading: true, error: undefined });\n this.abortRef = new AbortController();\n\n const run = await action(this.abortRef.signal);\n let clearedPreviousInterrupts = false;\n\n let streamError: StreamError | undefined;\n for await (const { event, data } of run) {\n if (event === \"error\") {\n streamError = new StreamError(data);\n break;\n }\n\n const namespace = event.includes(\"|\")\n ? event.split(\"|\").slice(1)\n : undefined;\n\n const mutate = this.getMutateFn(\"stream\", options.initialValues);\n\n if (event === \"metadata\") options.callbacks.onMetadataEvent?.(data);\n if (event === \"events\") options.callbacks.onLangChainEvent?.(data);\n\n if (this.matchEventType(\"updates\", event, data)) {\n options.callbacks.onUpdateEvent?.(data, { namespace, mutate });\n\n // Track subagent streaming updates from subgraph namespaces\n // Mark the subagent as running when we receive updates\n // The actual message content is handled via addMessageToSubagent\n if (namespace && isSubagentNamespace(namespace)) {\n const namespaceId = extractToolCallIdFromNamespace(namespace);\n if (namespaceId && this.filterSubagentMessages) {\n this.subagentManager.markRunningFromNamespace(\n namespaceId,\n namespace\n );\n }\n }\n\n // Also register subagents from main agent updates (tool_calls in messages)\n // AND process tool results to complete subagents\n // This is needed because tool_calls often appear complete in updates\n // before they appear in the messages stream\n if (!namespace || !isSubagentNamespace(namespace)) {\n const updateData = data as Record<string, unknown>;\n for (const nodeData of Object.values(updateData)) {\n if (\n nodeData &&\n typeof nodeData === \"object\" &&\n \"messages\" in nodeData\n ) {\n const { messages } = nodeData as { messages: unknown[] };\n if (Array.isArray(messages)) {\n for (const msg of messages) {\n if (!msg || typeof msg !== \"object\") continue;\n const msgObj = msg as Record<string, unknown>;\n\n // Register subagents from AI messages with tool_calls\n if (\n msgObj.type === \"ai\" &&\n \"tool_calls\" in msgObj &&\n Array.isArray(msgObj.tool_calls)\n ) {\n this.subagentManager.registerFromToolCalls(\n msgObj.tool_calls as Array<{\n id?: string;\n name: string;\n args: Record<string, unknown> | string;\n }>,\n msgObj.id as string | undefined\n );\n }\n\n // Complete subagents from tool messages (task results)\n if (\n msgObj.type === \"tool\" &&\n \"tool_call_id\" in msgObj &&\n typeof msgObj.tool_call_id === \"string\"\n ) {\n const content =\n typeof msgObj.content === \"string\"\n ? msgObj.content\n : JSON.stringify(msgObj.content);\n const status =\n \"status\" in msgObj && msgObj.status === \"error\"\n ? \"error\"\n : \"success\";\n this.subagentManager.processToolMessage(\n msgObj.tool_call_id,\n content,\n status\n );\n }\n }\n }\n }\n }\n }\n }\n\n if (this.matchEventType(\"custom\", event, data)) {\n options.callbacks.onCustomEvent?.(data, { namespace, mutate });\n }\n\n if (this.matchEventType(\"checkpoints\", event, data)) {\n options.callbacks.onCheckpointEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"tasks\", event, data)) {\n options.callbacks.onTaskEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"debug\", event, data)) {\n options.callbacks.onDebugEvent?.(data, { namespace });\n }\n\n if (this.matchEventType(\"tools\", event, data)) {\n options.callbacks.onToolEvent?.(data, { namespace, mutate });\n }\n\n // Handle values events - use startsWith to match both \"values\" and \"values|tools:xxx\"\n if (event === \"values\" || event.startsWith(\"values|\")) {\n // Check if this is a subgraph values event (for namespace mapping and values)\n if (namespace && isSubagentNamespace(namespace)) {\n const namespaceId = extractToolCallIdFromNamespace(namespace);\n if (namespaceId && this.filterSubagentMessages) {\n const valuesData = data as Record<string, unknown>;\n\n // Try to establish namespace mapping from the initial human message\n const messages = valuesData.messages as unknown[];\n if (Array.isArray(messages) && messages.length > 0) {\n const firstMsg = messages[0] as Record<string, unknown>;\n if (\n firstMsg?.type === \"human\" &&\n typeof firstMsg?.content === \"string\"\n ) {\n this.subagentManager.matchSubgraphToSubagent(\n namespaceId,\n firstMsg.content\n );\n }\n }\n\n // Update the subagent's values with the full state\n this.subagentManager.updateSubagentValues(\n namespaceId,\n valuesData\n );\n }\n } else {\n if (!clearedPreviousInterrupts) {\n // Clear stale __interrupt__ from the previous run once the new\n // stream starts delivering main values. This avoids carrying\n // resumed interrupts forward while still preserving the previous\n // interrupt state if the new stream fails before any values\n // arrive.\n this.setStreamValues((prev) => {\n if (prev && \"__interrupt__\" in prev) {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { __interrupt__, ...rest } = prev;\n return rest as StateType;\n }\n return prev;\n });\n clearedPreviousInterrupts = true;\n }\n\n if (data && typeof data === \"object\" && \"__interrupt__\" in data) {\n // When parallel branches each raise an interrupt, the backend\n // may stream separate values events per branch. We accumulate\n // the __interrupt__ arrays so none are lost, but still honor an\n // explicit empty array as \"clear interrupts\".\n const interruptData = data as Partial<StateType> & {\n __interrupt__?: Array<{ id?: string }>;\n };\n this.setStreamValues((prev) => {\n const prevInterrupts = (\n prev as\n | (StateType & { __interrupt__?: Array<{ id?: string }> })\n | null\n )?.__interrupt__;\n\n let interrupts = interruptData.__interrupt__;\n if (Array.isArray(interrupts)) {\n if (interrupts.length === 0) {\n interrupts = [];\n } else if (Array.isArray(prevInterrupts)) {\n const mergedInterrupts = [...prevInterrupts];\n const existingIds = new Set(\n prevInterrupts.map((i) => i.id).filter((id) => id != null)\n );\n for (const interrupt of interrupts) {\n if (interrupt.id != null) {\n if (existingIds.has(interrupt.id)) continue;\n existingIds.add(interrupt.id);\n }\n mergedInterrupts.push(interrupt);\n }\n interrupts = mergedInterrupts;\n }\n }\n\n return {\n ...prev,\n __interrupt__: interrupts,\n } as unknown as StateType;\n });\n } else {\n // Non-interrupt values events must not wipe accumulated\n // __interrupt__ state. Preserve it when the incoming data\n // does not carry its own __interrupt__ field.\n this.setStreamValues((prev) => {\n if (\n prev &&\n \"__interrupt__\" in prev &&\n Array.isArray((prev as Record<string, unknown>).__interrupt__)\n ) {\n return {\n ...(data as StateType),\n __interrupt__: (prev as Record<string, unknown>)\n .__interrupt__,\n } as StateType;\n }\n return data as StateType;\n });\n }\n }\n }\n\n if (this.matchEventType(\"messages\", event, data)) {\n const [serialized, metadata] = data;\n\n // Check if this message is from a subagent namespace\n const eventCheckpointNs =\n namespace && isSubagentNamespace(namespace) ? namespace : undefined;\n const rawCheckpointNs =\n (metadata?.langgraph_checkpoint_ns as string | undefined) ||\n (metadata?.checkpoint_ns as string | undefined);\n const checkpointNs: string[] | undefined =\n eventCheckpointNs ??\n (typeof rawCheckpointNs === \"string\"\n ? rawCheckpointNs.split(\"|\")\n : undefined);\n const isFromSubagent = isSubagentNamespace(checkpointNs);\n const toolCallId = isFromSubagent\n ? extractToolCallIdFromNamespace(checkpointNs)\n : undefined;\n\n // If filtering is enabled and this is a subagent message,\n // add it to the subagent's messages instead of the main stream\n if (this.filterSubagentMessages && isFromSubagent && toolCallId) {\n // Add to subagent's message list\n this.subagentManager.addMessageToSubagent(\n toolCallId,\n serialized,\n metadata\n );\n continue;\n }\n\n const messageId = this.messages.add(serialized, metadata);\n if (!messageId) {\n console.warn(\n \"Failed to add message to manager, no message ID found\"\n );\n continue;\n }\n\n this.setStreamValues((streamValues) => {\n const values = {\n ...options.initialValues,\n ...streamValues,\n };\n\n // Assumption: we're concatenating the message\n let messages = options.getMessages(values).slice();\n const { chunk, index } =\n this.messages.get(messageId, messages.length) ?? {};\n\n if (!chunk || index == null) return values;\n if (chunk.getType() === \"remove\") {\n // Check for special REMOVE_ALL_MESSAGES sentinel\n if (chunk.id === REMOVE_ALL_MESSAGES) {\n // Clear all messages when __remove_all__ is received\n messages = [];\n } else {\n messages.splice(index, 1);\n }\n } else {\n const msgDict = this.toMessage(chunk) as Message;\n messages[index] = msgDict;\n\n // Track subagents from AI messages with tool calls (main agent only)\n if (\n !isFromSubagent &&\n msgDict.type === \"ai\" &&\n \"tool_calls\" in msgDict &&\n Array.isArray(msgDict.tool_calls)\n ) {\n this.subagentManager.registerFromToolCalls(\n msgDict.tool_calls,\n msgDict.id as string | undefined\n );\n }\n\n // Complete subagents when tool messages arrive (main agent only)\n if (\n !isFromSubagent &&\n msgDict.type === \"tool\" &&\n \"tool_call_id\" in msgDict\n ) {\n const tcId = msgDict.tool_call_id as string;\n const content =\n typeof msgDict.content === \"string\"\n ? msgDict.content\n : JSON.stringify(msgDict.content);\n const status =\n \"status\" in msgDict && msgDict.status === \"error\"\n ? \"error\"\n : \"success\";\n this.subagentManager.processToolMessage(tcId, content, status);\n }\n }\n\n return options.setMessages(values, messages);\n });\n }\n }\n\n if (streamError != null) throw streamError;\n\n // Skip onSuccess when the stream was aborted (e.g., by multitask interrupt).\n // This avoids unnecessary HTTP calls (like history fetching) that would\n // delay the next queued stream from starting.\n if (!this.abortRef.signal.aborted) {\n const values = await options.onSuccess?.();\n if (typeof values !== \"undefined\" && this.queueSize === 0) {\n this.setStreamValues(values);\n }\n }\n } catch (error) {\n if (\n !(\n error instanceof Error && // eslint-disable-line no-instanceof/no-instanceof\n (error.name === \"AbortError\" || error.name === \"TimeoutError\")\n )\n ) {\n console.error(error);\n this.setState({ error });\n await options.onError?.(error);\n }\n } finally {\n this.setState({ isLoading: false });\n this.abortRef = new AbortController();\n options.onFinish?.();\n }\n };\n\n start = async (\n action: (\n signal: AbortSignal\n ) => Promise<\n AsyncGenerator<\n EventStreamEvent<\n StateType,\n GetUpdateType<Bag, StateType>,\n GetCustomEventType<Bag>\n >\n >\n >,\n options: {\n getMessages: (values: StateType) => Message[];\n\n setMessages: (current: StateType, messages: Message[]) => StateType;\n\n initialValues: StateType;\n\n callbacks: StreamManagerEventCallbacks<StateType, Bag>;\n\n onSuccess: () =>\n | StateType\n | null\n | undefined\n | void\n | Promise<StateType | null | undefined | void>;\n\n onError: (error: unknown) => void | Promise<void>;\n\n onFinish?: () => void;\n },\n startOptions?: {\n /**\n * If true, abort any currently running stream before starting this one.\n * Used for multitask_strategy: \"interrupt\" and \"rollback\" to unblock\n * the queue so the new run request can proceed immediately.\n */\n abortPrevious?: boolean;\n }\n ): Promise<void> => {\n if (startOptions?.abortPrevious) {\n this.abortRef.abort();\n }\n this.queueSize += 1;\n const queued = this.queue.then(() => this.enqueue(action, options));\n this.queue = queued;\n await queued;\n };\n\n stop = async (\n historyValues: StateType,\n options: {\n onStop?: (options: {\n mutate: (\n update: Partial<StateType> | ((prev: StateType) => Partial<StateType>)\n ) => void;\n }) => void;\n }\n ): Promise<void> => {\n this.abortRef.abort();\n this.abortRef = new AbortController();\n\n options.onStop?.({ mutate: this.getMutateFn(\"stop\", historyValues) });\n };\n\n clear = () => {\n // Cancel any running streams\n this.abortRef.abort();\n this.abortRef = new AbortController();\n\n // Set the stream state to null\n this.setState({ error: undefined, values: null, isLoading: false });\n\n // Clear any pending messages\n this.messages.clear();\n\n // Clear subagent state\n this.subagentManager.clear();\n };\n}\n"],"mappings":"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"}
require("../_virtual/_rolldown/runtime.cjs");
const require_constants = require("../stream/constants.cjs");
const require_message_coercion = require("../stream/message-coercion.cjs");

@@ -84,3 +85,3 @@ let _langchain_core_messages = require("@langchain/core/messages");

*/
function ensureHistoryMessageInstances(history, messagesKey = "messages") {
function ensureHistoryMessageInstances(history, messagesKey = require_constants.DEFAULT_MESSAGES_KEY) {
return history.map((state) => {

@@ -87,0 +88,0 @@ if (state.values == null) return state;

@@ -1,1 +0,1 @@

{"version":3,"file":"messages.cjs","names":["BaseMessageChunk","HumanMessageChunk","AIMessageChunk","normalizeAIMessageToolCalls","SystemMessageChunk","ToolMessageChunk","tryCoerceMessageLikeToMessage"],"sources":["../../src/ui/messages.ts"],"sourcesContent":["import {\n type BaseMessage,\n BaseMessageChunk,\n convertToChunk,\n HumanMessageChunk,\n SystemMessageChunk,\n AIMessageChunk,\n ToolMessageChunk,\n} from \"@langchain/core/messages\";\n\nimport type { Message } from \"../types.messages.js\";\nimport type { ThreadState } from \"../schema.js\";\nimport {\n normalizeAIMessageToolCalls,\n tryCoerceMessageLikeToMessage,\n} from \"../stream/message-coercion.js\";\n\nexport { tryCoerceMessageLikeToMessage };\n\n/**\n * Replaces the `messages` property in a state type with `BaseMessage[]`.\n * Used by framework SDKs to reflect that `ensureHistoryMessageInstances`\n * converts plain message objects to class instances at runtime.\n */\nexport type StateWithBaseMessages<S> = S extends { messages: unknown }\n ? Omit<S, \"messages\"> & { messages: BaseMessage[] }\n : S;\n\n/**\n * Maps a `ThreadState<StateType>[]` so that the `messages` field inside\n * `values` is typed as `BaseMessage[]` instead of `Message[]`.\n */\nexport type HistoryWithBaseMessages<T> = T extends ThreadState<infer S>[]\n ? ThreadState<StateWithBaseMessages<S>>[]\n : T;\n\nexport function tryConvertToChunk(\n message: BaseMessage | BaseMessageChunk\n): BaseMessageChunk | null {\n try {\n if (BaseMessageChunk.isInstance(message)) return message;\n return convertToChunk(message);\n } catch {\n return null;\n }\n}\n\nfunction tryCoerceMessageLikeToChunk(\n message: Omit<Message, \"type\"> & { type: string }\n): BaseMessage | BaseMessageChunk {\n if (message.type === \"human\" || message.type === \"user\") {\n return new HumanMessageChunk(message);\n }\n\n if (message.type === \"ai\" || message.type === \"assistant\") {\n return new AIMessageChunk(normalizeAIMessageToolCalls(message));\n }\n\n if (message.type === \"system\") {\n return new SystemMessageChunk(message);\n }\n\n if (message.type === \"tool\" && \"tool_call_id\" in message) {\n return new ToolMessageChunk({\n ...message,\n tool_call_id: message.tool_call_id as string,\n });\n }\n\n return tryCoerceMessageLikeToMessage(message);\n}\n\nexport class MessageTupleManager {\n chunks: Record<\n string,\n {\n chunk?: BaseMessageChunk | BaseMessage;\n metadata?: Record<string, unknown>;\n index?: number;\n }\n > = {};\n\n constructor() {\n this.chunks = {};\n }\n\n add(\n serialized: Message,\n metadata: Record<string, unknown> | undefined\n ): string | null {\n // TODO: this is sometimes sent from the API\n // figure out how to prevent this or move this to LC.js\n if (serialized.type.endsWith(\"MessageChunk\")) {\n // eslint-disable-next-line no-param-reassign\n serialized.type = serialized.type\n .slice(0, -\"MessageChunk\".length)\n .toLowerCase() as Message[\"type\"];\n }\n\n const message = tryCoerceMessageLikeToChunk(serialized);\n const chunk = tryConvertToChunk(message);\n\n const { id } = chunk ?? message;\n if (!id) {\n console.warn(\n \"No message ID found for chunk, ignoring in state\",\n serialized\n );\n return null;\n }\n\n this.chunks[id] ??= {};\n this.chunks[id].metadata = metadata ?? this.chunks[id].metadata;\n if (chunk) {\n const prev = this.chunks[id].chunk;\n this.chunks[id].chunk =\n (BaseMessageChunk.isInstance(prev) ? prev : null)?.concat(chunk) ??\n chunk;\n } else {\n this.chunks[id].chunk = message;\n }\n\n return id;\n }\n\n clear() {\n this.chunks = {};\n }\n\n get(id: string | null | undefined, defaultIndex?: number) {\n if (id == null) return null;\n if (this.chunks[id] == null) return null;\n if (defaultIndex != null) this.chunks[id].index ??= defaultIndex;\n return this.chunks[id];\n }\n}\n\nexport const toMessageDict = (chunk: BaseMessage): Message => {\n const { type, data } = chunk.toDict();\n return { ...data, type } as Message;\n};\n\n/**\n * Identity converter that keeps @langchain/core class instances.\n * Used by framework SDKs to expose BaseMessage instances instead of plain dicts.\n */\nexport const toMessageClass = (chunk: BaseMessage): BaseMessage => chunk;\n\n/**\n * Ensures all messages in an array are BaseMessage class instances.\n * Messages that are already class instances pass through unchanged.\n * Plain message objects (e.g. from API values/history) are converted\n * via {@link tryCoerceMessageLikeToMessage}.\n */\nexport function ensureMessageInstances(\n messages: (Message | BaseMessage)[]\n): (BaseMessage | BaseMessageChunk)[] {\n return messages.map((msg) => {\n if (typeof (msg as BaseMessage).getType === \"function\") {\n return msg as BaseMessage;\n }\n return tryCoerceMessageLikeToMessage(\n msg as Omit<Message, \"type\"> & { type: string }\n );\n });\n}\n\n/**\n * Converts plain message objects within each history state's values\n * to proper BaseMessage class instances. Returns a new array with\n * shallow-copied states whose messages have been coerced.\n */\nexport function ensureHistoryMessageInstances<\n StateType extends Record<string, unknown>,\n>(\n history: ThreadState<StateType>[],\n messagesKey: string = \"messages\"\n): ThreadState<StateType>[] {\n return history.map((state) => {\n if (state.values == null) return state;\n const messages = state.values[messagesKey];\n if (!Array.isArray(messages)) return state;\n return {\n ...state,\n values: {\n ...state.values,\n [messagesKey]: ensureMessageInstances(messages),\n },\n };\n });\n}\n"],"mappings":";;;;AAoCA,SAAgB,kBACd,SACyB;AACzB,KAAI;AACF,MAAIA,yBAAAA,iBAAiB,WAAW,QAAQ,CAAE,QAAO;AACjD,UAAA,GAAA,yBAAA,gBAAsB,QAAQ;SACxB;AACN,SAAO;;;AAIX,SAAS,4BACP,SACgC;AAChC,KAAI,QAAQ,SAAS,WAAW,QAAQ,SAAS,OAC/C,QAAO,IAAIC,yBAAAA,kBAAkB,QAAQ;AAGvC,KAAI,QAAQ,SAAS,QAAQ,QAAQ,SAAS,YAC5C,QAAO,IAAIC,yBAAAA,eAAeC,yBAAAA,4BAA4B,QAAQ,CAAC;AAGjE,KAAI,QAAQ,SAAS,SACnB,QAAO,IAAIC,yBAAAA,mBAAmB,QAAQ;AAGxC,KAAI,QAAQ,SAAS,UAAU,kBAAkB,QAC/C,QAAO,IAAIC,yBAAAA,iBAAiB;EAC1B,GAAG;EACH,cAAc,QAAQ;EACvB,CAAC;AAGJ,QAAOC,yBAAAA,8BAA8B,QAAQ;;AAG/C,IAAa,sBAAb,MAAiC;CAC/B,SAOI,EAAE;CAEN,cAAc;AACZ,OAAK,SAAS,EAAE;;CAGlB,IACE,YACA,UACe;AAGf,MAAI,WAAW,KAAK,SAAS,eAAe,CAE1C,YAAW,OAAO,WAAW,KAC1B,MAAM,GAAG,IAAuB,CAChC,aAAa;EAGlB,MAAM,UAAU,4BAA4B,WAAW;EACvD,MAAM,QAAQ,kBAAkB,QAAQ;EAExC,MAAM,EAAE,OAAO,SAAS;AACxB,MAAI,CAAC,IAAI;AACP,WAAQ,KACN,oDACA,WACD;AACD,UAAO;;AAGT,OAAK,OAAO,QAAQ,EAAE;AACtB,OAAK,OAAO,IAAI,WAAW,YAAY,KAAK,OAAO,IAAI;AACvD,MAAI,OAAO;GACT,MAAM,OAAO,KAAK,OAAO,IAAI;AAC7B,QAAK,OAAO,IAAI,SACbN,yBAAAA,iBAAiB,WAAW,KAAK,GAAG,OAAO,OAAO,OAAO,MAAM,IAChE;QAEF,MAAK,OAAO,IAAI,QAAQ;AAG1B,SAAO;;CAGT,QAAQ;AACN,OAAK,SAAS,EAAE;;CAGlB,IAAI,IAA+B,cAAuB;AACxD,MAAI,MAAM,KAAM,QAAO;AACvB,MAAI,KAAK,OAAO,OAAO,KAAM,QAAO;AACpC,MAAI,gBAAgB,KAAM,MAAK,OAAO,IAAI,UAAU;AACpD,SAAO,KAAK,OAAO;;;AAIvB,MAAa,iBAAiB,UAAgC;CAC5D,MAAM,EAAE,MAAM,SAAS,MAAM,QAAQ;AACrC,QAAO;EAAE,GAAG;EAAM;EAAM;;;;;;AAO1B,MAAa,kBAAkB,UAAoC;;;;;;;AAQnE,SAAgB,uBACd,UACoC;AACpC,QAAO,SAAS,KAAK,QAAQ;AAC3B,MAAI,OAAQ,IAAoB,YAAY,WAC1C,QAAO;AAET,SAAOM,yBAAAA,8BACL,IACD;GACD;;;;;;;AAQJ,SAAgB,8BAGd,SACA,cAAsB,YACI;AAC1B,QAAO,QAAQ,KAAK,UAAU;AAC5B,MAAI,MAAM,UAAU,KAAM,QAAO;EACjC,MAAM,WAAW,MAAM,OAAO;AAC9B,MAAI,CAAC,MAAM,QAAQ,SAAS,CAAE,QAAO;AACrC,SAAO;GACL,GAAG;GACH,QAAQ;IACN,GAAG,MAAM;KACR,cAAc,uBAAuB,SAAS;IAChD;GACF;GACD"}
{"version":3,"file":"messages.cjs","names":["BaseMessageChunk","HumanMessageChunk","AIMessageChunk","normalizeAIMessageToolCalls","SystemMessageChunk","ToolMessageChunk","tryCoerceMessageLikeToMessage","DEFAULT_MESSAGES_KEY"],"sources":["../../src/ui/messages.ts"],"sourcesContent":["import {\n type BaseMessage,\n BaseMessageChunk,\n convertToChunk,\n HumanMessageChunk,\n SystemMessageChunk,\n AIMessageChunk,\n ToolMessageChunk,\n} from \"@langchain/core/messages\";\n\nimport type { Message } from \"../types.messages.js\";\nimport type { ThreadState } from \"../schema.js\";\nimport { DEFAULT_MESSAGES_KEY } from \"../stream/constants.js\";\nimport {\n normalizeAIMessageToolCalls,\n tryCoerceMessageLikeToMessage,\n} from \"../stream/message-coercion.js\";\n\nexport { tryCoerceMessageLikeToMessage };\n\n/**\n * Replaces the `messages` property in a state type with `BaseMessage[]`.\n * Used by framework SDKs to reflect that `ensureHistoryMessageInstances`\n * converts plain message objects to class instances at runtime.\n */\nexport type StateWithBaseMessages<S> = S extends { messages: unknown }\n ? Omit<S, \"messages\"> & { messages: BaseMessage[] }\n : S;\n\n/**\n * Maps a `ThreadState<StateType>[]` so that the `messages` field inside\n * `values` is typed as `BaseMessage[]` instead of `Message[]`.\n */\nexport type HistoryWithBaseMessages<T> = T extends ThreadState<infer S>[]\n ? ThreadState<StateWithBaseMessages<S>>[]\n : T;\n\nexport function tryConvertToChunk(\n message: BaseMessage | BaseMessageChunk\n): BaseMessageChunk | null {\n try {\n if (BaseMessageChunk.isInstance(message)) return message;\n return convertToChunk(message);\n } catch {\n return null;\n }\n}\n\nfunction tryCoerceMessageLikeToChunk(\n message: Omit<Message, \"type\"> & { type: string }\n): BaseMessage | BaseMessageChunk {\n if (message.type === \"human\" || message.type === \"user\") {\n return new HumanMessageChunk(message);\n }\n\n if (message.type === \"ai\" || message.type === \"assistant\") {\n return new AIMessageChunk(normalizeAIMessageToolCalls(message));\n }\n\n if (message.type === \"system\") {\n return new SystemMessageChunk(message);\n }\n\n if (message.type === \"tool\" && \"tool_call_id\" in message) {\n return new ToolMessageChunk({\n ...message,\n tool_call_id: message.tool_call_id as string,\n });\n }\n\n return tryCoerceMessageLikeToMessage(message);\n}\n\nexport class MessageTupleManager {\n chunks: Record<\n string,\n {\n chunk?: BaseMessageChunk | BaseMessage;\n metadata?: Record<string, unknown>;\n index?: number;\n }\n > = {};\n\n constructor() {\n this.chunks = {};\n }\n\n add(\n serialized: Message,\n metadata: Record<string, unknown> | undefined\n ): string | null {\n // TODO: this is sometimes sent from the API\n // figure out how to prevent this or move this to LC.js\n if (serialized.type.endsWith(\"MessageChunk\")) {\n // eslint-disable-next-line no-param-reassign\n serialized.type = serialized.type\n .slice(0, -\"MessageChunk\".length)\n .toLowerCase() as Message[\"type\"];\n }\n\n const message = tryCoerceMessageLikeToChunk(serialized);\n const chunk = tryConvertToChunk(message);\n\n const { id } = chunk ?? message;\n if (!id) {\n console.warn(\n \"No message ID found for chunk, ignoring in state\",\n serialized\n );\n return null;\n }\n\n this.chunks[id] ??= {};\n this.chunks[id].metadata = metadata ?? this.chunks[id].metadata;\n if (chunk) {\n const prev = this.chunks[id].chunk;\n this.chunks[id].chunk =\n (BaseMessageChunk.isInstance(prev) ? prev : null)?.concat(chunk) ??\n chunk;\n } else {\n this.chunks[id].chunk = message;\n }\n\n return id;\n }\n\n clear() {\n this.chunks = {};\n }\n\n get(id: string | null | undefined, defaultIndex?: number) {\n if (id == null) return null;\n if (this.chunks[id] == null) return null;\n if (defaultIndex != null) this.chunks[id].index ??= defaultIndex;\n return this.chunks[id];\n }\n}\n\nexport const toMessageDict = (chunk: BaseMessage): Message => {\n const { type, data } = chunk.toDict();\n return { ...data, type } as Message;\n};\n\n/**\n * Identity converter that keeps @langchain/core class instances.\n * Used by framework SDKs to expose BaseMessage instances instead of plain dicts.\n */\nexport const toMessageClass = (chunk: BaseMessage): BaseMessage => chunk;\n\n/**\n * Ensures all messages in an array are BaseMessage class instances.\n * Messages that are already class instances pass through unchanged.\n * Plain message objects (e.g. from API values/history) are converted\n * via {@link tryCoerceMessageLikeToMessage}.\n */\nexport function ensureMessageInstances(\n messages: (Message | BaseMessage)[]\n): (BaseMessage | BaseMessageChunk)[] {\n return messages.map((msg) => {\n if (typeof (msg as BaseMessage).getType === \"function\") {\n return msg as BaseMessage;\n }\n return tryCoerceMessageLikeToMessage(\n msg as Omit<Message, \"type\"> & { type: string }\n );\n });\n}\n\n/**\n * Converts plain message objects within each history state's values\n * to proper BaseMessage class instances. Returns a new array with\n * shallow-copied states whose messages have been coerced.\n */\nexport function ensureHistoryMessageInstances<\n StateType extends Record<string, unknown>,\n>(\n history: ThreadState<StateType>[],\n messagesKey: string = DEFAULT_MESSAGES_KEY\n): ThreadState<StateType>[] {\n return history.map((state) => {\n if (state.values == null) return state;\n const messages = state.values[messagesKey];\n if (!Array.isArray(messages)) return state;\n return {\n ...state,\n values: {\n ...state.values,\n [messagesKey]: ensureMessageInstances(messages),\n },\n };\n });\n}\n"],"mappings":";;;;;AAqCA,SAAgB,kBACd,SACyB;AACzB,KAAI;AACF,MAAIA,yBAAAA,iBAAiB,WAAW,QAAQ,CAAE,QAAO;AACjD,UAAA,GAAA,yBAAA,gBAAsB,QAAQ;SACxB;AACN,SAAO;;;AAIX,SAAS,4BACP,SACgC;AAChC,KAAI,QAAQ,SAAS,WAAW,QAAQ,SAAS,OAC/C,QAAO,IAAIC,yBAAAA,kBAAkB,QAAQ;AAGvC,KAAI,QAAQ,SAAS,QAAQ,QAAQ,SAAS,YAC5C,QAAO,IAAIC,yBAAAA,eAAeC,yBAAAA,4BAA4B,QAAQ,CAAC;AAGjE,KAAI,QAAQ,SAAS,SACnB,QAAO,IAAIC,yBAAAA,mBAAmB,QAAQ;AAGxC,KAAI,QAAQ,SAAS,UAAU,kBAAkB,QAC/C,QAAO,IAAIC,yBAAAA,iBAAiB;EAC1B,GAAG;EACH,cAAc,QAAQ;EACvB,CAAC;AAGJ,QAAOC,yBAAAA,8BAA8B,QAAQ;;AAG/C,IAAa,sBAAb,MAAiC;CAC/B,SAOI,EAAE;CAEN,cAAc;AACZ,OAAK,SAAS,EAAE;;CAGlB,IACE,YACA,UACe;AAGf,MAAI,WAAW,KAAK,SAAS,eAAe,CAE1C,YAAW,OAAO,WAAW,KAC1B,MAAM,GAAG,IAAuB,CAChC,aAAa;EAGlB,MAAM,UAAU,4BAA4B,WAAW;EACvD,MAAM,QAAQ,kBAAkB,QAAQ;EAExC,MAAM,EAAE,OAAO,SAAS;AACxB,MAAI,CAAC,IAAI;AACP,WAAQ,KACN,oDACA,WACD;AACD,UAAO;;AAGT,OAAK,OAAO,QAAQ,EAAE;AACtB,OAAK,OAAO,IAAI,WAAW,YAAY,KAAK,OAAO,IAAI;AACvD,MAAI,OAAO;GACT,MAAM,OAAO,KAAK,OAAO,IAAI;AAC7B,QAAK,OAAO,IAAI,SACbN,yBAAAA,iBAAiB,WAAW,KAAK,GAAG,OAAO,OAAO,OAAO,MAAM,IAChE;QAEF,MAAK,OAAO,IAAI,QAAQ;AAG1B,SAAO;;CAGT,QAAQ;AACN,OAAK,SAAS,EAAE;;CAGlB,IAAI,IAA+B,cAAuB;AACxD,MAAI,MAAM,KAAM,QAAO;AACvB,MAAI,KAAK,OAAO,OAAO,KAAM,QAAO;AACpC,MAAI,gBAAgB,KAAM,MAAK,OAAO,IAAI,UAAU;AACpD,SAAO,KAAK,OAAO;;;AAIvB,MAAa,iBAAiB,UAAgC;CAC5D,MAAM,EAAE,MAAM,SAAS,MAAM,QAAQ;AACrC,QAAO;EAAE,GAAG;EAAM;EAAM;;;;;;AAO1B,MAAa,kBAAkB,UAAoC;;;;;;;AAQnE,SAAgB,uBACd,UACoC;AACpC,QAAO,SAAS,KAAK,QAAQ;AAC3B,MAAI,OAAQ,IAAoB,YAAY,WAC1C,QAAO;AAET,SAAOM,yBAAAA,8BACL,IACD;GACD;;;;;;;AAQJ,SAAgB,8BAGd,SACA,cAAsBC,kBAAAA,sBACI;AAC1B,QAAO,QAAQ,KAAK,UAAU;AAC5B,MAAI,MAAM,UAAU,KAAM,QAAO;EACjC,MAAM,WAAW,MAAM,OAAO;AAC9B,MAAI,CAAC,MAAM,QAAQ,SAAS,CAAE,QAAO;AACrC,SAAO;GACL,GAAG;GACH,QAAQ;IACN,GAAG,MAAM;KACR,cAAc,uBAAuB,SAAS;IAChD;GACF;GACD"}

@@ -1,1 +0,1 @@

{"version":3,"file":"messages.d.cts","names":[],"sources":["../../src/ui/messages.ts"],"mappings":";;;;;;;AAwBA;;;;KAAY,qBAAA,MAA2B,CAAA;EAAY,QAAA;AAAA,IAC/C,IAAA,CAAK,CAAA;EAAmB,QAAA,EAAU,WAAA;AAAA,IAClC,CAAA;;;;;KAMQ,uBAAA,MAA6B,CAAA,SAAU,WAAA,cAC/C,WAAA,CAAY,qBAAA,CAAsB,CAAA,OAClC,CAAA;AAAA,cAsCS,mBAAA;EACX,MAAA,EAAQ,MAAA;IAGJ,KAAA,GAAQ,gBAAA,GAAmB,WAAA;IAC3B,QAAA,GAAW,MAAA;IACX,KAAA;EAAA;EAIJ,WAAA,CAAA;EAIA,GAAA,CACE,UAAA,EAAY,OAAA,EACZ,QAAA,EAAU,MAAA;EAqCZ,KAAA,CAAA;EAIA,GAAA,CAAI,EAAA,6BAA+B,YAAA;mEAzCjB,yBAAA,CAAA,cAAA;;;;;cAiDP,aAAA,GAAa,KAAA,EAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAGzB,yBAAA,CAHyB,cAAA,GAAA,yBAAA,CAAA,WAAA,MAAA,OAAA;;;;;cASb,cAAA,GAAc,KAAA,EAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAA6C,yBAAA,CAA7C,cAAA,GAAA,yBAAA,CAAA,WAAA,MAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAAA,yBAAA,CAAA,cAAA,GAAA,yBAAA,CAAA,WAAA;;;;;;AA1E3B;iBAkFgB,sBAAA,CACd,QAAA,GAAW,OAAA,GAAU,WAAA,OACnB,WAAA,GAAc,gBAAA;;;;;;iBAgBF,6BAAA,mBACI,MAAA,kBAAA,CAElB,OAAA,EAAS,WAAA,CAAY,SAAA,KACrB,WAAA,YACC,WAAA,CAAY,SAAA"}
{"version":3,"file":"messages.d.cts","names":[],"sources":["../../src/ui/messages.ts"],"mappings":";;;;;;;AAyBA;;;;KAAY,qBAAA,MAA2B,CAAA;EAAY,QAAA;AAAA,IAC/C,IAAA,CAAK,CAAA;EAAmB,QAAA,EAAU,WAAA;AAAA,IAClC,CAAA;;;;;KAMQ,uBAAA,MAA6B,CAAA,SAAU,WAAA,cAC/C,WAAA,CAAY,qBAAA,CAAsB,CAAA,OAClC,CAAA;AAAA,cAsCS,mBAAA;EACX,MAAA,EAAQ,MAAA;IAGJ,KAAA,GAAQ,gBAAA,GAAmB,WAAA;IAC3B,QAAA,GAAW,MAAA;IACX,KAAA;EAAA;EAIJ,WAAA,CAAA;EAIA,GAAA,CACE,UAAA,EAAY,OAAA,EACZ,QAAA,EAAU,MAAA;EAqCZ,KAAA,CAAA;EAIA,GAAA,CAAI,EAAA,6BAA+B,YAAA;mEAzCjB,yBAAA,CAAA,cAAA;;;;;cAiDP,aAAA,GAAa,KAAA,EAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAGzB,yBAAA,CAHyB,cAAA,GAAA,yBAAA,CAAA,WAAA,MAAA,OAAA;;;;;cASb,cAAA,GAAc,KAAA,EAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAA6C,yBAAA,CAA7C,cAAA,GAAA,yBAAA,CAAA,WAAA,MAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAAA,yBAAA,CAAA,cAAA,GAAA,yBAAA,CAAA,WAAA;;;;;;AA1E3B;iBAkFgB,sBAAA,CACd,QAAA,GAAW,OAAA,GAAU,WAAA,OACnB,WAAA,GAAc,gBAAA;;;;;;iBAgBF,6BAAA,mBACI,MAAA,kBAAA,CAElB,OAAA,EAAS,WAAA,CAAY,SAAA,KACrB,WAAA,YACC,WAAA,CAAY,SAAA"}

@@ -1,1 +0,1 @@

{"version":3,"file":"messages.d.ts","names":[],"sources":["../../src/ui/messages.ts"],"mappings":";;;;;;;;AAwBA;;;KAAY,qBAAA,MAA2B,CAAA;EAAY,QAAA;AAAA,IAC/C,IAAA,CAAK,CAAA;EAAmB,QAAA,EAAU,WAAA;AAAA,IAClC,CAAA;;;;;KAMQ,uBAAA,MAA6B,CAAA,SAAU,WAAA,cAC/C,WAAA,CAAY,qBAAA,CAAsB,CAAA,OAClC,CAAA;AAAA,cAsCS,mBAAA;EACX,MAAA,EAAQ,MAAA;IAGJ,KAAA,GAAQ,gBAAA,GAAmB,WAAA;IAC3B,QAAA,GAAW,MAAA;IACX,KAAA;EAAA;EAIJ,WAAA,CAAA;EAIA,GAAA,CACE,UAAA,EAAY,OAAA,EACZ,QAAA,EAAU,MAAA;EAqCZ,KAAA,CAAA;EAIA,GAAA,CAAI,EAAA,6BAA+B,YAAA;mEAzCjB,yBAAA,CAAA,cAAA;;;;;cAiDP,aAAA,GAAa,KAAA,EAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAGzB,yBAAA,CAHyB,cAAA,GAAA,yBAAA,CAAA,WAAA,MAAA,OAAA;;;;;cASb,cAAA,GAAc,KAAA,EAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAA6C,yBAAA,CAA7C,cAAA,GAAA,yBAAA,CAAA,WAAA,MAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAAA,yBAAA,CAAA,cAAA,GAAA,yBAAA,CAAA,WAAA;;;;;;;iBAQX,sBAAA,CACd,QAAA,GAAW,OAAA,GAAU,WAAA,OACnB,WAAA,GAAc,gBAAA;;;;;;iBAgBF,6BAAA,mBACI,MAAA,kBAAA,CAElB,OAAA,EAAS,WAAA,CAAY,SAAA,KACrB,WAAA,YACC,WAAA,CAAY,SAAA"}
{"version":3,"file":"messages.d.ts","names":[],"sources":["../../src/ui/messages.ts"],"mappings":";;;;;;;;AAyBA;;;KAAY,qBAAA,MAA2B,CAAA;EAAY,QAAA;AAAA,IAC/C,IAAA,CAAK,CAAA;EAAmB,QAAA,EAAU,WAAA;AAAA,IAClC,CAAA;;;;;KAMQ,uBAAA,MAA6B,CAAA,SAAU,WAAA,cAC/C,WAAA,CAAY,qBAAA,CAAsB,CAAA,OAClC,CAAA;AAAA,cAsCS,mBAAA;EACX,MAAA,EAAQ,MAAA;IAGJ,KAAA,GAAQ,gBAAA,GAAmB,WAAA;IAC3B,QAAA,GAAW,MAAA;IACX,KAAA;EAAA;EAIJ,WAAA,CAAA;EAIA,GAAA,CACE,UAAA,EAAY,OAAA,EACZ,QAAA,EAAU,MAAA;EAqCZ,KAAA,CAAA;EAIA,GAAA,CAAI,EAAA,6BAA+B,YAAA;mEAzCjB,yBAAA,CAAA,cAAA;;;;;cAiDP,aAAA,GAAa,KAAA,EAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAGzB,yBAAA,CAHyB,cAAA,GAAA,yBAAA,CAAA,WAAA,MAAA,OAAA;;;;;cASb,cAAA,GAAc,KAAA,EAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAA6C,yBAAA,CAA7C,cAAA,GAAA,yBAAA,CAAA,WAAA,MAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAAA,yBAAA,CAAA,cAAA,GAAA,yBAAA,CAAA,WAAA;;;;;;;iBAQX,sBAAA,CACd,QAAA,GAAW,OAAA,GAAU,WAAA,OACnB,WAAA,GAAc,gBAAA;;;;;;iBAgBF,6BAAA,mBACI,MAAA,kBAAA,CAElB,OAAA,EAAS,WAAA,CAAY,SAAA,KACrB,WAAA,YACC,WAAA,CAAY,SAAA"}

@@ -0,1 +1,2 @@

import { DEFAULT_MESSAGES_KEY } from "../stream/constants.js";
import { normalizeAIMessageToolCalls, tryCoerceMessageLikeToMessage } from "../stream/message-coercion.js";

@@ -83,3 +84,3 @@ import { AIMessageChunk, BaseMessageChunk, HumanMessageChunk, SystemMessageChunk, ToolMessageChunk, convertToChunk } from "@langchain/core/messages";

*/
function ensureHistoryMessageInstances(history, messagesKey = "messages") {
function ensureHistoryMessageInstances(history, messagesKey = DEFAULT_MESSAGES_KEY) {
return history.map((state) => {

@@ -86,0 +87,0 @@ if (state.values == null) return state;

@@ -1,1 +0,1 @@

{"version":3,"file":"messages.js","names":[],"sources":["../../src/ui/messages.ts"],"sourcesContent":["import {\n type BaseMessage,\n BaseMessageChunk,\n convertToChunk,\n HumanMessageChunk,\n SystemMessageChunk,\n AIMessageChunk,\n ToolMessageChunk,\n} from \"@langchain/core/messages\";\n\nimport type { Message } from \"../types.messages.js\";\nimport type { ThreadState } from \"../schema.js\";\nimport {\n normalizeAIMessageToolCalls,\n tryCoerceMessageLikeToMessage,\n} from \"../stream/message-coercion.js\";\n\nexport { tryCoerceMessageLikeToMessage };\n\n/**\n * Replaces the `messages` property in a state type with `BaseMessage[]`.\n * Used by framework SDKs to reflect that `ensureHistoryMessageInstances`\n * converts plain message objects to class instances at runtime.\n */\nexport type StateWithBaseMessages<S> = S extends { messages: unknown }\n ? Omit<S, \"messages\"> & { messages: BaseMessage[] }\n : S;\n\n/**\n * Maps a `ThreadState<StateType>[]` so that the `messages` field inside\n * `values` is typed as `BaseMessage[]` instead of `Message[]`.\n */\nexport type HistoryWithBaseMessages<T> = T extends ThreadState<infer S>[]\n ? ThreadState<StateWithBaseMessages<S>>[]\n : T;\n\nexport function tryConvertToChunk(\n message: BaseMessage | BaseMessageChunk\n): BaseMessageChunk | null {\n try {\n if (BaseMessageChunk.isInstance(message)) return message;\n return convertToChunk(message);\n } catch {\n return null;\n }\n}\n\nfunction tryCoerceMessageLikeToChunk(\n message: Omit<Message, \"type\"> & { type: string }\n): BaseMessage | BaseMessageChunk {\n if (message.type === \"human\" || message.type === \"user\") {\n return new HumanMessageChunk(message);\n }\n\n if (message.type === \"ai\" || message.type === \"assistant\") {\n return new AIMessageChunk(normalizeAIMessageToolCalls(message));\n }\n\n if (message.type === \"system\") {\n return new SystemMessageChunk(message);\n }\n\n if (message.type === \"tool\" && \"tool_call_id\" in message) {\n return new ToolMessageChunk({\n ...message,\n tool_call_id: message.tool_call_id as string,\n });\n }\n\n return tryCoerceMessageLikeToMessage(message);\n}\n\nexport class MessageTupleManager {\n chunks: Record<\n string,\n {\n chunk?: BaseMessageChunk | BaseMessage;\n metadata?: Record<string, unknown>;\n index?: number;\n }\n > = {};\n\n constructor() {\n this.chunks = {};\n }\n\n add(\n serialized: Message,\n metadata: Record<string, unknown> | undefined\n ): string | null {\n // TODO: this is sometimes sent from the API\n // figure out how to prevent this or move this to LC.js\n if (serialized.type.endsWith(\"MessageChunk\")) {\n // eslint-disable-next-line no-param-reassign\n serialized.type = serialized.type\n .slice(0, -\"MessageChunk\".length)\n .toLowerCase() as Message[\"type\"];\n }\n\n const message = tryCoerceMessageLikeToChunk(serialized);\n const chunk = tryConvertToChunk(message);\n\n const { id } = chunk ?? message;\n if (!id) {\n console.warn(\n \"No message ID found for chunk, ignoring in state\",\n serialized\n );\n return null;\n }\n\n this.chunks[id] ??= {};\n this.chunks[id].metadata = metadata ?? this.chunks[id].metadata;\n if (chunk) {\n const prev = this.chunks[id].chunk;\n this.chunks[id].chunk =\n (BaseMessageChunk.isInstance(prev) ? prev : null)?.concat(chunk) ??\n chunk;\n } else {\n this.chunks[id].chunk = message;\n }\n\n return id;\n }\n\n clear() {\n this.chunks = {};\n }\n\n get(id: string | null | undefined, defaultIndex?: number) {\n if (id == null) return null;\n if (this.chunks[id] == null) return null;\n if (defaultIndex != null) this.chunks[id].index ??= defaultIndex;\n return this.chunks[id];\n }\n}\n\nexport const toMessageDict = (chunk: BaseMessage): Message => {\n const { type, data } = chunk.toDict();\n return { ...data, type } as Message;\n};\n\n/**\n * Identity converter that keeps @langchain/core class instances.\n * Used by framework SDKs to expose BaseMessage instances instead of plain dicts.\n */\nexport const toMessageClass = (chunk: BaseMessage): BaseMessage => chunk;\n\n/**\n * Ensures all messages in an array are BaseMessage class instances.\n * Messages that are already class instances pass through unchanged.\n * Plain message objects (e.g. from API values/history) are converted\n * via {@link tryCoerceMessageLikeToMessage}.\n */\nexport function ensureMessageInstances(\n messages: (Message | BaseMessage)[]\n): (BaseMessage | BaseMessageChunk)[] {\n return messages.map((msg) => {\n if (typeof (msg as BaseMessage).getType === \"function\") {\n return msg as BaseMessage;\n }\n return tryCoerceMessageLikeToMessage(\n msg as Omit<Message, \"type\"> & { type: string }\n );\n });\n}\n\n/**\n * Converts plain message objects within each history state's values\n * to proper BaseMessage class instances. Returns a new array with\n * shallow-copied states whose messages have been coerced.\n */\nexport function ensureHistoryMessageInstances<\n StateType extends Record<string, unknown>,\n>(\n history: ThreadState<StateType>[],\n messagesKey: string = \"messages\"\n): ThreadState<StateType>[] {\n return history.map((state) => {\n if (state.values == null) return state;\n const messages = state.values[messagesKey];\n if (!Array.isArray(messages)) return state;\n return {\n ...state,\n values: {\n ...state.values,\n [messagesKey]: ensureMessageInstances(messages),\n },\n };\n });\n}\n"],"mappings":";;;AAoCA,SAAgB,kBACd,SACyB;AACzB,KAAI;AACF,MAAI,iBAAiB,WAAW,QAAQ,CAAE,QAAO;AACjD,SAAO,eAAe,QAAQ;SACxB;AACN,SAAO;;;AAIX,SAAS,4BACP,SACgC;AAChC,KAAI,QAAQ,SAAS,WAAW,QAAQ,SAAS,OAC/C,QAAO,IAAI,kBAAkB,QAAQ;AAGvC,KAAI,QAAQ,SAAS,QAAQ,QAAQ,SAAS,YAC5C,QAAO,IAAI,eAAe,4BAA4B,QAAQ,CAAC;AAGjE,KAAI,QAAQ,SAAS,SACnB,QAAO,IAAI,mBAAmB,QAAQ;AAGxC,KAAI,QAAQ,SAAS,UAAU,kBAAkB,QAC/C,QAAO,IAAI,iBAAiB;EAC1B,GAAG;EACH,cAAc,QAAQ;EACvB,CAAC;AAGJ,QAAO,8BAA8B,QAAQ;;AAG/C,IAAa,sBAAb,MAAiC;CAC/B,SAOI,EAAE;CAEN,cAAc;AACZ,OAAK,SAAS,EAAE;;CAGlB,IACE,YACA,UACe;AAGf,MAAI,WAAW,KAAK,SAAS,eAAe,CAE1C,YAAW,OAAO,WAAW,KAC1B,MAAM,GAAG,IAAuB,CAChC,aAAa;EAGlB,MAAM,UAAU,4BAA4B,WAAW;EACvD,MAAM,QAAQ,kBAAkB,QAAQ;EAExC,MAAM,EAAE,OAAO,SAAS;AACxB,MAAI,CAAC,IAAI;AACP,WAAQ,KACN,oDACA,WACD;AACD,UAAO;;AAGT,OAAK,OAAO,QAAQ,EAAE;AACtB,OAAK,OAAO,IAAI,WAAW,YAAY,KAAK,OAAO,IAAI;AACvD,MAAI,OAAO;GACT,MAAM,OAAO,KAAK,OAAO,IAAI;AAC7B,QAAK,OAAO,IAAI,SACb,iBAAiB,WAAW,KAAK,GAAG,OAAO,OAAO,OAAO,MAAM,IAChE;QAEF,MAAK,OAAO,IAAI,QAAQ;AAG1B,SAAO;;CAGT,QAAQ;AACN,OAAK,SAAS,EAAE;;CAGlB,IAAI,IAA+B,cAAuB;AACxD,MAAI,MAAM,KAAM,QAAO;AACvB,MAAI,KAAK,OAAO,OAAO,KAAM,QAAO;AACpC,MAAI,gBAAgB,KAAM,MAAK,OAAO,IAAI,UAAU;AACpD,SAAO,KAAK,OAAO;;;AAIvB,MAAa,iBAAiB,UAAgC;CAC5D,MAAM,EAAE,MAAM,SAAS,MAAM,QAAQ;AACrC,QAAO;EAAE,GAAG;EAAM;EAAM;;;;;;AAO1B,MAAa,kBAAkB,UAAoC;;;;;;;AAQnE,SAAgB,uBACd,UACoC;AACpC,QAAO,SAAS,KAAK,QAAQ;AAC3B,MAAI,OAAQ,IAAoB,YAAY,WAC1C,QAAO;AAET,SAAO,8BACL,IACD;GACD;;;;;;;AAQJ,SAAgB,8BAGd,SACA,cAAsB,YACI;AAC1B,QAAO,QAAQ,KAAK,UAAU;AAC5B,MAAI,MAAM,UAAU,KAAM,QAAO;EACjC,MAAM,WAAW,MAAM,OAAO;AAC9B,MAAI,CAAC,MAAM,QAAQ,SAAS,CAAE,QAAO;AACrC,SAAO;GACL,GAAG;GACH,QAAQ;IACN,GAAG,MAAM;KACR,cAAc,uBAAuB,SAAS;IAChD;GACF;GACD"}
{"version":3,"file":"messages.js","names":[],"sources":["../../src/ui/messages.ts"],"sourcesContent":["import {\n type BaseMessage,\n BaseMessageChunk,\n convertToChunk,\n HumanMessageChunk,\n SystemMessageChunk,\n AIMessageChunk,\n ToolMessageChunk,\n} from \"@langchain/core/messages\";\n\nimport type { Message } from \"../types.messages.js\";\nimport type { ThreadState } from \"../schema.js\";\nimport { DEFAULT_MESSAGES_KEY } from \"../stream/constants.js\";\nimport {\n normalizeAIMessageToolCalls,\n tryCoerceMessageLikeToMessage,\n} from \"../stream/message-coercion.js\";\n\nexport { tryCoerceMessageLikeToMessage };\n\n/**\n * Replaces the `messages` property in a state type with `BaseMessage[]`.\n * Used by framework SDKs to reflect that `ensureHistoryMessageInstances`\n * converts plain message objects to class instances at runtime.\n */\nexport type StateWithBaseMessages<S> = S extends { messages: unknown }\n ? Omit<S, \"messages\"> & { messages: BaseMessage[] }\n : S;\n\n/**\n * Maps a `ThreadState<StateType>[]` so that the `messages` field inside\n * `values` is typed as `BaseMessage[]` instead of `Message[]`.\n */\nexport type HistoryWithBaseMessages<T> = T extends ThreadState<infer S>[]\n ? ThreadState<StateWithBaseMessages<S>>[]\n : T;\n\nexport function tryConvertToChunk(\n message: BaseMessage | BaseMessageChunk\n): BaseMessageChunk | null {\n try {\n if (BaseMessageChunk.isInstance(message)) return message;\n return convertToChunk(message);\n } catch {\n return null;\n }\n}\n\nfunction tryCoerceMessageLikeToChunk(\n message: Omit<Message, \"type\"> & { type: string }\n): BaseMessage | BaseMessageChunk {\n if (message.type === \"human\" || message.type === \"user\") {\n return new HumanMessageChunk(message);\n }\n\n if (message.type === \"ai\" || message.type === \"assistant\") {\n return new AIMessageChunk(normalizeAIMessageToolCalls(message));\n }\n\n if (message.type === \"system\") {\n return new SystemMessageChunk(message);\n }\n\n if (message.type === \"tool\" && \"tool_call_id\" in message) {\n return new ToolMessageChunk({\n ...message,\n tool_call_id: message.tool_call_id as string,\n });\n }\n\n return tryCoerceMessageLikeToMessage(message);\n}\n\nexport class MessageTupleManager {\n chunks: Record<\n string,\n {\n chunk?: BaseMessageChunk | BaseMessage;\n metadata?: Record<string, unknown>;\n index?: number;\n }\n > = {};\n\n constructor() {\n this.chunks = {};\n }\n\n add(\n serialized: Message,\n metadata: Record<string, unknown> | undefined\n ): string | null {\n // TODO: this is sometimes sent from the API\n // figure out how to prevent this or move this to LC.js\n if (serialized.type.endsWith(\"MessageChunk\")) {\n // eslint-disable-next-line no-param-reassign\n serialized.type = serialized.type\n .slice(0, -\"MessageChunk\".length)\n .toLowerCase() as Message[\"type\"];\n }\n\n const message = tryCoerceMessageLikeToChunk(serialized);\n const chunk = tryConvertToChunk(message);\n\n const { id } = chunk ?? message;\n if (!id) {\n console.warn(\n \"No message ID found for chunk, ignoring in state\",\n serialized\n );\n return null;\n }\n\n this.chunks[id] ??= {};\n this.chunks[id].metadata = metadata ?? this.chunks[id].metadata;\n if (chunk) {\n const prev = this.chunks[id].chunk;\n this.chunks[id].chunk =\n (BaseMessageChunk.isInstance(prev) ? prev : null)?.concat(chunk) ??\n chunk;\n } else {\n this.chunks[id].chunk = message;\n }\n\n return id;\n }\n\n clear() {\n this.chunks = {};\n }\n\n get(id: string | null | undefined, defaultIndex?: number) {\n if (id == null) return null;\n if (this.chunks[id] == null) return null;\n if (defaultIndex != null) this.chunks[id].index ??= defaultIndex;\n return this.chunks[id];\n }\n}\n\nexport const toMessageDict = (chunk: BaseMessage): Message => {\n const { type, data } = chunk.toDict();\n return { ...data, type } as Message;\n};\n\n/**\n * Identity converter that keeps @langchain/core class instances.\n * Used by framework SDKs to expose BaseMessage instances instead of plain dicts.\n */\nexport const toMessageClass = (chunk: BaseMessage): BaseMessage => chunk;\n\n/**\n * Ensures all messages in an array are BaseMessage class instances.\n * Messages that are already class instances pass through unchanged.\n * Plain message objects (e.g. from API values/history) are converted\n * via {@link tryCoerceMessageLikeToMessage}.\n */\nexport function ensureMessageInstances(\n messages: (Message | BaseMessage)[]\n): (BaseMessage | BaseMessageChunk)[] {\n return messages.map((msg) => {\n if (typeof (msg as BaseMessage).getType === \"function\") {\n return msg as BaseMessage;\n }\n return tryCoerceMessageLikeToMessage(\n msg as Omit<Message, \"type\"> & { type: string }\n );\n });\n}\n\n/**\n * Converts plain message objects within each history state's values\n * to proper BaseMessage class instances. Returns a new array with\n * shallow-copied states whose messages have been coerced.\n */\nexport function ensureHistoryMessageInstances<\n StateType extends Record<string, unknown>,\n>(\n history: ThreadState<StateType>[],\n messagesKey: string = DEFAULT_MESSAGES_KEY\n): ThreadState<StateType>[] {\n return history.map((state) => {\n if (state.values == null) return state;\n const messages = state.values[messagesKey];\n if (!Array.isArray(messages)) return state;\n return {\n ...state,\n values: {\n ...state.values,\n [messagesKey]: ensureMessageInstances(messages),\n },\n };\n });\n}\n"],"mappings":";;;;AAqCA,SAAgB,kBACd,SACyB;AACzB,KAAI;AACF,MAAI,iBAAiB,WAAW,QAAQ,CAAE,QAAO;AACjD,SAAO,eAAe,QAAQ;SACxB;AACN,SAAO;;;AAIX,SAAS,4BACP,SACgC;AAChC,KAAI,QAAQ,SAAS,WAAW,QAAQ,SAAS,OAC/C,QAAO,IAAI,kBAAkB,QAAQ;AAGvC,KAAI,QAAQ,SAAS,QAAQ,QAAQ,SAAS,YAC5C,QAAO,IAAI,eAAe,4BAA4B,QAAQ,CAAC;AAGjE,KAAI,QAAQ,SAAS,SACnB,QAAO,IAAI,mBAAmB,QAAQ;AAGxC,KAAI,QAAQ,SAAS,UAAU,kBAAkB,QAC/C,QAAO,IAAI,iBAAiB;EAC1B,GAAG;EACH,cAAc,QAAQ;EACvB,CAAC;AAGJ,QAAO,8BAA8B,QAAQ;;AAG/C,IAAa,sBAAb,MAAiC;CAC/B,SAOI,EAAE;CAEN,cAAc;AACZ,OAAK,SAAS,EAAE;;CAGlB,IACE,YACA,UACe;AAGf,MAAI,WAAW,KAAK,SAAS,eAAe,CAE1C,YAAW,OAAO,WAAW,KAC1B,MAAM,GAAG,IAAuB,CAChC,aAAa;EAGlB,MAAM,UAAU,4BAA4B,WAAW;EACvD,MAAM,QAAQ,kBAAkB,QAAQ;EAExC,MAAM,EAAE,OAAO,SAAS;AACxB,MAAI,CAAC,IAAI;AACP,WAAQ,KACN,oDACA,WACD;AACD,UAAO;;AAGT,OAAK,OAAO,QAAQ,EAAE;AACtB,OAAK,OAAO,IAAI,WAAW,YAAY,KAAK,OAAO,IAAI;AACvD,MAAI,OAAO;GACT,MAAM,OAAO,KAAK,OAAO,IAAI;AAC7B,QAAK,OAAO,IAAI,SACb,iBAAiB,WAAW,KAAK,GAAG,OAAO,OAAO,OAAO,MAAM,IAChE;QAEF,MAAK,OAAO,IAAI,QAAQ;AAG1B,SAAO;;CAGT,QAAQ;AACN,OAAK,SAAS,EAAE;;CAGlB,IAAI,IAA+B,cAAuB;AACxD,MAAI,MAAM,KAAM,QAAO;AACvB,MAAI,KAAK,OAAO,OAAO,KAAM,QAAO;AACpC,MAAI,gBAAgB,KAAM,MAAK,OAAO,IAAI,UAAU;AACpD,SAAO,KAAK,OAAO;;;AAIvB,MAAa,iBAAiB,UAAgC;CAC5D,MAAM,EAAE,MAAM,SAAS,MAAM,QAAQ;AACrC,QAAO;EAAE,GAAG;EAAM;EAAM;;;;;;AAO1B,MAAa,kBAAkB,UAAoC;;;;;;;AAQnE,SAAgB,uBACd,UACoC;AACpC,QAAO,SAAS,KAAK,QAAQ;AAC3B,MAAI,OAAQ,IAAoB,YAAY,WAC1C,QAAO;AAET,SAAO,8BACL,IACD;GACD;;;;;;;AAQJ,SAAgB,8BAGd,SACA,cAAsB,sBACI;AAC1B,QAAO,QAAQ,KAAK,UAAU;AAC5B,MAAI,MAAM,UAAU,KAAM,QAAO;EACjC,MAAM,WAAW,MAAM,OAAO;AAC9B,MAAI,CAAC,MAAM,QAAQ,SAAS,CAAE,QAAO;AACrC,SAAO;GACL,GAAG;GACH,QAAQ;IACN,GAAG,MAAM;KACR,cAAc,uBAAuB,SAAS;IAChD;GACF;GACD"}

@@ -0,1 +1,2 @@

require("../stream/constants.cjs");
const require_messages = require("./messages.cjs");

@@ -2,0 +3,0 @@ const require_headless_tools = require("../headless-tools.cjs");

@@ -1,1 +0,1 @@

{"version":3,"file":"orchestrator-custom.cjs","names":["#options","#historyValues","#threadId","MessageTupleManager","StreamManager","toMessageClass","#streamUnsub","#flushPendingHeadlessToolInterrupts","#notify","#getMessages","#listeners","#version","#disposed","#handledHeadlessToolInterruptIds","#branch","ensureMessageInstances","getToolCallsWithResults","userFacingInterruptsFromValuesArray","extractInterrupts","#setMessages"],"sources":["../../src/ui/orchestrator-custom.ts"],"sourcesContent":["import type { BaseMessage } from \"@langchain/core/messages\";\n\nimport type { ThreadState, Interrupt } from \"../schema.js\";\nimport type { StreamMode } from \"../types.stream.js\";\nimport type { Message } from \"../types.messages.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport { StreamManager, type EventStreamEvent } from \"./manager.js\";\nimport {\n MessageTupleManager,\n toMessageClass,\n ensureMessageInstances,\n} from \"./messages.js\";\nimport {\n extractInterrupts,\n userFacingInterruptsFromValuesArray,\n} from \"./interrupts.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport { flushPendingHeadlessToolInterrupts } from \"../headless-tools.js\";\nimport type {\n AnyStreamCustomOptions,\n CustomSubmitOptions,\n MessageMetadata,\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetConfigurableType,\n SubagentStreamInterface,\n} from \"./types.js\";\n\n/**\n * Create a custom transport thread state.\n * @param values - The values to use.\n * @param threadId - The ID of the thread to use.\n * @returns The custom transport thread state.\n */\nfunction createCustomTransportThreadState<\n StateType extends Record<string, unknown>,\n>(values: StateType, threadId: string): ThreadState<StateType> {\n return {\n values,\n next: [],\n tasks: [],\n metadata: undefined,\n created_at: null,\n checkpoint: {\n thread_id: threadId,\n checkpoint_id: null,\n checkpoint_ns: \"\",\n checkpoint_map: null,\n },\n parent_checkpoint: null,\n };\n}\n\n/**\n * Framework-agnostic orchestrator for custom transport streams.\n *\n * Encapsulates all business logic shared across React, Vue, Svelte, and Angular\n * for custom transport (non-LGP) streaming.\n */\nexport class CustomStreamOrchestrator<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n> {\n readonly stream: StreamManager<StateType, Bag>;\n\n readonly messageManager: MessageTupleManager;\n\n readonly #options: AnyStreamCustomOptions<StateType, Bag>;\n\n readonly #historyValues: StateType;\n\n #threadId: string | null;\n\n #branch: string = \"\";\n\n #listeners = new Set<() => void>();\n\n #version = 0;\n\n #streamUnsub: (() => void) | null = null;\n\n #disposed = false;\n\n #handledHeadlessToolInterruptIds = new Set<string>();\n\n /**\n * Create a new {@link CustomStreamOrchestrator} instance.\n *\n * @param options - Configuration options for the custom transport stream,\n * including thread ID, transport, callbacks, and subagent settings.\n */\n constructor(options: AnyStreamCustomOptions<StateType, Bag>) {\n this.#options = options;\n\n this.#threadId = options.threadId ?? null;\n\n this.messageManager = new MessageTupleManager();\n this.stream = new StreamManager<StateType, Bag>(this.messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n toMessage: options.toMessage ?? toMessageClass,\n });\n\n this.#historyValues = options.initialValues ?? ({} as StateType);\n\n this.#streamUnsub = this.stream.subscribe(() => {\n this.#flushPendingHeadlessToolInterrupts();\n this.#notify();\n });\n\n const historyMessages = this.#getMessages(this.#historyValues);\n if (\n options.filterSubagentMessages &&\n !this.stream.isLoading &&\n historyMessages.length > 0\n ) {\n this.stream.reconstructSubagents(historyMessages, {\n skipIfPopulated: true,\n });\n }\n }\n\n /**\n * Register a listener that is called whenever the orchestrator state changes.\n *\n * @param listener - Callback invoked on each state change.\n * @returns An unsubscribe function that removes the listener.\n */\n subscribe = (listener: () => void): (() => void) => {\n this.#listeners.add(listener);\n return () => {\n this.#listeners.delete(listener);\n };\n };\n\n /**\n * Return the current version number, incremented on each state change.\n * Useful as a cache key for external sync (e.g. `useSyncExternalStore`).\n *\n * @returns The current version counter.\n */\n getSnapshot = (): number => this.#version;\n\n /**\n * Custom transports do not negotiate stream modes with the server the way\n * LangGraph Platform streams do, but framework adapters call this method on\n * both orchestrator variants. Keep the API surface aligned as a no-op.\n */\n trackStreamMode(..._modes: StreamMode[]): void {}\n\n #notify(): void {\n if (this.#disposed) return;\n this.#version += 1;\n for (const listener of this.#listeners) {\n listener();\n }\n }\n\n /**\n * Synchronize the external thread ID with the orchestrator.\n * If the ID has changed, the current stream is cleared and listeners\n * are notified.\n *\n * @param newId - The new thread ID, or `null` to clear.\n */\n syncThreadId(newId: string | null): void {\n if (newId !== this.#threadId) {\n this.#threadId = newId;\n this.#handledHeadlessToolInterruptIds.clear();\n this.stream.clear();\n this.#notify();\n }\n }\n\n #getMessages = (value: StateType): Message[] => {\n const messagesKey = this.#options.messagesKey ?? \"messages\";\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n #setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = this.#options.messagesKey ?? \"messages\";\n return { ...current, [messagesKey]: messages };\n };\n\n /**\n * The current stream state values, falling back to an empty object\n * when no stream values are available.\n */\n get values(): StateType {\n return this.stream.values ?? ({} as StateType);\n }\n\n /**\n * The raw stream state values, or `null` if no stream has been started\n * or values have not yet been received.\n */\n get streamValues(): StateType | null {\n return this.stream.values;\n }\n\n /** The most recent stream error, or `undefined` if no error occurred. */\n get error(): unknown {\n return this.stream.error;\n }\n\n /** Whether a stream is currently in progress. */\n get isLoading(): boolean {\n return this.stream.isLoading;\n }\n\n /** The current branch identifier. */\n get branch(): string {\n return this.#branch;\n }\n\n /**\n * Update the current branch and notify listeners.\n *\n * @param value - The new branch identifier.\n */\n setBranch(value: string): void {\n this.#branch = value;\n this.#notify();\n }\n\n /**\n * All messages from the current stream values, converted to\n * {@link BaseMessage} instances. Returns an empty array when no\n * stream values are available.\n */\n get messages(): BaseMessage[] {\n if (!this.stream.values) return [];\n return ensureMessageInstances(\n this.#getMessages(this.stream.values)\n ) as BaseMessage[];\n }\n\n /**\n * All tool calls paired with their results extracted from the\n * current stream messages.\n */\n get toolCalls() {\n if (!this.stream.values) return [];\n return getToolCallsWithResults(this.#getMessages(this.stream.values));\n }\n\n /**\n * Get tool calls (with results) that belong to a specific AI message.\n *\n * @param message - The AI message whose tool calls to retrieve.\n * @returns Tool calls associated with the given message.\n */\n getToolCalls(message: Message) {\n if (!this.stream.values) return [];\n const allToolCalls = getToolCallsWithResults(\n this.#getMessages(this.stream.values)\n );\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n }\n\n /**\n * All active interrupts from the current stream values.\n * Returns a single breakpoint interrupt when the interrupt array is\n * present but empty, or an empty array when no interrupts exist.\n */\n get interrupts(): Interrupt<GetInterruptType<Bag>>[] {\n if (\n this.stream.values != null &&\n \"__interrupt__\" in this.stream.values &&\n Array.isArray(this.stream.values.__interrupt__)\n ) {\n return userFacingInterruptsFromValuesArray<GetInterruptType<Bag>>(\n this.stream.values.__interrupt__ as Interrupt<GetInterruptType<Bag>>[]\n );\n }\n return [];\n }\n\n /**\n * The first active interrupt extracted from the current stream values,\n * or `undefined` if there are no interrupts.\n */\n get interrupt(): Interrupt<GetInterruptType<Bag>> | undefined {\n return extractInterrupts<GetInterruptType<Bag>>(this.stream.values);\n }\n\n /**\n * Retrieve stream-level metadata for a given message.\n *\n * @param message - The message to look up metadata for.\n * @param index - Optional positional index used as fallback message ID.\n * @returns The metadata associated with the message, or `undefined`\n * if no stream metadata is available.\n */\n getMessagesMetadata(\n message: Message,\n index?: number\n ): MessageMetadata<StateType> | undefined {\n const streamMetadata = this.messageManager.get(message.id)?.metadata;\n if (streamMetadata != null) {\n return {\n messageId: message.id ?? String(index),\n firstSeenState: undefined,\n branch: undefined,\n branchOptions: undefined,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n return undefined;\n }\n\n /** A map of all tracked subagent streams, keyed by tool call ID. */\n get subagents(): Map<string, SubagentStreamInterface> {\n return this.stream.getSubagents();\n }\n\n /** The subset of subagent streams that are currently active (loading). */\n get activeSubagents(): SubagentStreamInterface[] {\n return this.stream.getActiveSubagents();\n }\n\n /**\n * Look up a single subagent stream by its tool call ID.\n *\n * @param toolCallId - The tool call ID that initiated the subagent.\n * @returns The subagent stream, or `undefined` if not found.\n */\n getSubagent(toolCallId: string) {\n return this.stream.getSubagent(toolCallId);\n }\n\n /**\n * Retrieve all subagent streams matching a given tool name / type.\n *\n * @param type - The subagent type (tool name) to filter by.\n * @returns An array of matching subagent streams.\n */\n getSubagentsByType(type: string) {\n return this.stream.getSubagentsByType(type);\n }\n\n /**\n * Retrieve all subagent streams associated with a specific AI message.\n *\n * @param messageId - The ID of the parent AI message.\n * @returns An array of subagent streams linked to the message.\n */\n getSubagentsByMessage(messageId: string) {\n return this.stream.getSubagentsByMessage(messageId);\n }\n\n /**\n * Reconstruct subagent streams from history values when subagent\n * filtering is enabled and the stream is not currently loading.\n * This is a no-op if subagents are already populated.\n */\n reconstructSubagentsIfNeeded(): void {\n const hvMessages = this.#getMessages(this.#historyValues);\n if (\n this.#options.filterSubagentMessages &&\n !this.stream.isLoading &&\n hvMessages.length > 0\n ) {\n this.stream.reconstructSubagents(hvMessages, { skipIfPopulated: true });\n }\n }\n\n /**\n * Abort the current stream and invoke the `onStop` callback\n * if one was provided in the options.\n */\n stop(): void {\n void this.stream.stop(this.#historyValues, {\n onStop: this.#options.onStop,\n });\n }\n\n /**\n * Switch to a different thread. If the thread ID actually changed,\n * the current stream is cleared and listeners are notified.\n *\n * @param newThreadId - The thread ID to switch to, or `null` to clear.\n */\n switchThread(newThreadId: string | null): void {\n if (newThreadId !== this.#threadId) {\n this.#threadId = newThreadId;\n this.#handledHeadlessToolInterruptIds.clear();\n this.stream.clear();\n this.#notify();\n }\n }\n\n /**\n * Start a new stream run against the custom transport.\n *\n * This is the low-level submit entry point that handles thread ID\n * resolution, optimistic value merging, and transport invocation.\n * Prefer {@link submit} unless you need to bypass higher-level wrappers.\n *\n * @param values - The input values to send, or `null`/`undefined` for\n * a resume-style invocation.\n * @param submitOptions - Optional per-call overrides such as\n * `optimisticValues`, `config`, `command`, and error callbacks.\n */\n async submitDirect(\n values: GetUpdateType<Bag, StateType> | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, GetConfigurableType<Bag>>\n ): Promise<void> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n\n const currentThreadId = this.#options.threadId ?? null;\n if (currentThreadId !== this.#threadId) {\n this.#threadId = currentThreadId;\n this.stream.clear();\n }\n\n let usableThreadId = this.#threadId ?? submitOptions?.threadId;\n\n this.stream.setStreamValues(() => {\n if (submitOptions?.optimisticValues != null) {\n return {\n ...this.#historyValues,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(this.#historyValues)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...this.#historyValues };\n });\n\n await this.stream.start(\n async (signal: AbortSignal) => {\n if (!usableThreadId) {\n usableThreadId = crypto.randomUUID();\n this.#threadId = usableThreadId;\n this.#options.onThreadId?.(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n return this.#options.transport.stream({\n input: values,\n context: submitOptions?.context,\n command: submitOptions?.command,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n signal,\n config: {\n ...submitOptions?.config,\n configurable: {\n thread_id: usableThreadId,\n ...submitOptions?.config?.configurable,\n } as unknown as GetConfigurableType<Bag>,\n },\n }) as Promise<\n AsyncGenerator<EventStreamEvent<StateType, UpdateType, CustomType>>\n >;\n },\n {\n getMessages: this.#getMessages,\n setMessages: this.#setMessages,\n initialValues: {} as StateType,\n callbacks: this.#options,\n onSuccess: () => {\n if (!usableThreadId) return undefined;\n\n const finalValues = this.stream.values ?? this.#historyValues;\n this.#options.onFinish?.(\n createCustomTransportThreadState(finalValues, usableThreadId),\n undefined\n );\n\n return undefined;\n },\n onError: (error) => {\n this.#options.onError?.(error, undefined);\n submitOptions?.onError?.(error, undefined);\n },\n }\n );\n }\n\n /**\n * Submit input values and start a new stream run.\n *\n * Delegates to {@link submitDirect}. Override or wrap this method\n * in framework adapters to add queuing or other middleware.\n *\n * @param values - The input values to send, or `null`/`undefined` for\n * a resume-style invocation.\n * @param submitOptions - Optional per-call overrides.\n */\n async submit(\n values: GetUpdateType<Bag, StateType> | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, GetConfigurableType<Bag>>\n ): Promise<void> {\n await this.submitDirect(values, submitOptions);\n }\n\n /**\n * Tear down the orchestrator. Marks the instance as disposed,\n * unsubscribes from the stream, and aborts any in-progress stream.\n * After calling this method, no further notifications will be emitted.\n */\n dispose(): void {\n this.#disposed = true;\n this.#streamUnsub?.();\n this.#streamUnsub = null;\n void this.stream.stop(this.#historyValues, {\n onStop: this.#options.onStop,\n });\n }\n\n #flushPendingHeadlessToolInterrupts(): void {\n flushPendingHeadlessToolInterrupts(\n this.stream.values as Record<string, unknown> | null,\n this.#options.tools,\n this.#handledHeadlessToolInterruptIds,\n {\n onTool: this.#options.onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n this.submit(null, {\n command,\n }),\n }\n );\n }\n}\n"],"mappings":"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"}
{"version":3,"file":"orchestrator-custom.cjs","names":["#options","#historyValues","#threadId","MessageTupleManager","StreamManager","toMessageClass","#streamUnsub","#flushPendingHeadlessToolInterrupts","#notify","#getMessages","#listeners","#version","#disposed","#handledHeadlessToolInterruptIds","#branch","ensureMessageInstances","getToolCallsWithResults","userFacingInterruptsFromValuesArray","extractInterrupts","#setMessages"],"sources":["../../src/ui/orchestrator-custom.ts"],"sourcesContent":["import type { BaseMessage } from \"@langchain/core/messages\";\n\nimport { DEFAULT_MESSAGES_KEY } from \"../stream/constants.js\";\nimport type { ThreadState, Interrupt } from \"../schema.js\";\nimport type { StreamMode } from \"../types.stream.js\";\nimport type { Message } from \"../types.messages.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport { StreamManager, type EventStreamEvent } from \"./manager.js\";\nimport {\n MessageTupleManager,\n toMessageClass,\n ensureMessageInstances,\n} from \"./messages.js\";\nimport {\n extractInterrupts,\n userFacingInterruptsFromValuesArray,\n} from \"./interrupts.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport { flushPendingHeadlessToolInterrupts } from \"../headless-tools.js\";\nimport type {\n AnyStreamCustomOptions,\n CustomSubmitOptions,\n MessageMetadata,\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetConfigurableType,\n SubagentStreamInterface,\n} from \"./types.js\";\n\n/**\n * Create a custom transport thread state.\n * @param values - The values to use.\n * @param threadId - The ID of the thread to use.\n * @returns The custom transport thread state.\n */\nfunction createCustomTransportThreadState<\n StateType extends Record<string, unknown>,\n>(values: StateType, threadId: string): ThreadState<StateType> {\n return {\n values,\n next: [],\n tasks: [],\n metadata: undefined,\n created_at: null,\n checkpoint: {\n thread_id: threadId,\n checkpoint_id: null,\n checkpoint_ns: \"\",\n checkpoint_map: null,\n },\n parent_checkpoint: null,\n };\n}\n\n/**\n * Framework-agnostic orchestrator for custom transport streams.\n *\n * Encapsulates all business logic shared across React, Vue, Svelte, and Angular\n * for custom transport (non-LGP) streaming.\n */\nexport class CustomStreamOrchestrator<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n> {\n readonly stream: StreamManager<StateType, Bag>;\n\n readonly messageManager: MessageTupleManager;\n\n readonly #options: AnyStreamCustomOptions<StateType, Bag>;\n\n readonly #historyValues: StateType;\n\n #threadId: string | null;\n\n #branch: string = \"\";\n\n #listeners = new Set<() => void>();\n\n #version = 0;\n\n #streamUnsub: (() => void) | null = null;\n\n #disposed = false;\n\n #handledHeadlessToolInterruptIds = new Set<string>();\n\n /**\n * Create a new {@link CustomStreamOrchestrator} instance.\n *\n * @param options - Configuration options for the custom transport stream,\n * including thread ID, transport, callbacks, and subagent settings.\n */\n constructor(options: AnyStreamCustomOptions<StateType, Bag>) {\n this.#options = options;\n\n this.#threadId = options.threadId ?? null;\n\n this.messageManager = new MessageTupleManager();\n this.stream = new StreamManager<StateType, Bag>(this.messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n toMessage: options.toMessage ?? toMessageClass,\n });\n\n this.#historyValues = options.initialValues ?? ({} as StateType);\n\n this.#streamUnsub = this.stream.subscribe(() => {\n this.#flushPendingHeadlessToolInterrupts();\n this.#notify();\n });\n\n const historyMessages = this.#getMessages(this.#historyValues);\n if (\n options.filterSubagentMessages &&\n !this.stream.isLoading &&\n historyMessages.length > 0\n ) {\n this.stream.reconstructSubagents(historyMessages, {\n skipIfPopulated: true,\n });\n }\n }\n\n /**\n * Register a listener that is called whenever the orchestrator state changes.\n *\n * @param listener - Callback invoked on each state change.\n * @returns An unsubscribe function that removes the listener.\n */\n subscribe = (listener: () => void): (() => void) => {\n this.#listeners.add(listener);\n return () => {\n this.#listeners.delete(listener);\n };\n };\n\n /**\n * Return the current version number, incremented on each state change.\n * Useful as a cache key for external sync (e.g. `useSyncExternalStore`).\n *\n * @returns The current version counter.\n */\n getSnapshot = (): number => this.#version;\n\n /**\n * Custom transports do not negotiate stream modes with the server the way\n * LangGraph Platform streams do, but framework adapters call this method on\n * both orchestrator variants. Keep the API surface aligned as a no-op.\n */\n trackStreamMode(..._modes: StreamMode[]): void {}\n\n #notify(): void {\n if (this.#disposed) return;\n this.#version += 1;\n for (const listener of this.#listeners) {\n listener();\n }\n }\n\n /**\n * Synchronize the external thread ID with the orchestrator.\n * If the ID has changed, the current stream is cleared and listeners\n * are notified.\n *\n * @param newId - The new thread ID, or `null` to clear.\n */\n syncThreadId(newId: string | null): void {\n if (newId !== this.#threadId) {\n this.#threadId = newId;\n this.#handledHeadlessToolInterruptIds.clear();\n this.stream.clear();\n this.#notify();\n }\n }\n\n #getMessages = (value: StateType): Message[] => {\n const messagesKey = this.#options.messagesKey ?? DEFAULT_MESSAGES_KEY;\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n #setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = this.#options.messagesKey ?? DEFAULT_MESSAGES_KEY;\n return { ...current, [messagesKey]: messages };\n };\n\n /**\n * The current stream state values, falling back to an empty object\n * when no stream values are available.\n */\n get values(): StateType {\n return this.stream.values ?? ({} as StateType);\n }\n\n /**\n * The raw stream state values, or `null` if no stream has been started\n * or values have not yet been received.\n */\n get streamValues(): StateType | null {\n return this.stream.values;\n }\n\n /** The most recent stream error, or `undefined` if no error occurred. */\n get error(): unknown {\n return this.stream.error;\n }\n\n /** Whether a stream is currently in progress. */\n get isLoading(): boolean {\n return this.stream.isLoading;\n }\n\n /** The current branch identifier. */\n get branch(): string {\n return this.#branch;\n }\n\n /**\n * Update the current branch and notify listeners.\n *\n * @param value - The new branch identifier.\n */\n setBranch(value: string): void {\n this.#branch = value;\n this.#notify();\n }\n\n /**\n * All messages from the current stream values, converted to\n * {@link BaseMessage} instances. Returns an empty array when no\n * stream values are available.\n */\n get messages(): BaseMessage[] {\n if (!this.stream.values) return [];\n return ensureMessageInstances(\n this.#getMessages(this.stream.values)\n ) as BaseMessage[];\n }\n\n /**\n * All tool calls paired with their results extracted from the\n * current stream messages.\n */\n get toolCalls() {\n if (!this.stream.values) return [];\n return getToolCallsWithResults(this.#getMessages(this.stream.values));\n }\n\n /**\n * Get tool calls (with results) that belong to a specific AI message.\n *\n * @param message - The AI message whose tool calls to retrieve.\n * @returns Tool calls associated with the given message.\n */\n getToolCalls(message: Message) {\n if (!this.stream.values) return [];\n const allToolCalls = getToolCallsWithResults(\n this.#getMessages(this.stream.values)\n );\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n }\n\n /**\n * All active interrupts from the current stream values.\n * Returns a single breakpoint interrupt when the interrupt array is\n * present but empty, or an empty array when no interrupts exist.\n */\n get interrupts(): Interrupt<GetInterruptType<Bag>>[] {\n if (\n this.stream.values != null &&\n \"__interrupt__\" in this.stream.values &&\n Array.isArray(this.stream.values.__interrupt__)\n ) {\n return userFacingInterruptsFromValuesArray<GetInterruptType<Bag>>(\n this.stream.values.__interrupt__ as Interrupt<GetInterruptType<Bag>>[]\n );\n }\n return [];\n }\n\n /**\n * The first active interrupt extracted from the current stream values,\n * or `undefined` if there are no interrupts.\n */\n get interrupt(): Interrupt<GetInterruptType<Bag>> | undefined {\n return extractInterrupts<GetInterruptType<Bag>>(this.stream.values);\n }\n\n /**\n * Retrieve stream-level metadata for a given message.\n *\n * @param message - The message to look up metadata for.\n * @param index - Optional positional index used as fallback message ID.\n * @returns The metadata associated with the message, or `undefined`\n * if no stream metadata is available.\n */\n getMessagesMetadata(\n message: Message,\n index?: number\n ): MessageMetadata<StateType> | undefined {\n const streamMetadata = this.messageManager.get(message.id)?.metadata;\n if (streamMetadata != null) {\n return {\n messageId: message.id ?? String(index),\n firstSeenState: undefined,\n branch: undefined,\n branchOptions: undefined,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n return undefined;\n }\n\n /** A map of all tracked subagent streams, keyed by tool call ID. */\n get subagents(): Map<string, SubagentStreamInterface> {\n return this.stream.getSubagents();\n }\n\n /** The subset of subagent streams that are currently active (loading). */\n get activeSubagents(): SubagentStreamInterface[] {\n return this.stream.getActiveSubagents();\n }\n\n /**\n * Look up a single subagent stream by its tool call ID.\n *\n * @param toolCallId - The tool call ID that initiated the subagent.\n * @returns The subagent stream, or `undefined` if not found.\n */\n getSubagent(toolCallId: string) {\n return this.stream.getSubagent(toolCallId);\n }\n\n /**\n * Retrieve all subagent streams matching a given tool name / type.\n *\n * @param type - The subagent type (tool name) to filter by.\n * @returns An array of matching subagent streams.\n */\n getSubagentsByType(type: string) {\n return this.stream.getSubagentsByType(type);\n }\n\n /**\n * Retrieve all subagent streams associated with a specific AI message.\n *\n * @param messageId - The ID of the parent AI message.\n * @returns An array of subagent streams linked to the message.\n */\n getSubagentsByMessage(messageId: string) {\n return this.stream.getSubagentsByMessage(messageId);\n }\n\n /**\n * Reconstruct subagent streams from history values when subagent\n * filtering is enabled and the stream is not currently loading.\n * This is a no-op if subagents are already populated.\n */\n reconstructSubagentsIfNeeded(): void {\n const hvMessages = this.#getMessages(this.#historyValues);\n if (\n this.#options.filterSubagentMessages &&\n !this.stream.isLoading &&\n hvMessages.length > 0\n ) {\n this.stream.reconstructSubagents(hvMessages, { skipIfPopulated: true });\n }\n }\n\n /**\n * Abort the current stream and invoke the `onStop` callback\n * if one was provided in the options.\n */\n stop(): void {\n void this.stream.stop(this.#historyValues, {\n onStop: this.#options.onStop,\n });\n }\n\n /**\n * Switch to a different thread. If the thread ID actually changed,\n * the current stream is cleared and listeners are notified.\n *\n * @param newThreadId - The thread ID to switch to, or `null` to clear.\n */\n switchThread(newThreadId: string | null): void {\n if (newThreadId !== this.#threadId) {\n this.#threadId = newThreadId;\n this.#handledHeadlessToolInterruptIds.clear();\n this.stream.clear();\n this.#notify();\n }\n }\n\n /**\n * Start a new stream run against the custom transport.\n *\n * This is the low-level submit entry point that handles thread ID\n * resolution, optimistic value merging, and transport invocation.\n * Prefer {@link submit} unless you need to bypass higher-level wrappers.\n *\n * @param values - The input values to send, or `null`/`undefined` for\n * a resume-style invocation.\n * @param submitOptions - Optional per-call overrides such as\n * `optimisticValues`, `config`, `command`, and error callbacks.\n */\n async submitDirect(\n values: GetUpdateType<Bag, StateType> | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, GetConfigurableType<Bag>>\n ): Promise<void> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n\n const currentThreadId = this.#options.threadId ?? null;\n if (currentThreadId !== this.#threadId) {\n this.#threadId = currentThreadId;\n this.stream.clear();\n }\n\n let usableThreadId = this.#threadId ?? submitOptions?.threadId;\n\n this.stream.setStreamValues(() => {\n if (submitOptions?.optimisticValues != null) {\n return {\n ...this.#historyValues,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(this.#historyValues)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...this.#historyValues };\n });\n\n await this.stream.start(\n async (signal: AbortSignal) => {\n if (!usableThreadId) {\n usableThreadId = crypto.randomUUID();\n this.#threadId = usableThreadId;\n this.#options.onThreadId?.(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n return this.#options.transport.stream({\n input: values,\n context: submitOptions?.context,\n command: submitOptions?.command,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n signal,\n config: {\n ...submitOptions?.config,\n configurable: {\n thread_id: usableThreadId,\n ...submitOptions?.config?.configurable,\n } as unknown as GetConfigurableType<Bag>,\n },\n }) as Promise<\n AsyncGenerator<EventStreamEvent<StateType, UpdateType, CustomType>>\n >;\n },\n {\n getMessages: this.#getMessages,\n setMessages: this.#setMessages,\n initialValues: {} as StateType,\n callbacks: this.#options,\n onSuccess: () => {\n if (!usableThreadId) return undefined;\n\n const finalValues = this.stream.values ?? this.#historyValues;\n this.#options.onFinish?.(\n createCustomTransportThreadState(finalValues, usableThreadId),\n undefined\n );\n\n return undefined;\n },\n onError: (error) => {\n this.#options.onError?.(error, undefined);\n submitOptions?.onError?.(error, undefined);\n },\n }\n );\n }\n\n /**\n * Submit input values and start a new stream run.\n *\n * Delegates to {@link submitDirect}. Override or wrap this method\n * in framework adapters to add queuing or other middleware.\n *\n * @param values - The input values to send, or `null`/`undefined` for\n * a resume-style invocation.\n * @param submitOptions - Optional per-call overrides.\n */\n async submit(\n values: GetUpdateType<Bag, StateType> | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, GetConfigurableType<Bag>>\n ): Promise<void> {\n await this.submitDirect(values, submitOptions);\n }\n\n /**\n * Tear down the orchestrator. Marks the instance as disposed,\n * unsubscribes from the stream, and aborts any in-progress stream.\n * After calling this method, no further notifications will be emitted.\n */\n dispose(): void {\n this.#disposed = true;\n this.#streamUnsub?.();\n this.#streamUnsub = null;\n void this.stream.stop(this.#historyValues, {\n onStop: this.#options.onStop,\n });\n }\n\n #flushPendingHeadlessToolInterrupts(): void {\n flushPendingHeadlessToolInterrupts(\n this.stream.values as Record<string, unknown> | null,\n this.#options.tools,\n this.#handledHeadlessToolInterruptIds,\n {\n onTool: this.#options.onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n this.submit(null, {\n command,\n }),\n }\n );\n }\n}\n"],"mappings":"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"}

@@ -1,1 +0,1 @@

{"version":3,"file":"orchestrator-custom.d.cts","names":[],"sources":["../../src/ui/orchestrator-custom.ts"],"mappings":";;;;;;;;;;;;AA4DA;;;;cAAa,wBAAA,mBACO,MAAA,oBAA0B,MAAA,+BAChC,WAAA,GAAc,WAAA;EAAA;WAEjB,MAAA,EAAQ,aAAA,CAAc,SAAA,EAAW,GAAA;EAAA,SAEjC,cAAA,EAAgB,mBAAA;EAFiB;;;;;;EA4B1C,WAAA,CAAY,OAAA,EAAS,sBAAA,CAAuB,SAAA,EAAW,GAAA;EAoGzC;;;;;;EA9Dd,SAAA,GAAS,QAAA;EA8HoB;;;;;;EAjH7B,WAAA;EA4JW;;;;;EArJX,eAAA,CAAA,GAAmB,MAAA,EAAQ,UAAA;EAqLG;;;;;;;EApK9B,YAAA,CAAa,KAAA;EAwL0B;;;;EAAA,IA/JnC,MAAA,CAAA,GAAU,SAAA;EA0NuD;;;;EAAA,IAlNjE,YAAA,CAAA,GAAgB,SAAA;EA4SS;EAAA,IAvSzB,KAAA,CAAA;EAwSkC;EAAA,IAnSlC,SAAA,CAAA;EAmS6C;EAAA,IA9R7C,MAAA,CAAA;EA+RD;;;;;EAtRH,SAAA,CAAU,KAAA;EAlKV;;;;;EAAA,IA4KI,QAAA,CAAA,GAAY,WAAA;EA1Ke;;;;EAAA,IAqL3B,SAAA,CAAA,GAAS,kBAAA,CAXc,eAAA;EA9IN;;;;;;EAoKrB,YAAA,CAAa,OAAA,EAAS,OAAA,GAAO,kBAAA,CAAA,eAAA;EA1G7B;;;;;EAAA,IAuHI,UAAA,CAAA,GAAc,SAAA,CAAU,gBAAA,CAAiB,GAAA;EA7E/B;;;;EAAA,IA8FV,SAAA,CAAA,GAAa,SAAA,CAAU,gBAAA,CAAiB,GAAA;EAvExC;;;;;;;;EAmFJ,mBAAA,CACE,OAAA,EAAS,OAAA,EACT,KAAA,YACC,eAAA,CAAgB,SAAA;EA7CG;EAAA,IA4DlB,SAAA,CAAA,GAAa,GAAA,SAAY,uBAAA;EA5DA;EAAA,IAiEzB,eAAA,CAAA,GAAmB,uBAAA;EApDnB;;;;;;EA8DJ,WAAA,CAAY,UAAA,WAAkB,uBAAA,CAAA,MAAA,mBAAA,eAAA;EA7Cc;;;;;;EAuD5C,kBAAA,CAAmB,IAAA,WAAY,uBAAA,CAAA,MAAA,mBAAA,eAAA;EAzB3B;;;;;;EAmCJ,qBAAA,CAAsB,SAAA,WAAiB,uBAAA,CAAA,MAAA,mBAAA,eAAA;EApBT;;;;;EA6B9B,4BAAA,CAAA;EAnB+B;;;;EAkC/B,IAAA,CAAA;EAxBuC;;;;;;EAoCvC,YAAA,CAAa,WAAA;EAsBH;;;;;;;;;;;;EADJ,YAAA,CACJ,MAAA,EAAQ,aAAA,CAAc,GAAA,EAAK,SAAA,sBAC3B,aAAA,GAAgB,mBAAA,CAAoB,SAAA,EAAW,mBAAA,CAAoB,GAAA,KAClE,OAAA;EAyF0B;;;;;;;;;;EADvB,MAAA,CACJ,MAAA,EAAQ,aAAA,CAAc,GAAA,EAAK,SAAA,sBAC3B,aAAA,GAAgB,mBAAA,CAAoB,SAAA,EAAW,mBAAA,CAAoB,GAAA,KAClE,OAAA;;;;;;EASH,OAAA,CAAA;AAAA"}
{"version":3,"file":"orchestrator-custom.d.cts","names":[],"sources":["../../src/ui/orchestrator-custom.ts"],"mappings":";;;;;;;;;;;;AA6DA;;;;cAAa,wBAAA,mBACO,MAAA,oBAA0B,MAAA,+BAChC,WAAA,GAAc,WAAA;EAAA;WAEjB,MAAA,EAAQ,aAAA,CAAc,SAAA,EAAW,GAAA;EAAA,SAEjC,cAAA,EAAgB,mBAAA;EAFiB;;;;;;EA4B1C,WAAA,CAAY,OAAA,EAAS,sBAAA,CAAuB,SAAA,EAAW,GAAA;EAoGzC;;;;;;EA9Dd,SAAA,GAAS,QAAA;EA8HoB;;;;;;EAjH7B,WAAA;EA4JW;;;;;EArJX,eAAA,CAAA,GAAmB,MAAA,EAAQ,UAAA;EAqLG;;;;;;;EApK9B,YAAA,CAAa,KAAA;EAwL0B;;;;EAAA,IA/JnC,MAAA,CAAA,GAAU,SAAA;EA0NuD;;;;EAAA,IAlNjE,YAAA,CAAA,GAAgB,SAAA;EA4SS;EAAA,IAvSzB,KAAA,CAAA;EAwSkC;EAAA,IAnSlC,SAAA,CAAA;EAmS6C;EAAA,IA9R7C,MAAA,CAAA;EA+RD;;;;;EAtRH,SAAA,CAAU,KAAA;EAlKV;;;;;EAAA,IA4KI,QAAA,CAAA,GAAY,WAAA;EA1Ke;;;;EAAA,IAqL3B,SAAA,CAAA,GAAS,kBAAA,CAXc,eAAA;EA9IN;;;;;;EAoKrB,YAAA,CAAa,OAAA,EAAS,OAAA,GAAO,kBAAA,CAAA,eAAA;EA1G7B;;;;;EAAA,IAuHI,UAAA,CAAA,GAAc,SAAA,CAAU,gBAAA,CAAiB,GAAA;EA7E/B;;;;EAAA,IA8FV,SAAA,CAAA,GAAa,SAAA,CAAU,gBAAA,CAAiB,GAAA;EAvExC;;;;;;;;EAmFJ,mBAAA,CACE,OAAA,EAAS,OAAA,EACT,KAAA,YACC,eAAA,CAAgB,SAAA;EA7CG;EAAA,IA4DlB,SAAA,CAAA,GAAa,GAAA,SAAY,uBAAA;EA5DA;EAAA,IAiEzB,eAAA,CAAA,GAAmB,uBAAA;EApDnB;;;;;;EA8DJ,WAAA,CAAY,UAAA,WAAkB,uBAAA,CAAA,MAAA,mBAAA,eAAA;EA7Cc;;;;;;EAuD5C,kBAAA,CAAmB,IAAA,WAAY,uBAAA,CAAA,MAAA,mBAAA,eAAA;EAzB3B;;;;;;EAmCJ,qBAAA,CAAsB,SAAA,WAAiB,uBAAA,CAAA,MAAA,mBAAA,eAAA;EApBT;;;;;EA6B9B,4BAAA,CAAA;EAnB+B;;;;EAkC/B,IAAA,CAAA;EAxBuC;;;;;;EAoCvC,YAAA,CAAa,WAAA;EAsBH;;;;;;;;;;;;EADJ,YAAA,CACJ,MAAA,EAAQ,aAAA,CAAc,GAAA,EAAK,SAAA,sBAC3B,aAAA,GAAgB,mBAAA,CAAoB,SAAA,EAAW,mBAAA,CAAoB,GAAA,KAClE,OAAA;EAyF0B;;;;;;;;;;EADvB,MAAA,CACJ,MAAA,EAAQ,aAAA,CAAc,GAAA,EAAK,SAAA,sBAC3B,aAAA,GAAgB,mBAAA,CAAoB,SAAA,EAAW,mBAAA,CAAoB,GAAA,KAClE,OAAA;;;;;;EASH,OAAA,CAAA;AAAA"}

@@ -1,1 +0,1 @@

{"version":3,"file":"orchestrator-custom.d.ts","names":[],"sources":["../../src/ui/orchestrator-custom.ts"],"mappings":";;;;;;;;;;;;AA4DA;;;;cAAa,wBAAA,mBACO,MAAA,oBAA0B,MAAA,+BAChC,WAAA,GAAc,WAAA;EAAA;WAEjB,MAAA,EAAQ,aAAA,CAAc,SAAA,EAAW,GAAA;EAAA,SAEjC,cAAA,EAAgB,mBAAA;EAFiB;;;;;;EA4B1C,WAAA,CAAY,OAAA,EAAS,sBAAA,CAAuB,SAAA,EAAW,GAAA;EAoGzC;;;;;;EA9Dd,SAAA,GAAS,QAAA;EA8HoB;;;;;;EAjH7B,WAAA;EA4JW;;;;;EArJX,eAAA,CAAA,GAAmB,MAAA,EAAQ,UAAA;EAqLG;;;;;;;EApK9B,YAAA,CAAa,KAAA;EAwL0B;;;;EAAA,IA/JnC,MAAA,CAAA,GAAU,SAAA;EA0NuD;;;;EAAA,IAlNjE,YAAA,CAAA,GAAgB,SAAA;EA4SS;EAAA,IAvSzB,KAAA,CAAA;EAwSkC;EAAA,IAnSlC,SAAA,CAAA;EAmS6C;EAAA,IA9R7C,MAAA,CAAA;EA+RD;;;;;EAtRH,SAAA,CAAU,KAAA;EAlKV;;;;;EAAA,IA4KI,QAAA,CAAA,GAAY,WAAA;EA1Ke;;;;EAAA,IAqL3B,SAAA,CAAA,GAAS,kBAAA,CAXc,eAAA;EA9IN;;;;;;EAoKrB,YAAA,CAAa,OAAA,EAAS,OAAA,GAAO,kBAAA,CAAA,eAAA;EA1G7B;;;;;EAAA,IAuHI,UAAA,CAAA,GAAc,SAAA,CAAU,gBAAA,CAAiB,GAAA;EA7E/B;;;;EAAA,IA8FV,SAAA,CAAA,GAAa,SAAA,CAAU,gBAAA,CAAiB,GAAA;EAvExC;;;;;;;;EAmFJ,mBAAA,CACE,OAAA,EAAS,OAAA,EACT,KAAA,YACC,eAAA,CAAgB,SAAA;EA7CG;EAAA,IA4DlB,SAAA,CAAA,GAAa,GAAA,SAAY,uBAAA;EA5DA;EAAA,IAiEzB,eAAA,CAAA,GAAmB,uBAAA;EApDnB;;;;;;EA8DJ,WAAA,CAAY,UAAA,WAAkB,uBAAA,CAAA,MAAA,mBAAA,eAAA;EA7Cc;;;;;;EAuD5C,kBAAA,CAAmB,IAAA,WAAY,uBAAA,CAAA,MAAA,mBAAA,eAAA;EAzB3B;;;;;;EAmCJ,qBAAA,CAAsB,SAAA,WAAiB,uBAAA,CAAA,MAAA,mBAAA,eAAA;EApBT;;;;;EA6B9B,4BAAA,CAAA;EAnB+B;;;;EAkC/B,IAAA,CAAA;EAxBuC;;;;;;EAoCvC,YAAA,CAAa,WAAA;EAsBH;;;;;;;;;;;;EADJ,YAAA,CACJ,MAAA,EAAQ,aAAA,CAAc,GAAA,EAAK,SAAA,sBAC3B,aAAA,GAAgB,mBAAA,CAAoB,SAAA,EAAW,mBAAA,CAAoB,GAAA,KAClE,OAAA;EAyF0B;;;;;;;;;;EADvB,MAAA,CACJ,MAAA,EAAQ,aAAA,CAAc,GAAA,EAAK,SAAA,sBAC3B,aAAA,GAAgB,mBAAA,CAAoB,SAAA,EAAW,mBAAA,CAAoB,GAAA,KAClE,OAAA;;;;;;EASH,OAAA,CAAA;AAAA"}
{"version":3,"file":"orchestrator-custom.d.ts","names":[],"sources":["../../src/ui/orchestrator-custom.ts"],"mappings":";;;;;;;;;;;;AA6DA;;;;cAAa,wBAAA,mBACO,MAAA,oBAA0B,MAAA,+BAChC,WAAA,GAAc,WAAA;EAAA;WAEjB,MAAA,EAAQ,aAAA,CAAc,SAAA,EAAW,GAAA;EAAA,SAEjC,cAAA,EAAgB,mBAAA;EAFiB;;;;;;EA4B1C,WAAA,CAAY,OAAA,EAAS,sBAAA,CAAuB,SAAA,EAAW,GAAA;EAoGzC;;;;;;EA9Dd,SAAA,GAAS,QAAA;EA8HoB;;;;;;EAjH7B,WAAA;EA4JW;;;;;EArJX,eAAA,CAAA,GAAmB,MAAA,EAAQ,UAAA;EAqLG;;;;;;;EApK9B,YAAA,CAAa,KAAA;EAwL0B;;;;EAAA,IA/JnC,MAAA,CAAA,GAAU,SAAA;EA0NuD;;;;EAAA,IAlNjE,YAAA,CAAA,GAAgB,SAAA;EA4SS;EAAA,IAvSzB,KAAA,CAAA;EAwSkC;EAAA,IAnSlC,SAAA,CAAA;EAmS6C;EAAA,IA9R7C,MAAA,CAAA;EA+RD;;;;;EAtRH,SAAA,CAAU,KAAA;EAlKV;;;;;EAAA,IA4KI,QAAA,CAAA,GAAY,WAAA;EA1Ke;;;;EAAA,IAqL3B,SAAA,CAAA,GAAS,kBAAA,CAXc,eAAA;EA9IN;;;;;;EAoKrB,YAAA,CAAa,OAAA,EAAS,OAAA,GAAO,kBAAA,CAAA,eAAA;EA1G7B;;;;;EAAA,IAuHI,UAAA,CAAA,GAAc,SAAA,CAAU,gBAAA,CAAiB,GAAA;EA7E/B;;;;EAAA,IA8FV,SAAA,CAAA,GAAa,SAAA,CAAU,gBAAA,CAAiB,GAAA;EAvExC;;;;;;;;EAmFJ,mBAAA,CACE,OAAA,EAAS,OAAA,EACT,KAAA,YACC,eAAA,CAAgB,SAAA;EA7CG;EAAA,IA4DlB,SAAA,CAAA,GAAa,GAAA,SAAY,uBAAA;EA5DA;EAAA,IAiEzB,eAAA,CAAA,GAAmB,uBAAA;EApDnB;;;;;;EA8DJ,WAAA,CAAY,UAAA,WAAkB,uBAAA,CAAA,MAAA,mBAAA,eAAA;EA7Cc;;;;;;EAuD5C,kBAAA,CAAmB,IAAA,WAAY,uBAAA,CAAA,MAAA,mBAAA,eAAA;EAzB3B;;;;;;EAmCJ,qBAAA,CAAsB,SAAA,WAAiB,uBAAA,CAAA,MAAA,mBAAA,eAAA;EApBT;;;;;EA6B9B,4BAAA,CAAA;EAnB+B;;;;EAkC/B,IAAA,CAAA;EAxBuC;;;;;;EAoCvC,YAAA,CAAa,WAAA;EAsBH;;;;;;;;;;;;EADJ,YAAA,CACJ,MAAA,EAAQ,aAAA,CAAc,GAAA,EAAK,SAAA,sBAC3B,aAAA,GAAgB,mBAAA,CAAoB,SAAA,EAAW,mBAAA,CAAoB,GAAA,KAClE,OAAA;EAyF0B;;;;;;;;;;EADvB,MAAA,CACJ,MAAA,EAAQ,aAAA,CAAc,GAAA,EAAK,SAAA,sBAC3B,aAAA,GAAgB,mBAAA,CAAoB,SAAA,EAAW,mBAAA,CAAoB,GAAA,KAClE,OAAA;;;;;;EASH,OAAA,CAAA;AAAA"}

@@ -0,1 +1,2 @@

import "../stream/constants.js";
import { MessageTupleManager, ensureMessageInstances, toMessageClass } from "./messages.js";

@@ -2,0 +3,0 @@ import { flushPendingHeadlessToolInterrupts } from "../headless-tools.js";

@@ -1,1 +0,1 @@

{"version":3,"file":"orchestrator-custom.js","names":["#options","#historyValues","#threadId","#streamUnsub","#flushPendingHeadlessToolInterrupts","#notify","#getMessages","#listeners","#version","#disposed","#handledHeadlessToolInterruptIds","#branch","#setMessages"],"sources":["../../src/ui/orchestrator-custom.ts"],"sourcesContent":["import type { BaseMessage } from \"@langchain/core/messages\";\n\nimport type { ThreadState, Interrupt } from \"../schema.js\";\nimport type { StreamMode } from \"../types.stream.js\";\nimport type { Message } from \"../types.messages.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport { StreamManager, type EventStreamEvent } from \"./manager.js\";\nimport {\n MessageTupleManager,\n toMessageClass,\n ensureMessageInstances,\n} from \"./messages.js\";\nimport {\n extractInterrupts,\n userFacingInterruptsFromValuesArray,\n} from \"./interrupts.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport { flushPendingHeadlessToolInterrupts } from \"../headless-tools.js\";\nimport type {\n AnyStreamCustomOptions,\n CustomSubmitOptions,\n MessageMetadata,\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetConfigurableType,\n SubagentStreamInterface,\n} from \"./types.js\";\n\n/**\n * Create a custom transport thread state.\n * @param values - The values to use.\n * @param threadId - The ID of the thread to use.\n * @returns The custom transport thread state.\n */\nfunction createCustomTransportThreadState<\n StateType extends Record<string, unknown>,\n>(values: StateType, threadId: string): ThreadState<StateType> {\n return {\n values,\n next: [],\n tasks: [],\n metadata: undefined,\n created_at: null,\n checkpoint: {\n thread_id: threadId,\n checkpoint_id: null,\n checkpoint_ns: \"\",\n checkpoint_map: null,\n },\n parent_checkpoint: null,\n };\n}\n\n/**\n * Framework-agnostic orchestrator for custom transport streams.\n *\n * Encapsulates all business logic shared across React, Vue, Svelte, and Angular\n * for custom transport (non-LGP) streaming.\n */\nexport class CustomStreamOrchestrator<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n> {\n readonly stream: StreamManager<StateType, Bag>;\n\n readonly messageManager: MessageTupleManager;\n\n readonly #options: AnyStreamCustomOptions<StateType, Bag>;\n\n readonly #historyValues: StateType;\n\n #threadId: string | null;\n\n #branch: string = \"\";\n\n #listeners = new Set<() => void>();\n\n #version = 0;\n\n #streamUnsub: (() => void) | null = null;\n\n #disposed = false;\n\n #handledHeadlessToolInterruptIds = new Set<string>();\n\n /**\n * Create a new {@link CustomStreamOrchestrator} instance.\n *\n * @param options - Configuration options for the custom transport stream,\n * including thread ID, transport, callbacks, and subagent settings.\n */\n constructor(options: AnyStreamCustomOptions<StateType, Bag>) {\n this.#options = options;\n\n this.#threadId = options.threadId ?? null;\n\n this.messageManager = new MessageTupleManager();\n this.stream = new StreamManager<StateType, Bag>(this.messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n toMessage: options.toMessage ?? toMessageClass,\n });\n\n this.#historyValues = options.initialValues ?? ({} as StateType);\n\n this.#streamUnsub = this.stream.subscribe(() => {\n this.#flushPendingHeadlessToolInterrupts();\n this.#notify();\n });\n\n const historyMessages = this.#getMessages(this.#historyValues);\n if (\n options.filterSubagentMessages &&\n !this.stream.isLoading &&\n historyMessages.length > 0\n ) {\n this.stream.reconstructSubagents(historyMessages, {\n skipIfPopulated: true,\n });\n }\n }\n\n /**\n * Register a listener that is called whenever the orchestrator state changes.\n *\n * @param listener - Callback invoked on each state change.\n * @returns An unsubscribe function that removes the listener.\n */\n subscribe = (listener: () => void): (() => void) => {\n this.#listeners.add(listener);\n return () => {\n this.#listeners.delete(listener);\n };\n };\n\n /**\n * Return the current version number, incremented on each state change.\n * Useful as a cache key for external sync (e.g. `useSyncExternalStore`).\n *\n * @returns The current version counter.\n */\n getSnapshot = (): number => this.#version;\n\n /**\n * Custom transports do not negotiate stream modes with the server the way\n * LangGraph Platform streams do, but framework adapters call this method on\n * both orchestrator variants. Keep the API surface aligned as a no-op.\n */\n trackStreamMode(..._modes: StreamMode[]): void {}\n\n #notify(): void {\n if (this.#disposed) return;\n this.#version += 1;\n for (const listener of this.#listeners) {\n listener();\n }\n }\n\n /**\n * Synchronize the external thread ID with the orchestrator.\n * If the ID has changed, the current stream is cleared and listeners\n * are notified.\n *\n * @param newId - The new thread ID, or `null` to clear.\n */\n syncThreadId(newId: string | null): void {\n if (newId !== this.#threadId) {\n this.#threadId = newId;\n this.#handledHeadlessToolInterruptIds.clear();\n this.stream.clear();\n this.#notify();\n }\n }\n\n #getMessages = (value: StateType): Message[] => {\n const messagesKey = this.#options.messagesKey ?? \"messages\";\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n #setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = this.#options.messagesKey ?? \"messages\";\n return { ...current, [messagesKey]: messages };\n };\n\n /**\n * The current stream state values, falling back to an empty object\n * when no stream values are available.\n */\n get values(): StateType {\n return this.stream.values ?? ({} as StateType);\n }\n\n /**\n * The raw stream state values, or `null` if no stream has been started\n * or values have not yet been received.\n */\n get streamValues(): StateType | null {\n return this.stream.values;\n }\n\n /** The most recent stream error, or `undefined` if no error occurred. */\n get error(): unknown {\n return this.stream.error;\n }\n\n /** Whether a stream is currently in progress. */\n get isLoading(): boolean {\n return this.stream.isLoading;\n }\n\n /** The current branch identifier. */\n get branch(): string {\n return this.#branch;\n }\n\n /**\n * Update the current branch and notify listeners.\n *\n * @param value - The new branch identifier.\n */\n setBranch(value: string): void {\n this.#branch = value;\n this.#notify();\n }\n\n /**\n * All messages from the current stream values, converted to\n * {@link BaseMessage} instances. Returns an empty array when no\n * stream values are available.\n */\n get messages(): BaseMessage[] {\n if (!this.stream.values) return [];\n return ensureMessageInstances(\n this.#getMessages(this.stream.values)\n ) as BaseMessage[];\n }\n\n /**\n * All tool calls paired with their results extracted from the\n * current stream messages.\n */\n get toolCalls() {\n if (!this.stream.values) return [];\n return getToolCallsWithResults(this.#getMessages(this.stream.values));\n }\n\n /**\n * Get tool calls (with results) that belong to a specific AI message.\n *\n * @param message - The AI message whose tool calls to retrieve.\n * @returns Tool calls associated with the given message.\n */\n getToolCalls(message: Message) {\n if (!this.stream.values) return [];\n const allToolCalls = getToolCallsWithResults(\n this.#getMessages(this.stream.values)\n );\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n }\n\n /**\n * All active interrupts from the current stream values.\n * Returns a single breakpoint interrupt when the interrupt array is\n * present but empty, or an empty array when no interrupts exist.\n */\n get interrupts(): Interrupt<GetInterruptType<Bag>>[] {\n if (\n this.stream.values != null &&\n \"__interrupt__\" in this.stream.values &&\n Array.isArray(this.stream.values.__interrupt__)\n ) {\n return userFacingInterruptsFromValuesArray<GetInterruptType<Bag>>(\n this.stream.values.__interrupt__ as Interrupt<GetInterruptType<Bag>>[]\n );\n }\n return [];\n }\n\n /**\n * The first active interrupt extracted from the current stream values,\n * or `undefined` if there are no interrupts.\n */\n get interrupt(): Interrupt<GetInterruptType<Bag>> | undefined {\n return extractInterrupts<GetInterruptType<Bag>>(this.stream.values);\n }\n\n /**\n * Retrieve stream-level metadata for a given message.\n *\n * @param message - The message to look up metadata for.\n * @param index - Optional positional index used as fallback message ID.\n * @returns The metadata associated with the message, or `undefined`\n * if no stream metadata is available.\n */\n getMessagesMetadata(\n message: Message,\n index?: number\n ): MessageMetadata<StateType> | undefined {\n const streamMetadata = this.messageManager.get(message.id)?.metadata;\n if (streamMetadata != null) {\n return {\n messageId: message.id ?? String(index),\n firstSeenState: undefined,\n branch: undefined,\n branchOptions: undefined,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n return undefined;\n }\n\n /** A map of all tracked subagent streams, keyed by tool call ID. */\n get subagents(): Map<string, SubagentStreamInterface> {\n return this.stream.getSubagents();\n }\n\n /** The subset of subagent streams that are currently active (loading). */\n get activeSubagents(): SubagentStreamInterface[] {\n return this.stream.getActiveSubagents();\n }\n\n /**\n * Look up a single subagent stream by its tool call ID.\n *\n * @param toolCallId - The tool call ID that initiated the subagent.\n * @returns The subagent stream, or `undefined` if not found.\n */\n getSubagent(toolCallId: string) {\n return this.stream.getSubagent(toolCallId);\n }\n\n /**\n * Retrieve all subagent streams matching a given tool name / type.\n *\n * @param type - The subagent type (tool name) to filter by.\n * @returns An array of matching subagent streams.\n */\n getSubagentsByType(type: string) {\n return this.stream.getSubagentsByType(type);\n }\n\n /**\n * Retrieve all subagent streams associated with a specific AI message.\n *\n * @param messageId - The ID of the parent AI message.\n * @returns An array of subagent streams linked to the message.\n */\n getSubagentsByMessage(messageId: string) {\n return this.stream.getSubagentsByMessage(messageId);\n }\n\n /**\n * Reconstruct subagent streams from history values when subagent\n * filtering is enabled and the stream is not currently loading.\n * This is a no-op if subagents are already populated.\n */\n reconstructSubagentsIfNeeded(): void {\n const hvMessages = this.#getMessages(this.#historyValues);\n if (\n this.#options.filterSubagentMessages &&\n !this.stream.isLoading &&\n hvMessages.length > 0\n ) {\n this.stream.reconstructSubagents(hvMessages, { skipIfPopulated: true });\n }\n }\n\n /**\n * Abort the current stream and invoke the `onStop` callback\n * if one was provided in the options.\n */\n stop(): void {\n void this.stream.stop(this.#historyValues, {\n onStop: this.#options.onStop,\n });\n }\n\n /**\n * Switch to a different thread. If the thread ID actually changed,\n * the current stream is cleared and listeners are notified.\n *\n * @param newThreadId - The thread ID to switch to, or `null` to clear.\n */\n switchThread(newThreadId: string | null): void {\n if (newThreadId !== this.#threadId) {\n this.#threadId = newThreadId;\n this.#handledHeadlessToolInterruptIds.clear();\n this.stream.clear();\n this.#notify();\n }\n }\n\n /**\n * Start a new stream run against the custom transport.\n *\n * This is the low-level submit entry point that handles thread ID\n * resolution, optimistic value merging, and transport invocation.\n * Prefer {@link submit} unless you need to bypass higher-level wrappers.\n *\n * @param values - The input values to send, or `null`/`undefined` for\n * a resume-style invocation.\n * @param submitOptions - Optional per-call overrides such as\n * `optimisticValues`, `config`, `command`, and error callbacks.\n */\n async submitDirect(\n values: GetUpdateType<Bag, StateType> | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, GetConfigurableType<Bag>>\n ): Promise<void> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n\n const currentThreadId = this.#options.threadId ?? null;\n if (currentThreadId !== this.#threadId) {\n this.#threadId = currentThreadId;\n this.stream.clear();\n }\n\n let usableThreadId = this.#threadId ?? submitOptions?.threadId;\n\n this.stream.setStreamValues(() => {\n if (submitOptions?.optimisticValues != null) {\n return {\n ...this.#historyValues,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(this.#historyValues)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...this.#historyValues };\n });\n\n await this.stream.start(\n async (signal: AbortSignal) => {\n if (!usableThreadId) {\n usableThreadId = crypto.randomUUID();\n this.#threadId = usableThreadId;\n this.#options.onThreadId?.(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n return this.#options.transport.stream({\n input: values,\n context: submitOptions?.context,\n command: submitOptions?.command,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n signal,\n config: {\n ...submitOptions?.config,\n configurable: {\n thread_id: usableThreadId,\n ...submitOptions?.config?.configurable,\n } as unknown as GetConfigurableType<Bag>,\n },\n }) as Promise<\n AsyncGenerator<EventStreamEvent<StateType, UpdateType, CustomType>>\n >;\n },\n {\n getMessages: this.#getMessages,\n setMessages: this.#setMessages,\n initialValues: {} as StateType,\n callbacks: this.#options,\n onSuccess: () => {\n if (!usableThreadId) return undefined;\n\n const finalValues = this.stream.values ?? this.#historyValues;\n this.#options.onFinish?.(\n createCustomTransportThreadState(finalValues, usableThreadId),\n undefined\n );\n\n return undefined;\n },\n onError: (error) => {\n this.#options.onError?.(error, undefined);\n submitOptions?.onError?.(error, undefined);\n },\n }\n );\n }\n\n /**\n * Submit input values and start a new stream run.\n *\n * Delegates to {@link submitDirect}. Override or wrap this method\n * in framework adapters to add queuing or other middleware.\n *\n * @param values - The input values to send, or `null`/`undefined` for\n * a resume-style invocation.\n * @param submitOptions - Optional per-call overrides.\n */\n async submit(\n values: GetUpdateType<Bag, StateType> | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, GetConfigurableType<Bag>>\n ): Promise<void> {\n await this.submitDirect(values, submitOptions);\n }\n\n /**\n * Tear down the orchestrator. Marks the instance as disposed,\n * unsubscribes from the stream, and aborts any in-progress stream.\n * After calling this method, no further notifications will be emitted.\n */\n dispose(): void {\n this.#disposed = true;\n this.#streamUnsub?.();\n this.#streamUnsub = null;\n void this.stream.stop(this.#historyValues, {\n onStop: this.#options.onStop,\n });\n }\n\n #flushPendingHeadlessToolInterrupts(): void {\n flushPendingHeadlessToolInterrupts(\n this.stream.values as Record<string, unknown> | null,\n this.#options.tools,\n this.#handledHeadlessToolInterruptIds,\n {\n onTool: this.#options.onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n this.submit(null, {\n command,\n }),\n }\n );\n }\n}\n"],"mappings":"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"}
{"version":3,"file":"orchestrator-custom.js","names":["#options","#historyValues","#threadId","#streamUnsub","#flushPendingHeadlessToolInterrupts","#notify","#getMessages","#listeners","#version","#disposed","#handledHeadlessToolInterruptIds","#branch","#setMessages"],"sources":["../../src/ui/orchestrator-custom.ts"],"sourcesContent":["import type { BaseMessage } from \"@langchain/core/messages\";\n\nimport { DEFAULT_MESSAGES_KEY } from \"../stream/constants.js\";\nimport type { ThreadState, Interrupt } from \"../schema.js\";\nimport type { StreamMode } from \"../types.stream.js\";\nimport type { Message } from \"../types.messages.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport { StreamManager, type EventStreamEvent } from \"./manager.js\";\nimport {\n MessageTupleManager,\n toMessageClass,\n ensureMessageInstances,\n} from \"./messages.js\";\nimport {\n extractInterrupts,\n userFacingInterruptsFromValuesArray,\n} from \"./interrupts.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport { flushPendingHeadlessToolInterrupts } from \"../headless-tools.js\";\nimport type {\n AnyStreamCustomOptions,\n CustomSubmitOptions,\n MessageMetadata,\n GetUpdateType,\n GetCustomEventType,\n GetInterruptType,\n GetConfigurableType,\n SubagentStreamInterface,\n} from \"./types.js\";\n\n/**\n * Create a custom transport thread state.\n * @param values - The values to use.\n * @param threadId - The ID of the thread to use.\n * @returns The custom transport thread state.\n */\nfunction createCustomTransportThreadState<\n StateType extends Record<string, unknown>,\n>(values: StateType, threadId: string): ThreadState<StateType> {\n return {\n values,\n next: [],\n tasks: [],\n metadata: undefined,\n created_at: null,\n checkpoint: {\n thread_id: threadId,\n checkpoint_id: null,\n checkpoint_ns: \"\",\n checkpoint_map: null,\n },\n parent_checkpoint: null,\n };\n}\n\n/**\n * Framework-agnostic orchestrator for custom transport streams.\n *\n * Encapsulates all business logic shared across React, Vue, Svelte, and Angular\n * for custom transport (non-LGP) streaming.\n */\nexport class CustomStreamOrchestrator<\n StateType extends Record<string, unknown> = Record<string, unknown>,\n Bag extends BagTemplate = BagTemplate,\n> {\n readonly stream: StreamManager<StateType, Bag>;\n\n readonly messageManager: MessageTupleManager;\n\n readonly #options: AnyStreamCustomOptions<StateType, Bag>;\n\n readonly #historyValues: StateType;\n\n #threadId: string | null;\n\n #branch: string = \"\";\n\n #listeners = new Set<() => void>();\n\n #version = 0;\n\n #streamUnsub: (() => void) | null = null;\n\n #disposed = false;\n\n #handledHeadlessToolInterruptIds = new Set<string>();\n\n /**\n * Create a new {@link CustomStreamOrchestrator} instance.\n *\n * @param options - Configuration options for the custom transport stream,\n * including thread ID, transport, callbacks, and subagent settings.\n */\n constructor(options: AnyStreamCustomOptions<StateType, Bag>) {\n this.#options = options;\n\n this.#threadId = options.threadId ?? null;\n\n this.messageManager = new MessageTupleManager();\n this.stream = new StreamManager<StateType, Bag>(this.messageManager, {\n throttle: options.throttle ?? false,\n subagentToolNames: options.subagentToolNames,\n filterSubagentMessages: options.filterSubagentMessages,\n toMessage: options.toMessage ?? toMessageClass,\n });\n\n this.#historyValues = options.initialValues ?? ({} as StateType);\n\n this.#streamUnsub = this.stream.subscribe(() => {\n this.#flushPendingHeadlessToolInterrupts();\n this.#notify();\n });\n\n const historyMessages = this.#getMessages(this.#historyValues);\n if (\n options.filterSubagentMessages &&\n !this.stream.isLoading &&\n historyMessages.length > 0\n ) {\n this.stream.reconstructSubagents(historyMessages, {\n skipIfPopulated: true,\n });\n }\n }\n\n /**\n * Register a listener that is called whenever the orchestrator state changes.\n *\n * @param listener - Callback invoked on each state change.\n * @returns An unsubscribe function that removes the listener.\n */\n subscribe = (listener: () => void): (() => void) => {\n this.#listeners.add(listener);\n return () => {\n this.#listeners.delete(listener);\n };\n };\n\n /**\n * Return the current version number, incremented on each state change.\n * Useful as a cache key for external sync (e.g. `useSyncExternalStore`).\n *\n * @returns The current version counter.\n */\n getSnapshot = (): number => this.#version;\n\n /**\n * Custom transports do not negotiate stream modes with the server the way\n * LangGraph Platform streams do, but framework adapters call this method on\n * both orchestrator variants. Keep the API surface aligned as a no-op.\n */\n trackStreamMode(..._modes: StreamMode[]): void {}\n\n #notify(): void {\n if (this.#disposed) return;\n this.#version += 1;\n for (const listener of this.#listeners) {\n listener();\n }\n }\n\n /**\n * Synchronize the external thread ID with the orchestrator.\n * If the ID has changed, the current stream is cleared and listeners\n * are notified.\n *\n * @param newId - The new thread ID, or `null` to clear.\n */\n syncThreadId(newId: string | null): void {\n if (newId !== this.#threadId) {\n this.#threadId = newId;\n this.#handledHeadlessToolInterruptIds.clear();\n this.stream.clear();\n this.#notify();\n }\n }\n\n #getMessages = (value: StateType): Message[] => {\n const messagesKey = this.#options.messagesKey ?? DEFAULT_MESSAGES_KEY;\n return Array.isArray(value[messagesKey])\n ? (value[messagesKey] as Message[])\n : [];\n };\n\n #setMessages = (current: StateType, messages: Message[]): StateType => {\n const messagesKey = this.#options.messagesKey ?? DEFAULT_MESSAGES_KEY;\n return { ...current, [messagesKey]: messages };\n };\n\n /**\n * The current stream state values, falling back to an empty object\n * when no stream values are available.\n */\n get values(): StateType {\n return this.stream.values ?? ({} as StateType);\n }\n\n /**\n * The raw stream state values, or `null` if no stream has been started\n * or values have not yet been received.\n */\n get streamValues(): StateType | null {\n return this.stream.values;\n }\n\n /** The most recent stream error, or `undefined` if no error occurred. */\n get error(): unknown {\n return this.stream.error;\n }\n\n /** Whether a stream is currently in progress. */\n get isLoading(): boolean {\n return this.stream.isLoading;\n }\n\n /** The current branch identifier. */\n get branch(): string {\n return this.#branch;\n }\n\n /**\n * Update the current branch and notify listeners.\n *\n * @param value - The new branch identifier.\n */\n setBranch(value: string): void {\n this.#branch = value;\n this.#notify();\n }\n\n /**\n * All messages from the current stream values, converted to\n * {@link BaseMessage} instances. Returns an empty array when no\n * stream values are available.\n */\n get messages(): BaseMessage[] {\n if (!this.stream.values) return [];\n return ensureMessageInstances(\n this.#getMessages(this.stream.values)\n ) as BaseMessage[];\n }\n\n /**\n * All tool calls paired with their results extracted from the\n * current stream messages.\n */\n get toolCalls() {\n if (!this.stream.values) return [];\n return getToolCallsWithResults(this.#getMessages(this.stream.values));\n }\n\n /**\n * Get tool calls (with results) that belong to a specific AI message.\n *\n * @param message - The AI message whose tool calls to retrieve.\n * @returns Tool calls associated with the given message.\n */\n getToolCalls(message: Message) {\n if (!this.stream.values) return [];\n const allToolCalls = getToolCallsWithResults(\n this.#getMessages(this.stream.values)\n );\n return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n }\n\n /**\n * All active interrupts from the current stream values.\n * Returns a single breakpoint interrupt when the interrupt array is\n * present but empty, or an empty array when no interrupts exist.\n */\n get interrupts(): Interrupt<GetInterruptType<Bag>>[] {\n if (\n this.stream.values != null &&\n \"__interrupt__\" in this.stream.values &&\n Array.isArray(this.stream.values.__interrupt__)\n ) {\n return userFacingInterruptsFromValuesArray<GetInterruptType<Bag>>(\n this.stream.values.__interrupt__ as Interrupt<GetInterruptType<Bag>>[]\n );\n }\n return [];\n }\n\n /**\n * The first active interrupt extracted from the current stream values,\n * or `undefined` if there are no interrupts.\n */\n get interrupt(): Interrupt<GetInterruptType<Bag>> | undefined {\n return extractInterrupts<GetInterruptType<Bag>>(this.stream.values);\n }\n\n /**\n * Retrieve stream-level metadata for a given message.\n *\n * @param message - The message to look up metadata for.\n * @param index - Optional positional index used as fallback message ID.\n * @returns The metadata associated with the message, or `undefined`\n * if no stream metadata is available.\n */\n getMessagesMetadata(\n message: Message,\n index?: number\n ): MessageMetadata<StateType> | undefined {\n const streamMetadata = this.messageManager.get(message.id)?.metadata;\n if (streamMetadata != null) {\n return {\n messageId: message.id ?? String(index),\n firstSeenState: undefined,\n branch: undefined,\n branchOptions: undefined,\n streamMetadata,\n } as MessageMetadata<StateType>;\n }\n return undefined;\n }\n\n /** A map of all tracked subagent streams, keyed by tool call ID. */\n get subagents(): Map<string, SubagentStreamInterface> {\n return this.stream.getSubagents();\n }\n\n /** The subset of subagent streams that are currently active (loading). */\n get activeSubagents(): SubagentStreamInterface[] {\n return this.stream.getActiveSubagents();\n }\n\n /**\n * Look up a single subagent stream by its tool call ID.\n *\n * @param toolCallId - The tool call ID that initiated the subagent.\n * @returns The subagent stream, or `undefined` if not found.\n */\n getSubagent(toolCallId: string) {\n return this.stream.getSubagent(toolCallId);\n }\n\n /**\n * Retrieve all subagent streams matching a given tool name / type.\n *\n * @param type - The subagent type (tool name) to filter by.\n * @returns An array of matching subagent streams.\n */\n getSubagentsByType(type: string) {\n return this.stream.getSubagentsByType(type);\n }\n\n /**\n * Retrieve all subagent streams associated with a specific AI message.\n *\n * @param messageId - The ID of the parent AI message.\n * @returns An array of subagent streams linked to the message.\n */\n getSubagentsByMessage(messageId: string) {\n return this.stream.getSubagentsByMessage(messageId);\n }\n\n /**\n * Reconstruct subagent streams from history values when subagent\n * filtering is enabled and the stream is not currently loading.\n * This is a no-op if subagents are already populated.\n */\n reconstructSubagentsIfNeeded(): void {\n const hvMessages = this.#getMessages(this.#historyValues);\n if (\n this.#options.filterSubagentMessages &&\n !this.stream.isLoading &&\n hvMessages.length > 0\n ) {\n this.stream.reconstructSubagents(hvMessages, { skipIfPopulated: true });\n }\n }\n\n /**\n * Abort the current stream and invoke the `onStop` callback\n * if one was provided in the options.\n */\n stop(): void {\n void this.stream.stop(this.#historyValues, {\n onStop: this.#options.onStop,\n });\n }\n\n /**\n * Switch to a different thread. If the thread ID actually changed,\n * the current stream is cleared and listeners are notified.\n *\n * @param newThreadId - The thread ID to switch to, or `null` to clear.\n */\n switchThread(newThreadId: string | null): void {\n if (newThreadId !== this.#threadId) {\n this.#threadId = newThreadId;\n this.#handledHeadlessToolInterruptIds.clear();\n this.stream.clear();\n this.#notify();\n }\n }\n\n /**\n * Start a new stream run against the custom transport.\n *\n * This is the low-level submit entry point that handles thread ID\n * resolution, optimistic value merging, and transport invocation.\n * Prefer {@link submit} unless you need to bypass higher-level wrappers.\n *\n * @param values - The input values to send, or `null`/`undefined` for\n * a resume-style invocation.\n * @param submitOptions - Optional per-call overrides such as\n * `optimisticValues`, `config`, `command`, and error callbacks.\n */\n async submitDirect(\n values: GetUpdateType<Bag, StateType> | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, GetConfigurableType<Bag>>\n ): Promise<void> {\n type UpdateType = GetUpdateType<Bag, StateType>;\n type CustomType = GetCustomEventType<Bag>;\n\n const currentThreadId = this.#options.threadId ?? null;\n if (currentThreadId !== this.#threadId) {\n this.#threadId = currentThreadId;\n this.stream.clear();\n }\n\n let usableThreadId = this.#threadId ?? submitOptions?.threadId;\n\n this.stream.setStreamValues(() => {\n if (submitOptions?.optimisticValues != null) {\n return {\n ...this.#historyValues,\n ...(typeof submitOptions.optimisticValues === \"function\"\n ? submitOptions.optimisticValues(this.#historyValues)\n : submitOptions.optimisticValues),\n };\n }\n\n return { ...this.#historyValues };\n });\n\n await this.stream.start(\n async (signal: AbortSignal) => {\n if (!usableThreadId) {\n usableThreadId = crypto.randomUUID();\n this.#threadId = usableThreadId;\n this.#options.onThreadId?.(usableThreadId);\n }\n\n if (!usableThreadId) {\n throw new Error(\"Failed to obtain valid thread ID.\");\n }\n\n return this.#options.transport.stream({\n input: values,\n context: submitOptions?.context,\n command: submitOptions?.command,\n streamSubgraphs: submitOptions?.streamSubgraphs,\n signal,\n config: {\n ...submitOptions?.config,\n configurable: {\n thread_id: usableThreadId,\n ...submitOptions?.config?.configurable,\n } as unknown as GetConfigurableType<Bag>,\n },\n }) as Promise<\n AsyncGenerator<EventStreamEvent<StateType, UpdateType, CustomType>>\n >;\n },\n {\n getMessages: this.#getMessages,\n setMessages: this.#setMessages,\n initialValues: {} as StateType,\n callbacks: this.#options,\n onSuccess: () => {\n if (!usableThreadId) return undefined;\n\n const finalValues = this.stream.values ?? this.#historyValues;\n this.#options.onFinish?.(\n createCustomTransportThreadState(finalValues, usableThreadId),\n undefined\n );\n\n return undefined;\n },\n onError: (error) => {\n this.#options.onError?.(error, undefined);\n submitOptions?.onError?.(error, undefined);\n },\n }\n );\n }\n\n /**\n * Submit input values and start a new stream run.\n *\n * Delegates to {@link submitDirect}. Override or wrap this method\n * in framework adapters to add queuing or other middleware.\n *\n * @param values - The input values to send, or `null`/`undefined` for\n * a resume-style invocation.\n * @param submitOptions - Optional per-call overrides.\n */\n async submit(\n values: GetUpdateType<Bag, StateType> | null | undefined,\n submitOptions?: CustomSubmitOptions<StateType, GetConfigurableType<Bag>>\n ): Promise<void> {\n await this.submitDirect(values, submitOptions);\n }\n\n /**\n * Tear down the orchestrator. Marks the instance as disposed,\n * unsubscribes from the stream, and aborts any in-progress stream.\n * After calling this method, no further notifications will be emitted.\n */\n dispose(): void {\n this.#disposed = true;\n this.#streamUnsub?.();\n this.#streamUnsub = null;\n void this.stream.stop(this.#historyValues, {\n onStop: this.#options.onStop,\n });\n }\n\n #flushPendingHeadlessToolInterrupts(): void {\n flushPendingHeadlessToolInterrupts(\n this.stream.values as Record<string, unknown> | null,\n this.#options.tools,\n this.#handledHeadlessToolInterruptIds,\n {\n onTool: this.#options.onTool,\n defer: (run) => {\n void Promise.resolve().then(run);\n },\n resumeSubmit: (command) =>\n this.submit(null, {\n command,\n }),\n }\n );\n }\n}\n"],"mappings":"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"}
const require_error = require("./error.cjs");
const require_reconnect = require("./reconnect.cjs");
//#region src/utils/stream.ts

@@ -32,2 +33,8 @@ /**

/**
* Default idle-reconnect policy for SSE streams. Heartbeat-adaptive
* `"auto"` stays dormant unless the server emits keep-alive heartbeats.
* Pass `0` to disable.
*/
const DEFAULT_IDLE_RECONNECT = "auto";
/**
* A pass-through {@link TransformStream} that errors the stream when it goes

@@ -169,3 +176,3 @@ * idle, so the surrounding reconnect logic can recover a half-open socket.

});
const delay = Math.min(1e3 * 2 ** (attempt - 1), 5e3) + Math.random() * 1e3;
const delay = require_reconnect.reconnectDelayMs(attempt);
await new Promise((resolve) => {

@@ -265,2 +272,3 @@ setTimeout(resolve, delay);

//#endregion
exports.DEFAULT_IDLE_RECONNECT = DEFAULT_IDLE_RECONNECT;
exports.IterableReadableStream = IterableReadableStream;

@@ -267,0 +275,0 @@ exports.idleReconnectStream = idleReconnectStream;

@@ -1,1 +0,1 @@

{"version":3,"file":"stream.cjs","names":["isNetworkError"],"sources":["../../src/utils/stream.ts"],"sourcesContent":["import { isNetworkError } from \"./error.js\";\n\n// in this case don't quite match.\ntype IterableReadableStreamInterface<T> = ReadableStream<T> & AsyncIterable<T>;\n\n/**\n * Options for streaming with automatic retry logic.\n */\nexport interface StreamWithRetryOptions {\n /**\n * Maximum number of reconnection attempts. Default is 5.\n */\n maxRetries?: number;\n\n /**\n * AbortSignal to cancel the stream.\n */\n signal?: AbortSignal;\n\n /**\n * Callback invoked when a reconnection attempt is made.\n */\n onReconnect?: (options: {\n attempt: number;\n lastEventId?: string;\n cause: unknown;\n }) => void;\n}\n\n/**\n * Parameters for making a stream request\n */\nexport interface StreamRequestParams {\n /**\n * Last event ID to resume from, if available\n */\n lastEventId?: string;\n\n /**\n * Optional reconnection path from the Location header\n */\n reconnectPath?: string;\n}\n\n/**\n * Error thrown when maximum reconnection attempts are exceeded.\n */\nexport class MaxReconnectAttemptsError extends Error {\n constructor(maxAttempts: number, cause: unknown) {\n super(`Exceeded maximum SSE reconnection attempts (${maxAttempts})`);\n this.name = \"MaxReconnectAttemptsError\";\n this.cause = cause;\n }\n}\n\n/**\n * Error injected into the stream by {@link idleReconnectStream} when no lines\n * arrive within the active idle window. Surfacing this during the read is what\n * lets the reconnect loops in `streamWithRetry` and the protocol SSE transport\n * recover from a half-open socket — one that was silently dropped (e.g. a hard\n * pod kill on a platform revision rollover) without a TCP FIN/RST, so neither\n * a `done` nor a thrown network error ever arrives.\n */\nexport class StreamIdleTimeoutError extends Error {\n readonly idleTimeoutMs: number;\n\n constructor(idleTimeoutMs: number) {\n super(\n `No SSE bytes received for ${idleTimeoutMs}ms; assuming the connection is half-open and reconnecting.`\n );\n this.name = \"StreamIdleTimeoutError\";\n this.idleTimeoutMs = idleTimeoutMs;\n }\n}\n\n/** `\":\"` — first byte of an SSE comment / keep-alive line. */\nconst SSE_COMMENT_BYTE = 0x3a;\n\n/**\n * How {@link idleReconnectStream} decides when the connection is idle.\n *\n * - A `number` is a fixed idle window in milliseconds: the watchdog arms\n * immediately (even before the first byte) and trips after that long with no\n * activity. Use when you know your server's behaviour and want guaranteed\n * coverage from t=0; it does not depend on heartbeats.\n * - `\"auto\"` is heartbeat-adaptive: the watchdog stays dormant until it has\n * observed the server's SSE keep-alive comments (e.g. LangGraph Platform's\n * `: heartbeat` every ~5s), then arms with a window derived from the\n * observed cadence. On a server that never sends heartbeats it never arms,\n * so it can't false-fire during a legitimately quiet period.\n */\nexport type IdleReconnectMode = number | \"auto\";\n\nexport interface IdleReconnectStreamOptions {\n /** Fixed timeout (ms) or `\"auto\"` heartbeat-adaptive. */\n mode: IdleReconnectMode;\n /** `\"auto\"`: multiplier applied to the observed heartbeat interval. Default 3. */\n timeoutFactor?: number;\n /** `\"auto\"`: lower clamp for the derived timeout (ms). Default 6000. */\n minTimeoutMs?: number;\n /** `\"auto\"`: upper clamp for the derived timeout (ms). Default 30000. */\n maxTimeoutMs?: number;\n /** Fired immediately before the stream is errored, for logging/metrics. */\n onIdle?: (info: { timeoutMs: number; source: \"fixed\" | \"heartbeat\" }) => void;\n}\n\n/**\n * A pass-through {@link TransformStream} that errors the stream when it goes\n * idle, so the surrounding reconnect logic can recover a half-open socket.\n *\n * MUST sit on the *line* stream — i.e. after\n * {@link import(\"./sse.js\").BytesLineDecoder} but before\n * {@link import(\"./sse.js\").SSEDecoder} (which discards `:` comment lines).\n * Operating at the line level lets the watchdog both (a) reset on any line\n * (data *or* heartbeat = liveness) and (b) recognise heartbeat comment lines\n * to drive `\"auto\"` mode.\n *\n * In `\"auto\"` mode the watchdog is intentionally dormant until it has seen at\n * least two heartbeats (so it can measure the cadence). This means a socket\n * that dies inside the first heartbeat interval won't be caught until a\n * heartbeat would have been due — an acceptable trade for never false-firing\n * on heartbeat-less servers. Pass a fixed `number` if you need coverage from\n * the very first byte.\n */\nexport function idleReconnectStream(\n options: IdleReconnectStreamOptions\n): TransformStream<Uint8Array, Uint8Array> {\n const factor = options.timeoutFactor ?? 3;\n const minTimeoutMs = options.minTimeoutMs ?? 6_000;\n const maxTimeoutMs = options.maxTimeoutMs ?? 30_000;\n const fixedTimeoutMs = typeof options.mode === \"number\" ? options.mode : null;\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n let controllerRef: TransformStreamDefaultController<Uint8Array> | undefined;\n\n // `\"auto\"` cadence inference.\n let lastHeartbeatAt: number | undefined;\n // The active idle window: the fixed value, or (auto) the heartbeat-derived\n // value once known. `null` means \"not armed yet\".\n let derivedTimeoutMs: number | null = fixedTimeoutMs;\n\n const clear = () => {\n if (timer != null) {\n clearTimeout(timer);\n timer = undefined;\n }\n };\n\n const arm = () => {\n clear();\n const timeoutMs = derivedTimeoutMs;\n if (timeoutMs == null || timeoutMs <= 0) return;\n timer = setTimeout(() => {\n options.onIdle?.({\n timeoutMs,\n source: fixedTimeoutMs != null ? \"fixed\" : \"heartbeat\",\n });\n try {\n controllerRef?.error(new StreamIdleTimeoutError(timeoutMs));\n } catch {\n // Stream already closed/errored/cancelled — nothing to abort.\n }\n }, timeoutMs);\n // Don't let the watchdog by itself keep a Node process alive.\n (timer as unknown as { unref?: () => void }).unref?.();\n };\n\n const noteHeartbeat = () => {\n if (fixedTimeoutMs != null) return; // cadence irrelevant in fixed mode\n const now = Date.now();\n if (lastHeartbeatAt != null) {\n const interval = now - lastHeartbeatAt;\n if (interval > 0) {\n const candidate = Math.min(\n Math.max(interval * factor, minTimeoutMs),\n maxTimeoutMs\n );\n // Keep the most conservative (largest) window observed so far.\n derivedTimeoutMs =\n derivedTimeoutMs == null\n ? candidate\n : Math.max(derivedTimeoutMs, candidate);\n }\n }\n lastHeartbeatAt = now;\n };\n\n return new TransformStream<Uint8Array, Uint8Array>({\n start(controller) {\n controllerRef = controller;\n // Fixed mode arms eagerly (also catches pre-first-byte silence). Auto\n // mode waits until a cadence is established in `transform`.\n arm();\n },\n transform(line, controller) {\n // A line beginning with \":\" is an SSE comment / keep-alive heartbeat.\n if (line.length > 0 && line[0] === SSE_COMMENT_BYTE) {\n noteHeartbeat();\n }\n // Any line is liveness — (re)arm the idle timer.\n arm();\n controller.enqueue(line);\n },\n flush() {\n clear();\n },\n });\n}\n\n/**\n * Stream with automatic retry logic for SSE connections.\n * Implements reconnection behavior similar to the Python SDK.\n *\n * @param makeRequest Function to make requests. When `params` is undefined/empty, it's the initial request.\n * When `params.reconnectPath` is provided, it's a reconnection request.\n * @param options Configuration options\n * @returns AsyncGenerator yielding stream events\n */\nexport async function* streamWithRetry<T extends { id?: string }>(\n makeRequest: (params?: StreamRequestParams) => Promise<{\n response: Response;\n stream: ReadableStream<T>;\n }>,\n options: StreamWithRetryOptions = {}\n): AsyncGenerator<T> {\n const maxRetries = options.maxRetries ?? 5;\n let attempt = 0;\n let lastEventId: string | undefined;\n let reconnectPath: string | undefined;\n\n while (true) {\n let shouldRetry = false;\n let lastError: unknown;\n let reader: ReadableStreamDefaultReader<T> | undefined;\n\n try {\n // Check if aborted before making request\n if (options.signal?.aborted) return;\n\n // Make request - initial if no reconnect path, reconnect otherwise\n const { response, stream } = await makeRequest(\n reconnectPath ? { lastEventId, reconnectPath } : undefined\n );\n\n // Check for Location header (server-provided reconnection path)\n const locationHeader = response.headers.get(\"location\");\n if (locationHeader) {\n reconnectPath = locationHeader;\n }\n\n // Verify content type\n const contentType = response.headers.get(\"content-type\")?.split(\";\")[0];\n if (contentType && !contentType.includes(\"text/event-stream\")) {\n throw new Error(\n `Expected response header Content-Type to contain 'text/event-stream', got '${contentType}'`\n );\n }\n\n reader = stream.getReader();\n\n try {\n while (true) {\n // Check abort signal before each read\n if (options.signal?.aborted) {\n await reader.cancel();\n return;\n }\n\n const { done, value } = await reader.read();\n\n if (done) {\n // Stream completed successfully\n break;\n }\n\n // Track last event ID for reconnection\n if (value.id) {\n lastEventId = value.id;\n }\n\n yield value;\n }\n\n // Stream completed successfully, exit retry loop\n break;\n } catch (error) {\n // Error during streaming - attempt reconnect if we have a location header\n if (reconnectPath && !options.signal?.aborted) {\n shouldRetry = true;\n } else {\n throw error;\n }\n } finally {\n if (reader) {\n try {\n reader.releaseLock();\n } catch {\n // Ignore errors when releasing lock\n }\n }\n }\n } catch (error) {\n lastError = error;\n\n // Only retry if we have reconnection capability and it's a network error\n if (isNetworkError(error) && reconnectPath && !options.signal?.aborted) {\n shouldRetry = true;\n } else {\n throw error;\n }\n }\n\n if (shouldRetry) {\n attempt += 1;\n if (attempt > maxRetries) {\n throw new MaxReconnectAttemptsError(maxRetries, lastError);\n }\n\n // Notify about reconnection attempt\n options.onReconnect?.({ attempt, lastEventId, cause: lastError });\n\n // Exponential backoff with jitter: min(1000 * 2^attempt, 5000) + random jitter\n const baseDelay = Math.min(1000 * 2 ** (attempt - 1), 5000);\n const jitter = Math.random() * 1000;\n const delay = baseDelay + jitter;\n\n await new Promise((resolve) => {\n setTimeout(resolve, delay);\n });\n\n continue;\n }\n\n // Successfully completed\n break;\n }\n}\n\n/*\n * Support async iterator syntax for ReadableStreams in all environments.\n * Source: https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490\n */\nexport class IterableReadableStream<T>\n extends ReadableStream<T>\n implements IterableReadableStreamInterface<T>\n{\n public reader: ReadableStreamDefaultReader<T>;\n\n ensureReader() {\n if (!this.reader) {\n this.reader = this.getReader();\n }\n }\n\n async next(): Promise<IteratorResult<T>> {\n this.ensureReader();\n try {\n const result = await this.reader.read();\n if (result.done) {\n this.reader.releaseLock(); // release lock when stream becomes closed\n return {\n done: true,\n value: undefined,\n };\n } else {\n return {\n done: false,\n value: result.value,\n };\n }\n } catch (e) {\n this.reader.releaseLock(); // release lock when stream becomes errored\n throw e;\n }\n }\n\n async return(): Promise<IteratorResult<T>> {\n this.ensureReader();\n // If wrapped in a Node stream, cancel is already called.\n if (this.locked) {\n const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet\n this.reader.releaseLock(); // release lock first\n await cancelPromise; // now await it\n }\n return { done: true, value: undefined };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async throw(e: any): Promise<IteratorResult<T>> {\n this.ensureReader();\n if (this.locked) {\n const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet\n this.reader.releaseLock(); // release lock first\n await cancelPromise; // now await it\n }\n throw e;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore Not present in Node 18 types, required in latest Node 22\n async [Symbol.asyncDispose]() {\n await this.return();\n }\n\n [Symbol.asyncIterator]() {\n return this;\n }\n\n static fromReadableStream<T>(stream: ReadableStream<T>) {\n // From https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams#reading_the_stream\n const reader = stream.getReader();\n return new IterableReadableStream<T>({\n start(controller) {\n return pump();\n function pump(): Promise<T | undefined> {\n return reader.read().then(({ done, value }) => {\n // When no more data needs to be consumed, close the stream\n if (done) {\n controller.close();\n return;\n }\n // Enqueue the next data chunk into our target stream\n controller.enqueue(value);\n return pump();\n });\n }\n },\n cancel() {\n reader.releaseLock();\n },\n });\n }\n\n static fromAsyncGenerator<T>(generator: AsyncGenerator<T>) {\n return new IterableReadableStream<T>({\n async pull(controller) {\n const { value, done } = await generator.next();\n // When no more data needs to be consumed, close the stream\n if (done) {\n controller.close();\n }\n // Fix: `else if (value)` will hang the streaming when nullish value (e.g. empty string) is pulled\n controller.enqueue(value);\n },\n async cancel(reason) {\n await generator.return(reason);\n },\n });\n }\n}\n"],"mappings":"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"}
{"version":3,"file":"stream.cjs","names":["isNetworkError","reconnectDelayMs"],"sources":["../../src/utils/stream.ts"],"sourcesContent":["import { isNetworkError } from \"./error.js\";\nimport {\n DEFAULT_MAX_RECONNECT_ATTEMPTS,\n reconnectDelayMs,\n} from \"./reconnect.js\";\n\n// in this case don't quite match.\ntype IterableReadableStreamInterface<T> = ReadableStream<T> & AsyncIterable<T>;\n\n/**\n * Options for streaming with automatic retry logic.\n */\nexport interface StreamWithRetryOptions {\n /**\n * Maximum number of reconnection attempts. Default is\n * {@link DEFAULT_MAX_RECONNECT_ATTEMPTS}.\n */\n maxRetries?: number;\n\n /**\n * AbortSignal to cancel the stream.\n */\n signal?: AbortSignal;\n\n /**\n * Callback invoked when a reconnection attempt is made.\n */\n onReconnect?: (options: {\n attempt: number;\n lastEventId?: string;\n cause: unknown;\n }) => void;\n}\n\n/**\n * Parameters for making a stream request\n */\nexport interface StreamRequestParams {\n /**\n * Last event ID to resume from, if available\n */\n lastEventId?: string;\n\n /**\n * Optional reconnection path from the Location header\n */\n reconnectPath?: string;\n}\n\n/**\n * Error thrown when maximum reconnection attempts are exceeded.\n */\nexport class MaxReconnectAttemptsError extends Error {\n constructor(maxAttempts: number, cause: unknown) {\n super(`Exceeded maximum SSE reconnection attempts (${maxAttempts})`);\n this.name = \"MaxReconnectAttemptsError\";\n this.cause = cause;\n }\n}\n\n/**\n * Error injected into the stream by {@link idleReconnectStream} when no lines\n * arrive within the active idle window. Surfacing this during the read is what\n * lets the reconnect loops in `streamWithRetry` and the protocol SSE transport\n * recover from a half-open socket — one that was silently dropped (e.g. a hard\n * pod kill on a platform revision rollover) without a TCP FIN/RST, so neither\n * a `done` nor a thrown network error ever arrives.\n */\nexport class StreamIdleTimeoutError extends Error {\n readonly idleTimeoutMs: number;\n\n constructor(idleTimeoutMs: number) {\n super(\n `No SSE bytes received for ${idleTimeoutMs}ms; assuming the connection is half-open and reconnecting.`\n );\n this.name = \"StreamIdleTimeoutError\";\n this.idleTimeoutMs = idleTimeoutMs;\n }\n}\n\n/** `\":\"` — first byte of an SSE comment / keep-alive line. */\nconst SSE_COMMENT_BYTE = 0x3a;\n\n/**\n * How {@link idleReconnectStream} decides when the connection is idle.\n *\n * - A `number` is a fixed idle window in milliseconds: the watchdog arms\n * immediately (even before the first byte) and trips after that long with no\n * activity. Use when you know your server's behaviour and want guaranteed\n * coverage from t=0; it does not depend on heartbeats.\n * - `\"auto\"` is heartbeat-adaptive: the watchdog stays dormant until it has\n * observed the server's SSE keep-alive comments (e.g. LangGraph Platform's\n * `: heartbeat` every ~5s), then arms with a window derived from the\n * observed cadence. On a server that never sends heartbeats it never arms,\n * so it can't false-fire during a legitimately quiet period.\n */\nexport type IdleReconnectMode = number | \"auto\";\n\n/**\n * Default idle-reconnect policy for SSE streams. Heartbeat-adaptive\n * `\"auto\"` stays dormant unless the server emits keep-alive heartbeats.\n * Pass `0` to disable.\n */\nexport const DEFAULT_IDLE_RECONNECT: IdleReconnectMode = \"auto\";\n\nexport interface IdleReconnectStreamOptions {\n /** Fixed timeout (ms) or `\"auto\"` heartbeat-adaptive. */\n mode: IdleReconnectMode;\n /** `\"auto\"`: multiplier applied to the observed heartbeat interval. Default 3. */\n timeoutFactor?: number;\n /** `\"auto\"`: lower clamp for the derived timeout (ms). Default 6000. */\n minTimeoutMs?: number;\n /** `\"auto\"`: upper clamp for the derived timeout (ms). Default 30000. */\n maxTimeoutMs?: number;\n /** Fired immediately before the stream is errored, for logging/metrics. */\n onIdle?: (info: { timeoutMs: number; source: \"fixed\" | \"heartbeat\" }) => void;\n}\n\n/**\n * A pass-through {@link TransformStream} that errors the stream when it goes\n * idle, so the surrounding reconnect logic can recover a half-open socket.\n *\n * MUST sit on the *line* stream — i.e. after\n * {@link import(\"./sse.js\").BytesLineDecoder} but before\n * {@link import(\"./sse.js\").SSEDecoder} (which discards `:` comment lines).\n * Operating at the line level lets the watchdog both (a) reset on any line\n * (data *or* heartbeat = liveness) and (b) recognise heartbeat comment lines\n * to drive `\"auto\"` mode.\n *\n * In `\"auto\"` mode the watchdog is intentionally dormant until it has seen at\n * least two heartbeats (so it can measure the cadence). This means a socket\n * that dies inside the first heartbeat interval won't be caught until a\n * heartbeat would have been due — an acceptable trade for never false-firing\n * on heartbeat-less servers. Pass a fixed `number` if you need coverage from\n * the very first byte.\n */\nexport function idleReconnectStream(\n options: IdleReconnectStreamOptions\n): TransformStream<Uint8Array, Uint8Array> {\n const factor = options.timeoutFactor ?? 3;\n const minTimeoutMs = options.minTimeoutMs ?? 6_000;\n const maxTimeoutMs = options.maxTimeoutMs ?? 30_000;\n const fixedTimeoutMs = typeof options.mode === \"number\" ? options.mode : null;\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n let controllerRef: TransformStreamDefaultController<Uint8Array> | undefined;\n\n // `\"auto\"` cadence inference.\n let lastHeartbeatAt: number | undefined;\n // The active idle window: the fixed value, or (auto) the heartbeat-derived\n // value once known. `null` means \"not armed yet\".\n let derivedTimeoutMs: number | null = fixedTimeoutMs;\n\n const clear = () => {\n if (timer != null) {\n clearTimeout(timer);\n timer = undefined;\n }\n };\n\n const arm = () => {\n clear();\n const timeoutMs = derivedTimeoutMs;\n if (timeoutMs == null || timeoutMs <= 0) return;\n timer = setTimeout(() => {\n options.onIdle?.({\n timeoutMs,\n source: fixedTimeoutMs != null ? \"fixed\" : \"heartbeat\",\n });\n try {\n controllerRef?.error(new StreamIdleTimeoutError(timeoutMs));\n } catch {\n // Stream already closed/errored/cancelled — nothing to abort.\n }\n }, timeoutMs);\n // Don't let the watchdog by itself keep a Node process alive.\n (timer as unknown as { unref?: () => void }).unref?.();\n };\n\n const noteHeartbeat = () => {\n if (fixedTimeoutMs != null) return; // cadence irrelevant in fixed mode\n const now = Date.now();\n if (lastHeartbeatAt != null) {\n const interval = now - lastHeartbeatAt;\n if (interval > 0) {\n const candidate = Math.min(\n Math.max(interval * factor, minTimeoutMs),\n maxTimeoutMs\n );\n // Keep the most conservative (largest) window observed so far.\n derivedTimeoutMs =\n derivedTimeoutMs == null\n ? candidate\n : Math.max(derivedTimeoutMs, candidate);\n }\n }\n lastHeartbeatAt = now;\n };\n\n return new TransformStream<Uint8Array, Uint8Array>({\n start(controller) {\n controllerRef = controller;\n // Fixed mode arms eagerly (also catches pre-first-byte silence). Auto\n // mode waits until a cadence is established in `transform`.\n arm();\n },\n transform(line, controller) {\n // A line beginning with \":\" is an SSE comment / keep-alive heartbeat.\n if (line.length > 0 && line[0] === SSE_COMMENT_BYTE) {\n noteHeartbeat();\n }\n // Any line is liveness — (re)arm the idle timer.\n arm();\n controller.enqueue(line);\n },\n flush() {\n clear();\n },\n });\n}\n\n/**\n * Stream with automatic retry logic for SSE connections.\n * Implements reconnection behavior similar to the Python SDK.\n *\n * @param makeRequest Function to make requests. When `params` is undefined/empty, it's the initial request.\n * When `params.reconnectPath` is provided, it's a reconnection request.\n * @param options Configuration options\n * @returns AsyncGenerator yielding stream events\n */\nexport async function* streamWithRetry<T extends { id?: string }>(\n makeRequest: (params?: StreamRequestParams) => Promise<{\n response: Response;\n stream: ReadableStream<T>;\n }>,\n options: StreamWithRetryOptions = {}\n): AsyncGenerator<T> {\n const maxRetries = options.maxRetries ?? DEFAULT_MAX_RECONNECT_ATTEMPTS;\n let attempt = 0;\n let lastEventId: string | undefined;\n let reconnectPath: string | undefined;\n\n while (true) {\n let shouldRetry = false;\n let lastError: unknown;\n let reader: ReadableStreamDefaultReader<T> | undefined;\n\n try {\n // Check if aborted before making request\n if (options.signal?.aborted) return;\n\n // Make request - initial if no reconnect path, reconnect otherwise\n const { response, stream } = await makeRequest(\n reconnectPath ? { lastEventId, reconnectPath } : undefined\n );\n\n // Check for Location header (server-provided reconnection path)\n const locationHeader = response.headers.get(\"location\");\n if (locationHeader) {\n reconnectPath = locationHeader;\n }\n\n // Verify content type\n const contentType = response.headers.get(\"content-type\")?.split(\";\")[0];\n if (contentType && !contentType.includes(\"text/event-stream\")) {\n throw new Error(\n `Expected response header Content-Type to contain 'text/event-stream', got '${contentType}'`\n );\n }\n\n reader = stream.getReader();\n\n try {\n while (true) {\n // Check abort signal before each read\n if (options.signal?.aborted) {\n await reader.cancel();\n return;\n }\n\n const { done, value } = await reader.read();\n\n if (done) {\n // Stream completed successfully\n break;\n }\n\n // Track last event ID for reconnection\n if (value.id) {\n lastEventId = value.id;\n }\n\n yield value;\n }\n\n // Stream completed successfully, exit retry loop\n break;\n } catch (error) {\n // Error during streaming - attempt reconnect if we have a location header\n if (reconnectPath && !options.signal?.aborted) {\n shouldRetry = true;\n } else {\n throw error;\n }\n } finally {\n if (reader) {\n try {\n reader.releaseLock();\n } catch {\n // Ignore errors when releasing lock\n }\n }\n }\n } catch (error) {\n lastError = error;\n\n // Only retry if we have reconnection capability and it's a network error\n if (isNetworkError(error) && reconnectPath && !options.signal?.aborted) {\n shouldRetry = true;\n } else {\n throw error;\n }\n }\n\n if (shouldRetry) {\n attempt += 1;\n if (attempt > maxRetries) {\n throw new MaxReconnectAttemptsError(maxRetries, lastError);\n }\n\n // Notify about reconnection attempt\n options.onReconnect?.({ attempt, lastEventId, cause: lastError });\n\n // Exponential backoff with jitter (shared with protocol transports).\n const delay = reconnectDelayMs(attempt);\n\n await new Promise((resolve) => {\n setTimeout(resolve, delay);\n });\n\n continue;\n }\n\n // Successfully completed\n break;\n }\n}\n\n/*\n * Support async iterator syntax for ReadableStreams in all environments.\n * Source: https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490\n */\nexport class IterableReadableStream<T>\n extends ReadableStream<T>\n implements IterableReadableStreamInterface<T>\n{\n public reader: ReadableStreamDefaultReader<T>;\n\n ensureReader() {\n if (!this.reader) {\n this.reader = this.getReader();\n }\n }\n\n async next(): Promise<IteratorResult<T>> {\n this.ensureReader();\n try {\n const result = await this.reader.read();\n if (result.done) {\n this.reader.releaseLock(); // release lock when stream becomes closed\n return {\n done: true,\n value: undefined,\n };\n } else {\n return {\n done: false,\n value: result.value,\n };\n }\n } catch (e) {\n this.reader.releaseLock(); // release lock when stream becomes errored\n throw e;\n }\n }\n\n async return(): Promise<IteratorResult<T>> {\n this.ensureReader();\n // If wrapped in a Node stream, cancel is already called.\n if (this.locked) {\n const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet\n this.reader.releaseLock(); // release lock first\n await cancelPromise; // now await it\n }\n return { done: true, value: undefined };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async throw(e: any): Promise<IteratorResult<T>> {\n this.ensureReader();\n if (this.locked) {\n const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet\n this.reader.releaseLock(); // release lock first\n await cancelPromise; // now await it\n }\n throw e;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore Not present in Node 18 types, required in latest Node 22\n async [Symbol.asyncDispose]() {\n await this.return();\n }\n\n [Symbol.asyncIterator]() {\n return this;\n }\n\n static fromReadableStream<T>(stream: ReadableStream<T>) {\n // From https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams#reading_the_stream\n const reader = stream.getReader();\n return new IterableReadableStream<T>({\n start(controller) {\n return pump();\n function pump(): Promise<T | undefined> {\n return reader.read().then(({ done, value }) => {\n // When no more data needs to be consumed, close the stream\n if (done) {\n controller.close();\n return;\n }\n // Enqueue the next data chunk into our target stream\n controller.enqueue(value);\n return pump();\n });\n }\n },\n cancel() {\n reader.releaseLock();\n },\n });\n }\n\n static fromAsyncGenerator<T>(generator: AsyncGenerator<T>) {\n return new IterableReadableStream<T>({\n async pull(controller) {\n const { value, done } = await generator.next();\n // When no more data needs to be consumed, close the stream\n if (done) {\n controller.close();\n }\n // Fix: `else if (value)` will hang the streaming when nullish value (e.g. empty string) is pulled\n controller.enqueue(value);\n },\n async cancel(reason) {\n await generator.return(reason);\n },\n });\n }\n}\n"],"mappings":"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"}

@@ -1,1 +0,1 @@

{"version":3,"file":"stream.d.cts","names":[],"sources":["../../src/utils/stream.ts"],"mappings":";KAGK,+BAAA,MAAqC,cAAA,CAAe,CAAA,IAAK,aAAA,CAAc,CAAA;;;;;;;;;;;;;;;;;KAwFhE,iBAAA;AAAA,cA2PC,sBAAA,YACH,cAAA,CAAe,CAAA,aACZ,+BAAA,CAAgC,CAAA;EAEpC,MAAA,EAAQ,2BAAA,CAA4B,CAAA;EAE3C,YAAA,CAAA;EAMM,IAAA,CAAA,GAAQ,OAAA,CAAQ,cAAA,CAAe,CAAA;EAsB/B,MAAA,CAAA,GAAU,OAAA,CAAQ,cAAA,CAAe,CAAA;EAYjC,KAAA,CAAM,CAAA,QAAS,OAAA,CAAQ,cAAA,CAAe,CAAA;EAAA,CAYrC,MAAA,CAAO,YAAA,KAAa,OAAA;EAAA,CAI1B,MAAA,CAAO,aAAA;EAAA,OAID,kBAAA,GAAA,CAAsB,MAAA,EAAQ,cAAA,CAAe,CAAA,IAAE,sBAAA,CAAA,CAAA;EAAA,OAyB/C,kBAAA,GAAA,CAAsB,SAAA,EAAW,cAAA,CAAe,CAAA,IAAE,sBAAA,CAAA,CAAA;AAAA"}
{"version":3,"file":"stream.d.cts","names":[],"sources":["../../src/utils/stream.ts"],"mappings":";KAOK,+BAAA,MAAqC,cAAA,CAAe,CAAA,IAAK,aAAA,CAAc,CAAA;;;;;;;;;;;;;;;;;KAyFhE,iBAAA;AAAA,cAgQC,sBAAA,YACH,cAAA,CAAe,CAAA,aACZ,+BAAA,CAAgC,CAAA;EAEpC,MAAA,EAAQ,2BAAA,CAA4B,CAAA;EAE3C,YAAA,CAAA;EAMM,IAAA,CAAA,GAAQ,OAAA,CAAQ,cAAA,CAAe,CAAA;EAsB/B,MAAA,CAAA,GAAU,OAAA,CAAQ,cAAA,CAAe,CAAA;EAYjC,KAAA,CAAM,CAAA,QAAS,OAAA,CAAQ,cAAA,CAAe,CAAA;EAAA,CAYrC,MAAA,CAAO,YAAA,KAAa,OAAA;EAAA,CAI1B,MAAA,CAAO,aAAA;EAAA,OAID,kBAAA,GAAA,CAAsB,MAAA,EAAQ,cAAA,CAAe,CAAA,IAAE,sBAAA,CAAA,CAAA;EAAA,OAyB/C,kBAAA,GAAA,CAAsB,SAAA,EAAW,cAAA,CAAe,CAAA,IAAE,sBAAA,CAAA,CAAA;AAAA"}

@@ -1,1 +0,1 @@

{"version":3,"file":"stream.d.ts","names":[],"sources":["../../src/utils/stream.ts"],"mappings":";KAGK,+BAAA,MAAqC,cAAA,CAAe,CAAA,IAAK,aAAA,CAAc,CAAA;;;;;;;;;;;;;;;;;KAwFhE,iBAAA;AAAA,cA2PC,sBAAA,YACH,cAAA,CAAe,CAAA,aACZ,+BAAA,CAAgC,CAAA;EAEpC,MAAA,EAAQ,2BAAA,CAA4B,CAAA;EAE3C,YAAA,CAAA;EAMM,IAAA,CAAA,GAAQ,OAAA,CAAQ,cAAA,CAAe,CAAA;EAsB/B,MAAA,CAAA,GAAU,OAAA,CAAQ,cAAA,CAAe,CAAA;EAYjC,KAAA,CAAM,CAAA,QAAS,OAAA,CAAQ,cAAA,CAAe,CAAA;EAAA,CAYrC,MAAA,CAAO,YAAA,KAAa,OAAA;EAAA,CAI1B,MAAA,CAAO,aAAA;EAAA,OAID,kBAAA,GAAA,CAAsB,MAAA,EAAQ,cAAA,CAAe,CAAA,IAAE,sBAAA,CAAA,CAAA;EAAA,OAyB/C,kBAAA,GAAA,CAAsB,SAAA,EAAW,cAAA,CAAe,CAAA,IAAE,sBAAA,CAAA,CAAA;AAAA"}
{"version":3,"file":"stream.d.ts","names":[],"sources":["../../src/utils/stream.ts"],"mappings":";KAOK,+BAAA,MAAqC,cAAA,CAAe,CAAA,IAAK,aAAA,CAAc,CAAA;;;;;;;;;;;;;;;;;KAyFhE,iBAAA;AAAA,cAgQC,sBAAA,YACH,cAAA,CAAe,CAAA,aACZ,+BAAA,CAAgC,CAAA;EAEpC,MAAA,EAAQ,2BAAA,CAA4B,CAAA;EAE3C,YAAA,CAAA;EAMM,IAAA,CAAA,GAAQ,OAAA,CAAQ,cAAA,CAAe,CAAA;EAsB/B,MAAA,CAAA,GAAU,OAAA,CAAQ,cAAA,CAAe,CAAA;EAYjC,KAAA,CAAM,CAAA,QAAS,OAAA,CAAQ,cAAA,CAAe,CAAA;EAAA,CAYrC,MAAA,CAAO,YAAA,KAAa,OAAA;EAAA,CAI1B,MAAA,CAAO,aAAA;EAAA,OAID,kBAAA,GAAA,CAAsB,MAAA,EAAQ,cAAA,CAAe,CAAA,IAAE,sBAAA,CAAA,CAAA;EAAA,OAyB/C,kBAAA,GAAA,CAAsB,SAAA,EAAW,cAAA,CAAe,CAAA,IAAE,sBAAA,CAAA,CAAA;AAAA"}
import { isNetworkError } from "./error.js";
import { reconnectDelayMs } from "./reconnect.js";
//#region src/utils/stream.ts

@@ -32,2 +33,8 @@ /**

/**
* Default idle-reconnect policy for SSE streams. Heartbeat-adaptive
* `"auto"` stays dormant unless the server emits keep-alive heartbeats.
* Pass `0` to disable.
*/
const DEFAULT_IDLE_RECONNECT = "auto";
/**
* A pass-through {@link TransformStream} that errors the stream when it goes

@@ -169,3 +176,3 @@ * idle, so the surrounding reconnect logic can recover a half-open socket.

});
const delay = Math.min(1e3 * 2 ** (attempt - 1), 5e3) + Math.random() * 1e3;
const delay = reconnectDelayMs(attempt);
await new Promise((resolve) => {

@@ -265,4 +272,4 @@ setTimeout(resolve, delay);

//#endregion
export { IterableReadableStream, idleReconnectStream, streamWithRetry };
export { DEFAULT_IDLE_RECONNECT, IterableReadableStream, idleReconnectStream, streamWithRetry };
//# sourceMappingURL=stream.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"stream.js","names":[],"sources":["../../src/utils/stream.ts"],"sourcesContent":["import { isNetworkError } from \"./error.js\";\n\n// in this case don't quite match.\ntype IterableReadableStreamInterface<T> = ReadableStream<T> & AsyncIterable<T>;\n\n/**\n * Options for streaming with automatic retry logic.\n */\nexport interface StreamWithRetryOptions {\n /**\n * Maximum number of reconnection attempts. Default is 5.\n */\n maxRetries?: number;\n\n /**\n * AbortSignal to cancel the stream.\n */\n signal?: AbortSignal;\n\n /**\n * Callback invoked when a reconnection attempt is made.\n */\n onReconnect?: (options: {\n attempt: number;\n lastEventId?: string;\n cause: unknown;\n }) => void;\n}\n\n/**\n * Parameters for making a stream request\n */\nexport interface StreamRequestParams {\n /**\n * Last event ID to resume from, if available\n */\n lastEventId?: string;\n\n /**\n * Optional reconnection path from the Location header\n */\n reconnectPath?: string;\n}\n\n/**\n * Error thrown when maximum reconnection attempts are exceeded.\n */\nexport class MaxReconnectAttemptsError extends Error {\n constructor(maxAttempts: number, cause: unknown) {\n super(`Exceeded maximum SSE reconnection attempts (${maxAttempts})`);\n this.name = \"MaxReconnectAttemptsError\";\n this.cause = cause;\n }\n}\n\n/**\n * Error injected into the stream by {@link idleReconnectStream} when no lines\n * arrive within the active idle window. Surfacing this during the read is what\n * lets the reconnect loops in `streamWithRetry` and the protocol SSE transport\n * recover from a half-open socket — one that was silently dropped (e.g. a hard\n * pod kill on a platform revision rollover) without a TCP FIN/RST, so neither\n * a `done` nor a thrown network error ever arrives.\n */\nexport class StreamIdleTimeoutError extends Error {\n readonly idleTimeoutMs: number;\n\n constructor(idleTimeoutMs: number) {\n super(\n `No SSE bytes received for ${idleTimeoutMs}ms; assuming the connection is half-open and reconnecting.`\n );\n this.name = \"StreamIdleTimeoutError\";\n this.idleTimeoutMs = idleTimeoutMs;\n }\n}\n\n/** `\":\"` — first byte of an SSE comment / keep-alive line. */\nconst SSE_COMMENT_BYTE = 0x3a;\n\n/**\n * How {@link idleReconnectStream} decides when the connection is idle.\n *\n * - A `number` is a fixed idle window in milliseconds: the watchdog arms\n * immediately (even before the first byte) and trips after that long with no\n * activity. Use when you know your server's behaviour and want guaranteed\n * coverage from t=0; it does not depend on heartbeats.\n * - `\"auto\"` is heartbeat-adaptive: the watchdog stays dormant until it has\n * observed the server's SSE keep-alive comments (e.g. LangGraph Platform's\n * `: heartbeat` every ~5s), then arms with a window derived from the\n * observed cadence. On a server that never sends heartbeats it never arms,\n * so it can't false-fire during a legitimately quiet period.\n */\nexport type IdleReconnectMode = number | \"auto\";\n\nexport interface IdleReconnectStreamOptions {\n /** Fixed timeout (ms) or `\"auto\"` heartbeat-adaptive. */\n mode: IdleReconnectMode;\n /** `\"auto\"`: multiplier applied to the observed heartbeat interval. Default 3. */\n timeoutFactor?: number;\n /** `\"auto\"`: lower clamp for the derived timeout (ms). Default 6000. */\n minTimeoutMs?: number;\n /** `\"auto\"`: upper clamp for the derived timeout (ms). Default 30000. */\n maxTimeoutMs?: number;\n /** Fired immediately before the stream is errored, for logging/metrics. */\n onIdle?: (info: { timeoutMs: number; source: \"fixed\" | \"heartbeat\" }) => void;\n}\n\n/**\n * A pass-through {@link TransformStream} that errors the stream when it goes\n * idle, so the surrounding reconnect logic can recover a half-open socket.\n *\n * MUST sit on the *line* stream — i.e. after\n * {@link import(\"./sse.js\").BytesLineDecoder} but before\n * {@link import(\"./sse.js\").SSEDecoder} (which discards `:` comment lines).\n * Operating at the line level lets the watchdog both (a) reset on any line\n * (data *or* heartbeat = liveness) and (b) recognise heartbeat comment lines\n * to drive `\"auto\"` mode.\n *\n * In `\"auto\"` mode the watchdog is intentionally dormant until it has seen at\n * least two heartbeats (so it can measure the cadence). This means a socket\n * that dies inside the first heartbeat interval won't be caught until a\n * heartbeat would have been due — an acceptable trade for never false-firing\n * on heartbeat-less servers. Pass a fixed `number` if you need coverage from\n * the very first byte.\n */\nexport function idleReconnectStream(\n options: IdleReconnectStreamOptions\n): TransformStream<Uint8Array, Uint8Array> {\n const factor = options.timeoutFactor ?? 3;\n const minTimeoutMs = options.minTimeoutMs ?? 6_000;\n const maxTimeoutMs = options.maxTimeoutMs ?? 30_000;\n const fixedTimeoutMs = typeof options.mode === \"number\" ? options.mode : null;\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n let controllerRef: TransformStreamDefaultController<Uint8Array> | undefined;\n\n // `\"auto\"` cadence inference.\n let lastHeartbeatAt: number | undefined;\n // The active idle window: the fixed value, or (auto) the heartbeat-derived\n // value once known. `null` means \"not armed yet\".\n let derivedTimeoutMs: number | null = fixedTimeoutMs;\n\n const clear = () => {\n if (timer != null) {\n clearTimeout(timer);\n timer = undefined;\n }\n };\n\n const arm = () => {\n clear();\n const timeoutMs = derivedTimeoutMs;\n if (timeoutMs == null || timeoutMs <= 0) return;\n timer = setTimeout(() => {\n options.onIdle?.({\n timeoutMs,\n source: fixedTimeoutMs != null ? \"fixed\" : \"heartbeat\",\n });\n try {\n controllerRef?.error(new StreamIdleTimeoutError(timeoutMs));\n } catch {\n // Stream already closed/errored/cancelled — nothing to abort.\n }\n }, timeoutMs);\n // Don't let the watchdog by itself keep a Node process alive.\n (timer as unknown as { unref?: () => void }).unref?.();\n };\n\n const noteHeartbeat = () => {\n if (fixedTimeoutMs != null) return; // cadence irrelevant in fixed mode\n const now = Date.now();\n if (lastHeartbeatAt != null) {\n const interval = now - lastHeartbeatAt;\n if (interval > 0) {\n const candidate = Math.min(\n Math.max(interval * factor, minTimeoutMs),\n maxTimeoutMs\n );\n // Keep the most conservative (largest) window observed so far.\n derivedTimeoutMs =\n derivedTimeoutMs == null\n ? candidate\n : Math.max(derivedTimeoutMs, candidate);\n }\n }\n lastHeartbeatAt = now;\n };\n\n return new TransformStream<Uint8Array, Uint8Array>({\n start(controller) {\n controllerRef = controller;\n // Fixed mode arms eagerly (also catches pre-first-byte silence). Auto\n // mode waits until a cadence is established in `transform`.\n arm();\n },\n transform(line, controller) {\n // A line beginning with \":\" is an SSE comment / keep-alive heartbeat.\n if (line.length > 0 && line[0] === SSE_COMMENT_BYTE) {\n noteHeartbeat();\n }\n // Any line is liveness — (re)arm the idle timer.\n arm();\n controller.enqueue(line);\n },\n flush() {\n clear();\n },\n });\n}\n\n/**\n * Stream with automatic retry logic for SSE connections.\n * Implements reconnection behavior similar to the Python SDK.\n *\n * @param makeRequest Function to make requests. When `params` is undefined/empty, it's the initial request.\n * When `params.reconnectPath` is provided, it's a reconnection request.\n * @param options Configuration options\n * @returns AsyncGenerator yielding stream events\n */\nexport async function* streamWithRetry<T extends { id?: string }>(\n makeRequest: (params?: StreamRequestParams) => Promise<{\n response: Response;\n stream: ReadableStream<T>;\n }>,\n options: StreamWithRetryOptions = {}\n): AsyncGenerator<T> {\n const maxRetries = options.maxRetries ?? 5;\n let attempt = 0;\n let lastEventId: string | undefined;\n let reconnectPath: string | undefined;\n\n while (true) {\n let shouldRetry = false;\n let lastError: unknown;\n let reader: ReadableStreamDefaultReader<T> | undefined;\n\n try {\n // Check if aborted before making request\n if (options.signal?.aborted) return;\n\n // Make request - initial if no reconnect path, reconnect otherwise\n const { response, stream } = await makeRequest(\n reconnectPath ? { lastEventId, reconnectPath } : undefined\n );\n\n // Check for Location header (server-provided reconnection path)\n const locationHeader = response.headers.get(\"location\");\n if (locationHeader) {\n reconnectPath = locationHeader;\n }\n\n // Verify content type\n const contentType = response.headers.get(\"content-type\")?.split(\";\")[0];\n if (contentType && !contentType.includes(\"text/event-stream\")) {\n throw new Error(\n `Expected response header Content-Type to contain 'text/event-stream', got '${contentType}'`\n );\n }\n\n reader = stream.getReader();\n\n try {\n while (true) {\n // Check abort signal before each read\n if (options.signal?.aborted) {\n await reader.cancel();\n return;\n }\n\n const { done, value } = await reader.read();\n\n if (done) {\n // Stream completed successfully\n break;\n }\n\n // Track last event ID for reconnection\n if (value.id) {\n lastEventId = value.id;\n }\n\n yield value;\n }\n\n // Stream completed successfully, exit retry loop\n break;\n } catch (error) {\n // Error during streaming - attempt reconnect if we have a location header\n if (reconnectPath && !options.signal?.aborted) {\n shouldRetry = true;\n } else {\n throw error;\n }\n } finally {\n if (reader) {\n try {\n reader.releaseLock();\n } catch {\n // Ignore errors when releasing lock\n }\n }\n }\n } catch (error) {\n lastError = error;\n\n // Only retry if we have reconnection capability and it's a network error\n if (isNetworkError(error) && reconnectPath && !options.signal?.aborted) {\n shouldRetry = true;\n } else {\n throw error;\n }\n }\n\n if (shouldRetry) {\n attempt += 1;\n if (attempt > maxRetries) {\n throw new MaxReconnectAttemptsError(maxRetries, lastError);\n }\n\n // Notify about reconnection attempt\n options.onReconnect?.({ attempt, lastEventId, cause: lastError });\n\n // Exponential backoff with jitter: min(1000 * 2^attempt, 5000) + random jitter\n const baseDelay = Math.min(1000 * 2 ** (attempt - 1), 5000);\n const jitter = Math.random() * 1000;\n const delay = baseDelay + jitter;\n\n await new Promise((resolve) => {\n setTimeout(resolve, delay);\n });\n\n continue;\n }\n\n // Successfully completed\n break;\n }\n}\n\n/*\n * Support async iterator syntax for ReadableStreams in all environments.\n * Source: https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490\n */\nexport class IterableReadableStream<T>\n extends ReadableStream<T>\n implements IterableReadableStreamInterface<T>\n{\n public reader: ReadableStreamDefaultReader<T>;\n\n ensureReader() {\n if (!this.reader) {\n this.reader = this.getReader();\n }\n }\n\n async next(): Promise<IteratorResult<T>> {\n this.ensureReader();\n try {\n const result = await this.reader.read();\n if (result.done) {\n this.reader.releaseLock(); // release lock when stream becomes closed\n return {\n done: true,\n value: undefined,\n };\n } else {\n return {\n done: false,\n value: result.value,\n };\n }\n } catch (e) {\n this.reader.releaseLock(); // release lock when stream becomes errored\n throw e;\n }\n }\n\n async return(): Promise<IteratorResult<T>> {\n this.ensureReader();\n // If wrapped in a Node stream, cancel is already called.\n if (this.locked) {\n const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet\n this.reader.releaseLock(); // release lock first\n await cancelPromise; // now await it\n }\n return { done: true, value: undefined };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async throw(e: any): Promise<IteratorResult<T>> {\n this.ensureReader();\n if (this.locked) {\n const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet\n this.reader.releaseLock(); // release lock first\n await cancelPromise; // now await it\n }\n throw e;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore Not present in Node 18 types, required in latest Node 22\n async [Symbol.asyncDispose]() {\n await this.return();\n }\n\n [Symbol.asyncIterator]() {\n return this;\n }\n\n static fromReadableStream<T>(stream: ReadableStream<T>) {\n // From https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams#reading_the_stream\n const reader = stream.getReader();\n return new IterableReadableStream<T>({\n start(controller) {\n return pump();\n function pump(): Promise<T | undefined> {\n return reader.read().then(({ done, value }) => {\n // When no more data needs to be consumed, close the stream\n if (done) {\n controller.close();\n return;\n }\n // Enqueue the next data chunk into our target stream\n controller.enqueue(value);\n return pump();\n });\n }\n },\n cancel() {\n reader.releaseLock();\n },\n });\n }\n\n static fromAsyncGenerator<T>(generator: AsyncGenerator<T>) {\n return new IterableReadableStream<T>({\n async pull(controller) {\n const { value, done } = await generator.next();\n // When no more data needs to be consumed, close the stream\n if (done) {\n controller.close();\n }\n // Fix: `else if (value)` will hang the streaming when nullish value (e.g. empty string) is pulled\n controller.enqueue(value);\n },\n async cancel(reason) {\n await generator.return(reason);\n },\n });\n }\n}\n"],"mappings":"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"}
{"version":3,"file":"stream.js","names":[],"sources":["../../src/utils/stream.ts"],"sourcesContent":["import { isNetworkError } from \"./error.js\";\nimport {\n DEFAULT_MAX_RECONNECT_ATTEMPTS,\n reconnectDelayMs,\n} from \"./reconnect.js\";\n\n// in this case don't quite match.\ntype IterableReadableStreamInterface<T> = ReadableStream<T> & AsyncIterable<T>;\n\n/**\n * Options for streaming with automatic retry logic.\n */\nexport interface StreamWithRetryOptions {\n /**\n * Maximum number of reconnection attempts. Default is\n * {@link DEFAULT_MAX_RECONNECT_ATTEMPTS}.\n */\n maxRetries?: number;\n\n /**\n * AbortSignal to cancel the stream.\n */\n signal?: AbortSignal;\n\n /**\n * Callback invoked when a reconnection attempt is made.\n */\n onReconnect?: (options: {\n attempt: number;\n lastEventId?: string;\n cause: unknown;\n }) => void;\n}\n\n/**\n * Parameters for making a stream request\n */\nexport interface StreamRequestParams {\n /**\n * Last event ID to resume from, if available\n */\n lastEventId?: string;\n\n /**\n * Optional reconnection path from the Location header\n */\n reconnectPath?: string;\n}\n\n/**\n * Error thrown when maximum reconnection attempts are exceeded.\n */\nexport class MaxReconnectAttemptsError extends Error {\n constructor(maxAttempts: number, cause: unknown) {\n super(`Exceeded maximum SSE reconnection attempts (${maxAttempts})`);\n this.name = \"MaxReconnectAttemptsError\";\n this.cause = cause;\n }\n}\n\n/**\n * Error injected into the stream by {@link idleReconnectStream} when no lines\n * arrive within the active idle window. Surfacing this during the read is what\n * lets the reconnect loops in `streamWithRetry` and the protocol SSE transport\n * recover from a half-open socket — one that was silently dropped (e.g. a hard\n * pod kill on a platform revision rollover) without a TCP FIN/RST, so neither\n * a `done` nor a thrown network error ever arrives.\n */\nexport class StreamIdleTimeoutError extends Error {\n readonly idleTimeoutMs: number;\n\n constructor(idleTimeoutMs: number) {\n super(\n `No SSE bytes received for ${idleTimeoutMs}ms; assuming the connection is half-open and reconnecting.`\n );\n this.name = \"StreamIdleTimeoutError\";\n this.idleTimeoutMs = idleTimeoutMs;\n }\n}\n\n/** `\":\"` — first byte of an SSE comment / keep-alive line. */\nconst SSE_COMMENT_BYTE = 0x3a;\n\n/**\n * How {@link idleReconnectStream} decides when the connection is idle.\n *\n * - A `number` is a fixed idle window in milliseconds: the watchdog arms\n * immediately (even before the first byte) and trips after that long with no\n * activity. Use when you know your server's behaviour and want guaranteed\n * coverage from t=0; it does not depend on heartbeats.\n * - `\"auto\"` is heartbeat-adaptive: the watchdog stays dormant until it has\n * observed the server's SSE keep-alive comments (e.g. LangGraph Platform's\n * `: heartbeat` every ~5s), then arms with a window derived from the\n * observed cadence. On a server that never sends heartbeats it never arms,\n * so it can't false-fire during a legitimately quiet period.\n */\nexport type IdleReconnectMode = number | \"auto\";\n\n/**\n * Default idle-reconnect policy for SSE streams. Heartbeat-adaptive\n * `\"auto\"` stays dormant unless the server emits keep-alive heartbeats.\n * Pass `0` to disable.\n */\nexport const DEFAULT_IDLE_RECONNECT: IdleReconnectMode = \"auto\";\n\nexport interface IdleReconnectStreamOptions {\n /** Fixed timeout (ms) or `\"auto\"` heartbeat-adaptive. */\n mode: IdleReconnectMode;\n /** `\"auto\"`: multiplier applied to the observed heartbeat interval. Default 3. */\n timeoutFactor?: number;\n /** `\"auto\"`: lower clamp for the derived timeout (ms). Default 6000. */\n minTimeoutMs?: number;\n /** `\"auto\"`: upper clamp for the derived timeout (ms). Default 30000. */\n maxTimeoutMs?: number;\n /** Fired immediately before the stream is errored, for logging/metrics. */\n onIdle?: (info: { timeoutMs: number; source: \"fixed\" | \"heartbeat\" }) => void;\n}\n\n/**\n * A pass-through {@link TransformStream} that errors the stream when it goes\n * idle, so the surrounding reconnect logic can recover a half-open socket.\n *\n * MUST sit on the *line* stream — i.e. after\n * {@link import(\"./sse.js\").BytesLineDecoder} but before\n * {@link import(\"./sse.js\").SSEDecoder} (which discards `:` comment lines).\n * Operating at the line level lets the watchdog both (a) reset on any line\n * (data *or* heartbeat = liveness) and (b) recognise heartbeat comment lines\n * to drive `\"auto\"` mode.\n *\n * In `\"auto\"` mode the watchdog is intentionally dormant until it has seen at\n * least two heartbeats (so it can measure the cadence). This means a socket\n * that dies inside the first heartbeat interval won't be caught until a\n * heartbeat would have been due — an acceptable trade for never false-firing\n * on heartbeat-less servers. Pass a fixed `number` if you need coverage from\n * the very first byte.\n */\nexport function idleReconnectStream(\n options: IdleReconnectStreamOptions\n): TransformStream<Uint8Array, Uint8Array> {\n const factor = options.timeoutFactor ?? 3;\n const minTimeoutMs = options.minTimeoutMs ?? 6_000;\n const maxTimeoutMs = options.maxTimeoutMs ?? 30_000;\n const fixedTimeoutMs = typeof options.mode === \"number\" ? options.mode : null;\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n let controllerRef: TransformStreamDefaultController<Uint8Array> | undefined;\n\n // `\"auto\"` cadence inference.\n let lastHeartbeatAt: number | undefined;\n // The active idle window: the fixed value, or (auto) the heartbeat-derived\n // value once known. `null` means \"not armed yet\".\n let derivedTimeoutMs: number | null = fixedTimeoutMs;\n\n const clear = () => {\n if (timer != null) {\n clearTimeout(timer);\n timer = undefined;\n }\n };\n\n const arm = () => {\n clear();\n const timeoutMs = derivedTimeoutMs;\n if (timeoutMs == null || timeoutMs <= 0) return;\n timer = setTimeout(() => {\n options.onIdle?.({\n timeoutMs,\n source: fixedTimeoutMs != null ? \"fixed\" : \"heartbeat\",\n });\n try {\n controllerRef?.error(new StreamIdleTimeoutError(timeoutMs));\n } catch {\n // Stream already closed/errored/cancelled — nothing to abort.\n }\n }, timeoutMs);\n // Don't let the watchdog by itself keep a Node process alive.\n (timer as unknown as { unref?: () => void }).unref?.();\n };\n\n const noteHeartbeat = () => {\n if (fixedTimeoutMs != null) return; // cadence irrelevant in fixed mode\n const now = Date.now();\n if (lastHeartbeatAt != null) {\n const interval = now - lastHeartbeatAt;\n if (interval > 0) {\n const candidate = Math.min(\n Math.max(interval * factor, minTimeoutMs),\n maxTimeoutMs\n );\n // Keep the most conservative (largest) window observed so far.\n derivedTimeoutMs =\n derivedTimeoutMs == null\n ? candidate\n : Math.max(derivedTimeoutMs, candidate);\n }\n }\n lastHeartbeatAt = now;\n };\n\n return new TransformStream<Uint8Array, Uint8Array>({\n start(controller) {\n controllerRef = controller;\n // Fixed mode arms eagerly (also catches pre-first-byte silence). Auto\n // mode waits until a cadence is established in `transform`.\n arm();\n },\n transform(line, controller) {\n // A line beginning with \":\" is an SSE comment / keep-alive heartbeat.\n if (line.length > 0 && line[0] === SSE_COMMENT_BYTE) {\n noteHeartbeat();\n }\n // Any line is liveness — (re)arm the idle timer.\n arm();\n controller.enqueue(line);\n },\n flush() {\n clear();\n },\n });\n}\n\n/**\n * Stream with automatic retry logic for SSE connections.\n * Implements reconnection behavior similar to the Python SDK.\n *\n * @param makeRequest Function to make requests. When `params` is undefined/empty, it's the initial request.\n * When `params.reconnectPath` is provided, it's a reconnection request.\n * @param options Configuration options\n * @returns AsyncGenerator yielding stream events\n */\nexport async function* streamWithRetry<T extends { id?: string }>(\n makeRequest: (params?: StreamRequestParams) => Promise<{\n response: Response;\n stream: ReadableStream<T>;\n }>,\n options: StreamWithRetryOptions = {}\n): AsyncGenerator<T> {\n const maxRetries = options.maxRetries ?? DEFAULT_MAX_RECONNECT_ATTEMPTS;\n let attempt = 0;\n let lastEventId: string | undefined;\n let reconnectPath: string | undefined;\n\n while (true) {\n let shouldRetry = false;\n let lastError: unknown;\n let reader: ReadableStreamDefaultReader<T> | undefined;\n\n try {\n // Check if aborted before making request\n if (options.signal?.aborted) return;\n\n // Make request - initial if no reconnect path, reconnect otherwise\n const { response, stream } = await makeRequest(\n reconnectPath ? { lastEventId, reconnectPath } : undefined\n );\n\n // Check for Location header (server-provided reconnection path)\n const locationHeader = response.headers.get(\"location\");\n if (locationHeader) {\n reconnectPath = locationHeader;\n }\n\n // Verify content type\n const contentType = response.headers.get(\"content-type\")?.split(\";\")[0];\n if (contentType && !contentType.includes(\"text/event-stream\")) {\n throw new Error(\n `Expected response header Content-Type to contain 'text/event-stream', got '${contentType}'`\n );\n }\n\n reader = stream.getReader();\n\n try {\n while (true) {\n // Check abort signal before each read\n if (options.signal?.aborted) {\n await reader.cancel();\n return;\n }\n\n const { done, value } = await reader.read();\n\n if (done) {\n // Stream completed successfully\n break;\n }\n\n // Track last event ID for reconnection\n if (value.id) {\n lastEventId = value.id;\n }\n\n yield value;\n }\n\n // Stream completed successfully, exit retry loop\n break;\n } catch (error) {\n // Error during streaming - attempt reconnect if we have a location header\n if (reconnectPath && !options.signal?.aborted) {\n shouldRetry = true;\n } else {\n throw error;\n }\n } finally {\n if (reader) {\n try {\n reader.releaseLock();\n } catch {\n // Ignore errors when releasing lock\n }\n }\n }\n } catch (error) {\n lastError = error;\n\n // Only retry if we have reconnection capability and it's a network error\n if (isNetworkError(error) && reconnectPath && !options.signal?.aborted) {\n shouldRetry = true;\n } else {\n throw error;\n }\n }\n\n if (shouldRetry) {\n attempt += 1;\n if (attempt > maxRetries) {\n throw new MaxReconnectAttemptsError(maxRetries, lastError);\n }\n\n // Notify about reconnection attempt\n options.onReconnect?.({ attempt, lastEventId, cause: lastError });\n\n // Exponential backoff with jitter (shared with protocol transports).\n const delay = reconnectDelayMs(attempt);\n\n await new Promise((resolve) => {\n setTimeout(resolve, delay);\n });\n\n continue;\n }\n\n // Successfully completed\n break;\n }\n}\n\n/*\n * Support async iterator syntax for ReadableStreams in all environments.\n * Source: https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490\n */\nexport class IterableReadableStream<T>\n extends ReadableStream<T>\n implements IterableReadableStreamInterface<T>\n{\n public reader: ReadableStreamDefaultReader<T>;\n\n ensureReader() {\n if (!this.reader) {\n this.reader = this.getReader();\n }\n }\n\n async next(): Promise<IteratorResult<T>> {\n this.ensureReader();\n try {\n const result = await this.reader.read();\n if (result.done) {\n this.reader.releaseLock(); // release lock when stream becomes closed\n return {\n done: true,\n value: undefined,\n };\n } else {\n return {\n done: false,\n value: result.value,\n };\n }\n } catch (e) {\n this.reader.releaseLock(); // release lock when stream becomes errored\n throw e;\n }\n }\n\n async return(): Promise<IteratorResult<T>> {\n this.ensureReader();\n // If wrapped in a Node stream, cancel is already called.\n if (this.locked) {\n const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet\n this.reader.releaseLock(); // release lock first\n await cancelPromise; // now await it\n }\n return { done: true, value: undefined };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async throw(e: any): Promise<IteratorResult<T>> {\n this.ensureReader();\n if (this.locked) {\n const cancelPromise = this.reader.cancel(); // cancel first, but don't await yet\n this.reader.releaseLock(); // release lock first\n await cancelPromise; // now await it\n }\n throw e;\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore Not present in Node 18 types, required in latest Node 22\n async [Symbol.asyncDispose]() {\n await this.return();\n }\n\n [Symbol.asyncIterator]() {\n return this;\n }\n\n static fromReadableStream<T>(stream: ReadableStream<T>) {\n // From https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams#reading_the_stream\n const reader = stream.getReader();\n return new IterableReadableStream<T>({\n start(controller) {\n return pump();\n function pump(): Promise<T | undefined> {\n return reader.read().then(({ done, value }) => {\n // When no more data needs to be consumed, close the stream\n if (done) {\n controller.close();\n return;\n }\n // Enqueue the next data chunk into our target stream\n controller.enqueue(value);\n return pump();\n });\n }\n },\n cancel() {\n reader.releaseLock();\n },\n });\n }\n\n static fromAsyncGenerator<T>(generator: AsyncGenerator<T>) {\n return new IterableReadableStream<T>({\n async pull(controller) {\n const { value, done } = await generator.next();\n // When no more data needs to be consumed, close the stream\n if (done) {\n controller.close();\n }\n // Fix: `else if (value)` will hang the streaming when nullish value (e.g. empty string) is pulled\n controller.enqueue(value);\n },\n async cancel(reason) {\n await generator.return(reason);\n },\n });\n }\n}\n"],"mappings":"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"}
{
"name": "@langchain/langgraph-sdk",
"version": "1.9.25",
"version": "1.9.26",
"description": "Client library for interacting with the LangGraph API",

@@ -23,13 +23,13 @@ "type": "module",

"@types/node": "^18.15.11",
"@types/react": "^19.2.16",
"@types/react": "^19.2.17",
"@types/react-dom": "^19.2.3",
"@types/ws": "^8.18.1",
"deepagents": "^1.10.5",
"langchain": "^1.5.1",
"langchain": "^1.5.2",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"svelte": "^5.56.1",
"svelte": "^5.56.4",
"typescript": "^4.9.5 || ^5.4.5",
"vitest": "^4.1.0",
"vue": "^3.5.35",
"vitest": "^4.1.9",
"vue": "^3.5.39",
"ws": "^8.21.0",

@@ -36,0 +36,0 @@ "zod": "^4.3.5",

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display