@langchain/langgraph-sdk 1.9.16 → 1.9.17

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 (108) hide show
  1. package/dist/client/base.cjs +70 -4
  2. package/dist/client/base.cjs.map +1 -1
  3. package/dist/client/base.d.cts +3 -0
  4. package/dist/client/base.d.cts.map +1 -1
  5. package/dist/client/base.d.ts +3 -0
  6. package/dist/client/base.d.ts.map +1 -1
  7. package/dist/client/base.js +70 -4
  8. package/dist/client/base.js.map +1 -1
  9. package/dist/client/threads/index.cjs +4 -2
  10. package/dist/client/threads/index.cjs.map +1 -1
  11. package/dist/client/threads/index.d.cts.map +1 -1
  12. package/dist/client/threads/index.d.ts.map +1 -1
  13. package/dist/client/threads/index.js +4 -2
  14. package/dist/client/threads/index.js.map +1 -1
  15. package/dist/stream/controller.cjs +451 -32
  16. package/dist/stream/controller.cjs.map +1 -1
  17. package/dist/stream/controller.d.cts +15 -0
  18. package/dist/stream/controller.d.cts.map +1 -1
  19. package/dist/stream/controller.d.ts +15 -0
  20. package/dist/stream/controller.d.ts.map +1 -1
  21. package/dist/stream/controller.js +472 -32
  22. package/dist/stream/controller.js.map +1 -1
  23. package/dist/stream/discovery/index.cjs +2 -0
  24. package/dist/stream/discovery/index.js +3 -0
  25. package/dist/stream/discovery/namespace-from-history.cjs +207 -0
  26. package/dist/stream/discovery/namespace-from-history.cjs.map +1 -0
  27. package/dist/stream/discovery/namespace-from-history.js +204 -0
  28. package/dist/stream/discovery/namespace-from-history.js.map +1 -0
  29. package/dist/stream/discovery/subagents.cjs +56 -1
  30. package/dist/stream/discovery/subagents.cjs.map +1 -1
  31. package/dist/stream/discovery/subagents.d.cts +31 -0
  32. package/dist/stream/discovery/subagents.d.cts.map +1 -1
  33. package/dist/stream/discovery/subagents.d.ts +31 -0
  34. package/dist/stream/discovery/subagents.d.ts.map +1 -1
  35. package/dist/stream/discovery/subagents.js +56 -1
  36. package/dist/stream/discovery/subagents.js.map +1 -1
  37. package/dist/stream/discovery/subgraphs.cjs +24 -0
  38. package/dist/stream/discovery/subgraphs.cjs.map +1 -1
  39. package/dist/stream/discovery/subgraphs.d.cts +13 -0
  40. package/dist/stream/discovery/subgraphs.d.cts.map +1 -1
  41. package/dist/stream/discovery/subgraphs.d.ts +13 -0
  42. package/dist/stream/discovery/subgraphs.d.ts.map +1 -1
  43. package/dist/stream/discovery/subgraphs.js +24 -0
  44. package/dist/stream/discovery/subgraphs.js.map +1 -1
  45. package/dist/stream/index.cjs +1 -0
  46. package/dist/stream/index.js +1 -0
  47. package/dist/stream/message-coercion.cjs +101 -0
  48. package/dist/stream/message-coercion.cjs.map +1 -0
  49. package/dist/stream/message-coercion.d.ts +1 -0
  50. package/dist/stream/message-coercion.js +98 -0
  51. package/dist/stream/message-coercion.js.map +1 -0
  52. package/dist/stream/message-metadata-tracker.cjs +92 -0
  53. package/dist/stream/message-metadata-tracker.cjs.map +1 -1
  54. package/dist/stream/message-metadata-tracker.d.cts +23 -0
  55. package/dist/stream/message-metadata-tracker.d.cts.map +1 -1
  56. package/dist/stream/message-metadata-tracker.d.ts +23 -0
  57. package/dist/stream/message-metadata-tracker.d.ts.map +1 -1
  58. package/dist/stream/message-metadata-tracker.js +92 -0
  59. package/dist/stream/message-metadata-tracker.js.map +1 -1
  60. package/dist/stream/message-reconciliation.cjs +2 -2
  61. package/dist/stream/message-reconciliation.cjs.map +1 -1
  62. package/dist/stream/message-reconciliation.js +2 -2
  63. package/dist/stream/message-reconciliation.js.map +1 -1
  64. package/dist/stream/optimistic-input.cjs +86 -0
  65. package/dist/stream/optimistic-input.cjs.map +1 -0
  66. package/dist/stream/optimistic-input.d.ts +1 -0
  67. package/dist/stream/optimistic-input.js +86 -0
  68. package/dist/stream/optimistic-input.js.map +1 -0
  69. package/dist/stream/projections/messages.cjs +24 -14
  70. package/dist/stream/projections/messages.cjs.map +1 -1
  71. package/dist/stream/projections/messages.js +21 -11
  72. package/dist/stream/projections/messages.js.map +1 -1
  73. package/dist/stream/projections/tool-calls.cjs +22 -10
  74. package/dist/stream/projections/tool-calls.cjs.map +1 -1
  75. package/dist/stream/projections/tool-calls.js +22 -10
  76. package/dist/stream/projections/tool-calls.js.map +1 -1
  77. package/dist/stream/projections/values.cjs +2 -2
  78. package/dist/stream/projections/values.cjs.map +1 -1
  79. package/dist/stream/projections/values.js +1 -1
  80. package/dist/stream/projections/values.js.map +1 -1
  81. package/dist/stream/root-message-projection.cjs +130 -3
  82. package/dist/stream/root-message-projection.cjs.map +1 -1
  83. package/dist/stream/root-message-projection.js +130 -3
  84. package/dist/stream/root-message-projection.js.map +1 -1
  85. package/dist/stream/submit-coordinator.cjs +28 -6
  86. package/dist/stream/submit-coordinator.cjs.map +1 -1
  87. package/dist/stream/submit-coordinator.d.cts.map +1 -1
  88. package/dist/stream/submit-coordinator.d.ts +0 -1
  89. package/dist/stream/submit-coordinator.d.ts.map +1 -1
  90. package/dist/stream/submit-coordinator.js +28 -6
  91. package/dist/stream/submit-coordinator.js.map +1 -1
  92. package/dist/stream/tool-calls.cjs +32 -0
  93. package/dist/stream/tool-calls.cjs.map +1 -1
  94. package/dist/stream/tool-calls.js +32 -1
  95. package/dist/stream/tool-calls.js.map +1 -1
  96. package/dist/stream/types.d.cts +43 -0
  97. package/dist/stream/types.d.cts.map +1 -1
  98. package/dist/stream/types.d.ts +43 -0
  99. package/dist/stream/types.d.ts.map +1 -1
  100. package/dist/ui/index.d.cts +1 -1
  101. package/dist/ui/index.d.ts +1 -1
  102. package/dist/ui/messages.cjs +4 -50
  103. package/dist/ui/messages.cjs.map +1 -1
  104. package/dist/ui/messages.d.cts.map +1 -1
  105. package/dist/ui/messages.d.ts.map +1 -1
  106. package/dist/ui/messages.js +3 -48
  107. package/dist/ui/messages.js.map +1 -1
  108. package/package.json +1 -1
@@ -103,6 +103,31 @@ interface UseStreamCommonOptions<StateType extends object, ThreadIdType = string
103
103
  tools?: AnyHeadlessToolImplementation[];
104
104
  /** Observe lifecycle events for registered {@link tools}. */
105
105
  onTool?: OnToolCallback;
106
+ /**
107
+ * Optimistic UI for `submit()`. When enabled (the default), the input
108
+ * passed to `submit()` is reflected in `values` / `messages`
109
+ * immediately — before the server responds — then reconciled against
110
+ * the authoritative server state as it streams in:
111
+ *
112
+ * - Messages in the input are appended right away. Any message
113
+ * without an `id` is assigned a stable client id (sent to the
114
+ * server, which `add_messages` preserves) so the server echo
115
+ * reconciles by id instead of duplicating. Per-message progress
116
+ * is exposed via `useMessageMetadata(stream, id).optimisticStatus`
117
+ * (`"pending"` → `"sent"`, or `"failed"` if the run errors before
118
+ * the message is echoed; failed optimistic messages are kept for
119
+ * retry UIs and dropped on the next `hydrate()`).
120
+ * - Other input keys are shallow-merged into `values` and converge
121
+ * to server truth on the first `values` event (or are rolled back
122
+ * if the run fails before any echo).
123
+ *
124
+ * Set to `false` to dispatch input verbatim with no client-side echo
125
+ * or id minting (server-authoritative only) — useful for non-chat
126
+ * state graphs or deterministic SSR/tests.
127
+ *
128
+ * @default true
129
+ */
130
+ optimistic?: boolean;
106
131
  }
107
132
  /**
108
133
  * Agent-server branch: caller points `useStream` at an assistant on a
@@ -169,6 +194,19 @@ interface RootEventBus {
169
194
  readonly channels: readonly Channel[];
170
195
  /** Subscribe; returns an unsubscribe handle. */
