@langchain/langgraph-sdk 1.9.3 → 1.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -20
- package/dist/client/base.cjs.map +1 -1
- package/dist/client/base.d.cts +37 -0
- package/dist/client/base.d.cts.map +1 -1
- package/dist/client/base.d.ts +37 -0
- package/dist/client/base.d.ts.map +1 -1
- package/dist/client/base.js.map +1 -1
- package/dist/client/index.d.cts +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/stream/handles/index.d.ts +1 -1
- package/dist/client/stream/handles/subagents.cjs +1 -1
- package/dist/client/stream/handles/subagents.cjs.map +1 -1
- package/dist/client/stream/handles/subagents.d.cts +2 -2
- package/dist/client/stream/handles/subagents.d.cts.map +1 -1
- package/dist/client/stream/handles/subagents.d.ts +2 -2
- package/dist/client/stream/handles/subagents.d.ts.map +1 -1
- package/dist/client/stream/handles/subagents.js +2 -2
- package/dist/client/stream/handles/subagents.js.map +1 -1
- package/dist/client/stream/handles/subgraphs.cjs +1 -1
- package/dist/client/stream/handles/subgraphs.cjs.map +1 -1
- package/dist/client/stream/handles/subgraphs.d.cts +2 -2
- package/dist/client/stream/handles/subgraphs.d.cts.map +1 -1
- package/dist/client/stream/handles/subgraphs.d.ts +2 -2
- package/dist/client/stream/handles/subgraphs.d.ts.map +1 -1
- package/dist/client/stream/handles/subgraphs.js +2 -2
- package/dist/client/stream/handles/subgraphs.js.map +1 -1
- package/dist/client/stream/handles/tools.cjs +124 -52
- package/dist/client/stream/handles/tools.cjs.map +1 -1
- package/dist/client/stream/handles/tools.d.cts +59 -13
- package/dist/client/stream/handles/tools.d.cts.map +1 -1
- package/dist/client/stream/handles/tools.d.ts +59 -13
- package/dist/client/stream/handles/tools.d.ts.map +1 -1
- package/dist/client/stream/handles/tools.js +122 -53
- package/dist/client/stream/handles/tools.js.map +1 -1
- package/dist/client/stream/index.cjs +2 -2
- package/dist/client/stream/index.cjs.map +1 -1
- package/dist/client/stream/index.d.cts +3 -3
- package/dist/client/stream/index.d.cts.map +1 -1
- package/dist/client/stream/index.d.ts +3 -3
- package/dist/client/stream/index.d.ts.map +1 -1
- package/dist/client/stream/index.js +3 -3
- package/dist/client/stream/index.js.map +1 -1
- package/dist/headless-tools.cjs +3 -0
- package/dist/headless-tools.cjs.map +1 -1
- package/dist/headless-tools.js +3 -0
- package/dist/headless-tools.js.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/stream/controller.cjs +51 -1
- package/dist/stream/controller.cjs.map +1 -1
- package/dist/stream/controller.d.cts.map +1 -1
- package/dist/stream/controller.d.ts.map +1 -1
- package/dist/stream/controller.js +51 -1
- package/dist/stream/controller.js.map +1 -1
- package/dist/stream/index.cjs +3 -0
- package/dist/stream/index.d.cts +5 -5
- package/dist/stream/index.d.ts +5 -5
- package/dist/stream/index.js +2 -1
- package/dist/stream/lifecycle-loading-tracker.cjs +1 -1
- package/dist/stream/lifecycle-loading-tracker.cjs.map +1 -1
- package/dist/stream/lifecycle-loading-tracker.js +1 -1
- package/dist/stream/lifecycle-loading-tracker.js.map +1 -1
- package/dist/stream/projections/tool-calls.cjs.map +1 -1
- package/dist/stream/projections/tool-calls.js.map +1 -1
- package/dist/stream/submit-coordinator.cjs +37 -4
- package/dist/stream/submit-coordinator.cjs.map +1 -1
- package/dist/stream/submit-coordinator.d.cts.map +1 -1
- package/dist/stream/submit-coordinator.d.ts.map +1 -1
- package/dist/stream/submit-coordinator.js +37 -4
- package/dist/stream/submit-coordinator.js.map +1 -1
- package/dist/stream/types-inference.d.cts +65 -7
- package/dist/stream/types-inference.d.cts.map +1 -1
- package/dist/stream/types-inference.d.ts +65 -7
- package/dist/stream/types-inference.d.ts.map +1 -1
- package/dist/stream/types.d.cts +40 -21
- package/dist/stream/types.d.cts.map +1 -1
- package/dist/stream/types.d.ts +40 -21
- package/dist/stream/types.d.ts.map +1 -1
- package/dist/types.messages.d.cts +38 -1
- package/dist/types.messages.d.cts.map +1 -1
- package/dist/types.messages.d.ts +38 -1
- package/dist/types.messages.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -10,9 +10,9 @@ graph executions in real time.
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
pnpm add @langchain/langgraph-sdk
|
|
14
|
-
# or: npm install @langchain/langgraph-sdk
|
|
15
|
-
# or: yarn add @langchain/langgraph-sdk
|
|
13
|
+
pnpm add @langchain/langgraph-sdk @langchain/core
|
|
14
|
+
# or: npm install @langchain/langgraph-sdk @langchain/core
|
|
15
|
+
# or: yarn add @langchain/langgraph-sdk @langchain/core
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Quick start
|
|
@@ -44,13 +44,13 @@ default `langgraph dev` URL).
|
|
|
44
44
|
|
|
45
45
|
## What's in the SDK
|
|
46
46
|
|
|
47
|
-
| Sub-client
|
|
48
|
-
|
|
|
49
|
-
| `client.threads`
|
|
50
|
-
| `client.assistants`
|
|
51
|
-
| `client.runs`
|
|
52
|
-
| `client.crons`
|
|
53
|
-
| `client.store`
|
|
47
|
+
| Sub-client | Purpose | Docs |
|
|
48
|
+
| ------------------- | -------------------------------------------------- | --------------------------------------------------------------- |
|
|
49
|
+
| `client.threads` | Create threads, manage state, and **stream** runs. | [Threads](./docs/threads.md) · [Streaming](./docs/streaming.md) |
|
|
50
|
+
| `client.assistants` | CRUD for assistants (schemas, graphs, versions). | [Assistants](./docs/assistants.md) |
|
|
51
|
+
| `client.runs` | Trigger / join / cancel runs without streaming. | [Runs (legacy)](./docs/runs.md) |
|
|
52
|
+
| `client.crons` | Schedule recurring runs. | [Crons](./docs/crons.md) |
|
|
53
|
+
| `client.store` | Namespaced KV + semantic store. | [Store](./docs/store.md) |
|
|
54
54
|
|
|
55
55
|
### Streaming
|
|
56
56
|
|
|
@@ -106,16 +106,16 @@ adapter.
|
|
|
106
106
|
The client code is organized into sub-client modules under
|
|
107
107
|
`src/client/`:
|
|
108
108
|
|
|
109
|
-
| Path
|
|
110
|
-
|
|
|
111
|
-
| `client/assistants
|
|
112
|
-
| `client/threads/`
|
|
113
|
-
| `client/runs/`
|
|
114
|
-
| `client/crons/`
|
|
115
|
-
| `client/store/`
|
|
116
|
-
| `client/stream/`
|
|
117
|
-
| `client/base.ts`
|
|
118
|
-
| `client/index.ts`
|
|
109
|
+
| Path | Module |
|
|
110
|
+
| -------------------- | --------------------------------------------------------- |
|
|
111
|
+
| `client/assistants/` | `AssistantsClient` |
|
|
112
|
+
| `client/threads/` | `ThreadsClient` (includes the v2 `stream(...)` primitive) |
|
|
113
|
+
| `client/runs/` | `RunsClient` (legacy streaming + CRUD) |
|
|
114
|
+
| `client/crons/` | `CronsClient` |
|
|
115
|
+
| `client/store/` | `StoreClient` |
|
|
116
|
+
| `client/stream/` | `ThreadStream`, assemblers, transports |
|
|
117
|
+
| `client/base.ts` | `BaseClient`, shared config & helpers |
|
|
118
|
+
| `client/index.ts` | Main `Client` class & re-exports |
|
|
119
119
|
|
|
120
120
|
## Change log
|
|
121
121
|
|
package/dist/client/base.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.cjs","names":["getEnvironmentVariable","AsyncCaller","mergeSignals","BytesLineDecoder","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 { streamWithRetry, StreamRequestParams } 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\nexport interface ClientConfig {\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 callerOptions?: AsyncCallerParams;\n timeoutMs?: number;\n defaultHeaders?: Record<string, HeaderValue>;\n onRequest?: RequestHook;\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 }\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 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 }\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 }\n ): Promise<T | [T, Response]> {\n const [url, init] = this.prepareFetchOptions(path, options);\n\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 = (() => {\n if (response.status === 202 || response.status === 204) {\n return undefined as T;\n }\n return response.json() as Promise<T>;\n })();\n\n if (options?.withResponse) {\n return [await body, response];\n }\n\n return body;\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 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 const stream: ReadableStream<T> = response.body\n .pipeThrough(BytesLineDecoder())\n .pipeThrough(SSEDecoder()) 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"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base.cjs","names":["getEnvironmentVariable","AsyncCaller","mergeSignals","BytesLineDecoder","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 { streamWithRetry, StreamRequestParams } 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 }\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 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 }\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 }\n ): Promise<T | [T, Response]> {\n const [url, init] = this.prepareFetchOptions(path, options);\n\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 = (() => {\n if (response.status === 202 || response.status === 204) {\n return undefined as T;\n }\n return response.json() as Promise<T>;\n })();\n\n if (options?.withResponse) {\n return [await body, response];\n }\n\n return body;\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 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 const stream: ReadableStream<T> = response.body\n .pipeThrough(BytesLineDecoder())\n .pipeThrough(SSEDecoder()) 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"],"mappings":"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"}
|
package/dist/client/base.d.cts
CHANGED
|
@@ -16,7 +16,17 @@ type HeaderValue = string | undefined | null;
|
|
|
16
16
|
*/
|
|
17
17
|
declare function getApiKey(apiKey?: string | null): string | undefined;
|
|
18
18
|
type RequestHook = (url: URL, init: RequestInit) => Promise<RequestInit> | RequestInit;
|
|
19
|
+
/**
|
|
20
|
+
* Configuration for {@link BaseClient} and the exported LangGraph SDK
|
|
21
|
+
* {@link Client}.
|
|
22
|
+
*/
|
|
19
23
|
interface ClientConfig {
|
|
24
|
+
/**
|
|
25
|
+
* Base URL of the LangGraph API server.
|
|
26
|
+
*
|
|
27
|
+
* Defaults to `http://localhost:8123`, unless the runtime provides a
|
|
28
|
+
* `langgraph_api:url` global override.
|
|
29
|
+
*/
|
|
20
30
|
apiUrl?: string;
|
|
21
31
|
/**
|
|
22
32
|
* API key for authentication.
|
|
@@ -25,10 +35,37 @@ interface ClientConfig {
|
|
|
25
35
|
* - If null, no API key will be set (skips auto-loading)
|
|
26
36
|
*/
|
|
27
37
|
apiKey?: string | null;
|
|
38
|
+
/**
|
|
39
|
+
* Options forwarded to the internal {@link AsyncCaller}, such as retry,
|
|
40
|
+
* concurrency, or custom `fetch` behavior.
|
|
41
|
+
*/
|
|
28
42
|
callerOptions?: AsyncCallerParams;
|
|
43
|
+
/**
|
|
44
|
+
* Default timeout, in milliseconds, applied to client requests.
|
|
45
|
+
*
|
|
46
|
+
* Per-request `timeoutMs` values override this default. Passing `null`
|
|
47
|
+
* at the request level disables the configured timeout for that request.
|
|
48
|
+
*/
|
|
29
49
|
timeoutMs?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Headers applied to every request.
|
|
52
|
+
*
|
|
53
|
+
* The configured API key, when present, is added as the `x-api-key`
|
|
54
|
+
* header after these defaults are initialized.
|
|
55
|
+
*/
|
|
30
56
|
defaultHeaders?: Record<string, HeaderValue>;
|
|
57
|
+
/**
|
|
58
|
+
* Hook for inspecting or mutating a request before it is sent.
|
|
59
|
+
*
|
|
60
|
+
* Receives the resolved URL and prepared `RequestInit`; return the
|
|
61
|
+
* original init or a replacement object to continue the request.
|
|
62
|
+
*/
|
|
31
63
|
onRequest?: RequestHook;
|
|
64
|
+
/**
|
|
65
|
+
* Streaming protocol used by stream-capable endpoints.
|
|
66
|
+
*
|
|
67
|
+
* Defaults to `"legacy"` for backwards compatibility.
|
|
68
|
+
*/
|
|
32
69
|
streamProtocol?: StreamProtocol;
|
|
33
70
|
}
|
|
34
71
|
declare class BaseClient {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.cts","names":[],"sources":["../../src/client/base.ts"],"mappings":";;;;KAOY,WAAA;;;AA6EZ;;;;;AAqBA;;;;iBArBgB,SAAA,CAAU,MAAA;AAAA,KAqBd,WAAA,IACV,GAAA,EAAK,GAAA,EACL,IAAA,EAAM,WAAA,KACH,OAAA,CAAQ,WAAA,IAAe,WAAA
|
|
1
|
+
{"version":3,"file":"base.d.cts","names":[],"sources":["../../src/client/base.ts"],"mappings":";;;;KAOY,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,UACD,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;EAAA,KAEA,GAAA,EAAK,GAAA,EAAK,IAAA,EAAM,WAAA;EAAA,UA+CJ,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;EAAA,IAED,OAAA,CAAQ,CAAA;EAAA,UAmCM,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,WAAA,IAAe,OAAA;MACb,OAAA;MACA,WAAA;MACA,KAAA;IAAA;IAEF,iBAAA,IAAqB,QAAA,EAAU,QAAA,YAAoB,OAAA;EAAA,IACjD,cAAA,CAAe,CAAA;AAAA"}
|
package/dist/client/base.d.ts
CHANGED
|
@@ -16,7 +16,17 @@ type HeaderValue = string | undefined | null;
|
|
|
16
16
|
*/
|
|
17
17
|
declare function getApiKey(apiKey?: string | null): string | undefined;
|
|
18
18
|
type RequestHook = (url: URL, init: RequestInit) => Promise<RequestInit> | RequestInit;
|
|
19
|
+
/**
|
|
20
|
+
* Configuration for {@link BaseClient} and the exported LangGraph SDK
|
|
21
|
+
* {@link Client}.
|
|
22
|
+
*/
|
|
19
23
|
interface ClientConfig {
|
|
24
|
+
/**
|
|
25
|
+
* Base URL of the LangGraph API server.
|
|
26
|
+
*
|
|
27
|
+
* Defaults to `http://localhost:8123`, unless the runtime provides a
|
|
28
|
+
* `langgraph_api:url` global override.
|
|
29
|
+
*/
|
|
20
30
|
apiUrl?: string;
|
|
21
31
|
/**
|
|
22
32
|
* API key for authentication.
|
|
@@ -25,10 +35,37 @@ interface ClientConfig {
|
|
|
25
35
|
* - If null, no API key will be set (skips auto-loading)
|
|
26
36
|
*/
|
|
27
37
|
apiKey?: string | null;
|
|
38
|
+
/**
|
|
39
|
+
* Options forwarded to the internal {@link AsyncCaller}, such as retry,
|
|
40
|
+
* concurrency, or custom `fetch` behavior.
|
|
41
|
+
*/
|
|
28
42
|
callerOptions?: AsyncCallerParams;
|
|
43
|
+
/**
|
|
44
|
+
* Default timeout, in milliseconds, applied to client requests.
|
|
45
|
+
*
|
|
46
|
+
* Per-request `timeoutMs` values override this default. Passing `null`
|
|
47
|
+
* at the request level disables the configured timeout for that request.
|
|
48
|
+
*/
|
|
29
49
|
timeoutMs?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Headers applied to every request.
|
|
52
|
+
*
|
|
53
|
+
* The configured API key, when present, is added as the `x-api-key`
|
|
54
|
+
* header after these defaults are initialized.
|
|
55
|
+
*/
|
|
30
56
|
defaultHeaders?: Record<string, HeaderValue>;
|
|
57
|
+
/**
|
|
58
|
+
* Hook for inspecting or mutating a request before it is sent.
|
|
59
|
+
*
|
|
60
|
+
* Receives the resolved URL and prepared `RequestInit`; return the
|
|
61
|
+
* original init or a replacement object to continue the request.
|
|
62
|
+
*/
|
|
31
63
|
onRequest?: RequestHook;
|
|
64
|
+
/**
|
|
65
|
+
* Streaming protocol used by stream-capable endpoints.
|
|
66
|
+
*
|
|
67
|
+
* Defaults to `"legacy"` for backwards compatibility.
|
|
68
|
+
*/
|
|
32
69
|
streamProtocol?: StreamProtocol;
|
|
33
70
|
}
|
|
34
71
|
declare class BaseClient {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","names":[],"sources":["../../src/client/base.ts"],"mappings":";;;;KAOY,WAAA;;;AA6EZ;;;;;AAqBA;;;;iBArBgB,SAAA,CAAU,MAAA;AAAA,KAqBd,WAAA,IACV,GAAA,EAAK,GAAA,EACL,IAAA,EAAM,WAAA,KACH,OAAA,CAAQ,WAAA,IAAe,WAAA
|
|
1
|
+
{"version":3,"file":"base.d.ts","names":[],"sources":["../../src/client/base.ts"],"mappings":";;;;KAOY,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,UACD,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;EAAA,KAEA,GAAA,EAAK,GAAA,EAAK,IAAA,EAAM,WAAA;EAAA,UA+CJ,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;EAAA,IAED,OAAA,CAAQ,CAAA;EAAA,UAmCM,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,WAAA,IAAe,OAAA;MACb,OAAA;MACA,WAAA;MACA,KAAA;IAAA;IAEF,iBAAA,IAAqB,QAAA,EAAU,QAAA,YAAoB,OAAA;EAAA,IACjD,cAAA,CAAe,CAAA;AAAA"}
|
package/dist/client/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","names":[],"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 { streamWithRetry, StreamRequestParams } 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\nexport interface ClientConfig {\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 callerOptions?: AsyncCallerParams;\n timeoutMs?: number;\n defaultHeaders?: Record<string, HeaderValue>;\n onRequest?: RequestHook;\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 }\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 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 }\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 }\n ): Promise<T | [T, Response]> {\n const [url, init] = this.prepareFetchOptions(path, options);\n\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 = (() => {\n if (response.status === 202 || response.status === 204) {\n return undefined as T;\n }\n return response.json() as Promise<T>;\n })();\n\n if (options?.withResponse) {\n return [await body, response];\n }\n\n return body;\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 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 const stream: ReadableStream<T> = response.body\n .pipeThrough(BytesLineDecoder())\n .pipeThrough(SSEDecoder()) 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"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base.js","names":[],"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 { streamWithRetry, StreamRequestParams } 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 }\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 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 }\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 }\n ): Promise<T | [T, Response]> {\n const [url, init] = this.prepareFetchOptions(path, options);\n\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 = (() => {\n if (response.status === 202 || response.status === 204) {\n return undefined as T;\n }\n return response.json() as Promise<T>;\n })();\n\n if (options?.withResponse) {\n return [await body, response];\n }\n\n return body;\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 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 const stream: ReadableStream<T> = response.body\n .pipeThrough(BytesLineDecoder())\n .pipeThrough(SSEDecoder()) 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"],"mappings":"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"}
|
package/dist/client/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DefaultValues } from "../schema.cjs";
|
|
2
2
|
import { BaseClient, ClientConfig, HeaderValue, RequestHook, getApiKey } from "./base.cjs";
|
|
3
3
|
import { AssistantsClient } from "./assistants/index.cjs";
|
|
4
|
-
import {
|
|
4
|
+
import { ClientAssembledToolCall, ToolCallStatus } from "./stream/handles/tools.cjs";
|
|
5
5
|
import { AssembledMessage, MessageAssembler, MessageAssemblyUpdate, StreamingMessage } from "./stream/messages.cjs";
|
|
6
6
|
import { AnyMediaHandle, AudioMedia, FileMedia, ImageMedia, MediaAssembler, MediaAssemblerCallbacks, MediaAssemblerOptions, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, VideoMedia } from "./stream/media.cjs";
|
|
7
7
|
import { AgentServerAdapter, TransportAdapter } from "./stream/transport.cjs";
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DefaultValues } from "../schema.js";
|
|
2
2
|
import { BaseClient, ClientConfig, HeaderValue, RequestHook, getApiKey } from "./base.js";
|
|
3
3
|
import { AssistantsClient } from "./assistants/index.js";
|
|
4
|
-
import {
|
|
4
|
+
import { ClientAssembledToolCall, ToolCallStatus } from "./stream/handles/tools.js";
|
|
5
5
|
import { AssembledMessage, MessageAssembler, MessageAssemblyUpdate, StreamingMessage } from "./stream/messages.js";
|
|
6
6
|
import { AnyMediaHandle, AudioMedia, FileMedia, ImageMedia, MediaAssembler, MediaAssemblerCallbacks, MediaAssemblerOptions, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, VideoMedia } from "./stream/media.js";
|
|
7
7
|
import { AgentServerAdapter, TransportAdapter } from "./stream/transport.js";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { AssembledToolCall, ToolCallStatus } from "./tools.js";
|
|
1
|
+
import { AssembledToolCall, ClientAssembledToolCall, ToolCallStatus, parseToolOutput, parseToolPayload } from "./tools.js";
|
|
2
2
|
import { SubagentHandle } from "./subagents.js";
|
|
3
3
|
import { SubgraphHandle, Subscribable } from "./subgraphs.js";
|
|
@@ -58,7 +58,7 @@ var SubagentHandle = class {
|
|
|
58
58
|
this.#startProjection(["tools"], (event) => {
|
|
59
59
|
if (event.method !== "tools") return;
|
|
60
60
|
const tc = assembler.consume(event);
|
|
61
|
-
if (tc) buffer.push(tc);
|
|
61
|
+
if (tc) buffer.push(require_tools.toClientAssembledToolCall(tc));
|
|
62
62
|
}, () => buffer.close());
|
|
63
63
|
return buffer;
|
|
64
64
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagents.cjs","names":["#session","#messagesIterable","MultiCursorBuffer","StreamingMessageAssembler","#startProjection","#toolCallsIterable","ToolCallAssembler","#ensureMediaDispatcher","#audioBuffer","#imagesBuffer","#videoBuffer","#filesBuffer","#mediaDispatcherStarted","MediaAssembler","#subgraphsIterable","SubgraphDiscoveryHandle","#source","#queue","#waiters","#pending","#sourcePump","#processEvent","#closed","#start"],"sources":["../../../../src/client/stream/handles/subagents.ts"],"sourcesContent":["import type {\n Channel,\n Event,\n MessagesEvent,\n SubscribeParams,\n ToolsEvent,\n} from \"@langchain/protocol\";\nimport type { SubscriptionHandle } from \"../index.js\";\nimport { MultiCursorBuffer } from \"../multi-cursor-buffer.js\";\nimport { StreamingMessageAssembler } from \"../messages.js\";\nimport type { StreamingMessage, StreamingMessageHandle } from \"../messages.js\";\nimport { ToolCallAssembler } from \"./tools.js\";\nimport type { AssembledToolCall } from \"./tools.js\";\nimport { MediaAssembler } from \"../media.js\";\nimport type {\n AudioMedia,\n FileMedia,\n ImageMedia,\n VideoMedia,\n} from \"../media.js\";\nimport type {\n EventForChannel,\n EventForChannels,\n SubscribeOptions,\n YieldForChannel,\n YieldForChannels,\n} from \"../types.js\";\nimport {\n type Subscribable,\n type SubgraphHandle,\n SubgraphDiscoveryHandle,\n} from \"./subgraphs.js\";\n\n/**\n * Discovered subagent within a streaming session. Mirrors the\n * in-process `SubagentRunStream` from DeepAgent.\n *\n * Each subagent is discovered when a `tool-started` event with\n * `tool_name === \"task\"` is observed. The `taskInput` and `output`\n * promises resolve from the task tool's lifecycle events.\n *\n * Use lazy getters (`sub.messages`, `sub.toolCalls`, etc.) for\n * namespace-scoped projections.\n */\nexport class SubagentHandle {\n readonly name: string;\n readonly callId: string;\n readonly taskInput: Promise<string>;\n readonly output: Promise<unknown>;\n readonly namespace: string[];\n readonly #session: Subscribable;\n\n #messagesIterable?: AsyncIterable<StreamingMessage>;\n #toolCallsIterable?: AsyncIterable<AssembledToolCall>;\n #subgraphsIterable?: AsyncIterable<SubgraphHandle>;\n\n #mediaDispatcherStarted = false;\n #audioBuffer?: MultiCursorBuffer<AudioMedia>;\n #imagesBuffer?: MultiCursorBuffer<ImageMedia>;\n #videoBuffer?: MultiCursorBuffer<VideoMedia>;\n #filesBuffer?: MultiCursorBuffer<FileMedia>;\n\n constructor(\n name: string,\n callId: string,\n namespace: string[],\n taskInput: Promise<string>,\n output: Promise<unknown>,\n session: Subscribable\n ) {\n this.name = name;\n this.callId = callId;\n this.namespace = namespace;\n this.taskInput = taskInput;\n this.output = output;\n this.#session = session;\n }\n\n get messages(): AsyncIterable<StreamingMessageHandle> {\n if (this.#messagesIterable) return this.#messagesIterable;\n const buffer = new MultiCursorBuffer<StreamingMessage>();\n this.#messagesIterable = buffer;\n const assembler = new StreamingMessageAssembler();\n void this.#startProjection(\n [\"messages\"],\n (event) => {\n if (event.method !== \"messages\") return;\n const msg = assembler.consume(event as MessagesEvent);\n if (msg) buffer.push(msg);\n },\n () => buffer.close()\n );\n return buffer;\n }\n\n get toolCalls(): AsyncIterable<AssembledToolCall> {\n if (this.#toolCallsIterable) return this.#toolCallsIterable;\n const buffer = new MultiCursorBuffer<AssembledToolCall>();\n this.#toolCallsIterable = buffer;\n const assembler = new ToolCallAssembler();\n void this.#startProjection(\n [\"tools\"],\n (event) => {\n if (event.method !== \"tools\") return;\n const tc = assembler.consume(event as ToolsEvent);\n if (tc) buffer.push(tc);\n },\n () => buffer.close()\n );\n return buffer;\n }\n\n get audio(): AsyncIterable<AudioMedia> {\n this.#ensureMediaDispatcher();\n return this.#audioBuffer!;\n }\n\n get images(): AsyncIterable<ImageMedia> {\n this.#ensureMediaDispatcher();\n return this.#imagesBuffer!;\n }\n\n get video(): AsyncIterable<VideoMedia> {\n this.#ensureMediaDispatcher();\n return this.#videoBuffer!;\n }\n\n get files(): AsyncIterable<FileMedia> {\n this.#ensureMediaDispatcher();\n return this.#filesBuffer!;\n }\n\n #ensureMediaDispatcher(): void {\n if (this.#mediaDispatcherStarted) return;\n this.#mediaDispatcherStarted = true;\n const audio = new MultiCursorBuffer<AudioMedia>();\n const images = new MultiCursorBuffer<ImageMedia>();\n const video = new MultiCursorBuffer<VideoMedia>();\n const files = new MultiCursorBuffer<FileMedia>();\n this.#audioBuffer = audio;\n this.#imagesBuffer = images;\n this.#videoBuffer = video;\n this.#filesBuffer = files;\n const assembler = new MediaAssembler({\n onAudio: (m: AudioMedia) => audio.push(m),\n onImage: (m: ImageMedia) => images.push(m),\n onVideo: (m: VideoMedia) => video.push(m),\n onFile: (m: FileMedia) => files.push(m),\n });\n void this.#startProjection(\n [\"messages\"],\n (event) => {\n if (event.method !== \"messages\") return;\n assembler.consume(event as MessagesEvent);\n },\n () => {\n assembler.close();\n audio.close();\n images.close();\n video.close();\n files.close();\n }\n );\n }\n\n get subgraphs(): AsyncIterable<SubgraphHandle> {\n if (this.#subgraphsIterable) return this.#subgraphsIterable;\n const buffer = new MultiCursorBuffer<SubgraphHandle>();\n this.#subgraphsIterable = buffer;\n void (async () => {\n const rawHandle = await this.#session.subscribe({\n channels: [\"lifecycle\"],\n namespaces: [this.namespace],\n });\n const discovery = new SubgraphDiscoveryHandle(\n rawHandle,\n this.#session,\n this.namespace\n );\n for await (const sub of discovery) {\n buffer.push(sub);\n }\n buffer.close();\n })();\n return buffer;\n }\n\n /**\n * Create a raw channel subscription scoped to this subagent's namespace.\n */\n subscribe<TChannel extends Channel>(\n channel: TChannel,\n options?: SubscribeOptions\n ): Promise<\n SubscriptionHandle<EventForChannel<TChannel>, YieldForChannel<TChannel>>\n >;\n subscribe<const TChannels extends readonly Channel[]>(\n channels: TChannels,\n options?: SubscribeOptions\n ): Promise<\n SubscriptionHandle<EventForChannels<TChannels>, YieldForChannels<TChannels>>\n >;\n subscribe(params: SubscribeParams): Promise<SubscriptionHandle<Event>>;\n subscribe(\n paramsOrChannels: SubscribeParams | Channel | string | readonly Channel[],\n options: SubscribeOptions = {}\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): Promise<any> {\n if (\n typeof paramsOrChannels === \"object\" &&\n !Array.isArray(paramsOrChannels) &&\n \"channels\" in paramsOrChannels\n ) {\n return this.#session.subscribe({\n ...paramsOrChannels,\n namespaces: paramsOrChannels.namespaces ?? [this.namespace],\n });\n }\n\n return this.#session.subscribe(paramsOrChannels as Channel, {\n ...options,\n namespaces: options.namespaces ?? [this.namespace],\n });\n }\n\n async #startProjection(\n channels: Channel[],\n onEvent: (event: Event) => void,\n onDone: () => void\n ): Promise<void> {\n try {\n const rawHandle = await this.#session.subscribe({\n channels,\n namespaces: [this.namespace],\n });\n for await (const event of rawHandle) {\n onEvent(event);\n }\n } finally {\n onDone();\n }\n }\n}\n\n/**\n * Async iterable that yields {@link SubagentHandle} instances as task\n * tool calls are discovered from the `tools` channel.\n *\n * Mirrors the in-process `createSubagentTransformer` from DeepAgent:\n * watches for `tool_name === \"task\"` with `tool-started`, extracts\n * `subagent_type` and `description` from the input, and resolves\n * `output` on `tool-finished`.\n */\nexport class SubagentDiscoveryHandle implements AsyncIterable<SubagentHandle> {\n readonly #source: SubscriptionHandle<Event>;\n readonly #session: Subscribable;\n readonly #queue: SubagentHandle[] = [];\n readonly #waiters: Array<(value: IteratorResult<SubagentHandle>) => void> =\n [];\n readonly #pending = new Map<\n string,\n {\n resolveOutput: (v: unknown) => void;\n rejectOutput: (e: unknown) => void;\n }\n >();\n #sourcePump?: Promise<void>;\n #closed = false;\n\n constructor(source: SubscriptionHandle<Event>, session: Subscribable) {\n this.#source = source;\n this.#session = session;\n }\n\n #processEvent(event: Event): SubagentHandle | undefined {\n if (event.method !== \"tools\") return undefined;\n const tools = event as ToolsEvent;\n const data = tools.params.data;\n const toolCallId = (data as Record<string, unknown>).tool_call_id as string;\n const toolName = (data as Record<string, unknown>).tool_name as string;\n\n if (toolName === \"task\" && data.event === \"tool-started\") {\n const rawInput = (data as Record<string, unknown>).input;\n const input: { description?: string; subagent_type?: string } =\n typeof rawInput === \"string\"\n ? JSON.parse(rawInput)\n : ((rawInput as Record<string, unknown>) ?? {});\n\n const name = input.subagent_type ?? \"unknown\";\n const description = input.description ?? \"\";\n\n let resolveTaskInput!: (v: string) => void;\n let resolveOutput!: (v: unknown) => void;\n let rejectOutput!: (e: unknown) => void;\n\n const taskInput = new Promise<string>((r) => {\n resolveTaskInput = r;\n });\n const output = new Promise<unknown>((res, rej) => {\n resolveOutput = res;\n rejectOutput = rej;\n });\n\n resolveTaskInput(description);\n this.#pending.set(toolCallId, { resolveOutput, rejectOutput });\n\n const namespace = [...tools.params.namespace];\n\n return new SubagentHandle(\n name,\n toolCallId,\n namespace,\n taskInput,\n output,\n this.#session\n );\n }\n\n if (toolCallId) {\n const pending = this.#pending.get(toolCallId);\n if (pending) {\n if (data.event === \"tool-finished\") {\n pending.resolveOutput((data as Record<string, unknown>).output);\n this.#pending.delete(toolCallId);\n } else if (data.event === \"tool-error\") {\n const message =\n ((data as Record<string, unknown>).message as string) ??\n \"unknown error\";\n pending.rejectOutput(new Error(message));\n this.#pending.delete(toolCallId);\n }\n }\n }\n\n return undefined;\n }\n\n #start(): void {\n if (this.#sourcePump) return;\n this.#sourcePump = (async () => {\n for await (const event of this.#source) {\n const handle = this.#processEvent(event);\n if (!handle) continue;\n\n const waiter = this.#waiters.shift();\n if (waiter) {\n waiter({ done: false, value: handle });\n } else {\n this.#queue.push(handle);\n }\n }\n this.#closed = true;\n for (const pending of this.#pending.values()) {\n pending.resolveOutput(undefined);\n }\n this.#pending.clear();\n while (this.#waiters.length > 0) {\n this.#waiters.shift()?.({ done: true, value: undefined });\n }\n })();\n }\n\n async close(): Promise<void> {\n this.#closed = true;\n await this.#source.unsubscribe();\n }\n\n [Symbol.asyncIterator](): AsyncIterator<SubagentHandle> {\n this.#start();\n return {\n next: async () => {\n if (this.#queue.length > 0) {\n return { done: false, value: this.#queue.shift()! };\n }\n if (this.#closed) {\n return { done: true, value: undefined };\n }\n return await new Promise<IteratorResult<SubagentHandle>>((resolve) => {\n this.#waiters.push(resolve);\n });\n },\n return: async () => {\n await this.close();\n return { done: true, value: undefined };\n },\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"subagents.cjs","names":["#session","#messagesIterable","MultiCursorBuffer","StreamingMessageAssembler","#startProjection","#toolCallsIterable","ToolCallAssembler","toClientAssembledToolCall","#ensureMediaDispatcher","#audioBuffer","#imagesBuffer","#videoBuffer","#filesBuffer","#mediaDispatcherStarted","MediaAssembler","#subgraphsIterable","SubgraphDiscoveryHandle","#source","#queue","#waiters","#pending","#sourcePump","#processEvent","#closed","#start"],"sources":["../../../../src/client/stream/handles/subagents.ts"],"sourcesContent":["import type {\n Channel,\n Event,\n MessagesEvent,\n SubscribeParams,\n ToolsEvent,\n} from \"@langchain/protocol\";\nimport type { SubscriptionHandle } from \"../index.js\";\nimport { MultiCursorBuffer } from \"../multi-cursor-buffer.js\";\nimport { StreamingMessageAssembler } from \"../messages.js\";\nimport type { StreamingMessage, StreamingMessageHandle } from \"../messages.js\";\nimport { ToolCallAssembler, toClientAssembledToolCall } from \"./tools.js\";\nimport type { ClientAssembledToolCall } from \"./tools.js\";\nimport { MediaAssembler } from \"../media.js\";\nimport type {\n AudioMedia,\n FileMedia,\n ImageMedia,\n VideoMedia,\n} from \"../media.js\";\nimport type {\n EventForChannel,\n EventForChannels,\n SubscribeOptions,\n YieldForChannel,\n YieldForChannels,\n} from \"../types.js\";\nimport {\n type Subscribable,\n type SubgraphHandle,\n SubgraphDiscoveryHandle,\n} from \"./subgraphs.js\";\n\n/**\n * Discovered subagent within a streaming session. Mirrors the\n * in-process `SubagentRunStream` from DeepAgent.\n *\n * Each subagent is discovered when a `tool-started` event with\n * `tool_name === \"task\"` is observed. The `taskInput` and `output`\n * promises resolve from the task tool's lifecycle events.\n *\n * Use lazy getters (`sub.messages`, `sub.toolCalls`, etc.) for\n * namespace-scoped projections.\n */\nexport class SubagentHandle {\n readonly name: string;\n readonly callId: string;\n readonly taskInput: Promise<string>;\n readonly output: Promise<unknown>;\n readonly namespace: string[];\n readonly #session: Subscribable;\n\n #messagesIterable?: AsyncIterable<StreamingMessage>;\n #toolCallsIterable?: AsyncIterable<ClientAssembledToolCall>;\n #subgraphsIterable?: AsyncIterable<SubgraphHandle>;\n\n #mediaDispatcherStarted = false;\n #audioBuffer?: MultiCursorBuffer<AudioMedia>;\n #imagesBuffer?: MultiCursorBuffer<ImageMedia>;\n #videoBuffer?: MultiCursorBuffer<VideoMedia>;\n #filesBuffer?: MultiCursorBuffer<FileMedia>;\n\n constructor(\n name: string,\n callId: string,\n namespace: string[],\n taskInput: Promise<string>,\n output: Promise<unknown>,\n session: Subscribable\n ) {\n this.name = name;\n this.callId = callId;\n this.namespace = namespace;\n this.taskInput = taskInput;\n this.output = output;\n this.#session = session;\n }\n\n get messages(): AsyncIterable<StreamingMessageHandle> {\n if (this.#messagesIterable) return this.#messagesIterable;\n const buffer = new MultiCursorBuffer<StreamingMessage>();\n this.#messagesIterable = buffer;\n const assembler = new StreamingMessageAssembler();\n void this.#startProjection(\n [\"messages\"],\n (event) => {\n if (event.method !== \"messages\") return;\n const msg = assembler.consume(event as MessagesEvent);\n if (msg) buffer.push(msg);\n },\n () => buffer.close()\n );\n return buffer;\n }\n\n get toolCalls(): AsyncIterable<ClientAssembledToolCall> {\n if (this.#toolCallsIterable) return this.#toolCallsIterable;\n const buffer = new MultiCursorBuffer<ClientAssembledToolCall>();\n this.#toolCallsIterable = buffer;\n const assembler = new ToolCallAssembler();\n void this.#startProjection(\n [\"tools\"],\n (event) => {\n if (event.method !== \"tools\") return;\n const tc = assembler.consume(event as ToolsEvent);\n if (tc) buffer.push(toClientAssembledToolCall(tc));\n },\n () => buffer.close()\n );\n return buffer;\n }\n\n get audio(): AsyncIterable<AudioMedia> {\n this.#ensureMediaDispatcher();\n return this.#audioBuffer!;\n }\n\n get images(): AsyncIterable<ImageMedia> {\n this.#ensureMediaDispatcher();\n return this.#imagesBuffer!;\n }\n\n get video(): AsyncIterable<VideoMedia> {\n this.#ensureMediaDispatcher();\n return this.#videoBuffer!;\n }\n\n get files(): AsyncIterable<FileMedia> {\n this.#ensureMediaDispatcher();\n return this.#filesBuffer!;\n }\n\n #ensureMediaDispatcher(): void {\n if (this.#mediaDispatcherStarted) return;\n this.#mediaDispatcherStarted = true;\n const audio = new MultiCursorBuffer<AudioMedia>();\n const images = new MultiCursorBuffer<ImageMedia>();\n const video = new MultiCursorBuffer<VideoMedia>();\n const files = new MultiCursorBuffer<FileMedia>();\n this.#audioBuffer = audio;\n this.#imagesBuffer = images;\n this.#videoBuffer = video;\n this.#filesBuffer = files;\n const assembler = new MediaAssembler({\n onAudio: (m: AudioMedia) => audio.push(m),\n onImage: (m: ImageMedia) => images.push(m),\n onVideo: (m: VideoMedia) => video.push(m),\n onFile: (m: FileMedia) => files.push(m),\n });\n void this.#startProjection(\n [\"messages\"],\n (event) => {\n if (event.method !== \"messages\") return;\n assembler.consume(event as MessagesEvent);\n },\n () => {\n assembler.close();\n audio.close();\n images.close();\n video.close();\n files.close();\n }\n );\n }\n\n get subgraphs(): AsyncIterable<SubgraphHandle> {\n if (this.#subgraphsIterable) return this.#subgraphsIterable;\n const buffer = new MultiCursorBuffer<SubgraphHandle>();\n this.#subgraphsIterable = buffer;\n void (async () => {\n const rawHandle = await this.#session.subscribe({\n channels: [\"lifecycle\"],\n namespaces: [this.namespace],\n });\n const discovery = new SubgraphDiscoveryHandle(\n rawHandle,\n this.#session,\n this.namespace\n );\n for await (const sub of discovery) {\n buffer.push(sub);\n }\n buffer.close();\n })();\n return buffer;\n }\n\n /**\n * Create a raw channel subscription scoped to this subagent's namespace.\n */\n subscribe<TChannel extends Channel>(\n channel: TChannel,\n options?: SubscribeOptions\n ): Promise<\n SubscriptionHandle<EventForChannel<TChannel>, YieldForChannel<TChannel>>\n >;\n subscribe<const TChannels extends readonly Channel[]>(\n channels: TChannels,\n options?: SubscribeOptions\n ): Promise<\n SubscriptionHandle<EventForChannels<TChannels>, YieldForChannels<TChannels>>\n >;\n subscribe(params: SubscribeParams): Promise<SubscriptionHandle<Event>>;\n subscribe(\n paramsOrChannels: SubscribeParams | Channel | string | readonly Channel[],\n options: SubscribeOptions = {}\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): Promise<any> {\n if (\n typeof paramsOrChannels === \"object\" &&\n !Array.isArray(paramsOrChannels) &&\n \"channels\" in paramsOrChannels\n ) {\n return this.#session.subscribe({\n ...paramsOrChannels,\n namespaces: paramsOrChannels.namespaces ?? [this.namespace],\n });\n }\n\n return this.#session.subscribe(paramsOrChannels as Channel, {\n ...options,\n namespaces: options.namespaces ?? [this.namespace],\n });\n }\n\n async #startProjection(\n channels: Channel[],\n onEvent: (event: Event) => void,\n onDone: () => void\n ): Promise<void> {\n try {\n const rawHandle = await this.#session.subscribe({\n channels,\n namespaces: [this.namespace],\n });\n for await (const event of rawHandle) {\n onEvent(event);\n }\n } finally {\n onDone();\n }\n }\n}\n\n/**\n * Async iterable that yields {@link SubagentHandle} instances as task\n * tool calls are discovered from the `tools` channel.\n *\n * Mirrors the in-process `createSubagentTransformer` from DeepAgent:\n * watches for `tool_name === \"task\"` with `tool-started`, extracts\n * `subagent_type` and `description` from the input, and resolves\n * `output` on `tool-finished`.\n */\nexport class SubagentDiscoveryHandle implements AsyncIterable<SubagentHandle> {\n readonly #source: SubscriptionHandle<Event>;\n readonly #session: Subscribable;\n readonly #queue: SubagentHandle[] = [];\n readonly #waiters: Array<(value: IteratorResult<SubagentHandle>) => void> =\n [];\n readonly #pending = new Map<\n string,\n {\n resolveOutput: (v: unknown) => void;\n rejectOutput: (e: unknown) => void;\n }\n >();\n #sourcePump?: Promise<void>;\n #closed = false;\n\n constructor(source: SubscriptionHandle<Event>, session: Subscribable) {\n this.#source = source;\n this.#session = session;\n }\n\n #processEvent(event: Event): SubagentHandle | undefined {\n if (event.method !== \"tools\") return undefined;\n const tools = event as ToolsEvent;\n const data = tools.params.data;\n const toolCallId = (data as Record<string, unknown>).tool_call_id as string;\n const toolName = (data as Record<string, unknown>).tool_name as string;\n\n if (toolName === \"task\" && data.event === \"tool-started\") {\n const rawInput = (data as Record<string, unknown>).input;\n const input: { description?: string; subagent_type?: string } =\n typeof rawInput === \"string\"\n ? JSON.parse(rawInput)\n : ((rawInput as Record<string, unknown>) ?? {});\n\n const name = input.subagent_type ?? \"unknown\";\n const description = input.description ?? \"\";\n\n let resolveTaskInput!: (v: string) => void;\n let resolveOutput!: (v: unknown) => void;\n let rejectOutput!: (e: unknown) => void;\n\n const taskInput = new Promise<string>((r) => {\n resolveTaskInput = r;\n });\n const output = new Promise<unknown>((res, rej) => {\n resolveOutput = res;\n rejectOutput = rej;\n });\n\n resolveTaskInput(description);\n this.#pending.set(toolCallId, { resolveOutput, rejectOutput });\n\n const namespace = [...tools.params.namespace];\n\n return new SubagentHandle(\n name,\n toolCallId,\n namespace,\n taskInput,\n output,\n this.#session\n );\n }\n\n if (toolCallId) {\n const pending = this.#pending.get(toolCallId);\n if (pending) {\n if (data.event === \"tool-finished\") {\n pending.resolveOutput((data as Record<string, unknown>).output);\n this.#pending.delete(toolCallId);\n } else if (data.event === \"tool-error\") {\n const message =\n ((data as Record<string, unknown>).message as string) ??\n \"unknown error\";\n pending.rejectOutput(new Error(message));\n this.#pending.delete(toolCallId);\n }\n }\n }\n\n return undefined;\n }\n\n #start(): void {\n if (this.#sourcePump) return;\n this.#sourcePump = (async () => {\n for await (const event of this.#source) {\n const handle = this.#processEvent(event);\n if (!handle) continue;\n\n const waiter = this.#waiters.shift();\n if (waiter) {\n waiter({ done: false, value: handle });\n } else {\n this.#queue.push(handle);\n }\n }\n this.#closed = true;\n for (const pending of this.#pending.values()) {\n pending.resolveOutput(undefined);\n }\n this.#pending.clear();\n while (this.#waiters.length > 0) {\n this.#waiters.shift()?.({ done: true, value: undefined });\n }\n })();\n }\n\n async close(): Promise<void> {\n this.#closed = true;\n await this.#source.unsubscribe();\n }\n\n [Symbol.asyncIterator](): AsyncIterator<SubagentHandle> {\n this.#start();\n return {\n next: async () => {\n if (this.#queue.length > 0) {\n return { done: false, value: this.#queue.shift()! };\n }\n if (this.#closed) {\n return { done: true, value: undefined };\n }\n return await new Promise<IteratorResult<SubagentHandle>>((resolve) => {\n this.#waiters.push(resolve);\n });\n },\n return: async () => {\n await this.close();\n return { done: true, value: undefined };\n },\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ClientAssembledToolCall } from "./tools.cjs";
|
|
2
2
|
import { StreamingMessageHandle } from "../messages.cjs";
|
|
3
3
|
import { AudioMedia, FileMedia, ImageMedia, VideoMedia } from "../media.cjs";
|
|
4
4
|
import { EventForChannel, EventForChannels, SubscribeOptions, YieldForChannel, YieldForChannels } from "../types.cjs";
|
|
@@ -27,7 +27,7 @@ declare class SubagentHandle {
|
|
|
27
27
|
readonly namespace: string[];
|
|
28
28
|
constructor(name: string, callId: string, namespace: string[], taskInput: Promise<string>, output: Promise<unknown>, session: Subscribable);
|
|
29
29
|
get messages(): AsyncIterable<StreamingMessageHandle>;
|
|
30
|
-
get toolCalls(): AsyncIterable<
|
|
30
|
+
get toolCalls(): AsyncIterable<ClientAssembledToolCall>;
|
|
31
31
|
get audio(): AsyncIterable<AudioMedia>;
|
|
32
32
|
get images(): AsyncIterable<ImageMedia>;
|
|
33
33
|
get video(): AsyncIterable<VideoMedia>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagents.d.cts","names":[],"sources":["../../../../src/client/stream/handles/subagents.ts"],"mappings":";;;;;;;;;;;AA4CA;;;;;;;;;cAAa,cAAA;EAAA;WACF,IAAA;EAAA,SACA,MAAA;EAAA,SACA,SAAA,EAAW,OAAA;EAAA,SACX,MAAA,EAAQ,OAAA;EAAA,SACR,SAAA;EAaT,WAAA,CACE,IAAA,UACA,MAAA,UACA,SAAA,YACA,SAAA,EAAW,OAAA,UACX,MAAA,EAAQ,OAAA,WACR,OAAA,EAAS,YAAA;EAAA,IAUP,QAAA,CAAA,GAAY,aAAA,CAAc,sBAAA;EAAA,IAiB1B,SAAA,CAAA,GAAa,aAAA,CAAc,
|
|
1
|
+
{"version":3,"file":"subagents.d.cts","names":[],"sources":["../../../../src/client/stream/handles/subagents.ts"],"mappings":";;;;;;;;;;;AA4CA;;;;;;;;;cAAa,cAAA;EAAA;WACF,IAAA;EAAA,SACA,MAAA;EAAA,SACA,SAAA,EAAW,OAAA;EAAA,SACX,MAAA,EAAQ,OAAA;EAAA,SACR,SAAA;EAaT,WAAA,CACE,IAAA,UACA,MAAA,UACA,SAAA,YACA,SAAA,EAAW,OAAA,UACX,MAAA,EAAQ,OAAA,WACR,OAAA,EAAS,YAAA;EAAA,IAUP,QAAA,CAAA,GAAY,aAAA,CAAc,sBAAA;EAAA,IAiB1B,SAAA,CAAA,GAAa,aAAA,CAAc,uBAAA;EAAA,IAiB3B,KAAA,CAAA,GAAS,aAAA,CAAc,UAAA;EAAA,IAKvB,MAAA,CAAA,GAAU,aAAA,CAAc,UAAA;EAAA,IAKxB,KAAA,CAAA,GAAS,aAAA,CAAc,UAAA;EAAA,IAKvB,KAAA,CAAA,GAAS,aAAA,CAAc,SAAA;EAAA,IAsCvB,SAAA,CAAA,GAAa,aAAA,CAAc,cAAA;EA2BnB;;;EAFZ,SAAA,kBAA2B,OAAA,CAAA,CACzB,OAAA,EAAS,QAAA,EACT,OAAA,GAAU,gBAAA,GACT,OAAA,CACD,kBAAA,CAAmB,eAAA,CAAgB,QAAA,GAAW,eAAA,CAAgB,QAAA;EAEhE,SAAA,kCAA2C,OAAA,GAAA,CACzC,QAAA,EAAU,SAAA,EACV,OAAA,GAAU,gBAAA,GACT,OAAA,CACD,kBAAA,CAAmB,gBAAA,CAAiB,SAAA,GAAY,gBAAA,CAAiB,SAAA;EAEnE,SAAA,CAAU,MAAA,EAAQ,eAAA,GAAkB,OAAA,CAAQ,kBAAA,CAAmB,KAAA;AAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ClientAssembledToolCall } from "./tools.js";
|
|
2
2
|
import { StreamingMessageHandle } from "../messages.js";
|
|
3
3
|
import { AudioMedia, FileMedia, ImageMedia, VideoMedia } from "../media.js";
|
|
4
4
|
import { EventForChannel, EventForChannels, SubscribeOptions, YieldForChannel, YieldForChannels } from "../types.js";
|
|
@@ -27,7 +27,7 @@ declare class SubagentHandle {
|
|
|
27
27
|
readonly namespace: string[];
|
|
28
28
|
constructor(name: string, callId: string, namespace: string[], taskInput: Promise<string>, output: Promise<unknown>, session: Subscribable);
|
|
29
29
|
get messages(): AsyncIterable<StreamingMessageHandle>;
|
|
30
|
-
get toolCalls(): AsyncIterable<
|
|
30
|
+
get toolCalls(): AsyncIterable<ClientAssembledToolCall>;
|
|
31
31
|
get audio(): AsyncIterable<AudioMedia>;
|
|
32
32
|
get images(): AsyncIterable<ImageMedia>;
|
|
33
33
|
get video(): AsyncIterable<VideoMedia>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagents.d.ts","names":[],"sources":["../../../../src/client/stream/handles/subagents.ts"],"mappings":";;;;;;;;;;;AA4CA;;;;;;;;;cAAa,cAAA;EAAA;WACF,IAAA;EAAA,SACA,MAAA;EAAA,SACA,SAAA,EAAW,OAAA;EAAA,SACX,MAAA,EAAQ,OAAA;EAAA,SACR,SAAA;EAaT,WAAA,CACE,IAAA,UACA,MAAA,UACA,SAAA,YACA,SAAA,EAAW,OAAA,UACX,MAAA,EAAQ,OAAA,WACR,OAAA,EAAS,YAAA;EAAA,IAUP,QAAA,CAAA,GAAY,aAAA,CAAc,sBAAA;EAAA,IAiB1B,SAAA,CAAA,GAAa,aAAA,CAAc,
|
|
1
|
+
{"version":3,"file":"subagents.d.ts","names":[],"sources":["../../../../src/client/stream/handles/subagents.ts"],"mappings":";;;;;;;;;;;AA4CA;;;;;;;;;cAAa,cAAA;EAAA;WACF,IAAA;EAAA,SACA,MAAA;EAAA,SACA,SAAA,EAAW,OAAA;EAAA,SACX,MAAA,EAAQ,OAAA;EAAA,SACR,SAAA;EAaT,WAAA,CACE,IAAA,UACA,MAAA,UACA,SAAA,YACA,SAAA,EAAW,OAAA,UACX,MAAA,EAAQ,OAAA,WACR,OAAA,EAAS,YAAA;EAAA,IAUP,QAAA,CAAA,GAAY,aAAA,CAAc,sBAAA;EAAA,IAiB1B,SAAA,CAAA,GAAa,aAAA,CAAc,uBAAA;EAAA,IAiB3B,KAAA,CAAA,GAAS,aAAA,CAAc,UAAA;EAAA,IAKvB,MAAA,CAAA,GAAU,aAAA,CAAc,UAAA;EAAA,IAKxB,KAAA,CAAA,GAAS,aAAA,CAAc,UAAA;EAAA,IAKvB,KAAA,CAAA,GAAS,aAAA,CAAc,SAAA;EAAA,IAsCvB,SAAA,CAAA,GAAa,aAAA,CAAc,cAAA;EA2BnB;;;EAFZ,SAAA,kBAA2B,OAAA,CAAA,CACzB,OAAA,EAAS,QAAA,EACT,OAAA,GAAU,gBAAA,GACT,OAAA,CACD,kBAAA,CAAmB,eAAA,CAAgB,QAAA,GAAW,eAAA,CAAgB,QAAA;EAEhE,SAAA,kCAA2C,OAAA,GAAA,CACzC,QAAA,EAAU,SAAA,EACV,OAAA,GAAU,gBAAA,GACT,OAAA,CACD,kBAAA,CAAmB,gBAAA,CAAiB,SAAA,GAAY,gBAAA,CAAiB,SAAA;EAEnE,SAAA,CAAU,MAAA,EAAQ,eAAA,GAAkB,OAAA,CAAQ,kBAAA,CAAmB,KAAA;AAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MultiCursorBuffer } from "../multi-cursor-buffer.js";
|
|
2
|
-
import { ToolCallAssembler } from "./tools.js";
|
|
2
|
+
import { ToolCallAssembler, toClientAssembledToolCall } from "./tools.js";
|
|
3
3
|
import { StreamingMessageAssembler } from "../messages.js";
|
|
4
4
|
import { MediaAssembler } from "../media.js";
|
|
5
5
|
import { SubgraphDiscoveryHandle } from "./subgraphs.js";
|
|
@@ -58,7 +58,7 @@ var SubagentHandle = class {
|
|
|
58
58
|
this.#startProjection(["tools"], (event) => {
|
|
59
59
|
if (event.method !== "tools") return;
|
|
60
60
|
const tc = assembler.consume(event);
|
|
61
|
-
if (tc) buffer.push(tc);
|
|
61
|
+
if (tc) buffer.push(toClientAssembledToolCall(tc));
|
|
62
62
|
}, () => buffer.close());
|
|
63
63
|
return buffer;
|
|
64
64
|
}
|