@mongodb-js/agent-engine-sdk-langgraph 0.11.3

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 (128) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/LICENSE.md +201 -0
  3. package/README.md +149 -0
  4. package/dist/agent.d.ts +53 -0
  5. package/dist/agent.d.ts.map +1 -0
  6. package/dist/agent.js +508 -0
  7. package/dist/agent.js.map +1 -0
  8. package/dist/backends/tool_sandbox.d.ts +15 -0
  9. package/dist/backends/tool_sandbox.d.ts.map +1 -0
  10. package/dist/backends/tool_sandbox.js +15 -0
  11. package/dist/backends/tool_sandbox.js.map +1 -0
  12. package/dist/backends/toolpod.d.ts +68 -0
  13. package/dist/backends/toolpod.d.ts.map +1 -0
  14. package/dist/backends/toolpod.js +451 -0
  15. package/dist/backends/toolpod.js.map +1 -0
  16. package/dist/call_interrupt.d.ts +20 -0
  17. package/dist/call_interrupt.d.ts.map +1 -0
  18. package/dist/call_interrupt.js +23 -0
  19. package/dist/call_interrupt.js.map +1 -0
  20. package/dist/checkpoint_branch.d.ts +58 -0
  21. package/dist/checkpoint_branch.d.ts.map +1 -0
  22. package/dist/checkpoint_branch.js +239 -0
  23. package/dist/checkpoint_branch.js.map +1 -0
  24. package/dist/checkpointer.d.ts +21 -0
  25. package/dist/checkpointer.d.ts.map +1 -0
  26. package/dist/checkpointer.js +31 -0
  27. package/dist/checkpointer.js.map +1 -0
  28. package/dist/deep_agent.d.ts +49 -0
  29. package/dist/deep_agent.d.ts.map +1 -0
  30. package/dist/deep_agent.js +110 -0
  31. package/dist/deep_agent.js.map +1 -0
  32. package/dist/deep_agent_checkpointer.d.ts +11 -0
  33. package/dist/deep_agent_checkpointer.d.ts.map +1 -0
  34. package/dist/deep_agent_checkpointer.js +19 -0
  35. package/dist/deep_agent_checkpointer.js.map +1 -0
  36. package/dist/deep_agent_task.d.ts +26 -0
  37. package/dist/deep_agent_task.d.ts.map +1 -0
  38. package/dist/deep_agent_task.js +49 -0
  39. package/dist/deep_agent_task.js.map +1 -0
  40. package/dist/durable_deep_agent.d.ts +23 -0
  41. package/dist/durable_deep_agent.d.ts.map +1 -0
  42. package/dist/durable_deep_agent.js +176 -0
  43. package/dist/durable_deep_agent.js.map +1 -0
  44. package/dist/durable_message_identity.d.ts +5 -0
  45. package/dist/durable_message_identity.d.ts.map +1 -0
  46. package/dist/durable_message_identity.js +106 -0
  47. package/dist/durable_message_identity.js.map +1 -0
  48. package/dist/durable_session.d.ts +30 -0
  49. package/dist/durable_session.d.ts.map +1 -0
  50. package/dist/durable_session.js +400 -0
  51. package/dist/durable_session.js.map +1 -0
  52. package/dist/durable_subgraphs.d.ts +13 -0
  53. package/dist/durable_subgraphs.d.ts.map +1 -0
  54. package/dist/durable_subgraphs.js +82 -0
  55. package/dist/durable_subgraphs.js.map +1 -0
  56. package/dist/durable_tools.d.ts +12 -0
  57. package/dist/durable_tools.d.ts.map +1 -0
  58. package/dist/durable_tools.js +41 -0
  59. package/dist/durable_tools.js.map +1 -0
  60. package/dist/execution_session.d.ts +63 -0
  61. package/dist/execution_session.d.ts.map +1 -0
  62. package/dist/execution_session.js +300 -0
  63. package/dist/execution_session.js.map +1 -0
  64. package/dist/index.d.ts +19 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +17 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/llm_adapter.d.ts +41 -0
  69. package/dist/llm_adapter.d.ts.map +1 -0
  70. package/dist/llm_adapter.js +177 -0
  71. package/dist/llm_adapter.js.map +1 -0
  72. package/dist/messages.d.ts +56 -0
  73. package/dist/messages.d.ts.map +1 -0
  74. package/dist/messages.js +592 -0
  75. package/dist/messages.js.map +1 -0
  76. package/dist/node_logger_adapter.d.ts +51 -0
  77. package/dist/node_logger_adapter.d.ts.map +1 -0
  78. package/dist/node_logger_adapter.js +163 -0
  79. package/dist/node_logger_adapter.js.map +1 -0
  80. package/dist/platform_checkpointer.d.ts +70 -0
  81. package/dist/platform_checkpointer.d.ts.map +1 -0
  82. package/dist/platform_checkpointer.js +252 -0
  83. package/dist/platform_checkpointer.js.map +1 -0
  84. package/dist/query.d.ts +103 -0
  85. package/dist/query.d.ts.map +1 -0
  86. package/dist/query.js +623 -0
  87. package/dist/query.js.map +1 -0
  88. package/dist/runtime.d.ts +336 -0
  89. package/dist/runtime.d.ts.map +1 -0
  90. package/dist/runtime.js +881 -0
  91. package/dist/runtime.js.map +1 -0
  92. package/dist/secure_llm.d.ts +93 -0
  93. package/dist/secure_llm.d.ts.map +1 -0
  94. package/dist/secure_llm.js +423 -0
  95. package/dist/secure_llm.js.map +1 -0
  96. package/dist/session_factory.d.ts +6 -0
  97. package/dist/session_factory.d.ts.map +1 -0
  98. package/dist/session_factory.js +29 -0
  99. package/dist/session_factory.js.map +1 -0
  100. package/dist/session_fork.d.ts +76 -0
  101. package/dist/session_fork.d.ts.map +1 -0
  102. package/dist/session_fork.js +428 -0
  103. package/dist/session_fork.js.map +1 -0
  104. package/dist/subagents.d.ts +37 -0
  105. package/dist/subagents.d.ts.map +1 -0
  106. package/dist/subagents.js +67 -0
  107. package/dist/subagents.js.map +1 -0
  108. package/dist/suspend.d.ts +27 -0
  109. package/dist/suspend.d.ts.map +1 -0
  110. package/dist/suspend.js +87 -0
  111. package/dist/suspend.js.map +1 -0
  112. package/dist/thread_id.d.ts +30 -0
  113. package/dist/thread_id.d.ts.map +1 -0
  114. package/dist/thread_id.js +69 -0
  115. package/dist/thread_id.js.map +1 -0
  116. package/dist/workflow_json.d.ts +11 -0
  117. package/dist/workflow_json.d.ts.map +1 -0
  118. package/dist/workflow_json.js +49 -0
  119. package/dist/workflow_json.js.map +1 -0
  120. package/dist/workflow_message.d.ts +11 -0
  121. package/dist/workflow_message.d.ts.map +1 -0
  122. package/dist/workflow_message.js +179 -0
  123. package/dist/workflow_message.js.map +1 -0
  124. package/dist/workflow_state.d.ts +7 -0
  125. package/dist/workflow_state.d.ts.map +1 -0
  126. package/dist/workflow_state.js +62 -0
  127. package/dist/workflow_state.js.map +1 -0
  128. package/package.json +66 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm_adapter.js","sourceRoot":"","sources":["../src/llm_adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * LangChain message conversion layer.