171
196
  subscribe(listener: (event: Event$1) => void): () => void;
197
+ /**
198
+ * Optional fast path for idle/stale threads: seed a scoped projection from
199
+ * checkpoint history instead of opening a replaying `/events` subscription.
200
+ * This produces a snapshot for finished-thread reconnects; active and
201
+ * interrupted threads return `false` so projections subscribe normally.
202
+ * Returns `false` when history cannot satisfy the projection and the caller
203
+ * should fall back to its normal subscription.
204
+ */
205
+ trySeedFromHistory?<T>(params: {
206
+ kind: "messages" | "toolCalls";
207
+ namespace: readonly string[];
208
+ store: StreamStore<T>;
209
+ }): Promise<boolean>;
172
210
  }
173
211
  /**
174
212
  * Always-on root snapshot surfaced by {@link StreamController.rootStore}.
@@ -233,6 +271,11 @@ interface StreamControllerOptions<StateType extends object = Record<string, unkn
233
271
  initialValues?: StateType;
234
272
  /** Key inside `values` that holds the message array. Defaults to `"messages"`. */
235
273
  messagesKey?: string;
274
+ /**
275
+ * Optimistic UI for `submit()`. Defaults to `true`. See
276
+ * {@link UseStreamCommonOptions.optimistic} for the full contract.
277
+ */
278
+ optimistic?: boolean;
236
279
  }
237
280
  interface StreamSubmitOptions<StateType extends object = Record<string, unknown>, ConfigurableType extends object = Record<string, unknown>> {
238
281
  config?: {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.cts","names":[],"sources":["../../src/stream/types.ts"],"mappings":"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"}
1
+ {"version":3,"file":"types.d.cts","names":[],"sources":["../../src/stream/types.ts"],"mappings":"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"}
@@ -103,6 +103,31 @@ interface UseStreamCommonOptions<StateType extends object, ThreadIdType = string
103
103
  tools?: AnyHeadlessToolImplementation[];
104
104
  /** Observe lifecycle events for registered {@link tools}. */
105
105
  onTool?: OnToolCallback;
106
+ /**
107
+ * Optimistic UI for `submit()`. When enabled (the default), the input
108
+ * passed to `submit()` is reflected in `values` / `messages`
109
+ * immediately — before the server responds — then reconciled against
110
+ * the authoritative server state as it streams in:
111
+ *
112
+ * - Messages in the input are appended right away. Any message
113
+ * without an `id` is assigned a stable client id (sent to the
114
+ * server, which `add_messages` preserves) so the server echo
115
+ * reconciles by id instead of duplicating. Per-message progress
116
+ * is exposed via `useMessageMetadata(stream, id).optimisticStatus`
117
+ * (`"pending"` → `"sent"`, or `"failed"` if the run errors before
118
+ * the message is echoed; failed optimistic messages are kept for
119
+ * retry UIs and dropped on the next `hydrate()`).
120
+ * - Other input keys are shallow-merged into `values` and converge
121
+ * to server truth on the first `values` event (or are rolled back
122
+ * if the run fails before any echo).
123
+ *
124
+ * Set to `false` to dispatch input verbatim with no client-side echo
125
+ * or id minting (server-authoritative only) — useful for non-chat
126
+ * state graphs or deterministic SSR/tests.
127
+ *
128
+ * @default true
129
+ */
130
+ optimistic?: boolean;
106
131
  }
107
132
  /**
108
133
  * Agent-server branch: caller points `useStream` at an assistant on a
@@ -169,6 +194,19 @@ interface RootEventBus {
169
194
  readonly channels: readonly Channel[];
170
195
  /** Subscribe; returns an unsubscribe handle. */
171
196
  subscribe(listener: (event: Event$1) => void): () => void;
197
+ /**
198
+ * Optional fast path for idle/stale threads: seed a scoped projection from
199
+ * checkpoint history instead of opening a replaying `/events` subscription.
200
+ * This produces a snapshot for finished-thread reconnects; active and
201
+ * interrupted threads return `false` so projections subscribe normally.
202
+ * Returns `false` when history cannot satisfy the projection and the caller
203
+ * should fall back to its normal subscription.
204
+ */
205
+ trySeedFromHistory?<T>(params: {
206
+ kind: "messages" | "toolCalls";
207
+ namespace: readonly string[];
208
+ store: StreamStore<T>;
209
+ }): Promise<boolean>;
172
210
  }
173
211
  /**
174
212
  * Always-on root snapshot surfaced by {@link StreamController.rootStore}.
@@ -233,6 +271,11 @@ interface StreamControllerOptions<StateType extends object = Record<string, unkn
233
271
  initialValues?: StateType;
234
272
  /** Key inside `values` that holds the message array. Defaults to `"messages"`. */
235
273
  messagesKey?: string;
274
+ /**
275
+ * Optimistic UI for `submit()`. Defaults to `true`. See
276
+ * {@link UseStreamCommonOptions.optimistic} for the full contract.
277
+ */
278
+ optimistic?: boolean;
236
279
  }
237
280
  interface StreamSubmitOptions<StateType extends object = Record<string, unknown>, ConfigurableType extends object = Record<string, unknown>> {
238
281
  config?: {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/stream/types.ts"],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/stream/types.ts"],"mappings":"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"}
@@ -5,9 +5,9 @@ import { BaseStream, StateRecord } from "./stream/base.cjs";
5
5
  import { UseAgentStream, UseAgentStreamOptions } from "./stream/agent.cjs";
6
6
  import { UseDeepAgentStream, UseDeepAgentStreamOptions } from "./stream/deep-agent.cjs";
7
7
  import { InferBag, InferNodeNames, InferNodeReturnTypes, InferStateType, InferSubagentStates, InferToolCalls, ResolveStreamInterface, ResolveStreamOptions } from "./stream/index.cjs";
8
- import { HistoryWithBaseMessages, MessageTupleManager, ensureHistoryMessageInstances, ensureMessageInstances, toMessageClass, toMessageDict } from "./messages.cjs";
9
8
  import { StreamError } from "./errors.cjs";
10
9
  import { SubagentManager, calculateDepthFromNamespace, extractParentIdFromNamespace, extractToolCallIdFromNamespace, isSubagentNamespace } from "./subagents.cjs";
10
+ import { HistoryWithBaseMessages, MessageTupleManager, ensureHistoryMessageInstances, ensureMessageInstances, toMessageClass, toMessageDict } from "./messages.cjs";
11
11
  import { ClassSubagentStreamInterface, ClassToolCallWithResult, WithClassMessages } from "./class-messages.cjs";
12
12
  import { EventStreamEvent, StreamManager } from "./manager.cjs";
13
13
  import { extractInterrupts, normalizeInterruptForClient, normalizeInterruptsList, userFacingInterruptsFromThreadTasks, userFacingInterruptsFromValuesArray } from "./interrupts.cjs";
@@ -5,9 +5,9 @@ import { BaseStream, StateRecord } from "./stream/base.js";
5
5
  import { UseAgentStream, UseAgentStreamOptions } from "./stream/agent.js";
6
6
  import { UseDeepAgentStream, UseDeepAgentStreamOptions } from "./stream/deep-agent.js";
7
7
  import { InferBag, InferNodeNames, InferNodeReturnTypes, InferStateType, InferSubagentStates, InferToolCalls, ResolveStreamInterface, ResolveStreamOptions } from "./stream/index.js";
8
- import { HistoryWithBaseMessages, MessageTupleManager, ensureHistoryMessageInstances, ensureMessageInstances, toMessageClass, toMessageDict } from "./messages.js";
9
8
  import { StreamError } from "./errors.js";
10
9
  import { SubagentManager, calculateDepthFromNamespace, extractParentIdFromNamespace, extractToolCallIdFromNamespace, isSubagentNamespace } from "./subagents.js";
10
+ import { HistoryWithBaseMessages, MessageTupleManager, ensureHistoryMessageInstances, ensureMessageInstances, toMessageClass, toMessageDict } from "./messages.js";
11
11
  import { ClassSubagentStreamInterface, ClassToolCallWithResult, WithClassMessages } from "./class-messages.js";
12
12
  import { EventStreamEvent, StreamManager } from "./manager.js";
13
13
  import { extractInterrupts, normalizeInterruptForClient, normalizeInterruptsList, userFacingInterruptsFromThreadTasks, userFacingInterruptsFromValuesArray } from "./interrupts.js";
@@ -1,4 +1,5 @@
1
1
  require("../_virtual/_rolldown/runtime.cjs");
2
+ const require_message_coercion = require("../stream/message-coercion.cjs");
2
3
  let _langchain_core_messages = require("@langchain/core/messages");
3
4
  //#region src/ui/messages.ts
4
5
  function tryConvertToChunk(message) {
@@ -9,61 +10,15 @@ function tryConvertToChunk(message) {
9
10
  return null;
10
11
  }
11
12
  }
