@langchain/langgraph-sdk 1.9.19 → 1.9.21

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.
Files changed (110) hide show
  1. package/dist/client/index.cjs +2 -1
  2. package/dist/client/index.cjs.map +1 -1
  3. package/dist/client/index.d.cts +1 -0
  4. package/dist/client/index.d.cts.map +1 -1
  5. package/dist/client/index.d.ts +1 -0
  6. package/dist/client/index.d.ts.map +1 -1
  7. package/dist/client/index.js +2 -1
  8. package/dist/client/index.js.map +1 -1
  9. package/dist/client/stream/error.cjs +21 -0
  10. package/dist/client/stream/error.cjs.map +1 -1
  11. package/dist/client/stream/error.js +21 -1
  12. package/dist/client/stream/error.js.map +1 -1
  13. package/dist/client/stream/index.cjs +24 -1
  14. package/dist/client/stream/index.cjs.map +1 -1
  15. package/dist/client/stream/index.d.cts.map +1 -1
  16. package/dist/client/stream/index.d.ts.map +1 -1
  17. package/dist/client/stream/index.js +24 -1
  18. package/dist/client/stream/index.js.map +1 -1
  19. package/dist/client/stream/resolve-client-api-url.cjs +20 -0
  20. package/dist/client/stream/resolve-client-api-url.cjs.map +1 -0
  21. package/dist/client/stream/resolve-client-api-url.d.cts +17 -0
  22. package/dist/client/stream/resolve-client-api-url.d.cts.map +1 -0
  23. package/dist/client/stream/resolve-client-api-url.d.ts +17 -0
  24. package/dist/client/stream/resolve-client-api-url.d.ts.map +1 -0
  25. package/dist/client/stream/resolve-client-api-url.js +20 -0
  26. package/dist/client/stream/resolve-client-api-url.js.map +1 -0
  27. package/dist/client/stream/transport/agent-server.cjs +13 -1
  28. package/dist/client/stream/transport/agent-server.cjs.map +1 -1
  29. package/dist/client/stream/transport/agent-server.d.cts +13 -0
  30. package/dist/client/stream/transport/agent-server.d.cts.map +1 -1
  31. package/dist/client/stream/transport/agent-server.d.ts +13 -0
  32. package/dist/client/stream/transport/agent-server.d.ts.map +1 -1
  33. package/dist/client/stream/transport/agent-server.js +13 -1
  34. package/dist/client/stream/transport/agent-server.js.map +1 -1
  35. package/dist/client/stream/transport/http.cjs +74 -10
  36. package/dist/client/stream/transport/http.cjs.map +1 -1
  37. package/dist/client/stream/transport/http.d.cts +25 -1
  38. package/dist/client/stream/transport/http.d.cts.map +1 -1
  39. package/dist/client/stream/transport/http.d.ts +25 -1
  40. package/dist/client/stream/transport/http.d.ts.map +1 -1
  41. package/dist/client/stream/transport/http.js +74 -10
  42. package/dist/client/stream/transport/http.js.map +1 -1
  43. package/dist/client/stream/transport/index.cjs +2 -1
  44. package/dist/client/stream/transport/index.js +2 -1
  45. package/dist/client/stream/transport/types.d.cts +46 -0
  46. package/dist/client/stream/transport/types.d.cts.map +1 -1
  47. package/dist/client/stream/transport/types.d.ts +46 -0
  48. package/dist/client/stream/transport/types.d.ts.map +1 -1
  49. package/dist/client/stream/transport/websocket.cjs +105 -16
  50. package/dist/client/stream/transport/websocket.cjs.map +1 -1
  51. package/dist/client/stream/transport/websocket.d.cts +19 -0
  52. package/dist/client/stream/transport/websocket.d.cts.map +1 -1
  53. package/dist/client/stream/transport/websocket.d.ts +19 -0
  54. package/dist/client/stream/transport/websocket.d.ts.map +1 -1
  55. package/dist/client/stream/transport/websocket.js +105 -17
  56. package/dist/client/stream/transport/websocket.js.map +1 -1
  57. package/dist/client/stream/transport.d.cts +10 -4
  58. package/dist/client/stream/transport.d.cts.map +1 -1
  59. package/dist/client/stream/transport.d.ts +10 -4
  60. package/dist/client/stream/transport.d.ts.map +1 -1
  61. package/dist/client/stream/types.d.cts +17 -0
  62. package/dist/client/stream/types.d.cts.map +1 -1
  63. package/dist/client/stream/types.d.ts +17 -0
  64. package/dist/client/stream/types.d.ts.map +1 -1
  65. package/dist/client/threads/index.cjs +30 -14
  66. package/dist/client/threads/index.cjs.map +1 -1
  67. package/dist/client/threads/index.js +30 -14
  68. package/dist/client/threads/index.js.map +1 -1
  69. package/dist/client.cjs +3 -1
  70. package/dist/client.d.cts +2 -1
  71. package/dist/client.d.ts +2 -1
  72. package/dist/client.js +3 -2
  73. package/dist/index.cjs +1 -1
  74. package/dist/index.js +1 -1
  75. package/dist/stream/controller.cjs +31 -2
  76. package/dist/stream/controller.cjs.map +1 -1
  77. package/dist/stream/controller.d.cts.map +1 -1
  78. package/dist/stream/controller.d.ts.map +1 -1
  79. package/dist/stream/controller.js +31 -2
  80. package/dist/stream/controller.js.map +1 -1
  81. package/dist/stream/index.cjs +2 -0
  82. package/dist/stream/index.d.cts +2 -1
  83. package/dist/stream/index.d.ts +2 -1
  84. package/dist/stream/index.js +2 -1
  85. package/dist/stream/projections/channel-effect.cjs +52 -0
  86. package/dist/stream/projections/channel-effect.cjs.map +1 -0
  87. package/dist/stream/projections/channel-effect.d.cts +35 -0
  88. package/dist/stream/projections/channel-effect.d.cts.map +1 -0
  89. package/dist/stream/projections/channel-effect.d.ts +35 -0
  90. package/dist/stream/projections/channel-effect.d.ts.map +1 -0
  91. package/dist/stream/projections/channel-effect.js +52 -0
  92. package/dist/stream/projections/channel-effect.js.map +1 -0
  93. package/dist/stream/projections/index.cjs +1 -0
  94. package/dist/stream/projections/index.d.ts +1 -0
  95. package/dist/stream/projections/index.js +1 -0
  96. package/dist/stream/root-message-projection.cjs +55 -0
  97. package/dist/stream/root-message-projection.cjs.map +1 -1
  98. package/dist/stream/root-message-projection.js +55 -0
  99. package/dist/stream/root-message-projection.js.map +1 -1
  100. package/dist/ui/branching.d.cts +1 -1
  101. package/dist/ui/branching.d.ts +1 -1
  102. package/dist/ui/orchestrator.d.cts +1 -1
  103. package/dist/ui/orchestrator.d.cts.map +1 -1
  104. package/dist/ui/orchestrator.d.ts +1 -1
  105. package/dist/ui/orchestrator.d.ts.map +1 -1
  106. package/dist/utils/stream.d.cts +1 -1
  107. package/dist/utils/stream.d.cts.map +1 -1
  108. package/dist/utils/stream.d.ts +1 -1
  109. package/dist/utils/stream.d.ts.map +1 -1
  110. package/package.json +5 -2
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["BaseClient","ProtocolWebSocketTransportAdapter","ProtocolSseTransportAdapter","ThreadStream"],"sources":["../../../src/client/threads/index.ts"],"sourcesContent":["import { v7 as uuidv7 } from \"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 let transport: TransportAdapter;\n if (options.transport != null && typeof options.transport !== \"string\") {\n transport = options.transport;\n } else {\n const transportKind: ThreadStreamTransportKind =\n options.transport ??\n (this.streamProtocol === \"v2-websocket\" ? \"websocket\" : \"sse\");\n transport =\n transportKind === \"websocket\"\n ? new ProtocolWebSocketTransportAdapter({\n apiUrl: this.apiUrl,\n threadId,\n defaultHeaders: this.defaultHeaders,\n onRequest: this.onRequest,\n webSocketFactory: options.webSocketFactory,\n })\n : new ProtocolSseTransportAdapter({\n apiUrl: this.apiUrl,\n threadId,\n defaultHeaders: this.defaultHeaders,\n onRequest: this.onRequest,\n fetch: options.fetch,\n });\n }\n\n return new ThreadStream<TExtensions>(transport, options);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["BaseClient","ProtocolWebSocketTransportAdapter","ProtocolSseTransportAdapter","ThreadStream"],"sources":["../../../src/client/threads/index.ts"],"sourcesContent":["import { v7 as uuidv7 } from \"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 } 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 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":";;;;;;;AA2BA,IAAa,gBAAb,cAGUA,aAAAA,WAAW;;;;;;;CAOnB,MAAM,IACJ,UACA,SAC6B;AAC7B,SAAO,KAAK,MAA0B,YAAY,YAAY;GAC5D,QAAQ,EACN,SAAS,SAAS,WAAW,KAAA,GAC9B;GACD,QAAQ,SAAS;GAClB,CAAC;;;;;;;;CASJ,MAAM,OAAO,SAUmB;EAC9B,MAAM,aACJ,OAAO,SAAS,QAAQ,WACpB;GAAE,KAAK,QAAQ;GAAK,UAAU;GAAmB,GACjD,SAAS;AAEf,SAAO,KAAK,MAA0B,YAAY;GAChD,QAAQ;GACR,MAAM;IACJ,UAAU;KACR,GAAG,SAAS;KACZ,UAAU,SAAS;KACpB;IACD,WAAW,SAAS;IACpB,WAAW,SAAS;IACpB,YAAY,SAAS,YAAY,KAAK,OAAO,EAC3C,SAAS,EAAE,QAAQ,KAAK,OAAO;KAC7B,QAAQ,EAAE;KACV,SAAS,EAAE;KACX,SAAS,EAAE;KACZ,EAAE,EACJ,EAAE;IACH,KAAK;IACN;GACD,QAAQ,SAAS;GAClB,CAAC;;;;;;;CAQJ,MAAM,KACJ,UACA,SAC6B;AAC7B,SAAO,KAAK,MAA0B,YAAY,SAAS,QAAQ;GACjE,QAAQ;GACR,QAAQ,SAAS;GAClB,CAAC;;CAqCJ,MAAM,OACJ,UACA,SAMwB;EACxB,MAAM,aACJ,OAAO,SAAS,QAAQ,WACpB;GAAE,KAAK,QAAQ;GAAK,UAAU;GAAmB,GACjD,SAAS;AAEf,SAAO,KAAK,MAAqB,YAAY,YAAY;GACvD,QAAQ;GACR,SAAS,SAAS,gBACd,EAAE,QAAQ,kBAAkB,GAC5B,KAAA;GACJ,MAAM;IAAE,UAAU,SAAS;IAAU,KAAK;IAAY;GACtD,QAAQ,SAAS;GAClB,CAAC;;;;;;;CAQJ,MAAM,OACJ,UACA,SACe;AACf,SAAO,KAAK,MAAY,YAAY,YAAY;GAC9C,QAAQ;GACR,QAAQ,SAAS;GAClB,CAAC;;;;;;;;;;;;;CAcJ,MAAM,MACJ,WACA,SAImC;AACnC,SAAO,KAAK,MAAgC,kBAAkB;GAC5D,QAAQ;GACR,MAAM;IACJ,YAAY;IACZ,UAAU,SAAS,YAAY;IAChC;GACD,QAAQ,SAAS;GAClB,CAAC;;;;;;;;CASJ,MAAM,OAAgC,OAYJ;AAChC,SAAO,KAAK,MAA4B,mBAAmB;GACzD,QAAQ;GACR,MAAM;IACJ,UAAU,OAAO,YAAY,KAAA;IAC7B,KAAK,OAAO,OAAO,KAAA;IACnB,OAAO,OAAO,SAAS;IACvB,QAAQ,OAAO,UAAU;IACzB,QAAQ,OAAO;IACf,SAAS,OAAO;IAChB,YAAY,OAAO;IACnB,QAAQ,OAAO,UAAU,KAAA;IACzB,QAAQ,OAAO,UAAU,KAAA;IACzB,SAAS,OAAO,WAAW,KAAA;IAC5B;GACD,QAAQ,OAAO;GAChB,CAAC;;;;;;;;;;CAWJ,MAAM,MAA+B,OAKjB;AAClB,SAAO,KAAK,MAAc,kBAAkB;GAC1C,QAAQ;GACR,MAAM;IACJ,UAAU,OAAO,YAAY,KAAA;IAC7B,QAAQ,OAAO,UAAU,KAAA;IACzB,QAAQ,OAAO,UAAU,KAAA;IAC1B;GACD,QAAQ,OAAO;GAChB,CAAC;;;;;;;;CASJ,MAAM,SACJ,UACA,YACA,SACkC;AAClC,MAAI,cAAc,MAAM;AACtB,OAAI,OAAO,eAAe,SACxB,QAAO,KAAK,MACV,YAAY,SAAS,oBACrB;IACE,QAAQ;IACR,MAAM;KAAE;KAAY,WAAW,SAAS;KAAW;IACnD,QAAQ,SAAS;IAClB,CACF;AAIH,UAAO,KAAK,MACV,YAAY,SAAS,SAAS,cAC9B;IAAE,QAAQ,EAAE,WAAW,SAAS,WAAW;IAAE,QAAQ,SAAS;IAAQ,CACvE;;AAGH,SAAO,KAAK,MAA+B,YAAY,SAAS,SAAS;GACvE,QAAQ,EAAE,WAAW,SAAS,WAAW;GACzC,QAAQ,SAAS;GAIjB,QAAQ;GACT,CAAC;;;;;;;;CASJ,MAAM,YACJ,UACA,SAOuC;AACvC,SAAO,KAAK,MACV,YAAY,SAAS,SACrB;GACE,QAAQ;GACR,MAAM;IACJ,QAAQ,QAAQ;IAChB,YAAY,QAAQ;IACpB,eAAe,QAAQ;IACvB,SAAS,SAAS;IACnB;GACD,QAAQ,SAAS;GAClB,CACF;;;;;;;;CASH,MAAM,WACJ,kBACA,UACA,SACe;EACf,IAAI;AAEJ,MAAI,OAAO,qBAAqB,UAAU;AACxC,OAAI,OAAO,iBAAiB,cAAc,cAAc,SACtD,OAAM,IAAI,MACR,2DACD;AAEH,cAAW,iBAAiB,aAAa;QAEzC,YAAW;AAGb,SAAO,KAAK,MAAY,YAAY,SAAS,SAAS;GACpD,QAAQ;GACR,MAAM,EAAE,UAAU;GAClB,QAAQ,SAAS;GAClB,CAAC;;;;;;;;;CAUJ,MAAM,WACJ,UACA,SAOoC;AACpC,SAAO,KAAK,MACV,YAAY,SAAS,WACrB;GACE,QAAQ;GACR,MAAM;IACJ,OAAO,SAAS,SAAS;IACzB,QAAQ,SAAS;IACjB,UAAU,SAAS;IACnB,YAAY,SAAS;IACtB;GACD,QAAQ,SAAS;GAIjB,QAAQ;GACT,CACF;;CAGH,OAAO,WACL,UACA,SAMgE;AAChE,SAAO,KAAK,gBAAgB;GAC1B,UAAU,YAAY,SAAS;GAC/B,QAAQ;GACR,QAAQ,SAAS;GACjB,SAAS,SAAS,cACd,EAAE,iBAAiB,QAAQ,aAAa,GACxC,KAAA;GACJ,QAAQ,SAAS,aACb,EAAE,aAAa,QAAQ,YAAY,GACnC,KAAA;GACL,CAAC;;CAyCJ,OACE,mBACA,cAC2B;EAC3B,MAAM,EAAE,UAAU,YAChB,OAAO,sBAAsB,WACzB;GACE,UAAU;GACV,SAAS;GACV,GACD;GAAE,WAAA,GAAA,KAAA,KAAkB;GAAE,SAAS;GAAmB;EASxD,MAAM,YAAY,QAAQ;EAC1B,MAAM,gBACJ,aAAa,KAAK,YAAY,MAAM,KAAK,KAAK,YAAY;EAE5D,IAAI;AACJ,MAAI,QAAQ,aAAa,QAAQ,OAAO,QAAQ,cAAc,SAC5D,aAAY,QAAQ;OACf;GACL,MAAM,gBACJ,QAAQ,cACP,KAAK,mBAAmB,iBAAiB,cAAc;GAC1D,MAAM,uBAAuB,QAAQ,wBAAwB;;;;GAK7D,MAAM,aAAa;IACjB,QAAQ,KAAK;IACb;IACA,gBAAgB,KAAK;IACrB,WAAW,KAAK;IAChB;IACA,kBAAkB,QAAQ;IAC1B,aAAa,QAAQ;IACtB;AAED,eACE,kBAAkB,cACd,IAAIC,kBAAAA,kCAAkC;IACpC,GAAG;IACH,kBAAkB,QAAQ;IAC3B,CAAC,GACF,IAAIC,aAAAA,4BAA4B;IAC9B,GAAG;IACH,OAAO;IACP,aAAa,YAAY,KAAA,IAAY,KAAK;IAC3C,CAAC;;AAGV,SAAO,IAAIC,cAAAA,aAA0B,WAAW;GAC9C,GAAG;GACH,OAAO;GACR,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { BaseClient } from "../base.js";
2
2
  import { ThreadStream } from "../stream/index.js";
3
- import { ProtocolSseTransportAdapter } from "../stream/transport/http.js";
4
3
  import { ProtocolWebSocketTransportAdapter } from "../stream/transport/websocket.js";
4
+ import { ProtocolSseTransportAdapter } from "../stream/transport/http.js";
5
5
  import { v7 } from "uuid";
6
6
  //#region src/client/threads/index.ts
7
7
  var ThreadsClient = class extends BaseClient {
@@ -248,22 +248,38 @@ var ThreadsClient = class extends BaseClient {
248
248
  threadId: v7(),
249
249
  options: threadIdOrOptions
250
250
  };
251
+ const userFetch = options.fetch;
252
+ const protocolFetch = userFetch ?? this.asyncCaller.fetch.bind(this.asyncCaller);
251
253
  let transport;
252
254
  if (options.transport != null && typeof options.transport !== "string") transport = options.transport;
253
- else transport = (options.transport ?? (this.streamProtocol === "v2-websocket" ? "websocket" : "sse")) === "websocket" ? new ProtocolWebSocketTransportAdapter({
254
- apiUrl: this.apiUrl,
255
- threadId,
256
- defaultHeaders: this.defaultHeaders,
257
- onRequest: this.onRequest,
258
- webSocketFactory: options.webSocketFactory
259
- }) : new ProtocolSseTransportAdapter({
260
- apiUrl: this.apiUrl,
261
- threadId,
262
- defaultHeaders: this.defaultHeaders,
263
- onRequest: this.onRequest,
264
- fetch: options.fetch
255
+ else {
256
+ const transportKind = options.transport ?? (this.streamProtocol === "v2-websocket" ? "websocket" : "sse");
257
+ const maxReconnectAttempts = options.maxReconnectAttempts ?? 5;
258
+ /**
259
+ * Common options for both transports.
260
+ */
261
+ const commonOpts = {
262
+ apiUrl: this.apiUrl,
263
+ threadId,
264
+ defaultHeaders: this.defaultHeaders,
265
+ onRequest: this.onRequest,
266
+ maxReconnectAttempts,
267
+ reconnectDelayMs: options.reconnectDelayMs,
268
+ onReconnect: options.onReconnect
269
+ };
270
+ transport = transportKind === "websocket" ? new ProtocolWebSocketTransportAdapter({
271
+ ...commonOpts,
272
+ webSocketFactory: options.webSocketFactory
273
+ }) : new ProtocolSseTransportAdapter({
274
+ ...commonOpts,
275
+ fetch: userFetch,
276
+ asyncCaller: userFetch ? void 0 : this.asyncCaller
277
+ });
278
+ }
279
+ return new ThreadStream(transport, {
280
+ ...options,
281
+ fetch: protocolFetch
265
282
  });
266
- return new ThreadStream(transport, options);
267
283
  }
268
284
  };
269
285
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["uuidv7"],"sources":["../../../src/client/threads/index.ts"],"sourcesContent":["import { v7 as uuidv7 } from \"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 let transport: TransportAdapter;\n if (options.transport != null && typeof options.transport !== \"string\") {\n transport = options.transport;\n } else {\n const transportKind: ThreadStreamTransportKind =\n options.transport ??\n (this.streamProtocol === \"v2-websocket\" ? \"websocket\" : \"sse\");\n transport =\n transportKind === \"websocket\"\n ? new ProtocolWebSocketTransportAdapter({\n apiUrl: this.apiUrl,\n threadId,\n defaultHeaders: this.defaultHeaders,\n onRequest: this.onRequest,\n webSocketFactory: options.webSocketFactory,\n })\n : new ProtocolSseTransportAdapter({\n apiUrl: this.apiUrl,\n threadId,\n defaultHeaders: this.defaultHeaders,\n onRequest: this.onRequest,\n fetch: options.fetch,\n });\n }\n\n return new ThreadStream<TExtensions>(transport, options);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["uuidv7"],"sources":["../../../src/client/threads/index.ts"],"sourcesContent":["import { v7 as uuidv7 } from \"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 } 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 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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"}
package/dist/client.cjs CHANGED
@@ -6,13 +6,14 @@ const require_messages = require("./client/stream/messages.cjs");
6
6
  const require_media = require("./client/stream/media.cjs");
7
7
  const require_error = require("./client/stream/error.cjs");
8
8
  const require_index$1 = require("./client/stream/index.cjs");
9
- const require_http = require("./client/stream/transport/http.cjs");
10
9
  const require_websocket = require("./client/stream/transport/websocket.cjs");
10
+ const require_http = require("./client/stream/transport/http.cjs");
11
11
  const require_index$2 = require("./client/threads/index.cjs");
12
12
  const require_index$3 = require("./client/runs/index.cjs");
13
13
  const require_index$4 = require("./client/crons/index.cjs");
14
14
  const require_index$5 = require("./client/store/index.cjs");
15
15
  const require_agent_server = require("./client/stream/transport/agent-server.cjs");
16
+ const require_resolve_client_api_url = require("./client/stream/resolve-client-api-url.cjs");
16
17
  const require_index$6 = require("./client/index.cjs");
17
18
  exports.AssistantsClient = require_index.AssistantsClient;
18
19
  exports.BaseClient = require_base.BaseClient;
@@ -34,3 +35,4 @@ exports.getApiKey = require_base.getApiKey;
34
35
  exports.getClientConfigHash = require_index$6.getClientConfigHash;
35
36
  exports.inferChannel = require_subscription.inferChannel;
36
37
  exports.matchesSubscription = require_subscription.matchesSubscription;
38
+ exports.resolveClientApiUrl = require_resolve_client_api_url.resolveClientApiUrl;
package/dist/client.d.cts CHANGED
@@ -15,5 +15,6 @@ import { HeaderValue as HeaderValue$1, ProtocolRequestHook, ProtocolSseTransport
15
15
  import { ProtocolSseTransportAdapter } from "./client/stream/transport/http.cjs";
16
16
  import { ProtocolWebSocketTransportAdapter } from "./client/stream/transport/websocket.cjs";
17
17
  import { HttpAgentServerAdapter, HttpAgentServerAdapterOptions } from "./client/stream/transport/agent-server.cjs";
18
+ import { resolveClientApiUrl } from "./client/stream/resolve-client-api-url.cjs";
18
19
  import { Client, getClientConfigHash } from "./client/index.cjs";
19
- export { type AgentServerAdapter, type AnyMediaHandle, type AssembledMessage, AssistantsClient, type AudioMedia, BaseClient, Client, type ClientConfig, CronsClient, type EventForChannel, type EventForChannels, type EventMethodByChannel, type EventSubscription, type FileMedia, type HeaderValue, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type ImageMedia, type InputModule, MediaAssembler, type MediaAssemblerCallbacks, type MediaAssemblerOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, MessageAssembler, type MessageAssemblyUpdate, type MessageSubscription, ProtocolError, type HeaderValue$1 as ProtocolHeaderValue, type ProtocolRequestHook, ProtocolSseTransportAdapter, type ProtocolSseTransportOptions, type ProtocolTransportPaths, ProtocolWebSocketTransportAdapter, type ProtocolWebSocketTransportOptions, type RequestHook, RunsClient, type SessionOrderingState, type StateModule, StoreClient, type SubscribeOptions, SubscriptionHandle, type ThreadExtension, type ThreadExtensions, type ThreadModules, ThreadStream, type ThreadStreamOptions, type ThreadStreamTransport, type ThreadStreamTransportKind, ThreadsClient, type TransportAdapter, type UnwrapExtension, type VideoMedia, getApiKey, getClientConfigHash, inferChannel, matchesSubscription };
20
+ export { type AgentServerAdapter, type AnyMediaHandle, type AssembledMessage, AssistantsClient, type AudioMedia, BaseClient, Client, type ClientConfig, CronsClient, type EventForChannel, type EventForChannels, type EventMethodByChannel, type EventSubscription, type FileMedia, type HeaderValue, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type ImageMedia, type InputModule, MediaAssembler, type MediaAssemblerCallbacks, type MediaAssemblerOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, MessageAssembler, type MessageAssemblyUpdate, type MessageSubscription, ProtocolError, type HeaderValue$1 as ProtocolHeaderValue, type ProtocolRequestHook, ProtocolSseTransportAdapter, type ProtocolSseTransportOptions, type ProtocolTransportPaths, ProtocolWebSocketTransportAdapter, type ProtocolWebSocketTransportOptions, type RequestHook, RunsClient, type SessionOrderingState, type StateModule, StoreClient, type SubscribeOptions, SubscriptionHandle, type ThreadExtension, type ThreadExtensions, type ThreadModules, ThreadStream, type ThreadStreamOptions, type ThreadStreamTransport, type ThreadStreamTransportKind, ThreadsClient, type TransportAdapter, type UnwrapExtension, type VideoMedia, getApiKey, getClientConfigHash, inferChannel, matchesSubscription, resolveClientApiUrl };
package/dist/client.d.ts CHANGED
@@ -15,5 +15,6 @@ import { HeaderValue as HeaderValue$1, ProtocolRequestHook, ProtocolSseTransport
15
15
  import { ProtocolSseTransportAdapter } from "./client/stream/transport/http.js";
16
16
  import { ProtocolWebSocketTransportAdapter } from "./client/stream/transport/websocket.js";
17
17
  import { HttpAgentServerAdapter, HttpAgentServerAdapterOptions } from "./client/stream/transport/agent-server.js";
18
+ import { resolveClientApiUrl } from "./client/stream/resolve-client-api-url.js";
18
19
  import { Client, getClientConfigHash } from "./client/index.js";
19
- export { type AgentServerAdapter, type AnyMediaHandle, type AssembledMessage, AssistantsClient, type AudioMedia, BaseClient, Client, type ClientConfig, CronsClient, type EventForChannel, type EventForChannels, type EventMethodByChannel, type EventSubscription, type FileMedia, type HeaderValue, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type ImageMedia, type InputModule, MediaAssembler, type MediaAssemblerCallbacks, type MediaAssemblerOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, MessageAssembler, type MessageAssemblyUpdate, type MessageSubscription, ProtocolError, type HeaderValue$1 as ProtocolHeaderValue, type ProtocolRequestHook, ProtocolSseTransportAdapter, type ProtocolSseTransportOptions, type ProtocolTransportPaths, ProtocolWebSocketTransportAdapter, type ProtocolWebSocketTransportOptions, type RequestHook, RunsClient, type SessionOrderingState, type StateModule, StoreClient, type SubscribeOptions, SubscriptionHandle, type ThreadExtension, type ThreadExtensions, type ThreadModules, ThreadStream, type ThreadStreamOptions, type ThreadStreamTransport, type ThreadStreamTransportKind, ThreadsClient, type TransportAdapter, type UnwrapExtension, type VideoMedia, getApiKey, getClientConfigHash, inferChannel, matchesSubscription };
20
+ export { type AgentServerAdapter, type AnyMediaHandle, type AssembledMessage, AssistantsClient, type AudioMedia, BaseClient, Client, type ClientConfig, CronsClient, type EventForChannel, type EventForChannels, type EventMethodByChannel, type EventSubscription, type FileMedia, type HeaderValue, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type ImageMedia, type InputModule, MediaAssembler, type MediaAssemblerCallbacks, type MediaAssemblerOptions, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, MessageAssembler, type MessageAssemblyUpdate, type MessageSubscription, ProtocolError, type HeaderValue$1 as ProtocolHeaderValue, type ProtocolRequestHook, ProtocolSseTransportAdapter, type ProtocolSseTransportOptions, type ProtocolTransportPaths, ProtocolWebSocketTransportAdapter, type ProtocolWebSocketTransportOptions, type RequestHook, RunsClient, type SessionOrderingState, type StateModule, StoreClient, type SubscribeOptions, SubscriptionHandle, type ThreadExtension, type ThreadExtensions, type ThreadModules, ThreadStream, type ThreadStreamOptions, type ThreadStreamTransport, type ThreadStreamTransportKind, ThreadsClient, type TransportAdapter, type UnwrapExtension, type VideoMedia, getApiKey, getClientConfigHash, inferChannel, matchesSubscription, resolveClientApiUrl };
package/dist/client.js CHANGED
@@ -5,12 +5,13 @@ import { MessageAssembler } from "./client/stream/messages.js";
5
5
  import { MediaAssembler, MediaAssemblyError } from "./client/stream/media.js";
6
6
  import { ProtocolError } from "./client/stream/error.js";
7
7
  import { SubscriptionHandle, ThreadStream } from "./client/stream/index.js";
8
- import { ProtocolSseTransportAdapter } from "./client/stream/transport/http.js";
9
8
  import { ProtocolWebSocketTransportAdapter } from "./client/stream/transport/websocket.js";
9
+ import { ProtocolSseTransportAdapter } from "./client/stream/transport/http.js";
10
10
  import { ThreadsClient } from "./client/threads/index.js";
11
11
  import { RunsClient } from "./client/runs/index.js";
12
12
  import { CronsClient } from "./client/crons/index.js";
13
13
  import { StoreClient } from "./client/store/index.js";
14
14
  import { HttpAgentServerAdapter } from "./client/stream/transport/agent-server.js";
15
+ import { resolveClientApiUrl } from "./client/stream/resolve-client-api-url.js";
15
16
  import { Client, getClientConfigHash } from "./client/index.js";
16
- export { AssistantsClient, BaseClient, Client, CronsClient, HttpAgentServerAdapter, MediaAssembler, MediaAssemblyError, MessageAssembler, ProtocolError, ProtocolSseTransportAdapter, ProtocolWebSocketTransportAdapter, RunsClient, StoreClient, SubscriptionHandle, ThreadStream, ThreadsClient, getApiKey, getClientConfigHash, inferChannel, matchesSubscription };
17
+ export { AssistantsClient, BaseClient, Client, CronsClient, HttpAgentServerAdapter, MediaAssembler, MediaAssemblyError, MessageAssembler, ProtocolError, ProtocolSseTransportAdapter, ProtocolWebSocketTransportAdapter, RunsClient, StoreClient, SubscriptionHandle, ThreadStream, ThreadsClient, getApiKey, getClientConfigHash, inferChannel, matchesSubscription, resolveClientApiUrl };
package/dist/index.cjs CHANGED
@@ -7,8 +7,8 @@ const require_error = require("./client/stream/error.cjs");
7
7
  const require_constants = require("./stream/constants.cjs");
8
8
  const require_headless_tools = require("./headless-tools.cjs");
9
9
  const require_index = require("./client/stream/index.cjs");
10
- const require_http = require("./client/stream/transport/http.cjs");
11
10
  const require_websocket = require("./client/stream/transport/websocket.cjs");
11
+ const require_http = require("./client/stream/transport/http.cjs");
12
12
  const require_agent_server = require("./client/stream/transport/agent-server.cjs");
13
13
  const require_index$1 = require("./client/index.cjs");
14
14
  require("./client.cjs");
package/dist/index.js CHANGED
@@ -6,8 +6,8 @@ import { ProtocolError } from "./client/stream/error.js";
6
6
  import { NAMESPACE_SEPARATOR } from "./stream/constants.js";
7
7
  import { applyHeadlessToolResumeCommand, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, scheduleCoalescedHeadlessToolFlush } from "./headless-tools.js";
8
8
  import { SubscriptionHandle, ThreadStream } from "./client/stream/index.js";
9
- import { ProtocolSseTransportAdapter } from "./client/stream/transport/http.js";
10
9
  import { ProtocolWebSocketTransportAdapter } from "./client/stream/transport/websocket.js";
10
+ import { ProtocolSseTransportAdapter } from "./client/stream/transport/http.js";
11
11
  import { HttpAgentServerAdapter } from "./client/stream/transport/agent-server.js";
12
12
  import { Client } from "./client/index.js";
13
13
  import "./client.js";
@@ -345,6 +345,17 @@ var StreamController = class {
345
345
  this.#hydrationPromise = this.#createHydrationPromise();
346
346
  }
347
347
  /**
348
+ * Load thread state for hydration, preferring the active custom
349
+ * adapter's `getState()` when present.
350
+ */
351
+ async #fetchHydrationState() {
352
+ const threadId = this.#currentThreadId;
353
+ if (threadId == null) return null;
354
+ const transport = this.#options.transport;
355
+ if (transport != null && typeof transport === "object" && typeof transport.getState === "function") return await transport.getState();
356
+ return this.#options.client.threads.getState(threadId);
357
+ }
358
+ /**
348
359
  * Fetch the checkpointed thread state and seed the root snapshot.
349
360
  * Re-calling with a different `threadId` swaps the underlying
350
361
  * {@link ThreadStream}, rewires the registry to the new thread, and
@@ -417,7 +428,7 @@ var StreamController = class {
417
428
  let threadExists = false;
418
429
  let threadActive = true;
419
430
  try {
420
- const state = await this.#options.client.threads.getState(this.#currentThreadId);
431
+ const state = await this.#fetchHydrationState();
421
432
  threadExists = state != null;
422
433
  threadActive = isThreadStateActive(state);
423
434
  if (state?.values != null) {
@@ -455,7 +466,25 @@ var StreamController = class {
455
466
  * idempotent, so this is safe on re-hydrate.
456
467
  */
457
468
  const seedMessages = state.values[this.#messagesKey];
458
- if (Array.isArray(seedMessages)) this.#subagents.seedFromCheckpointMessages(seedMessages);
469
+ if (Array.isArray(seedMessages)) {
470
+ this.#subagents.seedFromCheckpointMessages(seedMessages);
471
+ /**
472
+ * An idle (finished) thread defers its root SSE pump; the first
473
+ * `submit()` brings it up and the transport replays the finished
474
+ * run from `seq=0`. Seal the seeded message ids so that replay's
475
+ * `messages` channel deltas can't downgrade the already-complete
476
+ * tail to empty partials (a visible "messages replay"). Only safe
477
+ * for idle threads, where every seeded message is final — an
478
+ * active thread's tail may still be streaming and must keep
479
+ * receiving deltas. New ids from the next run are never sealed,
480
+ * and the seal lifts once a newer checkpoint advances the
481
+ * timeline.
482
+ */
483
+ if (!threadActive) {
484
+ const sealedIds = seedMessages.map((message) => message?.id).filter((id) => typeof id === "string");
485
+ if (sealedIds.length > 0) this.#rootMessages.sealMessageIds(sealedIds);
486
+ }
487
+ }
459
488
  }
460
489
  /**
461
490
  * Converge to server truth: drop any optimistic messages the