3
+ *
4
+ * Converts between LangChain message types (AIMessage, HumanMessage, etc.)
5
+ * and the framework-neutral Message model from agent-engine-sdk.
6
+ *
7
+ * Port of `agent_engine_sdk_langgraph/messages.py`.
8
+ */
9
+ import { AIMessage, AIMessageChunk, type BaseMessage, type MessageContent } from "@langchain/core/messages";
10
+ import { ChatGenerationChunk, type ChatResult } from "@langchain/core/outputs";
11
+ import { type LLMResponse, type LLMStreamChunk, type Message } from "@mongodb-js/agent-engine-sdk";
12
+ export declare const FRAMEWORK_LANGCHAIN: "langchain";
13
+ /** Return the messages inside a LangGraph Overwrite or ordinary message value. */
14
+ export declare function unwrapMessageValues(value: unknown): unknown[];
15
+ /** Normalize graph-input messages and assign IDs where the caller requires them. */
16
+ export declare function assignMissingGraphInputMessageIds(graphInput: unknown, missingId: (index: number) => string): unknown;
17
+ /** Normalize a platform tool result for LangChain's ToolMessage content field. */
18
+ export declare function toToolMessageContent(content: unknown): MessageContent;
19
+ /** Convert a LangChain message to a platform Message. */
20
+ export declare function lcToPlatformMessage(lcMessage: BaseMessage): Message;
21
+ /**
22
+ * Convert a platform Message to a LangChain message.
23
+ *
24
+ * Returns `null` if the message cannot be converted (e.g. a tool message with
25
+ * missing tool_call_id).
26
+ */
27
+ export declare function platformToLcMessage(message: Message): BaseMessage | null;
28
+ /** Convert a list of LangChain messages to platform Messages. */
29
+ export declare function lcMessagesToPlatform(messages: readonly BaseMessage[]): Message[];
30
+ /**
31
+ * Convert a list of platform Messages to LangChain messages.
32
+ *
33
+ * Invalid messages (e.g. tool messages with missing tool_call_id) are
34
+ * skipped with a warning logged.
35
+ */
36
+ export declare function platformMessagesToLc(messages: readonly Message[]): BaseMessage[];
37
+ /**
38
+ * Serialize a LangChain message to the platform wire format.
39
+ *
40
+ * Stamps every dict with `framework: "langchain"` so downstream consumers can
41
+ * identify which framework produced the message.
42
+ */
43
+ export declare function messageToDict(message: BaseMessage): Record<string, unknown>;
44
+ /** Deserialize a platform wire-format dict to a LangChain AIMessage. */
45
+ export declare function dictToAiMessage(data: unknown): AIMessage;
46
+ /**
47
+ * Deserialize a platform wire-format dict to a LangChain AIMessageChunk.
48
+ *
49
+ * Used for streaming replay where ChatGenerationChunk expects a chunk type.
50
+ */
51
+ export declare function dictToAiMessageChunk(data: unknown): AIMessageChunk;
52
+ /** Convert sdk-core LLMResponse to LangChain ChatResult. */
53
+ export declare function llmResponseToChatResult(response: LLMResponse): ChatResult;
54
+ /** Convert sdk-core LLMStreamChunk to LangChain ChatGenerationChunk. */
55
+ export declare function llmStreamChunkToGenerationChunk(chunk: LLMStreamChunk): ChatGenerationChunk;
56
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,SAAS,EACT,cAAc,EACd,KAAK,WAAW,EAGhB,KAAK,cAAc,EAGpB,MAAM,0BAA0B,CAAC;AAMlC,OAAO,EACL,mBAAmB,EAEnB,KAAK,UAAU,EAChB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAKL,KAAK,WAAW,EAChB,KAAK,cAAc,EAGnB,KAAK,OAAO,EAGb,MAAM,8BAA8B,CAAC;AA4CtC,eAAO,MAAM,mBAAmB,EAAG,WAAoB,CAAC;AAgBxD,kFAAkF;AAClF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,EAAE,CAM7D;AASD,oFAAoF;AACpF,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,OAAO,EACnB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GACnC,OAAO,CAiCT;AAED,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,CAmBrE;AAgID,yDAAyD;AACzD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,WAAW,GAAG,OAAO,CAgEnE;AAgDD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CA0FxE;AAMD,iEAAiE;AACjE,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,SAAS,WAAW,EAAE,GAC/B,OAAO,EAAE,CAEX;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAC3B,WAAW,EAAE,CAOf;AAMD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuB3E;AAaD,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,CAQxD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CAWlE;AAiCD,4DAA4D;AAC5D,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,WAAW,GAAG,UAAU,CA2CzE;AAED,wEAAwE;AACxE,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,cAAc,GACpB,mBAAmB,CAoCrB"}
@@ -0,0 +1,592 @@
1
+ /**
2
+ * LangChain message conversion layer.
3
+ *
4
+ * Converts between LangChain message types (AIMessage, HumanMessage, etc.)
5
+ * and the framework-neutral Message model from agent-engine-sdk.
6
+ *
7
+ * Port of `agent_engine_sdk_langgraph/messages.py`.
8
+ */
9
+ import { AIMessage, AIMessageChunk, coerceMessageLikeToMessage, HumanMessage, SystemMessage, ToolMessage, } from "@langchain/core/messages";
10
+ import { Overwrite } from "@langchain/langgraph";
11
+ import { ChatGenerationChunk, } from "@langchain/core/outputs";
12
+ import { LLMTokenUsage, LLMToolCall, } from "@mongodb-js/agent-engine-sdk";
13
+ import { getLogger } from "@mongodb-js/agent-engine-runner-shared";
14
+ /** Drop keys whose value is `undefined` — local helper (not in agent-engine-sdk). */
15
+ function stripUndefined(obj) {
16
+ const result = {};
17
+ for (const [key, value] of Object.entries(obj)) {
18
+ if (value !== undefined)
19
+ result[key] = value;
20
+ }
21
+ return result;
22
+ }
23
+ /**
24
+ * Build an `LLMTokenUsage` from a raw dict. His agent-engine-sdk class has only a
25
+ * data-constructor (no static `fromDict`); this helper centralises the cast.
26
+ */
27
+ function newLLMTokenUsageFromDict(data) {
28
+ return new LLMTokenUsage(data);
29
+ }
30
+ /** `LLMTokenUsage` no longer exposes `.toDict()`; round-trip via JSON-stripping. */
31
+ function llmTokenUsageToDict(usage) {
32
+ return stripUndefined({
33
+ input_tokens: usage.inputTokens,
34
+ output_tokens: usage.outputTokens,
35
+ prompt_tokens: usage.promptTokens,
36
+ completion_tokens: usage.completionTokens,
37
+ total_tokens: usage.totalTokens,
38
+ model: usage.model,
39
+ });
40
+ }
41
+ const logger = getLogger("agent_engine_sdk_langgraph.messages");
42
+ // ---------------------------------------------------------------------------
43
+ // Constants
44
+ // ---------------------------------------------------------------------------
45
+ export const FRAMEWORK_LANGCHAIN = "langchain";
46
+ // Keep in sync with Python's langchain_core.tools.base.TOOL_MESSAGE_BLOCK_TYPES,
47
+ // consumed by langgraph.prebuilt.tool_node.msg_content_output. Unsupported
48
+ // block lists are intentionally JSON-stringified on the durable path.
49
+ const TOOL_MESSAGE_BLOCK_TYPES = new Set([
50
+ "text",
51
+ "image_url",
52
+ "image",
53
+ "json",
54
+ "search_result",
55
+ "custom_tool_call_output",
56
+ "document",
57
+ "file",
58
+ ]);
59
+ /** Return the messages inside a LangGraph Overwrite or ordinary message value. */
60
+ export function unwrapMessageValues(value) {
61
+ if (Overwrite.isInstance(value) && "__overwrite__" in value) {
62
+ const overwritten = value.__overwrite__;
63
+ return Array.isArray(overwritten) ? [...overwritten] : [overwritten];
64
+ }
65
+ return Array.isArray(value) ? [...value] : [value];
66
+ }
67
+ function copyMessageWithId(message, id) {
68
+ const MessageType = message.constructor;
69
+ return new MessageType({ ...message, id });
70
+ }
71
+ /** Normalize graph-input messages and assign IDs where the caller requires them. */
72
+ export function assignMissingGraphInputMessageIds(graphInput, missingId) {
73
+ if (graphInput === null ||
74
+ typeof graphInput !== "object" ||
75
+ Array.isArray(graphInput)) {
76
+ return graphInput;
77
+ }
78
+ const input = graphInput;
79
+ const rawMessages = input["messages"];
80
+ if (rawMessages === undefined || rawMessages === null)
81
+ return graphInput;
82
+ const overwritten = Overwrite.isInstance(rawMessages) && "__overwrite__" in rawMessages;
83
+ const messages = unwrapMessageValues(rawMessages).map((value, index) => {
84
+ const message = coerceMessageLikeToMessage(value);
85
+ return message.id !== undefined && message.id !== null
86
+ ? message
87
+ : copyMessageWithId(message, missingId(index));
88
+ });
89
+ return {
90
+ ...input,
91
+ messages: overwritten
92
+ ? rawMessages instanceof Overwrite
93
+ ? new Overwrite(messages)
94
+ : {
95
+ ...rawMessages,
96
+ __overwrite__: messages,
97
+ }
98
+ : messages,
99
+ };
100
+ }
101
+ /** Normalize a platform tool result for LangChain's ToolMessage content field. */
102
+ export function toToolMessageContent(content) {
103
+ if (typeof content === "string")
104
+ return content;
105
+ if (Array.isArray(content) &&
106
+ content.every((item) => {
107
+ if (typeof item !== "object" || item === null)
108
+ return false;
109
+ const blockType = item["type"];
110
+ return (typeof blockType === "string" && TOOL_MESSAGE_BLOCK_TYPES.has(blockType));
111
+ })) {
112
+ return content;
113
+ }
114
+ try {
115
+ return JSON.stringify(content) ?? String(content);
116
+ }
117
+ catch {
118
+ return String(content);
119
+ }
120
+ }
121
+ // ---------------------------------------------------------------------------
122
+ // Internal helpers — content conversion
123
+ // ---------------------------------------------------------------------------
124
+ /**
125
+ * Convert LangChain message content to platform format.
126
+ *
127
+ * LangChain messages can have multimodal content as a list of content blocks.
128
+ * This function preserves the structure for multimodal content while keeping
129
+ * simple string content as-is.
130
+ */
131
+ function convertLcContentToPlatform(content) {
132
+ if (typeof content === "string")
133
+ return content;
134
+ if (!Array.isArray(content))
135
+ return String(content);
136
+ const blocks = [];
137
+ for (const block of content) {
138
+ if (block !== null && typeof block === "object") {
139
+ const b = block;
140
+ const blockType = typeof b["type"] === "string" ? b["type"] : "text";
141
+ if (blockType === "text") {
142
+ const text = typeof b["text"] === "string" ? b["text"] : "";
143
+ blocks.push({ type: "text", text });
144
+ }
145
+ else if (blockType === "image" || blockType === "image_url") {
146
+ const url = extractImageUrl(b);
147
+ if (url) {
148
+ const imageBlock = typeof b["mime_type"] === "string"
149
+ ? { type: "image", url, mime_type: b["mime_type"] }
150
+ : { type: "image", url };
151
+ blocks.push(imageBlock);
152
+ }
153
+ else {
154
+ logger.warn("Image block missing url; skipping");
155
+ }
156
+ }
157
+ else if (blockType === "file" || blockType === "document") {
158
+ const url = typeof b["url"] === "string" ? b["url"] : undefined;
159
+ if (url) {
160
+ const mimeType = typeof b["mime_type"] === "string" ? b["mime_type"] : undefined;
161
+ const filename = typeof b["filename"] === "string" ? b["filename"] : undefined;
162
+ const doc = {
163
+ type: "document",
164
+ url,
165
+ ...(mimeType !== undefined && { mime_type: mimeType }),
166
+ ...(filename !== undefined && { filename }),
167
+ };
168
+ blocks.push(doc);
169
+ }
170
+ else {
171
+ logger.warn("Document block missing url; skipping");
172
+ }
173
+ }
174
+ else {
175
+ logger.warn(`Unknown content block type=${blockType}; serializing to TextBlock`);
176
+ blocks.push({
177
+ type: "text",
178
+ text: JSON.stringify(b),
179
+ });
180
+ }
181
+ }
182
+ else {
183
+ blocks.push({ type: "text", text: String(block) });
184
+ }
185
+ }
186
+ if (blocks.length === 1 && blocks[0]?.type === "text")
187
+ return blocks[0].text;
188
+ return blocks.length > 0 ? blocks : "";
189
+ }
190
+ /** Extract the URL from LangChain's image_url shape (either string or `{url, ...}`). */
191
+ function extractImageUrl(block) {
192
+ const imageData = block["image_url"];
193
+ if (imageData !== undefined) {
194
+ if (typeof imageData === "string")
195
+ return imageData;
196
+ if (imageData !== null && typeof imageData === "object") {
197
+ const url = imageData["url"];
198
+ return typeof url === "string" ? url : undefined;
199
+ }
200
+ return undefined;
201
+ }
202
+ const url = block["url"];
203
+ return typeof url === "string" ? url : undefined;
204
+ }
205
+ /**
206
+ * Serialize LangChain tool calls.
207
+ *
208
+ * LangChain's ToolCall is a TypedDict — at runtime, tool_calls on an
209
+ * AIMessage are always plain objects with `name`, `args`, `id`, and
210
+ * `type` keys (enforced by LangChain's model validator).
211
+ */
212
+ function serializeToolCalls(toolCalls) {
213
+ const requiredKeys = ["name", "args", "id"];
214
+ const result = [];
215
+ for (const tc of toolCalls) {
216
+ if (tc === null || typeof tc !== "object") {
217
+ throw new TypeError(`Expected object tool call, got ${typeof tc}`);
218
+ }
219
+ const tcObj = tc;
220
+ const missing = requiredKeys.filter((k) => !(k in tcObj));
221
+ if (missing.length > 0) {
222
+ logger.warn(`Tool call missing keys ${missing.join(", ")}: ${JSON.stringify(tc)}`);
223
+ }
224
+ result.push(new LLMToolCall(tcObj));
225
+ }
226
+ return result;
227
+ }
228
+ // ---------------------------------------------------------------------------
229
+ // Public API — single message conversion
230
+ // ---------------------------------------------------------------------------
231
+ const ROLE_MAP = {
232
+ human: "user",
233
+ ai: "assistant",
234
+ system: "system",
235
+ tool: "tool",
236
+ };
237
+ /** Convert a LangChain message to a platform Message. */
238
+ export function lcToPlatformMessage(lcMessage) {
239
+ const role = ROLE_MAP[lcMessage.type] ?? "user";
240
+ const content = convertLcContentToPlatform(lcMessage.content);
241
+ let toolCalls;
242
+ // LangChain JS's `AIMessageChunk` is NOT a subclass of `AIMessage` (unlike
243
+ // Python), so `instanceof AIMessage` misses chunks aggregated by
244
+ // `BaseChatModel.invoke` from `_streamResponseChunks`. Accept both, and also
245
+ // fall through on `type === "ai"` for already-deserialized messages from
246
+ // the LangGraph checkpointer.
247
+ if ((lcMessage instanceof AIMessage ||
248
+ lcMessage instanceof AIMessageChunk ||
249
+ lcMessage.type === "ai") &&
250
+ Array.isArray(lcMessage.tool_calls) &&
251
+ lcMessage.tool_calls.length > 0) {
252
+ const rawCalls = lcMessage
253
+ .tool_calls;
254
+ toolCalls = serializeToolCalls(rawCalls);
255
+ }
256
+ let toolCallId;
257
+ let isError;
258
+ if (lcMessage instanceof ToolMessage) {
259
+ toolCallId = lcMessage.tool_call_id;
260
+ isError = lcMessage.status === "error";
261
+ }
262
+ const rawAdditionalKwargs = nonEmptyDict(lcMessage.additional_kwargs);
263
+ let additionalKwargs = rawAdditionalKwargs;
264
+ if (toolCalls !== undefined &&
265
+ rawAdditionalKwargs?.["tool_calls"] !== undefined) {
266
+ // LangChain JS assembles provider stream fragments under
267
+ // additional_kwargs.tool_calls. The completed semantic tool_calls above
268
+ // are the portable source of truth and are what durable replay rebuilds.
269
+ const { tool_calls: _providerFragments, ...portableAdditionalKwargs } = rawAdditionalKwargs;
270
+ additionalKwargs = nonEmptyDict(portableAdditionalKwargs);
271
+ }
272
+ const responseMetadata = nonEmptyDict(lcMessage.response_metadata);
273
+ return {
274
+ role,
275
+ content,
276
+ ...(toolCalls !== undefined && { toolCalls }),
277
+ ...(toolCallId !== undefined && { toolCallId }),
278
+ ...(isError !== undefined && { isError }),
279
+ ...(lcMessage.name !== undefined &&
280
+ lcMessage.name !== null && { name: lcMessage.name }),
281
+ ...(lcMessage.id !== undefined &&
282
+ lcMessage.id !== null && { id: lcMessage.id }),
283
+ ...(additionalKwargs !== undefined && {
284
+ additionalKwargs,
285
+ }),
286
+ ...(responseMetadata !== undefined && {
287
+ responseMetadata,
288
+ }),
289
+ };
290
+ }
291
+ function nonEmptyDict(data) {
292
+ if (data === undefined || Object.keys(data).length === 0)
293
+ return undefined;
294
+ // LangChain typings allow `unknown` values but in practice they are JsonValue-compatible.
295
+ // The cast is documented here rather than narrowing every field at every call site.
296
+ return data;
297
+ }
298
+ /**
299
+ * Convert platform content to LangChain's `MessageContent` type.
300
+ *
301
+ * LangChain 1.x's `ContentBlock` interface is more strict than our internal
302
+ * shape (it expects provider-specific image/document variants). We emit the
303
+ * historical LangChain dict form (`{type, url, mime_type, ...}`) that all
304
+ * upstream chat models still accept at runtime, and cast to `MessageContent`
305
+ * at this single boundary.
306
+ */
307
+ function convertPlatformContentToLc(content) {
308
+ if (typeof content === "string")
309
+ return content;
310
+ const lcBlocks = [];
311
+ for (const block of content) {
312
+ if (block.type === "text") {
313
+ lcBlocks.push({ type: "text", text: block.text });
314
+ }
315
+ else if (block.type === "image") {
316
+ lcBlocks.push({
317
+ type: "image",
318
+ url: block.url,
319
+ ...(block.mime_type !== undefined && { mime_type: block.mime_type }),
320
+ });
321
+ }
322
+ else if (block.type === "document") {
323
+ lcBlocks.push({
324
+ type: "document",
325
+ url: block.url,
326
+ ...(block.mime_type !== undefined && { mime_type: block.mime_type }),
327
+ ...(block.filename !== undefined && { filename: block.filename }),
328
+ });
329
+ }
330
+ }
331
+ if (lcBlocks.length === 0)
332
+ return "";
333
+ return lcBlocks;
334
+ }
335
+ /**
336
+ * Convert a platform Message to a LangChain message.
337
+ *
338
+ * Returns `null` if the message cannot be converted (e.g. a tool message with
339
+ * missing tool_call_id).
340
+ */
341
+ export function platformToLcMessage(message) {
342
+ const role = message.role;
343
+ const lcContent = convertPlatformContentToLc(message.content);
344
+ // Messages may arrive as camelCase (Message interface) or snake_case (MessageSchema
345
+ // wire output from Zod). Check both so the Tool Pod /invoke_llm path works correctly.
346
+ const msgAny = message;
347
+ const resolvedToolCallId = message.toolCallId ?? msgAny["tool_call_id"];
348
+ const resolvedToolCalls = message.toolCalls ?? msgAny["tool_calls"];
349
+ const resolvedIsError = message.isError ?? msgAny["is_error"] ?? false;
350
+ const resolvedAdditionalKwargs = message.additionalKwargs ??
351
+ msgAny["additional_kwargs"];
352
+ const resolvedResponseMetadata = message.responseMetadata ??
353
+ msgAny["response_metadata"];
354
+ // LangChain's `additional_kwargs` / `response_metadata` are typed `Record<string, unknown>`;
355
+ // ours are `Record<string, JsonValue>`. `JsonValue` is a strict subset of `unknown`, so the
356
+ // bridge is safe and documented once via this helper rather than every call site.
357
+ const additionalKwargs = {
358
+ ...resolvedAdditionalKwargs,
359
+ };
360
+ const responseMetadata = {
361
+ ...resolvedResponseMetadata,
362
+ };
363
+ const baseFields = {
364
+ additional_kwargs: additionalKwargs,
365
+ response_metadata: responseMetadata,
366
+ ...(message.name !== undefined && { name: message.name }),
367
+ ...(message.id !== undefined && { id: message.id }),
368
+ };
369
+ if (role === "tool") {
370
+ if (resolvedToolCallId === undefined || resolvedToolCallId === "") {
371
+ const preview = typeof message.content === "string"
372
+ ? message.content.slice(0, 50)
373
+ : "...";
374
+ logger.warn(`Skipping tool message: missing tool_call_id (content=${JSON.stringify(preview)})`);
375
+ return null;
376
+ }
377
+ const strContent = typeof lcContent === "string" ? lcContent : JSON.stringify(lcContent);
378
+ return new ToolMessage({
379
+ ...baseFields,
380
+ content: strContent,
381
+ tool_call_id: resolvedToolCallId,
382
+ status: resolvedIsError ? "error" : "success",
383
+ });
384
+ }
385
+ if (role === "assistant") {
386
+ // The wire JSON roundtrip strips `LLMToolCall` class identity, so tool
387
+ // calls arrive here as plain objects after Zod parse. Handle both shapes.
388
+ const mappedToolCalls = (resolvedToolCalls ?? []).map((tc) => {
389
+ if (typeof tc
390
+ .toLangchainDict === "function") {
391
+ return tc.toLangchainDict();
392
+ }
393
+ const obj = tc;
394
+ return {
395
+ id: obj["id"],
396
+ name: obj["name"],
397
+ args: (obj["args"] ?? obj["arguments"] ?? {}),
398
+ type: obj["type"] ?? "tool_call",
399
+ };
400
+ });
401
+ return new AIMessage({
402
+ ...baseFields,
403
+ content: lcContent,
404
+ tool_calls: mappedToolCalls,
405
+ });
406
+ }
407
+ if (role === "system") {
408
+ return new SystemMessage({ ...baseFields, content: lcContent });
409
+ }
410
+ return new HumanMessage({ ...baseFields, content: lcContent });
411
+ }
412
+ // ---------------------------------------------------------------------------
413
+ // Public API — bulk conversion
414
+ // ---------------------------------------------------------------------------
415
+ /** Convert a list of LangChain messages to platform Messages. */
416
+ export function lcMessagesToPlatform(messages) {
417
+ return messages.map(lcToPlatformMessage);
418
+ }
419
+ /**
420
+ * Convert a list of platform Messages to LangChain messages.
421
+ *
422
+ * Invalid messages (e.g. tool messages with missing tool_call_id) are
423
+ * skipped with a warning logged.
424
+ */
425
+ export function platformMessagesToLc(messages) {
426
+ const result = [];
427
+ for (const msg of messages) {
428
+ const lc = platformToLcMessage(msg);
429
+ if (lc !== null)
430
+ result.push(lc);
431
+ }
432
+ return result;
433
+ }
434
+ // ---------------------------------------------------------------------------
435
+ // OE message serialization (LangChain ↔ dict)
436
+ // ---------------------------------------------------------------------------
437
+ /**
438
+ * Serialize a LangChain message to the platform wire format.
439
+ *
440
+ * Stamps every dict with `framework: "langchain"` so downstream consumers can
441
+ * identify which framework produced the message.
442
+ */
443
+ export function messageToDict(message) {
444
+ // Emit a FLAT dict matching Python's `message_to_dict`
445
+ // (`model_dump(exclude_none=True)`) — NOT LangChain JS's nested `toDict()`
446
+ // envelope (`{type, data:{…}}`), which is also lossy (drops id /
447
+ // response_metadata / usage_metadata). Building the flat shape explicitly
448
+ // keeps this the exact inverse of `dictToAiMessage` (`new AIMessage(flat)`)
449
+ // so the pair round-trips, mirroring Python's model_dump/model_validate.
450
+ const m = message;
451
+ const flat = stripUndefined({
452
+ type: message.type,
453
+ content: message.content,
454
+ additional_kwargs: m["additional_kwargs"],
455
+ response_metadata: m["response_metadata"],
456
+ name: m["name"],
457
+ id: m["id"],
458
+ tool_calls: m["tool_calls"],
459
+ invalid_tool_calls: m["invalid_tool_calls"],
460
+ usage_metadata: m["usage_metadata"],
461
+ tool_call_id: m["tool_call_id"],
462
+ artifact: m["artifact"],
463
+ status: m["status"],
464
+ });
465
+ return { ...flat, framework: FRAMEWORK_LANGCHAIN };
466
+ }
467
+ /** Throw if the wire-format dict came from an unsupported framework. */
468
+ function checkFramework(data) {
469
+ const fw = data["framework"];
470
+ // Match Python's `fw is not None` — skip the check if framework is missing or null.
471
+ if (fw != null && fw !== FRAMEWORK_LANGCHAIN) {
472
+ throw new Error(`Cannot deserialize message from framework ${JSON.stringify(fw)} with the LangChain deserializer`);
473
+ }
474
+ }
475
+ /** Deserialize a platform wire-format dict to a LangChain AIMessage. */
476
+ export function dictToAiMessage(data) {
477
+ if (data instanceof AIMessage)
478
+ return data;
479
+ if (data !== null && typeof data === "object") {
480
+ const obj = data;
481
+ checkFramework(obj);
482
+ return new AIMessage(obj);
483
+ }
484
+ return new AIMessage({ content: String(data) });
485
+ }
486
+ /**
487
+ * Deserialize a platform wire-format dict to a LangChain AIMessageChunk.
488
+ *
489
+ * Used for streaming replay where ChatGenerationChunk expects a chunk type.
490
+ */
491
+ export function dictToAiMessageChunk(data) {
492
+ if (data instanceof AIMessageChunk)
493
+ return data;
494
+ if (data !== null && typeof data === "object") {
495
+ const obj = data;
496
+ checkFramework(obj);
497
+ return new AIMessageChunk({
498
+ ...obj,
499
+ type: "AIMessageChunk",
500
+ });
501
+ }
502
+ return new AIMessageChunk({ content: String(data) });
503
+ }
504
+ // ---------------------------------------------------------------------------
505
+ // LLM Response conversion (sdk-core ↔ LangChain)
506
+ // ---------------------------------------------------------------------------
507
+ const TOKEN_KEYS = new Set([
508
+ "input_tokens",
509
+ "output_tokens",
510
+ "prompt_tokens",
511
+ "completion_tokens",
512
+ "total_tokens",
513
+ "model",
514
+ ]);
515
+ function usageFromResponse(response) {
516
+ if (response.usage !== undefined)
517
+ return response.usage;
518
+ const metadata = { ...response.metadata };
519
+ const nestedUsage = metadata["usage"];
520
+ if (nestedUsage !== null &&
521
+ typeof nestedUsage === "object" &&
522
+ !Array.isArray(nestedUsage)) {
523
+ return newLLMTokenUsageFromDict(nestedUsage);
524
+ }
525
+ const hasTokenKey = Object.keys(metadata).some((k) => TOKEN_KEYS.has(k));
526
+ if (hasTokenKey)
527
+ return newLLMTokenUsageFromDict(metadata);
528
+ return undefined;
529
+ }
530
+ /** Convert sdk-core LLMResponse to LangChain ChatResult. */
531
+ export function llmResponseToChatResult(response) {
532
+ const responseMetadata = { ...response.metadata };
533
+ const rawMetadata = responseMetadata["_raw_response_metadata"];
534
+ delete responseMetadata["_raw_response_metadata"];
535
+ const rawResponseMetadata = rawMetadata !== null &&
536
+ typeof rawMetadata === "object" &&
537
+ !Array.isArray(rawMetadata)
538
+ ? rawMetadata
539
+ : {};
540
+ delete responseMetadata["usage"];
541
+ const explicitResponseMetadata = response.responseMetadata ?? {};
542
+ const usage = usageFromResponse(response);
543
+ const usageMetadata = usage !== undefined ? llmTokenUsageToDict(usage) : {};
544
+ const mergedMetadata = {
545
+ ...responseMetadata,
546
+ ...usageMetadata,
547
+ ...rawResponseMetadata,
548
+ ...explicitResponseMetadata,
549
+ };
550
+ const aiMessage = new AIMessage({
551
+ content: response.content,
552
+ tool_calls: (response.toolCalls ?? []).map((tc) => tc.toLangchainDict()),
553
+ ...(response.id !== undefined ? { id: response.id } : {}),
554
+ ...(response.name !== undefined ? { name: response.name } : {}),
555
+ additional_kwargs: (response.additionalKwargs ?? {}),
556
+ response_metadata: mergedMetadata,
557
+ });
558
+ // ChatGeneration is an interface in LangChain 1.x — construct via object literal.
559
+ const generation = {
560
+ message: aiMessage,
561
+ text: response.content,
562
+ };
563
+ return { generations: [generation] };
564
+ }
565
+ /** Convert sdk-core LLMStreamChunk to LangChain ChatGenerationChunk. */
566
+ export function llmStreamChunkToGenerationChunk(chunk) {
567
+ const toolCallChunks = (chunk.toolCalls ?? []).map((tc) => ({
568
+ type: "tool_call_chunk",
569
+ ...(tc.id !== undefined ? { id: tc.id } : {}),
570
+ ...(tc.name !== undefined ? { name: tc.name } : {}),
571
+ ...(tc.args !== undefined ? { args: tc.args } : {}),
572
+ ...(tc.index !== undefined ? { index: tc.index } : {}),
573
+ }));
574
+ const usageMetadata = chunk.usage?.toLangchainUsageMetadata();
575
+ // LangChain 1.x's AIMessageChunkFields generic uses inferred response_metadata /
576
+ // usage_metadata shapes that don't unify with our plain Record types. The cast
577
+ // is the single bridging point — runtime shape matches AIMessageChunkFields.
578
+ const aiChunk = new AIMessageChunk({
579
+ content: chunk.content ?? "",
580
+ tool_call_chunks: toolCallChunks,
581
+ ...(chunk.id !== undefined ? { id: chunk.id } : {}),
582
+ ...(chunk.name !== undefined ? { name: chunk.name } : {}),
583
+ additional_kwargs: (chunk.additionalKwargs ?? {}),
584
+ response_metadata: (chunk.responseMetadata ?? {}),
585
+ ...(usageMetadata !== undefined ? { usage_metadata: usageMetadata } : {}),
586
+ });
587
+ return new ChatGenerationChunk({
588
+ message: aiChunk,
589
+ text: chunk.content ?? "",
590
+ });
591
+ }
592
+ //# sourceMappingURL=messages.js.map