12
- function tryCoerceMessageLikeToMessage(message) {
13
- if (message.type === "human" || message.type === "user") return new _langchain_core_messages.HumanMessage(message);
14
- if (message.type === "ai" || message.type === "assistant") return new _langchain_core_messages.AIMessage(normalizeAIMessageToolCalls(message));
15
- if (message.type === "system") return new _langchain_core_messages.SystemMessage(message);
16
- if (message.type === "tool" && "tool_call_id" in message) return new _langchain_core_messages.ToolMessage({
17
- ...message,
18
- tool_call_id: message.tool_call_id
19
- });
20
- if (message.type === "remove" && message.id != null) return new _langchain_core_messages.RemoveMessage({
21
- ...message,
22
- id: message.id
23
- });
24
- return (0, _langchain_core_messages.coerceMessageLikeToMessage)(message);
25
- }
26
13
  function tryCoerceMessageLikeToChunk(message) {
27
14
  if (message.type === "human" || message.type === "user") return new _langchain_core_messages.HumanMessageChunk(message);
28
- if (message.type === "ai" || message.type === "assistant") return new _langchain_core_messages.AIMessageChunk(normalizeAIMessageToolCalls(message));
15
+ if (message.type === "ai" || message.type === "assistant") return new _langchain_core_messages.AIMessageChunk(require_message_coercion.normalizeAIMessageToolCalls(message));
29
16
  if (message.type === "system") return new _langchain_core_messages.SystemMessageChunk(message);
30
17
  if (message.type === "tool" && "tool_call_id" in message) return new _langchain_core_messages.ToolMessageChunk({
31
18
  ...message,
32
19
  tool_call_id: message.tool_call_id
33
20
  });
34
- return tryCoerceMessageLikeToMessage(message);
35
- }
36
- function normalizeAIMessageToolCalls(message) {
37
- const record = message;
38
- if (Array.isArray(record.tool_calls) && record.tool_calls.length > 0) return message;
39
- const toolCalls = extractToolCallsFromContent(record.content);
40
- if (toolCalls.length === 0) return message;
41
- return {
42
- ...message,
43
- tool_calls: toolCalls
44
- };
45
- }
46
- function extractToolCallsFromContent(content) {
47
- if (!Array.isArray(content)) return [];
48
- return content.flatMap((block) => {
49
- if (block == null || typeof block !== "object") return [];
50
- const record = block;
51
- if (record.type !== "tool_call" && record.type !== "tool_use") return [];
52
- return [{
53
- id: record.id ?? "",
54
- name: record.name ?? "",
55
- args: normalizeToolCallArgs(record.args ?? record.input),
56
- type: "tool_call"
57
- }];
58
- });
59
- }
60
- function normalizeToolCallArgs(value) {
61
- if (value != null && typeof value === "object" && !Array.isArray(value)) return value;
62
- if (typeof value === "string" && value.length > 0) try {
63
- const parsed = JSON.parse(value);
64
- if (parsed != null && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
65
- } catch {}
66
- return {};
21
+ return require_message_coercion.tryCoerceMessageLikeToMessage(message);
67
22
  }
68
23
  var MessageTupleManager = class {
69
24
  chunks = {};
@@ -118,7 +73,7 @@ const toMessageClass = (chunk) => chunk;
118
73
  function ensureMessageInstances(messages) {
119
74
  return messages.map((msg) => {
120
75
  if (typeof msg.getType === "function") return msg;
121
- return tryCoerceMessageLikeToMessage(msg);
76
+ return require_message_coercion.tryCoerceMessageLikeToMessage(msg);
122
77
  });
123
78
  }
124
79
  /**
@@ -146,6 +101,5 @@ exports.ensureHistoryMessageInstances = ensureHistoryMessageInstances;
146
101
  exports.ensureMessageInstances = ensureMessageInstances;
147
102
  exports.toMessageClass = toMessageClass;
148
103
  exports.toMessageDict = toMessageDict;
149
- exports.tryCoerceMessageLikeToMessage = tryCoerceMessageLikeToMessage;
150
104
 
151
105
  //# sourceMappingURL=messages.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"messages.cjs","names":["BaseMessageChunk","HumanMessage","AIMessage","SystemMessage","ToolMessage","RemoveMessage","HumanMessageChunk","AIMessageChunk","SystemMessageChunk","ToolMessageChunk"],"sources":["../../src/ui/messages.ts"],"sourcesContent":["import {\n type BaseMessage,\n BaseMessageChunk,\n RemoveMessage,\n convertToChunk,\n coerceMessageLikeToMessage,\n HumanMessageChunk,\n HumanMessage,\n SystemMessageChunk,\n SystemMessage,\n AIMessageChunk,\n AIMessage,\n ToolMessageChunk,\n ToolMessage,\n} from \"@langchain/core/messages\";\n\nimport type { Message } from \"../types.messages.js\";\nimport type { ThreadState } from \"../schema.js\";\n\n/**\n * Replaces the `messages` property in a state type with `BaseMessage[]`.\n * Used by framework SDKs to reflect that `ensureHistoryMessageInstances`\n * converts plain message objects to class instances at runtime.\n */\nexport type StateWithBaseMessages<S> = S extends { messages: unknown }\n ? Omit<S, \"messages\"> & { messages: BaseMessage[] }\n : S;\n\n/**\n * Maps a `ThreadState<StateType>[]` so that the `messages` field inside\n * `values` is typed as `BaseMessage[]` instead of `Message[]`.\n */\nexport type HistoryWithBaseMessages<T> = T extends ThreadState<infer S>[]\n ? ThreadState<StateWithBaseMessages<S>>[]\n : T;\n\nexport function tryConvertToChunk(\n message: BaseMessage | BaseMessageChunk\n): BaseMessageChunk | null {\n try {\n if (BaseMessageChunk.isInstance(message)) return message;\n return convertToChunk(message);\n } catch {\n return null;\n }\n}\n\nexport function tryCoerceMessageLikeToMessage(\n message: Omit<Message, \"type\"> & { type: string }\n): BaseMessage | BaseMessageChunk {\n if (message.type === \"human\" || message.type === \"user\") {\n return new HumanMessage(message);\n }\n\n if (message.type === \"ai\" || message.type === \"assistant\") {\n return new AIMessage(normalizeAIMessageToolCalls(message));\n }\n\n if (message.type === \"system\") {\n return new SystemMessage(message);\n }\n\n if (message.type === \"tool\" && \"tool_call_id\" in message) {\n return new ToolMessage({\n ...message,\n tool_call_id: message.tool_call_id as string,\n });\n }\n\n if (message.type === \"remove\" && message.id != null) {\n return new RemoveMessage({ ...message, id: message.id });\n }\n\n return coerceMessageLikeToMessage(message);\n}\n\nfunction tryCoerceMessageLikeToChunk(\n message: Omit<Message, \"type\"> & { type: string }\n): BaseMessage | BaseMessageChunk {\n if (message.type === \"human\" || message.type === \"user\") {\n return new HumanMessageChunk(message);\n }\n\n if (message.type === \"ai\" || message.type === \"assistant\") {\n return new AIMessageChunk(normalizeAIMessageToolCalls(message));\n }\n\n if (message.type === \"system\") {\n return new SystemMessageChunk(message);\n }\n\n if (message.type === \"tool\" && \"tool_call_id\" in message) {\n return new ToolMessageChunk({\n ...message,\n tool_call_id: message.tool_call_id as string,\n });\n }\n\n return tryCoerceMessageLikeToMessage(message);\n}\n\ntype ToolCallLike = {\n id?: string;\n name?: string;\n args?: unknown;\n input?: unknown;\n};\n\nfunction normalizeAIMessageToolCalls<\n T extends Omit<Message, \"type\"> & { type: string },\n>(message: T): T {\n const record = message as T & {\n content?: unknown;\n tool_calls?: unknown;\n };\n if (Array.isArray(record.tool_calls) && record.tool_calls.length > 0) {\n return message;\n }\n\n const toolCalls = extractToolCallsFromContent(record.content);\n if (toolCalls.length === 0) return message;\n return {\n ...message,\n tool_calls: toolCalls,\n };\n}\n\nfunction extractToolCallsFromContent(content: unknown) {\n if (!Array.isArray(content)) return [];\n return content.flatMap(\n (\n block\n ): Array<{\n id: string;\n name: string;\n args: Record<string, unknown>;\n type: \"tool_call\";\n }> => {\n if (block == null || typeof block !== \"object\") return [];\n const record = block as ToolCallLike & { type?: unknown };\n if (record.type !== \"tool_call\" && record.type !== \"tool_use\") return [];\n return [\n {\n id: record.id ?? \"\",\n name: record.name ?? \"\",\n args: normalizeToolCallArgs(record.args ?? record.input),\n type: \"tool_call\",\n },\n ];\n }\n );\n}\n\nfunction normalizeToolCallArgs(value: unknown): Record<string, unknown> {\n if (value != null && typeof value === \"object\" && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n if (typeof value === \"string\" && value.length > 0) {\n try {\n const parsed = JSON.parse(value);\n if (\n parsed != null &&\n typeof parsed === \"object\" &&\n !Array.isArray(parsed)\n ) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n // Streaming input fragments are expected to be invalid until finalized.\n }\n }\n return {};\n}\n\nexport class MessageTupleManager {\n chunks: Record<\n string,\n {\n chunk?: BaseMessageChunk | BaseMessage;\n metadata?: Record<string, unknown>;\n index?: number;\n }\n > = {};\n\n constructor() {\n this.chunks = {};\n }\n\n add(\n serialized: Message,\n metadata: Record<string, unknown> | undefined\n ): string | null {\n // TODO: this is sometimes sent from the API\n // figure out how to prevent this or move this to LC.js\n if (serialized.type.endsWith(\"MessageChunk\")) {\n // eslint-disable-next-line no-param-reassign\n serialized.type = serialized.type\n .slice(0, -\"MessageChunk\".length)\n .toLowerCase() as Message[\"type\"];\n }\n\n const message = tryCoerceMessageLikeToChunk(serialized);\n const chunk = tryConvertToChunk(message);\n\n const { id } = chunk ?? message;\n if (!id) {\n console.warn(\n \"No message ID found for chunk, ignoring in state\",\n serialized\n );\n return null;\n }\n\n this.chunks[id] ??= {};\n this.chunks[id].metadata = metadata ?? this.chunks[id].metadata;\n if (chunk) {\n const prev = this.chunks[id].chunk;\n this.chunks[id].chunk =\n (BaseMessageChunk.isInstance(prev) ? prev : null)?.concat(chunk) ??\n chunk;\n } else {\n this.chunks[id].chunk = message;\n }\n\n return id;\n }\n\n clear() {\n this.chunks = {};\n }\n\n get(id: string | null | undefined, defaultIndex?: number) {\n if (id == null) return null;\n if (this.chunks[id] == null) return null;\n if (defaultIndex != null) this.chunks[id].index ??= defaultIndex;\n return this.chunks[id];\n }\n}\n\nexport const toMessageDict = (chunk: BaseMessage): Message => {\n const { type, data } = chunk.toDict();\n return { ...data, type } as Message;\n};\n\n/**\n * Identity converter that keeps @langchain/core class instances.\n * Used by framework SDKs to expose BaseMessage instances instead of plain dicts.\n */\nexport const toMessageClass = (chunk: BaseMessage): BaseMessage => chunk;\n\n/**\n * Ensures all messages in an array are BaseMessage class instances.\n * Messages that are already class instances pass through unchanged.\n * Plain message objects (e.g. from API values/history) are converted\n * via {@link tryCoerceMessageLikeToMessage}.\n */\nexport function ensureMessageInstances(\n messages: (Message | BaseMessage)[]\n): (BaseMessage | BaseMessageChunk)[] {\n return messages.map((msg) => {\n if (typeof (msg as BaseMessage).getType === \"function\") {\n return msg as BaseMessage;\n }\n return tryCoerceMessageLikeToMessage(\n msg as Omit<Message, \"type\"> & { type: string }\n );\n });\n}\n\n/**\n * Converts plain message objects within each history state's values\n * to proper BaseMessage class instances. Returns a new array with\n * shallow-copied states whose messages have been coerced.\n */\nexport function ensureHistoryMessageInstances<\n StateType extends Record<string, unknown>,\n>(\n history: ThreadState<StateType>[],\n messagesKey: string = \"messages\"\n): ThreadState<StateType>[] {\n return history.map((state) => {\n if (state.values == null) return state;\n const messages = state.values[messagesKey];\n if (!Array.isArray(messages)) return state;\n return {\n ...state,\n values: {\n ...state.values,\n [messagesKey]: ensureMessageInstances(messages),\n },\n };\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"messages.cjs","names":["BaseMessageChunk","HumanMessageChunk","AIMessageChunk","normalizeAIMessageToolCalls","SystemMessageChunk","ToolMessageChunk","tryCoerceMessageLikeToMessage"],"sources":["../../src/ui/messages.ts"],"sourcesContent":["import {\n type BaseMessage,\n BaseMessageChunk,\n convertToChunk,\n HumanMessageChunk,\n SystemMessageChunk,\n AIMessageChunk,\n ToolMessageChunk,\n} from \"@langchain/core/messages\";\n\nimport type { Message } from \"../types.messages.js\";\nimport type { ThreadState } from \"../schema.js\";\nimport {\n normalizeAIMessageToolCalls,\n tryCoerceMessageLikeToMessage,\n} from \"../stream/message-coercion.js\";\n\nexport { tryCoerceMessageLikeToMessage };\n\n/**\n * Replaces the `messages` property in a state type with `BaseMessage[]`.\n * Used by framework SDKs to reflect that `ensureHistoryMessageInstances`\n * converts plain message objects to class instances at runtime.\n */\nexport type StateWithBaseMessages<S> = S extends { messages: unknown }\n ? Omit<S, \"messages\"> & { messages: BaseMessage[] }\n : S;\n\n/**\n * Maps a `ThreadState<StateType>[]` so that the `messages` field inside\n * `values` is typed as `BaseMessage[]` instead of `Message[]`.\n */\nexport type HistoryWithBaseMessages<T> = T extends ThreadState<infer S>[]\n ? ThreadState<StateWithBaseMessages<S>>[]\n : T;\n\nexport function tryConvertToChunk(\n message: BaseMessage | BaseMessageChunk\n): BaseMessageChunk | null {\n try {\n if (BaseMessageChunk.isInstance(message)) return message;\n return convertToChunk(message);\n } catch {\n return null;\n }\n}\n\nfunction tryCoerceMessageLikeToChunk(\n message: Omit<Message, \"type\"> & { type: string }\n): BaseMessage | BaseMessageChunk {\n if (message.type === \"human\" || message.type === \"user\") {\n return new HumanMessageChunk(message);\n }\n\n if (message.type === \"ai\" || message.type === \"assistant\") {\n return new AIMessageChunk(normalizeAIMessageToolCalls(message));\n }\n\n if (message.type === \"system\") {\n return new SystemMessageChunk(message);\n }\n\n if (message.type === \"tool\" && \"tool_call_id\" in message) {\n return new ToolMessageChunk({\n ...message,\n tool_call_id: message.tool_call_id as string,\n });\n }\n\n return tryCoerceMessageLikeToMessage(message);\n}\n\nexport class MessageTupleManager {\n chunks: Record<\n string,\n {\n chunk?: BaseMessageChunk | BaseMessage;\n metadata?: Record<string, unknown>;\n index?: number;\n }\n > = {};\n\n constructor() {\n this.chunks = {};\n }\n\n add(\n serialized: Message,\n metadata: Record<string, unknown> | undefined\n ): string | null {\n // TODO: this is sometimes sent from the API\n // figure out how to prevent this or move this to LC.js\n if (serialized.type.endsWith(\"MessageChunk\")) {\n // eslint-disable-next-line no-param-reassign\n serialized.type = serialized.type\n .slice(0, -\"MessageChunk\".length)\n .toLowerCase() as Message[\"type\"];\n }\n\n const message = tryCoerceMessageLikeToChunk(serialized);\n const chunk = tryConvertToChunk(message);\n\n const { id } = chunk ?? message;\n if (!id) {\n console.warn(\n \"No message ID found for chunk, ignoring in state\",\n serialized\n );\n return null;\n }\n\n this.chunks[id] ??= {};\n this.chunks[id].metadata = metadata ?? this.chunks[id].metadata;\n if (chunk) {\n const prev = this.chunks[id].chunk;\n this.chunks[id].chunk =\n (BaseMessageChunk.isInstance(prev) ? prev : null)?.concat(chunk) ??\n chunk;\n } else {\n this.chunks[id].chunk = message;\n }\n\n return id;\n }\n\n clear() {\n this.chunks = {};\n }\n\n get(id: string | null | undefined, defaultIndex?: number) {\n if (id == null) return null;\n if (this.chunks[id] == null) return null;\n if (defaultIndex != null) this.chunks[id].index ??= defaultIndex;\n return this.chunks[id];\n }\n}\n\nexport const toMessageDict = (chunk: BaseMessage): Message => {\n const { type, data } = chunk.toDict();\n return { ...data, type } as Message;\n};\n\n/**\n * Identity converter that keeps @langchain/core class instances.\n * Used by framework SDKs to expose BaseMessage instances instead of plain dicts.\n */\nexport const toMessageClass = (chunk: BaseMessage): BaseMessage => chunk;\n\n/**\n * Ensures all messages in an array are BaseMessage class instances.\n * Messages that are already class instances pass through unchanged.\n * Plain message objects (e.g. from API values/history) are converted\n * via {@link tryCoerceMessageLikeToMessage}.\n */\nexport function ensureMessageInstances(\n messages: (Message | BaseMessage)[]\n): (BaseMessage | BaseMessageChunk)[] {\n return messages.map((msg) => {\n if (typeof (msg as BaseMessage).getType === \"function\") {\n return msg as BaseMessage;\n }\n return tryCoerceMessageLikeToMessage(\n msg as Omit<Message, \"type\"> & { type: string }\n );\n });\n}\n\n/**\n * Converts plain message objects within each history state's values\n * to proper BaseMessage class instances. Returns a new array with\n * shallow-copied states whose messages have been coerced.\n */\nexport function ensureHistoryMessageInstances<\n StateType extends Record<string, unknown>,\n>(\n history: ThreadState<StateType>[],\n messagesKey: string = \"messages\"\n): ThreadState<StateType>[] {\n return history.map((state) => {\n if (state.values == null) return state;\n const messages = state.values[messagesKey];\n if (!Array.isArray(messages)) return state;\n return {\n ...state,\n values: {\n ...state.values,\n [messagesKey]: ensureMessageInstances(messages),\n },\n };\n });\n}\n"],"mappings":";;;;AAoCA,SAAgB,kBACd,SACyB;AACzB,KAAI;AACF,MAAIA,yBAAAA,iBAAiB,WAAW,QAAQ,CAAE,QAAO;AACjD,UAAA,GAAA,yBAAA,gBAAsB,QAAQ;SACxB;AACN,SAAO;;;AAIX,SAAS,4BACP,SACgC;AAChC,KAAI,QAAQ,SAAS,WAAW,QAAQ,SAAS,OAC/C,QAAO,IAAIC,yBAAAA,kBAAkB,QAAQ;AAGvC,KAAI,QAAQ,SAAS,QAAQ,QAAQ,SAAS,YAC5C,QAAO,IAAIC,yBAAAA,eAAeC,yBAAAA,4BAA4B,QAAQ,CAAC;AAGjE,KAAI,QAAQ,SAAS,SACnB,QAAO,IAAIC,yBAAAA,mBAAmB,QAAQ;AAGxC,KAAI,QAAQ,SAAS,UAAU,kBAAkB,QAC/C,QAAO,IAAIC,yBAAAA,iBAAiB;EAC1B,GAAG;EACH,cAAc,QAAQ;EACvB,CAAC;AAGJ,QAAOC,yBAAAA,8BAA8B,QAAQ;;AAG/C,IAAa,sBAAb,MAAiC;CAC/B,SAOI,EAAE;CAEN,cAAc;AACZ,OAAK,SAAS,EAAE;;CAGlB,IACE,YACA,UACe;AAGf,MAAI,WAAW,KAAK,SAAS,eAAe,CAE1C,YAAW,OAAO,WAAW,KAC1B,MAAM,GAAG,IAAuB,CAChC,aAAa;EAGlB,MAAM,UAAU,4BAA4B,WAAW;EACvD,MAAM,QAAQ,kBAAkB,QAAQ;EAExC,MAAM,EAAE,OAAO,SAAS;AACxB,MAAI,CAAC,IAAI;AACP,WAAQ,KACN,oDACA,WACD;AACD,UAAO;;AAGT,OAAK,OAAO,QAAQ,EAAE;AACtB,OAAK,OAAO,IAAI,WAAW,YAAY,KAAK,OAAO,IAAI;AACvD,MAAI,OAAO;GACT,MAAM,OAAO,KAAK,OAAO,IAAI;AAC7B,QAAK,OAAO,IAAI,SACbN,yBAAAA,iBAAiB,WAAW,KAAK,GAAG,OAAO,OAAO,OAAO,MAAM,IAChE;QAEF,MAAK,OAAO,IAAI,QAAQ;AAG1B,SAAO;;CAGT,QAAQ;AACN,OAAK,SAAS,EAAE;;CAGlB,IAAI,IAA+B,cAAuB;AACxD,MAAI,MAAM,KAAM,QAAO;AACvB,MAAI,KAAK,OAAO,OAAO,KAAM,QAAO;AACpC,MAAI,gBAAgB,KAAM,MAAK,OAAO,IAAI,UAAU;AACpD,SAAO,KAAK,OAAO;;;AAIvB,MAAa,iBAAiB,UAAgC;CAC5D,MAAM,EAAE,MAAM,SAAS,MAAM,QAAQ;AACrC,QAAO;EAAE,GAAG;EAAM;EAAM;;;;;;AAO1B,MAAa,kBAAkB,UAAoC;;;;;;;AAQnE,SAAgB,uBACd,UACoC;AACpC,QAAO,SAAS,KAAK,QAAQ;AAC3B,MAAI,OAAQ,IAAoB,YAAY,WAC1C,QAAO;AAET,SAAOM,yBAAAA,8BACL,IACD;GACD;;;;;;;AAQJ,SAAgB,8BAGd,SACA,cAAsB,YACI;AAC1B,QAAO,QAAQ,KAAK,UAAU;AAC5B,MAAI,MAAM,UAAU,KAAM,QAAO;EACjC,MAAM,WAAW,MAAM,OAAO;AAC9B,MAAI,CAAC,MAAM,QAAQ,SAAS,CAAE,QAAO;AACrC,SAAO;GACL,GAAG;GACH,QAAQ;IACN,GAAG,MAAM;KACR,cAAc,uBAAuB,SAAS;IAChD;GACF;GACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.cts","names":[],"sources":["../../src/ui/messages.ts"],"mappings":";;;;;;;;;AAwBA;;KAAY,qBAAA,MAA2B,CAAA;EAAY,QAAA;AAAA,IAC/C,IAAA,CAAK,CAAA;EAAmB,QAAA,EAAU,WAAA;AAAA,IAClC,CAAA;;;;;KAMQ,uBAAA,MAA6B,CAAA,SAAU,WAAA,cAC/C,WAAA,CAAY,qBAAA,CAAsB,CAAA,OAClC,CAAA;AAAA,cA4IS,mBAAA;EACX,MAAA,EAAQ,MAAA;IAGJ,KAAA,GAAQ,gBAAA,GAAmB,WAAA;IAC3B,QAAA,GAAW,MAAA;IACX,KAAA;EAAA;EAIJ,WAAA,CAAA;EAIA,GAAA,CACE,UAAA,EAAY,OAAA,EACZ,QAAA,EAAU,MAAA;EAqCZ,KAAA,CAAA;EAIA,GAAA,CAAI,EAAA,6BAA+B,YAAA;mEAzCjB,yBAAA,CAAA,cAAA;;;;;cAiDP,aAAA,GAAa,KAAA,EAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAGzB,yBAAA,CAHyB,cAAA,GAAA,yBAAA,CAAA,WAAA,MAAA,OAAA;;;;;cASb,cAAA,GAAc,KAAA,EAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAA6C,yBAAA,CAA7C,cAAA,GAAA,yBAAA,CAAA,WAAA,MAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAAA,yBAAA,CAAA,cAAA,GAAA,yBAAA,CAAA,WAAA;;;;;AA1E3B;;iBAkFgB,sBAAA,CACd,QAAA,GAAW,OAAA,GAAU,WAAA,OACnB,WAAA,GAAc,gBAAA;;;;;;iBAgBF,6BAAA,mBACI,MAAA,kBAAA,CAElB,OAAA,EAAS,WAAA,CAAY,SAAA,KACrB,WAAA,YACC,WAAA,CAAY,SAAA"}
1
+ {"version":3,"file":"messages.d.cts","names":[],"sources":["../../src/ui/messages.ts"],"mappings":";;;;;;;AAwBA;;;;KAAY,qBAAA,MAA2B,CAAA;EAAY,QAAA;AAAA,IAC/C,IAAA,CAAK,CAAA;EAAmB,QAAA,EAAU,WAAA;AAAA,IAClC,CAAA;;;;;KAMQ,uBAAA,MAA6B,CAAA,SAAU,WAAA,cAC/C,WAAA,CAAY,qBAAA,CAAsB,CAAA,OAClC,CAAA;AAAA,cAsCS,mBAAA;EACX,MAAA,EAAQ,MAAA;IAGJ,KAAA,GAAQ,gBAAA,GAAmB,WAAA;IAC3B,QAAA,GAAW,MAAA;IACX,KAAA;EAAA;EAIJ,WAAA,CAAA;EAIA,GAAA,CACE,UAAA,EAAY,OAAA,EACZ,QAAA,EAAU,MAAA;EAqCZ,KAAA,CAAA;EAIA,GAAA,CAAI,EAAA,6BAA+B,YAAA;mEAzCjB,yBAAA,CAAA,cAAA;;;;;cAiDP,aAAA,GAAa,KAAA,EAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAGzB,yBAAA,CAHyB,cAAA,GAAA,yBAAA,CAAA,WAAA,MAAA,OAAA;;;;;cASb,cAAA,GAAc,KAAA,EAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAA6C,yBAAA,CAA7C,cAAA,GAAA,yBAAA,CAAA,WAAA,MAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAAA,yBAAA,CAAA,cAAA,GAAA,yBAAA,CAAA,WAAA;;;;;;AA1E3B;iBAkFgB,sBAAA,CACd,QAAA,GAAW,OAAA,GAAU,WAAA,OACnB,WAAA,GAAc,gBAAA;;;;;;iBAgBF,6BAAA,mBACI,MAAA,kBAAA,CAElB,OAAA,EAAS,WAAA,CAAY,SAAA,KACrB,WAAA,YACC,WAAA,CAAY,SAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","names":[],"sources":["../../src/ui/messages.ts"],"mappings":";;;;;;;;;AAwBA;;KAAY,qBAAA,MAA2B,CAAA;EAAY,QAAA;AAAA,IAC/C,IAAA,CAAK,CAAA;EAAmB,QAAA,EAAU,WAAA;AAAA,IAClC,CAAA;;;;;KAMQ,uBAAA,MAA6B,CAAA,SAAU,WAAA,cAC/C,WAAA,CAAY,qBAAA,CAAsB,CAAA,OAClC,CAAA;AAAA,cA4IS,mBAAA;EACX,MAAA,EAAQ,MAAA;IAGJ,KAAA,GAAQ,gBAAA,GAAmB,WAAA;IAC3B,QAAA,GAAW,MAAA;IACX,KAAA;EAAA;EAIJ,WAAA,CAAA;EAIA,GAAA,CACE,UAAA,EAAY,OAAA,EACZ,QAAA,EAAU,MAAA;EAqCZ,KAAA,CAAA;EAIA,GAAA,CAAI,EAAA,6BAA+B,YAAA;mEAzCjB,yBAAA,CAAA,cAAA;;;;;cAiDP,aAAA,GAAa,KAAA,EAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAGzB,yBAAA,CAHyB,cAAA,GAAA,yBAAA,CAAA,WAAA,MAAA,OAAA;;;;;cASb,cAAA,GAAc,KAAA,EAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAA6C,yBAAA,CAA7C,cAAA,GAAA,yBAAA,CAAA,WAAA,MAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAAA,yBAAA,CAAA,cAAA,GAAA,yBAAA,CAAA,WAAA;;;;;AA1E3B;;iBAkFgB,sBAAA,CACd,QAAA,GAAW,OAAA,GAAU,WAAA,OACnB,WAAA,GAAc,gBAAA;;;;;;iBAgBF,6BAAA,mBACI,MAAA,kBAAA,CAElB,OAAA,EAAS,WAAA,CAAY,SAAA,KACrB,WAAA,YACC,WAAA,CAAY,SAAA"}
1
+ {"version":3,"file":"messages.d.ts","names":[],"sources":["../../src/ui/messages.ts"],"mappings":";;;;;;;;AAwBA;;;KAAY,qBAAA,MAA2B,CAAA;EAAY,QAAA;AAAA,IAC/C,IAAA,CAAK,CAAA;EAAmB,QAAA,EAAU,WAAA;AAAA,IAClC,CAAA;;;;;KAMQ,uBAAA,MAA6B,CAAA,SAAU,WAAA,cAC/C,WAAA,CAAY,qBAAA,CAAsB,CAAA,OAClC,CAAA;AAAA,cAsCS,mBAAA;EACX,MAAA,EAAQ,MAAA;IAGJ,KAAA,GAAQ,gBAAA,GAAmB,WAAA;IAC3B,QAAA,GAAW,MAAA;IACX,KAAA;EAAA;EAIJ,WAAA,CAAA;EAIA,GAAA,CACE,UAAA,EAAY,OAAA,EACZ,QAAA,EAAU,MAAA;EAqCZ,KAAA,CAAA;EAIA,GAAA,CAAI,EAAA,6BAA+B,YAAA;mEAzCjB,yBAAA,CAAA,cAAA;;;;;cAiDP,aAAA,GAAa,KAAA,EAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAGzB,yBAAA,CAHyB,cAAA,GAAA,yBAAA,CAAA,WAAA,MAAA,OAAA;;;;;cASb,cAAA,GAAc,KAAA,EAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAA6C,yBAAA,CAA7C,cAAA,GAAA,yBAAA,CAAA,WAAA,MAAA,WAAA,CAAA,yBAAA,CAAA,gBAAA,CAAA,yBAAA,CAAA,cAAA,GAAA,yBAAA,CAAA,WAAA;;;;;;;iBAQX,sBAAA,CACd,QAAA,GAAW,OAAA,GAAU,WAAA,OACnB,WAAA,GAAc,gBAAA;;;;;;iBAgBF,6BAAA,mBACI,MAAA,kBAAA,CAElB,OAAA,EAAS,WAAA,CAAY,SAAA,KACrB,WAAA,YACC,WAAA,CAAY,SAAA"}
@@ -1,4 +1,5 @@
1
- import { AIMessage, AIMessageChunk, BaseMessageChunk, HumanMessage, HumanMessageChunk, RemoveMessage, SystemMessage, SystemMessageChunk, ToolMessage, ToolMessageChunk, coerceMessageLikeToMessage, convertToChunk } from "@langchain/core/messages";
1
+ import { normalizeAIMessageToolCalls, tryCoerceMessageLikeToMessage } from "../stream/message-coercion.js";
2
+ import { AIMessageChunk, BaseMessageChunk, HumanMessageChunk, SystemMessageChunk, ToolMessageChunk, convertToChunk } from "@langchain/core/messages";
2
3
  //#region src/ui/messages.ts
3
4
  function tryConvertToChunk(message) {
4
5
  try {
@@ -8,20 +9,6 @@ function tryConvertToChunk(message) {
8
9
  return null;
9
10
  }
10
11
  }
11
- function tryCoerceMessageLikeToMessage(message) {
12
- if (message.type === "human" || message.type === "user") return new HumanMessage(message);
13
- if (message.type === "ai" || message.type === "assistant") return new AIMessage(normalizeAIMessageToolCalls(message));
14
- if (message.type === "system") return new SystemMessage(message);
15
- if (message.type === "tool" && "tool_call_id" in message) return new ToolMessage({
16
- ...message,
17
- tool_call_id: message.tool_call_id
18
- });
19
- if (message.type === "remove" && message.id != null) return new RemoveMessage({
20
- ...message,
21
- id: message.id
22
- });
23
- return coerceMessageLikeToMessage(message);
24
- }
25
12
  function tryCoerceMessageLikeToChunk(message) {
26
13
  if (message.type === "human" || message.type === "user") return new HumanMessageChunk(message);
27
14
  if (message.type === "ai" || message.type === "assistant") return new AIMessageChunk(normalizeAIMessageToolCalls(message));
@@ -32,38 +19,6 @@ function tryCoerceMessageLikeToChunk(message) {
32
19
  });
33
20
  return tryCoerceMessageLikeToMessage(message);
34
21
  }
35
- function normalizeAIMessageToolCalls(message) {
36
- const record = message;
37
- if (Array.isArray(record.tool_calls) && record.tool_calls.length > 0) return message;
38
- const toolCalls = extractToolCallsFromContent(record.content);
39
- if (toolCalls.length === 0) return message;
40
- return {
41
- ...message,
42
- tool_calls: toolCalls
43
- };
44
- }
45
- function extractToolCallsFromContent(content) {
46
- if (!Array.isArray(content)) return [];
47
- return content.flatMap((block) => {
48
- if (block == null || typeof block !== "object") return [];
49
- const record = block;
50
- if (record.type !== "tool_call" && record.type !== "tool_use") return [];
51
- return [{
52
- id: record.id ?? "",
53
- name: record.name ?? "",
54
- args: normalizeToolCallArgs(record.args ?? record.input),
55
- type: "tool_call"
56
- }];
57
- });
58
- }
59
- function normalizeToolCallArgs(value) {
60
- if (value != null && typeof value === "object" && !Array.isArray(value)) return value;
61
- if (typeof value === "string" && value.length > 0) try {
62
- const parsed = JSON.parse(value);
63
- if (parsed != null && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
64
- } catch {}
65
- return {};
66
- }
67
22
  var MessageTupleManager = class {
68
23
  chunks = {};
69
24
  constructor() {
@@ -140,6 +95,6 @@ function ensureHistoryMessageInstances(history, messagesKey = "messages") {
140
95
  });
141
96
  }
142
97
  //#endregion
143
- export { MessageTupleManager, ensureHistoryMessageInstances, ensureMessageInstances, toMessageClass, toMessageDict, tryCoerceMessageLikeToMessage };
98
+ export { MessageTupleManager, ensureHistoryMessageInstances, ensureMessageInstances, toMessageClass, toMessageDict };
144
99
 
145
100
  //# sourceMappingURL=messages.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","names":[],"sources":["../../src/ui/messages.ts"],"sourcesContent":["import {\n type BaseMessage,\n BaseMessageChunk,\n RemoveMessage,\n convertToChunk,\n coerceMessageLikeToMessage,\n HumanMessageChunk,\n HumanMessage,\n SystemMessageChunk,\n SystemMessage,\n AIMessageChunk,\n AIMessage,\n ToolMessageChunk,\n ToolMessage,\n} from \"@langchain/core/messages\";\n\nimport type { Message } from \"../types.messages.js\";\nimport type { ThreadState } from \"../schema.js\";\n\n/**\n * Replaces the `messages` property in a state type with `BaseMessage[]`.\n * Used by framework SDKs to reflect that `ensureHistoryMessageInstances`\n * converts plain message objects to class instances at runtime.\n */\nexport type StateWithBaseMessages<S> = S extends { messages: unknown }\n ? Omit<S, \"messages\"> & { messages: BaseMessage[] }\n : S;\n\n/**\n * Maps a `ThreadState<StateType>[]` so that the `messages` field inside\n * `values` is typed as `BaseMessage[]` instead of `Message[]`.\n */\nexport type HistoryWithBaseMessages<T> = T extends ThreadState<infer S>[]\n ? ThreadState<StateWithBaseMessages<S>>[]\n : T;\n\nexport function tryConvertToChunk(\n message: BaseMessage | BaseMessageChunk\n): BaseMessageChunk | null {\n try {\n if (BaseMessageChunk.isInstance(message)) return message;\n return convertToChunk(message);\n } catch {\n return null;\n }\n}\n\nexport function tryCoerceMessageLikeToMessage(\n message: Omit<Message, \"type\"> & { type: string }\n): BaseMessage | BaseMessageChunk {\n if (message.type === \"human\" || message.type === \"user\") {\n return new HumanMessage(message);\n }\n\n if (message.type === \"ai\" || message.type === \"assistant\") {\n return new AIMessage(normalizeAIMessageToolCalls(message));\n }\n\n if (message.type === \"system\") {\n return new SystemMessage(message);\n }\n\n if (message.type === \"tool\" && \"tool_call_id\" in message) {\n return new ToolMessage({\n ...message,\n tool_call_id: message.tool_call_id as string,\n });\n }\n\n if (message.type === \"remove\" && message.id != null) {\n return new RemoveMessage({ ...message, id: message.id });\n }\n\n return coerceMessageLikeToMessage(message);\n}\n\nfunction tryCoerceMessageLikeToChunk(\n message: Omit<Message, \"type\"> & { type: string }\n): BaseMessage | BaseMessageChunk {\n if (message.type === \"human\" || message.type === \"user\") {\n return new HumanMessageChunk(message);\n }\n\n if (message.type === \"ai\" || message.type === \"assistant\") {\n return new AIMessageChunk(normalizeAIMessageToolCalls(message));\n }\n\n if (message.type === \"system\") {\n return new SystemMessageChunk(message);\n }\n\n if (message.type === \"tool\" && \"tool_call_id\" in message) {\n return new ToolMessageChunk({\n ...message,\n tool_call_id: message.tool_call_id as string,\n });\n }\n\n return tryCoerceMessageLikeToMessage(message);\n}\n\ntype ToolCallLike = {\n id?: string;\n name?: string;\n args?: unknown;\n input?: unknown;\n};\n\nfunction normalizeAIMessageToolCalls<\n T extends Omit<Message, \"type\"> & { type: string },\n>(message: T): T {\n const record = message as T & {\n content?: unknown;\n tool_calls?: unknown;\n };\n if (Array.isArray(record.tool_calls) && record.tool_calls.length > 0) {\n return message;\n }\n\n const toolCalls = extractToolCallsFromContent(record.content);\n if (toolCalls.length === 0) return message;\n return {\n ...message,\n tool_calls: toolCalls,\n };\n}\n\nfunction extractToolCallsFromContent(content: unknown) {\n if (!Array.isArray(content)) return [];\n return content.flatMap(\n (\n block\n ): Array<{\n id: string;\n name: string;\n args: Record<string, unknown>;\n type: \"tool_call\";\n }> => {\n if (block == null || typeof block !== \"object\") return [];\n const record = block as ToolCallLike & { type?: unknown };\n if (record.type !== \"tool_call\" && record.type !== \"tool_use\") return [];\n return [\n {\n id: record.id ?? \"\",\n name: record.name ?? \"\",\n args: normalizeToolCallArgs(record.args ?? record.input),\n type: \"tool_call\",\n },\n ];\n }\n );\n}\n\nfunction normalizeToolCallArgs(value: unknown): Record<string, unknown> {\n if (value != null && typeof value === \"object\" && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n if (typeof value === \"string\" && value.length > 0) {\n try {\n const parsed = JSON.parse(value);\n if (\n parsed != null &&\n typeof parsed === \"object\" &&\n !Array.isArray(parsed)\n ) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n // Streaming input fragments are expected to be invalid until finalized.\n }\n }\n return {};\n}\n\nexport class MessageTupleManager {\n chunks: Record<\n string,\n {\n chunk?: BaseMessageChunk | BaseMessage;\n metadata?: Record<string, unknown>;\n index?: number;\n }\n > = {};\n\n constructor() {\n this.chunks = {};\n }\n\n add(\n serialized: Message,\n metadata: Record<string, unknown> | undefined\n ): string | null {\n // TODO: this is sometimes sent from the API\n // figure out how to prevent this or move this to LC.js\n if (serialized.type.endsWith(\"MessageChunk\")) {\n // eslint-disable-next-line no-param-reassign\n serialized.type = serialized.type\n .slice(0, -\"MessageChunk\".length)\n .toLowerCase() as Message[\"type\"];\n }\n\n const message = tryCoerceMessageLikeToChunk(serialized);\n const chunk = tryConvertToChunk(message);\n\n const { id } = chunk ?? message;\n if (!id) {\n console.warn(\n \"No message ID found for chunk, ignoring in state\",\n serialized\n );\n return null;\n }\n\n this.chunks[id] ??= {};\n this.chunks[id].metadata = metadata ?? this.chunks[id].metadata;\n if (chunk) {\n const prev = this.chunks[id].chunk;\n this.chunks[id].chunk =\n (BaseMessageChunk.isInstance(prev) ? prev : null)?.concat(chunk) ??\n chunk;\n } else {\n this.chunks[id].chunk = message;\n }\n\n return id;\n }\n\n clear() {\n this.chunks = {};\n }\n\n get(id: string | null | undefined, defaultIndex?: number) {\n if (id == null) return null;\n if (this.chunks[id] == null) return null;\n if (defaultIndex != null) this.chunks[id].index ??= defaultIndex;\n return this.chunks[id];\n }\n}\n\nexport const toMessageDict = (chunk: BaseMessage): Message => {\n const { type, data } = chunk.toDict();\n return { ...data, type } as Message;\n};\n\n/**\n * Identity converter that keeps @langchain/core class instances.\n * Used by framework SDKs to expose BaseMessage instances instead of plain dicts.\n */\nexport const toMessageClass = (chunk: BaseMessage): BaseMessage => chunk;\n\n/**\n * Ensures all messages in an array are BaseMessage class instances.\n * Messages that are already class instances pass through unchanged.\n * Plain message objects (e.g. from API values/history) are converted\n * via {@link tryCoerceMessageLikeToMessage}.\n */\nexport function ensureMessageInstances(\n messages: (Message | BaseMessage)[]\n): (BaseMessage | BaseMessageChunk)[] {\n return messages.map((msg) => {\n if (typeof (msg as BaseMessage).getType === \"function\") {\n return msg as BaseMessage;\n }\n return tryCoerceMessageLikeToMessage(\n msg as Omit<Message, \"type\"> & { type: string }\n );\n });\n}\n\n/**\n * Converts plain message objects within each history state's values\n * to proper BaseMessage class instances. Returns a new array with\n * shallow-copied states whose messages have been coerced.\n */\nexport function ensureHistoryMessageInstances<\n StateType extends Record<string, unknown>,\n>(\n history: ThreadState<StateType>[],\n messagesKey: string = \"messages\"\n): ThreadState<StateType>[] {\n return history.map((state) => {\n if (state.values == null) return state;\n const messages = state.values[messagesKey];\n if (!Array.isArray(messages)) return state;\n return {\n ...state,\n values: {\n ...state.values,\n [messagesKey]: ensureMessageInstances(messages),\n },\n };\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"messages.js","names":[],"sources":["../../src/ui/messages.ts"],"sourcesContent":["import {\n type BaseMessage,\n BaseMessageChunk,\n convertToChunk,\n HumanMessageChunk,\n SystemMessageChunk,\n AIMessageChunk,\n ToolMessageChunk,\n} from \"@langchain/core/messages\";\n\nimport type { Message } from \"../types.messages.js\";\nimport type { ThreadState } from \"../schema.js\";\nimport {\n normalizeAIMessageToolCalls,\n tryCoerceMessageLikeToMessage,\n} from \"../stream/message-coercion.js\";\n\nexport { tryCoerceMessageLikeToMessage };\n\n/**\n * Replaces the `messages` property in a state type with `BaseMessage[]`.\n * Used by framework SDKs to reflect that `ensureHistoryMessageInstances`\n * converts plain message objects to class instances at runtime.\n */\nexport type StateWithBaseMessages<S> = S extends { messages: unknown }\n ? Omit<S, \"messages\"> & { messages: BaseMessage[] }\n : S;\n\n/**\n * Maps a `ThreadState<StateType>[]` so that the `messages` field inside\n * `values` is typed as `BaseMessage[]` instead of `Message[]`.\n */\nexport type HistoryWithBaseMessages<T> = T extends ThreadState<infer S>[]\n ? ThreadState<StateWithBaseMessages<S>>[]\n : T;\n\nexport function tryConvertToChunk(\n message: BaseMessage | BaseMessageChunk\n): BaseMessageChunk | null {\n try {\n if (BaseMessageChunk.isInstance(message)) return message;\n return convertToChunk(message);\n } catch {\n return null;\n }\n}\n\nfunction tryCoerceMessageLikeToChunk(\n message: Omit<Message, \"type\"> & { type: string }\n): BaseMessage | BaseMessageChunk {\n if (message.type === \"human\" || message.type === \"user\") {\n return new HumanMessageChunk(message);\n }\n\n if (message.type === \"ai\" || message.type === \"assistant\") {\n return new AIMessageChunk(normalizeAIMessageToolCalls(message));\n }\n\n if (message.type === \"system\") {\n return new SystemMessageChunk(message);\n }\n\n if (message.type === \"tool\" && \"tool_call_id\" in message) {\n return new ToolMessageChunk({\n ...message,\n tool_call_id: message.tool_call_id as string,\n });\n }\n\n return tryCoerceMessageLikeToMessage(message);\n}\n\nexport class MessageTupleManager {\n chunks: Record<\n string,\n {\n chunk?: BaseMessageChunk | BaseMessage;\n metadata?: Record<string, unknown>;\n index?: number;\n }\n > = {};\n\n constructor() {\n this.chunks = {};\n }\n\n add(\n serialized: Message,\n metadata: Record<string, unknown> | undefined\n ): string | null {\n // TODO: this is sometimes sent from the API\n // figure out how to prevent this or move this to LC.js\n if (serialized.type.endsWith(\"MessageChunk\")) {\n // eslint-disable-next-line no-param-reassign\n serialized.type = serialized.type\n .slice(0, -\"MessageChunk\".length)\n .toLowerCase() as Message[\"type\"];\n }\n\n const message = tryCoerceMessageLikeToChunk(serialized);\n const chunk = tryConvertToChunk(message);\n\n const { id } = chunk ?? message;\n if (!id) {\n console.warn(\n \"No message ID found for chunk, ignoring in state\",\n serialized\n );\n return null;\n }\n\n this.chunks[id] ??= {};\n this.chunks[id].metadata = metadata ?? this.chunks[id].metadata;\n if (chunk) {\n const prev = this.chunks[id].chunk;\n this.chunks[id].chunk =\n (BaseMessageChunk.isInstance(prev) ? prev : null)?.concat(chunk) ??\n chunk;\n } else {\n this.chunks[id].chunk = message;\n }\n\n return id;\n }\n\n clear() {\n this.chunks = {};\n }\n\n get(id: string | null | undefined, defaultIndex?: number) {\n if (id == null) return null;\n if (this.chunks[id] == null) return null;\n if (defaultIndex != null) this.chunks[id].index ??= defaultIndex;\n return this.chunks[id];\n }\n}\n\nexport const toMessageDict = (chunk: BaseMessage): Message => {\n const { type, data } = chunk.toDict();\n return { ...data, type } as Message;\n};\n\n/**\n * Identity converter that keeps @langchain/core class instances.\n * Used by framework SDKs to expose BaseMessage instances instead of plain dicts.\n */\nexport const toMessageClass = (chunk: BaseMessage): BaseMessage => chunk;\n\n/**\n * Ensures all messages in an array are BaseMessage class instances.\n * Messages that are already class instances pass through unchanged.\n * Plain message objects (e.g. from API values/history) are converted\n * via {@link tryCoerceMessageLikeToMessage}.\n */\nexport function ensureMessageInstances(\n messages: (Message | BaseMessage)[]\n): (BaseMessage | BaseMessageChunk)[] {\n return messages.map((msg) => {\n if (typeof (msg as BaseMessage).getType === \"function\") {\n return msg as BaseMessage;\n }\n return tryCoerceMessageLikeToMessage(\n msg as Omit<Message, \"type\"> & { type: string }\n );\n });\n}\n\n/**\n * Converts plain message objects within each history state's values\n * to proper BaseMessage class instances. Returns a new array with\n * shallow-copied states whose messages have been coerced.\n */\nexport function ensureHistoryMessageInstances<\n StateType extends Record<string, unknown>,\n>(\n history: ThreadState<StateType>[],\n messagesKey: string = \"messages\"\n): ThreadState<StateType>[] {\n return history.map((state) => {\n if (state.values == null) return state;\n const messages = state.values[messagesKey];\n if (!Array.isArray(messages)) return state;\n return {\n ...state,\n values: {\n ...state.values,\n [messagesKey]: ensureMessageInstances(messages),\n },\n };\n });\n}\n"],"mappings":";;;AAoCA,SAAgB,kBACd,SACyB;AACzB,KAAI;AACF,MAAI,iBAAiB,WAAW,QAAQ,CAAE,QAAO;AACjD,SAAO,eAAe,QAAQ;SACxB;AACN,SAAO;;;AAIX,SAAS,4BACP,SACgC;AAChC,KAAI,QAAQ,SAAS,WAAW,QAAQ,SAAS,OAC/C,QAAO,IAAI,kBAAkB,QAAQ;AAGvC,KAAI,QAAQ,SAAS,QAAQ,QAAQ,SAAS,YAC5C,QAAO,IAAI,eAAe,4BAA4B,QAAQ,CAAC;AAGjE,KAAI,QAAQ,SAAS,SACnB,QAAO,IAAI,mBAAmB,QAAQ;AAGxC,KAAI,QAAQ,SAAS,UAAU,kBAAkB,QAC/C,QAAO,IAAI,iBAAiB;EAC1B,GAAG;EACH,cAAc,QAAQ;EACvB,CAAC;AAGJ,QAAO,8BAA8B,QAAQ;;AAG/C,IAAa,sBAAb,MAAiC;CAC/B,SAOI,EAAE;CAEN,cAAc;AACZ,OAAK,SAAS,EAAE;;CAGlB,IACE,YACA,UACe;AAGf,MAAI,WAAW,KAAK,SAAS,eAAe,CAE1C,YAAW,OAAO,WAAW,KAC1B,MAAM,GAAG,IAAuB,CAChC,aAAa;EAGlB,MAAM,UAAU,4BAA4B,WAAW;EACvD,MAAM,QAAQ,kBAAkB,QAAQ;EAExC,MAAM,EAAE,OAAO,SAAS;AACxB,MAAI,CAAC,IAAI;AACP,WAAQ,KACN,oDACA,WACD;AACD,UAAO;;AAGT,OAAK,OAAO,QAAQ,EAAE;AACtB,OAAK,OAAO,IAAI,WAAW,YAAY,KAAK,OAAO,IAAI;AACvD,MAAI,OAAO;GACT,MAAM,OAAO,KAAK,OAAO,IAAI;AAC7B,QAAK,OAAO,IAAI,SACb,iBAAiB,WAAW,KAAK,GAAG,OAAO,OAAO,OAAO,MAAM,IAChE;QAEF,MAAK,OAAO,IAAI,QAAQ;AAG1B,SAAO;;CAGT,QAAQ;AACN,OAAK,SAAS,EAAE;;CAGlB,IAAI,IAA+B,cAAuB;AACxD,MAAI,MAAM,KAAM,QAAO;AACvB,MAAI,KAAK,OAAO,OAAO,KAAM,QAAO;AACpC,MAAI,gBAAgB,KAAM,MAAK,OAAO,IAAI,UAAU;AACpD,SAAO,KAAK,OAAO;;;AAIvB,MAAa,iBAAiB,UAAgC;CAC5D,MAAM,EAAE,MAAM,SAAS,MAAM,QAAQ;AACrC,QAAO;EAAE,GAAG;EAAM;EAAM;;;;;;AAO1B,MAAa,kBAAkB,UAAoC;;;;;;;AAQnE,SAAgB,uBACd,UACoC;AACpC,QAAO,SAAS,KAAK,QAAQ;AAC3B,MAAI,OAAQ,IAAoB,YAAY,WAC1C,QAAO;AAET,SAAO,8BACL,IACD;GACD;;;;;;;AAQJ,SAAgB,8BAGd,SACA,cAAsB,YACI;AAC1B,QAAO,QAAQ,KAAK,UAAU;AAC5B,MAAI,MAAM,UAAU,KAAM,QAAO;EACjC,MAAM,WAAW,MAAM,OAAO;AAC9B,MAAI,CAAC,MAAM,QAAQ,SAAS,CAAE,QAAO;AACrC,SAAO;GACL,GAAG;GACH,QAAQ;IACN,GAAG,MAAM;KACR,cAAc,uBAAuB,SAAS;IAChD;GACF;GACD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/langgraph-sdk",
3
- "version": "1.9.16",
3
+ "version": "1.9.17",
4
4
  "description": "Client library for interacting with the LangGraph API",
5
5
  "type": "module",
6
6
  "repository": {