@librechat/agents 3.3.2 → 3.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/agents/AgentContext.cjs +2 -1
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +342 -109
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +3 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/langfuse.cjs +6 -0
- package/dist/cjs/langfuse.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +79 -6
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +37 -10
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/google/utils/common.cjs +19 -7
- package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
- package/dist/cjs/llm/invoke.cjs +64 -3
- package/dist/cjs/llm/invoke.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +41 -5
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +25 -4
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/index.cjs +4 -1
- package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +19 -2
- package/dist/cjs/messages/cache.cjs +54 -33
- package/dist/cjs/messages/cache.cjs.map +1 -1
- package/dist/cjs/messages/contextPruning.cjs +17 -43
- package/dist/cjs/messages/contextPruning.cjs.map +1 -1
- package/dist/cjs/messages/core.cjs +315 -23
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +218 -60
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/index.cjs +1 -1
- package/dist/cjs/messages/prune.cjs +503 -127
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/stream.cjs +7 -3
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/summarization/node.cjs +28 -14
- package/dist/cjs/summarization/node.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +54 -41
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/toolOutputReferences.cjs +6 -0
- package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -1
- package/dist/cjs/utils/index.cjs +1 -1
- package/dist/cjs/utils/llm.cjs +1 -1
- package/dist/cjs/utils/llm.cjs.map +1 -1
- package/dist/cjs/utils/tokens.cjs +307 -20
- package/dist/cjs/utils/tokens.cjs.map +1 -1
- package/dist/cjs/utils/toolContent.cjs +1514 -0
- package/dist/cjs/utils/toolContent.cjs.map +1 -0
- package/dist/esm/agents/AgentContext.mjs +2 -1
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +349 -116
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +3 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/langfuse.mjs +6 -0
- package/dist/esm/langfuse.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +79 -6
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs +37 -10
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/google/utils/common.mjs +19 -7
- package/dist/esm/llm/google/utils/common.mjs.map +1 -1
- package/dist/esm/llm/invoke.mjs +65 -5
- package/dist/esm/llm/invoke.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +41 -5
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +25 -4
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/index.mjs +4 -1
- package/dist/esm/llm/openrouter/index.mjs.map +1 -1
- package/dist/esm/main.mjs +7 -7
- package/dist/esm/messages/cache.mjs +55 -34
- package/dist/esm/messages/cache.mjs.map +1 -1
- package/dist/esm/messages/contextPruning.mjs +17 -43
- package/dist/esm/messages/contextPruning.mjs.map +1 -1
- package/dist/esm/messages/core.mjs +305 -24
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +218 -61
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/index.mjs +1 -1
- package/dist/esm/messages/prune.mjs +500 -128
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/stream.mjs +7 -3
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/summarization/node.mjs +28 -14
- package/dist/esm/summarization/node.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +54 -41
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/toolOutputReferences.mjs +6 -0
- package/dist/esm/tools/toolOutputReferences.mjs.map +1 -1
- package/dist/esm/utils/index.mjs +1 -1
- package/dist/esm/utils/llm.mjs +1 -1
- package/dist/esm/utils/llm.mjs.map +1 -1
- package/dist/esm/utils/tokens.mjs +307 -21
- package/dist/esm/utils/tokens.mjs.map +1 -1
- package/dist/esm/utils/toolContent.mjs +1503 -0
- package/dist/esm/utils/toolContent.mjs.map +1 -0
- package/dist/types/graphs/Graph.d.ts +1 -1
- package/dist/types/llm/invoke.d.ts +27 -1
- package/dist/types/llm/openai/index.d.ts +4 -0
- package/dist/types/llm/openai/utils/index.d.ts +2 -0
- package/dist/types/llm/openrouter/index.d.ts +5 -0
- package/dist/types/messages/contextPruning.d.ts +2 -1
- package/dist/types/messages/core.d.ts +36 -0
- package/dist/types/messages/format.d.ts +6 -0
- package/dist/types/messages/prune.d.ts +16 -12
- package/dist/types/types/stream.d.ts +1 -1
- package/dist/types/utils/tokens.d.ts +7 -0
- package/dist/types/utils/toolContent.d.ts +107 -0
- package/package.json +13 -9
- package/src/__tests__/stream.eagerEventExecution.test.ts +74 -0
- package/src/agents/AgentContext.ts +1 -0
- package/src/graphs/Graph.ts +698 -200
- package/src/graphs/MultiAgentGraph.ts +6 -1
- package/src/graphs/__tests__/Graph.contextOverflow.test.ts +1128 -4
- package/src/langfuse.ts +15 -0
- package/src/llm/anthropic/utils/message_inputs.ts +158 -12
- package/src/llm/anthropic/utils/tool-id-normalization.test.ts +109 -0
- package/src/llm/bedrock/utils/message_inputs.test.ts +49 -1
- package/src/llm/bedrock/utils/message_inputs.ts +86 -13
- package/src/llm/google/utils/common.test.ts +75 -9
- package/src/llm/google/utils/common.ts +34 -3
- package/src/llm/invoke.test.ts +488 -0
- package/src/llm/invoke.ts +196 -2
- package/src/llm/openai/index.ts +106 -6
- package/src/llm/openai/utils/index.ts +109 -53
- package/src/llm/openai/utils/messages.test.ts +330 -1
- package/src/llm/openrouter/index.ts +12 -2
- package/src/llm/openrouter/reasoning.test.ts +314 -0
- package/src/messages/__tests__/observationMasking.test.ts +93 -2
- package/src/messages/cache.tail.test.ts +193 -0
- package/src/messages/cache.test.ts +113 -0
- package/src/messages/cache.ts +92 -60
- package/src/messages/contextPruning.test.ts +184 -0
- package/src/messages/contextPruning.ts +49 -42
- package/src/messages/core.ts +653 -40
- package/src/messages/ensureThinkingBlock.test.ts +49 -1
- package/src/messages/foldToollessToolBlocks.test.ts +163 -5
- package/src/messages/format.ts +363 -91
- package/src/messages/formatAgentMessages.test.ts +604 -14
- package/src/messages/formatAgentMessages.tools.test.ts +103 -0
- package/src/messages/prune.ts +996 -183
- package/src/specs/langfuse-callbacks.test.ts +203 -1
- package/src/specs/prune.test.ts +1083 -6
- package/src/specs/summarization-unit.test.ts +105 -0
- package/src/specs/tokens.test.ts +609 -32
- package/src/stream.ts +23 -15
- package/src/summarization/__tests__/node.test.ts +77 -0
- package/src/summarization/node.ts +46 -18
- package/src/tools/ToolNode.ts +147 -68
- package/src/tools/__tests__/ToolNode.onResultCompletion.test.ts +148 -1
- package/src/tools/__tests__/ToolNode.outputReferences.test.ts +112 -3
- package/src/tools/__tests__/annotateMessagesForLLM.test.ts +32 -0
- package/src/tools/__tests__/directToolHooks.test.ts +255 -7
- package/src/tools/toolOutputReferences.ts +6 -0
- package/src/types/stream.ts +1 -1
- package/src/utils/llm.test.ts +18 -0
- package/src/utils/llm.ts +4 -1
- package/src/utils/tokens.ts +586 -31
- package/src/utils/toolContent.test.ts +1432 -0
- package/src/utils/toolContent.ts +2707 -0
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
require("../common/enum.cjs");
|
|
2
2
|
require("../common/index.cjs");
|
|
3
|
+
const require_truncation = require("../utils/truncation.cjs");
|
|
4
|
+
const require_toolContent = require("../utils/toolContent.cjs");
|
|
3
5
|
const require_langchain = require("./langchain.cjs");
|
|
6
|
+
const require_cache = require("./cache.cjs");
|
|
4
7
|
let _langchain_core_messages = require("@langchain/core/messages");
|
|
8
|
+
let node_util_types = require("node:util/types");
|
|
5
9
|
//#region src/messages/core.ts
|
|
6
10
|
function getConverseOverrideMessage({ userMessage, lastMessageX, lastMessageY }) {
|
|
7
11
|
return new _langchain_core_messages.HumanMessage(`
|
|
@@ -247,43 +251,320 @@ function convertMessagesToContent(messages) {
|
|
|
247
251
|
function stringifyToolMessageContent(content) {
|
|
248
252
|
return content == null ? "" : String(content);
|
|
249
253
|
}
|
|
250
|
-
function
|
|
254
|
+
function appendContentBlocks(target, content) {
|
|
255
|
+
if (typeof content === "string") {
|
|
256
|
+
target.push({
|
|
257
|
+
type: "text",
|
|
258
|
+
text: content
|
|
259
|
+
});
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
for (const block of content) target.push(block);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Appends one artifact/tool-content segment without retaining an unbounded
|
|
266
|
+
* intermediate block array. Both operands are compacted before they are
|
|
267
|
+
* combined, and the combined result is compacted again under the aggregate
|
|
268
|
+
* cap.
|
|
269
|
+
*/
|
|
270
|
+
function appendBoundedContent(current, next, maxChars) {
|
|
271
|
+
const boundedNext = require_toolContent.compactToolContent(next, maxChars).content;
|
|
272
|
+
if (current == null) return boundedNext;
|
|
273
|
+
const combined = [];
|
|
274
|
+
appendContentBlocks(combined, current);
|
|
275
|
+
appendContentBlocks(combined, boundedNext);
|
|
276
|
+
return require_toolContent.compactToolContent(require_langchain.toLangChainContent(combined), maxChars).content;
|
|
277
|
+
}
|
|
278
|
+
function cloneAIMessageWithToolCalls(message, toolCalls, removedCallIds) {
|
|
279
|
+
const descriptors = Object.getOwnPropertyDescriptors(message);
|
|
280
|
+
let descriptor = descriptors.tool_calls;
|
|
281
|
+
descriptors.tool_calls = {
|
|
282
|
+
configurable: descriptor?.configurable ?? true,
|
|
283
|
+
enumerable: descriptor?.enumerable ?? true,
|
|
284
|
+
value: toolCalls,
|
|
285
|
+
writable: descriptor?.writable ?? true
|
|
286
|
+
};
|
|
287
|
+
const toolCallChunks = descriptors.tool_call_chunks?.value;
|
|
288
|
+
if (Array.isArray(toolCallChunks)) {
|
|
289
|
+
descriptor = descriptors.tool_call_chunks;
|
|
290
|
+
descriptors.tool_call_chunks = {
|
|
291
|
+
configurable: descriptor?.configurable ?? true,
|
|
292
|
+
enumerable: descriptor?.enumerable ?? true,
|
|
293
|
+
value: toolCallChunks.filter((chunk) => typeof chunk.id !== "string" || !removedCallIds.has(chunk.id)),
|
|
294
|
+
writable: descriptor?.writable ?? true
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
return Object.create(Object.getPrototypeOf(message), descriptors);
|
|
298
|
+
}
|
|
299
|
+
function cloneAIMessageWithContent(message, content) {
|
|
300
|
+
const descriptors = Object.getOwnPropertyDescriptors(message);
|
|
301
|
+
const descriptor = descriptors.content;
|
|
302
|
+
descriptors.content = {
|
|
303
|
+
configurable: descriptor?.configurable ?? true,
|
|
304
|
+
enumerable: descriptor?.enumerable ?? true,
|
|
305
|
+
value: content,
|
|
306
|
+
writable: descriptor?.writable ?? true
|
|
307
|
+
};
|
|
308
|
+
const lcKwargs = descriptors.lc_kwargs;
|
|
309
|
+
if (lcKwargs != null && "value" in lcKwargs && typeof lcKwargs.value === "object" && lcKwargs.value != null) descriptors.lc_kwargs = {
|
|
310
|
+
...lcKwargs,
|
|
311
|
+
value: {
|
|
312
|
+
...lcKwargs.value,
|
|
313
|
+
content
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
return Object.create(Object.getPrototypeOf(message), descriptors);
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Drops incomplete streamed text-input fragments that some providers retain
|
|
320
|
+
* beside the assembled parsed tool call. They are neither user-visible text
|
|
321
|
+
* nor valid content blocks for a subsequent provider.
|
|
322
|
+
*/
|
|
323
|
+
function projectToolStreamContentForProvider(messages) {
|
|
324
|
+
let projected;
|
|
325
|
+
for (let i = 0; i < messages.length; i++) {
|
|
326
|
+
const message = messages[i];
|
|
327
|
+
if (message.getType() !== "ai" || !Array.isArray(message.content)) continue;
|
|
328
|
+
const content = message.content.filter((block) => {
|
|
329
|
+
if (block == null || typeof block !== "object") return true;
|
|
330
|
+
try {
|
|
331
|
+
if ((0, node_util_types.isProxy)(block)) return false;
|
|
332
|
+
const type = Object.getOwnPropertyDescriptor(block, "type");
|
|
333
|
+
if (type == null) return true;
|
|
334
|
+
if (type.enumerable !== true || !("value" in type)) return false;
|
|
335
|
+
if (type.value !== "text") return true;
|
|
336
|
+
const text = Object.getOwnPropertyDescriptor(block, "text");
|
|
337
|
+
return text?.enumerable === true && "value" in text && typeof text.value === "string" && text.value !== "";
|
|
338
|
+
} catch {
|
|
339
|
+
return false;
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
if (content.length === message.content.length) continue;
|
|
343
|
+
projected ??= [...messages];
|
|
344
|
+
projected[i] = cloneAIMessageWithContent(message, require_langchain.toLangChainContent(content));
|
|
345
|
+
}
|
|
346
|
+
return projected ?? messages;
|
|
347
|
+
}
|
|
348
|
+
function projectStructuredOpenAIToolContent(content, maxChars, cacheControlledTextProjection) {
|
|
349
|
+
if (cacheControlledTextProjection !== "serialize") {
|
|
350
|
+
const cacheControlledContent = require_toolContent.getBoundedCacheControlledTextToolContent(content, maxChars);
|
|
351
|
+
if (cacheControlledContent != null) return cacheControlledTextProjection === "preserve" ? cacheControlledContent : cacheControlledContent[0].text;
|
|
352
|
+
const singleTextContent = require_toolContent.getBoundedSingleTextToolContent(content, maxChars);
|
|
353
|
+
if (singleTextContent != null) return singleTextContent;
|
|
354
|
+
}
|
|
355
|
+
return require_toolContent.serializeToolContentBounded(cacheControlledTextProjection === "preserve" ? require_cache.stripAnthropicCacheControl([{ content }])[0].content : content, maxChars);
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* OpenAI Chat tool messages only accept strings or text-only parts, while the
|
|
359
|
+
* Responses API serializes any structured ToolMessage after graph accounting.
|
|
360
|
+
* Project every non-string tool result to one bounded string before the final
|
|
361
|
+
* provider payload is measured so both APIs receive the exact representation
|
|
362
|
+
* the budget guard counted. Native Responses computer screenshots stay
|
|
363
|
+
* structured because their dedicated converter sends the media block directly.
|
|
364
|
+
*/
|
|
365
|
+
function projectOpenAIToolMessageContentInternal(messages, maxChars, deduplicateResponsesComputerCalls, cacheControlledTextProjection) {
|
|
366
|
+
const pendingComputerCallIds = [];
|
|
367
|
+
const seenComputerCallIds = /* @__PURE__ */ new Set();
|
|
368
|
+
let projected;
|
|
369
|
+
for (let i = 0; i < messages.length; i++) {
|
|
370
|
+
const message = messages[i];
|
|
371
|
+
const messageRole = message.role;
|
|
372
|
+
if (message.getType() === "ai" || messageRole === "assistant") {
|
|
373
|
+
const parsedComputerCallIds = /* @__PURE__ */ new Set();
|
|
374
|
+
const toolCalls = message.tool_calls;
|
|
375
|
+
if (Array.isArray(toolCalls)) for (const toolCall of toolCalls) {
|
|
376
|
+
const record = toolCall;
|
|
377
|
+
if (record.type !== "tool_call" || record.isComputerTool !== true || typeof record.id !== "string" || record.id === "") continue;
|
|
378
|
+
if (parsedComputerCallIds.has(record.id)) throw new Error(`Duplicate computer call id "${record.id}"`);
|
|
379
|
+
parsedComputerCallIds.add(record.id);
|
|
380
|
+
if (seenComputerCallIds.has(record.id)) throw new Error(`Duplicate computer call id "${record.id}"`);
|
|
381
|
+
seenComputerCallIds.add(record.id);
|
|
382
|
+
pendingComputerCallIds.push(record.id);
|
|
383
|
+
}
|
|
384
|
+
const rawOutput = message.response_metadata.output;
|
|
385
|
+
const fallbackOutput = message.additional_kwargs.tool_outputs;
|
|
386
|
+
let actualToolOutputs = [];
|
|
387
|
+
if (Array.isArray(rawOutput) && rawOutput.length > 0) actualToolOutputs = rawOutput;
|
|
388
|
+
else if (Array.isArray(fallbackOutput)) actualToolOutputs = fallbackOutput;
|
|
389
|
+
const rawComputerCallIds = /* @__PURE__ */ new Set();
|
|
390
|
+
for (const item of actualToolOutputs) {
|
|
391
|
+
if (item == null || typeof item !== "object") continue;
|
|
392
|
+
const record = item;
|
|
393
|
+
if (record.type !== "computer_call" || typeof record.call_id !== "string" || record.call_id === "") continue;
|
|
394
|
+
if (rawComputerCallIds.has(record.call_id)) throw new Error(`Duplicate computer call id "${record.call_id}"`);
|
|
395
|
+
rawComputerCallIds.add(record.call_id);
|
|
396
|
+
if (parsedComputerCallIds.has(record.call_id)) continue;
|
|
397
|
+
if (seenComputerCallIds.has(record.call_id)) throw new Error(`Duplicate computer call id "${record.call_id}"`);
|
|
398
|
+
seenComputerCallIds.add(record.call_id);
|
|
399
|
+
pendingComputerCallIds.push(record.call_id);
|
|
400
|
+
}
|
|
401
|
+
if (deduplicateResponsesComputerCalls && Array.isArray(toolCalls) && rawComputerCallIds.size > 0) {
|
|
402
|
+
/**
|
|
403
|
+
* The non-streaming Responses converter marks parsed computer calls,
|
|
404
|
+
* but the streaming converter currently emits the same call as an
|
|
405
|
+
* ordinary parsed `computer_use` tool call. In both cases the raw
|
|
406
|
+
* `computer_call` item is authoritative and is replayed by LangChain,
|
|
407
|
+
* so remove every parsed representation with the same call id.
|
|
408
|
+
*/
|
|
409
|
+
const projectedToolCalls = toolCalls.filter((toolCall) => typeof toolCall.id !== "string" || !rawComputerCallIds.has(toolCall.id));
|
|
410
|
+
if (projectedToolCalls.length !== toolCalls.length) {
|
|
411
|
+
projected ??= [...messages];
|
|
412
|
+
projected[i] = cloneAIMessageWithToolCalls(message, projectedToolCalls, rawComputerCallIds);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
if (message instanceof _langchain_core_messages.ToolMessage && require_toolContent.hasComputerCallOutputMarker(message)) {
|
|
417
|
+
const screenshot = require_toolContent.getComputerCallOutputScreenshot(message.content);
|
|
418
|
+
if (screenshot == null) throw new Error("Invalid computer call output screenshot");
|
|
419
|
+
if (pendingComputerCallIds[0] !== message.tool_call_id) throw new Error(`Invalid computer call output pairing for "${message.tool_call_id}"`);
|
|
420
|
+
pendingComputerCallIds.shift();
|
|
421
|
+
projected ??= [...messages];
|
|
422
|
+
projected[i] = require_toolContent.cloneToolMessageWithContent(message, [screenshot]);
|
|
423
|
+
continue;
|
|
424
|
+
}
|
|
425
|
+
if (!(message instanceof _langchain_core_messages.ToolMessage) || typeof message.content === "string") continue;
|
|
426
|
+
projected ??= [...messages];
|
|
427
|
+
projected[i] = require_toolContent.cloneToolMessageWithContent(message, projectStructuredOpenAIToolContent(message.content, maxChars, cacheControlledTextProjection));
|
|
428
|
+
}
|
|
429
|
+
if (pendingComputerCallIds.length > 0) throw new Error(`Missing computer call output for "${pendingComputerCallIds[0]}"`);
|
|
430
|
+
return projected ?? messages;
|
|
431
|
+
}
|
|
432
|
+
/** Projects OpenAI-compatible tool content without changing parsed call parents. */
|
|
433
|
+
function projectOpenAIToolMessageContent(messages, maxChars = require_truncation.HARD_MAX_TOOL_RESULT_CHARS) {
|
|
434
|
+
return projectOpenAIToolMessageContentInternal(messages, maxChars, false, "serialize");
|
|
435
|
+
}
|
|
436
|
+
/** Projects an actual OpenAI-compatible Chat attempt and removes cache metadata. */
|
|
437
|
+
function projectOpenAIChatToolMessageContent(messages, maxChars = require_truncation.HARD_MAX_TOOL_RESULT_CHARS) {
|
|
438
|
+
return projectOpenAIToolMessageContentInternal(messages, maxChars, false, "text");
|
|
439
|
+
}
|
|
440
|
+
/** Preserves OpenRouter's cache-decorated text blocks for a Chat attempt. */
|
|
441
|
+
function projectOpenRouterToolMessageContent(messages, maxChars = require_truncation.HARD_MAX_TOOL_RESULT_CHARS) {
|
|
442
|
+
return projectOpenAIToolMessageContentInternal(messages, maxChars, false, "preserve");
|
|
443
|
+
}
|
|
444
|
+
/** Projects Responses tool content and collapses parsed/raw computer-call mirrors. */
|
|
445
|
+
function projectOpenAIResponsesToolMessageContent(messages, maxChars = require_truncation.HARD_MAX_TOOL_RESULT_CHARS) {
|
|
446
|
+
return projectOpenAIToolMessageContentInternal(messages, maxChars, true, "text");
|
|
447
|
+
}
|
|
448
|
+
/** Removes Anthropic/OpenRouter cache metadata before unsupported providers run. */
|
|
449
|
+
function projectCacheControlledToolOutputsToText(messages, maxChars = require_truncation.HARD_MAX_TOOL_RESULT_CHARS) {
|
|
450
|
+
let projected;
|
|
451
|
+
for (let i = 0; i < messages.length; i++) {
|
|
452
|
+
const message = messages[i];
|
|
453
|
+
if (!(message instanceof _langchain_core_messages.ToolMessage) || typeof message.content === "string") continue;
|
|
454
|
+
const cacheControlledContent = require_toolContent.getBoundedCacheControlledTextToolContent(message.content, maxChars);
|
|
455
|
+
if (cacheControlledContent == null) continue;
|
|
456
|
+
projected ??= [...messages];
|
|
457
|
+
projected[i] = require_toolContent.cloneToolMessageWithContent(message, cacheControlledContent[0].text);
|
|
458
|
+
}
|
|
459
|
+
return projected ?? messages;
|
|
460
|
+
}
|
|
461
|
+
/** Unwraps a canonical single text block after provider cache markers are removed. */
|
|
462
|
+
function projectSingleTextToolOutputsToText(messages, maxChars = require_truncation.HARD_MAX_TOOL_RESULT_CHARS) {
|
|
463
|
+
let projected;
|
|
464
|
+
for (let i = 0; i < messages.length; i++) {
|
|
465
|
+
const message = messages[i];
|
|
466
|
+
if (!(message instanceof _langchain_core_messages.ToolMessage) || typeof message.content === "string") continue;
|
|
467
|
+
const text = require_toolContent.getBoundedSingleTextToolContent(message.content, maxChars);
|
|
468
|
+
if (text == null) continue;
|
|
469
|
+
projected ??= [...messages];
|
|
470
|
+
projected[i] = require_toolContent.cloneToolMessageWithContent(message, text);
|
|
471
|
+
}
|
|
472
|
+
return projected ?? messages;
|
|
473
|
+
}
|
|
474
|
+
/** Serializes provider-neutral structured tool outputs without media pairing. */
|
|
475
|
+
function projectStructuredToolOutputsToText(messages, maxChars = require_truncation.HARD_MAX_TOOL_RESULT_CHARS) {
|
|
476
|
+
let projected;
|
|
477
|
+
for (let i = 0; i < messages.length; i++) {
|
|
478
|
+
const message = messages[i];
|
|
479
|
+
if (!(message instanceof _langchain_core_messages.ToolMessage) || typeof message.content === "string" || require_toolContent.hasComputerCallOutputMarker(message)) continue;
|
|
480
|
+
projected ??= [...messages];
|
|
481
|
+
projected[i] = require_toolContent.cloneToolMessageWithContent(message, require_toolContent.serializeToolContentBounded(message.content, maxChars));
|
|
482
|
+
}
|
|
483
|
+
return projected ?? messages;
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Non-Responses providers cannot consume native computer screenshots. Keep
|
|
487
|
+
* the tool-call structure intact, but replace screenshot bytes with a bounded
|
|
488
|
+
* text marker at the actual invocation boundary.
|
|
489
|
+
*/
|
|
490
|
+
function projectComputerCallOutputsToText(messages) {
|
|
491
|
+
let projected;
|
|
492
|
+
for (let i = 0; i < messages.length; i++) {
|
|
493
|
+
const message = messages[i];
|
|
494
|
+
if (!(message instanceof _langchain_core_messages.ToolMessage) || !require_toolContent.hasComputerCallOutputMarker(message)) continue;
|
|
495
|
+
projected ??= [...messages];
|
|
496
|
+
projected[i] = require_toolContent.cloneToolMessageWithContent(message, "[Computer screenshot omitted for this provider]");
|
|
497
|
+
}
|
|
498
|
+
return projected ?? messages;
|
|
499
|
+
}
|
|
500
|
+
function projectAnthropicArtifactContent(messages, maxChars = require_truncation.HARD_MAX_TOOL_RESULT_CHARS) {
|
|
251
501
|
const lastMessage = messages[messages.length - 1];
|
|
252
|
-
if (!(lastMessage instanceof _langchain_core_messages.ToolMessage)) return;
|
|
253
|
-
const latestAIParentIndex = findLastIndex(messages, (msg) => (msg instanceof _langchain_core_messages.AIMessageChunk && (msg.tool_calls?.length ?? 0) > 0 && msg.tool_calls?.some((tc) => tc.id === lastMessage.tool_call_id)) ?? false);
|
|
254
|
-
if (latestAIParentIndex === -1) return;
|
|
502
|
+
if (!(lastMessage instanceof _langchain_core_messages.ToolMessage)) return messages;
|
|
503
|
+
const latestAIParentIndex = findLastIndex(messages, (msg) => ((msg instanceof _langchain_core_messages.AIMessage || msg instanceof _langchain_core_messages.AIMessageChunk) && (msg.tool_calls?.length ?? 0) > 0 && msg.tool_calls?.some((tc) => tc.id === lastMessage.tool_call_id)) ?? false);
|
|
504
|
+
if (latestAIParentIndex === -1) return messages;
|
|
255
505
|
const message = messages[latestAIParentIndex];
|
|
256
506
|
const toolCallIdSet = /* @__PURE__ */ new Set();
|
|
257
507
|
if (message.tool_calls) {
|
|
258
508
|
for (const tc of message.tool_calls) if (tc.id != null) toolCallIdSet.add(tc.id);
|
|
259
509
|
}
|
|
510
|
+
let formattedMessages;
|
|
260
511
|
for (let j = latestAIParentIndex + 1; j < messages.length; j++) {
|
|
261
512
|
const msg = messages[j];
|
|
262
|
-
if (msg instanceof _langchain_core_messages.ToolMessage && toolCallIdSet.has(msg.tool_call_id) && msg.artifact != null &&
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
513
|
+
if (msg instanceof _langchain_core_messages.ToolMessage && !require_toolContent.isComputerCallOutputMessage(msg) && toolCallIdSet.has(msg.tool_call_id) && msg.artifact != null && (typeof msg.artifact?.content === "string" && msg.artifact.content.length > 0 || Array.isArray(msg.artifact?.content) && msg.artifact.content.length > 0)) {
|
|
514
|
+
const artifactContent = typeof msg.artifact.content === "string" ? [{
|
|
515
|
+
type: "text",
|
|
516
|
+
text: msg.artifact.content
|
|
517
|
+
}] : msg.artifact.content;
|
|
518
|
+
const content = appendBoundedContent(require_toolContent.compactToolContent(Array.isArray(msg.content) ? msg.content : stringifyToolMessageContent(msg.content), maxChars).content, artifactContent, maxChars);
|
|
519
|
+
formattedMessages ??= [...messages];
|
|
520
|
+
formattedMessages[j] = require_toolContent.cloneToolMessageWithContent(msg, content, {
|
|
521
|
+
...msg.artifact,
|
|
522
|
+
content: []
|
|
523
|
+
});
|
|
524
|
+
}
|
|
266
525
|
}
|
|
526
|
+
return formattedMessages ?? messages;
|
|
267
527
|
}
|
|
268
|
-
|
|
528
|
+
/**
|
|
529
|
+
* Mutating compatibility wrapper retained for existing package consumers.
|
|
530
|
+
* New provider-call paths should use `projectAnthropicArtifactContent`.
|
|
531
|
+
*/
|
|
532
|
+
function formatAnthropicArtifactContent(messages) {
|
|
533
|
+
const projected = projectAnthropicArtifactContent(messages);
|
|
534
|
+
if (projected === messages) return;
|
|
535
|
+
for (let i = 0; i < messages.length; i++) if (messages[i] instanceof _langchain_core_messages.ToolMessage && projected[i] instanceof _langchain_core_messages.ToolMessage && projected[i] !== messages[i]) messages[i].content = projected[i].content;
|
|
536
|
+
}
|
|
537
|
+
function projectArtifactPayload(messages, maxChars = require_truncation.HARD_MAX_TOOL_RESULT_CHARS) {
|
|
269
538
|
const lastMessageY = messages[messages.length - 1];
|
|
270
|
-
if (!(lastMessageY instanceof _langchain_core_messages.ToolMessage)) return;
|
|
271
|
-
const latestAIParentIndex = findLastIndex(messages, (msg) => (msg instanceof _langchain_core_messages.AIMessageChunk && (msg.tool_calls?.length ?? 0) > 0 && msg.tool_calls?.some((tc) => tc.id === lastMessageY.tool_call_id)) ?? false);
|
|
272
|
-
if (latestAIParentIndex === -1) return;
|
|
273
|
-
|
|
539
|
+
if (!(lastMessageY instanceof _langchain_core_messages.ToolMessage)) return messages;
|
|
540
|
+
const latestAIParentIndex = findLastIndex(messages, (msg) => ((msg instanceof _langchain_core_messages.AIMessage || msg instanceof _langchain_core_messages.AIMessageChunk) && (msg.tool_calls?.length ?? 0) > 0 && msg.tool_calls?.some((tc) => tc.id === lastMessageY.tool_call_id)) ?? false);
|
|
541
|
+
if (latestAIParentIndex === -1) return messages;
|
|
542
|
+
let aggregatedContent;
|
|
543
|
+
let formattedMessages;
|
|
274
544
|
for (let i = latestAIParentIndex + 1; i < messages.length; i++) {
|
|
275
545
|
const msg = messages[i];
|
|
276
|
-
if (!(msg instanceof _langchain_core_messages.ToolMessage) || !Array.isArray(msg.artifact?.content)) continue;
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
aggregatedContent.push(...msg.artifact.content);
|
|
546
|
+
if (!(msg instanceof _langchain_core_messages.ToolMessage) || require_toolContent.isComputerCallOutputMessage(msg) || !(typeof msg.artifact?.content === "string" && msg.artifact.content.length > 0 || Array.isArray(msg.artifact?.content) && msg.artifact.content.length > 0)) continue;
|
|
547
|
+
aggregatedContent = appendBoundedContent(aggregatedContent, msg.content, maxChars);
|
|
548
|
+
formattedMessages ??= [...messages];
|
|
549
|
+
formattedMessages[i] = require_toolContent.cloneToolMessageWithContent(msg, "Tool response is included in the next message as a Human message", {
|
|
550
|
+
...msg.artifact,
|
|
551
|
+
content: []
|
|
552
|
+
});
|
|
553
|
+
aggregatedContent = appendBoundedContent(aggregatedContent, msg.artifact.content, maxChars);
|
|
285
554
|
}
|
|
286
|
-
if (aggregatedContent
|
|
555
|
+
if (aggregatedContent != null) formattedMessages?.push(new _langchain_core_messages.HumanMessage({ content: aggregatedContent }));
|
|
556
|
+
return formattedMessages ?? messages;
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Mutating compatibility wrapper retained for existing package consumers.
|
|
560
|
+
* New provider-call paths should use `projectArtifactPayload`.
|
|
561
|
+
*/
|
|
562
|
+
function formatArtifactPayload(messages) {
|
|
563
|
+
const originalLength = messages.length;
|
|
564
|
+
const projected = projectArtifactPayload(messages);
|
|
565
|
+
if (projected === messages) return;
|
|
566
|
+
for (let i = 0; i < originalLength; i++) if (messages[i] instanceof _langchain_core_messages.ToolMessage && projected[i] instanceof _langchain_core_messages.ToolMessage && projected[i] !== messages[i]) messages[i].content = projected[i].content;
|
|
567
|
+
messages.push(...projected.slice(originalLength));
|
|
287
568
|
}
|
|
288
569
|
function findLastIndex(array, predicate) {
|
|
289
570
|
for (let i = array.length - 1; i >= 0; i--) if (predicate(array[i])) return i;
|
|
@@ -297,5 +578,16 @@ exports.formatAnthropicMessage = formatAnthropicMessage;
|
|
|
297
578
|
exports.formatArtifactPayload = formatArtifactPayload;
|
|
298
579
|
exports.getConverseOverrideMessage = getConverseOverrideMessage;
|
|
299
580
|
exports.modifyDeltaProperties = modifyDeltaProperties;
|
|
581
|
+
exports.projectAnthropicArtifactContent = projectAnthropicArtifactContent;
|
|
582
|
+
exports.projectArtifactPayload = projectArtifactPayload;
|
|
583
|
+
exports.projectCacheControlledToolOutputsToText = projectCacheControlledToolOutputsToText;
|
|
584
|
+
exports.projectComputerCallOutputsToText = projectComputerCallOutputsToText;
|
|
585
|
+
exports.projectOpenAIChatToolMessageContent = projectOpenAIChatToolMessageContent;
|
|
586
|
+
exports.projectOpenAIResponsesToolMessageContent = projectOpenAIResponsesToolMessageContent;
|
|
587
|
+
exports.projectOpenAIToolMessageContent = projectOpenAIToolMessageContent;
|
|
588
|
+
exports.projectOpenRouterToolMessageContent = projectOpenRouterToolMessageContent;
|
|
589
|
+
exports.projectSingleTextToolOutputsToText = projectSingleTextToolOutputsToText;
|
|
590
|
+
exports.projectStructuredToolOutputsToText = projectStructuredToolOutputsToText;
|
|
591
|
+
exports.projectToolStreamContentForProvider = projectToolStreamContentForProvider;
|
|
300
592
|
|
|
301
593
|
//# sourceMappingURL=core.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.cjs","names":["HumanMessage","toLangChainContent","AIMessage","ToolMessage","AIMessageChunk"],"sources":["../../../src/messages/core.ts"],"sourcesContent":["// src/messages.ts\nimport {\n AIMessage,\n BaseMessage,\n ToolMessage,\n HumanMessage,\n AIMessageChunk,\n} from '@langchain/core/messages';\nimport type { ToolCall } from '@langchain/core/messages/tool';\nimport type * as t from '@/types';\nimport { ContentTypes, Providers } from '@/common';\nimport { toLangChainContent } from './langchain';\n\ntype ReasoningSummary = { summary?: Array<{ text?: string }> };\ntype ReasoningDetail = { type?: string; text?: string };\ntype ReasoningAdditionalKwargs = {\n reasoning_content?: string | Partial<ReasoningSummary> | null;\n reasoning?: string | Partial<ReasoningSummary> | null;\n reasoning_details?: ReasoningDetail[] | null;\n};\n\nexport function getConverseOverrideMessage({\n userMessage,\n lastMessageX,\n lastMessageY,\n}: {\n userMessage: string[];\n lastMessageX: AIMessageChunk | null;\n lastMessageY: ToolMessage;\n}): HumanMessage {\n const content = `\nUser: ${userMessage[1]}\n\n---\n# YOU HAVE ALREADY RESPONDED TO THE LATEST USER MESSAGE:\n\n# Observations:\n- ${lastMessageX?.content}\n\n# Tool Calls:\n- ${lastMessageX?.tool_calls?.join('\\n- ')}\n\n# Tool Responses:\n- ${lastMessageY.content}\n`;\n\n return new HumanMessage(content);\n}\n\nconst _allowedTypes = ['image_url', 'text', 'tool_use', 'tool_result'];\nconst allowedTypesByProvider: Record<string, string[]> = {\n default: _allowedTypes,\n [Providers.ANTHROPIC]: [\n ..._allowedTypes,\n 'thinking',\n 'redacted_thinking',\n 'server_tool_use',\n 'web_search_tool_result',\n 'web_search_result',\n ],\n [Providers.BEDROCK]: [..._allowedTypes, 'reasoning_content'],\n [Providers.OPENAI]: _allowedTypes,\n};\n\nconst modifyContent = ({\n provider,\n messageType,\n content,\n}: {\n provider: Providers;\n messageType: string;\n content: t.ExtendedMessageContent[];\n}): (t.ExtendedMessageContent | null)[] => {\n const allowedTypes =\n allowedTypesByProvider[provider] ?? allowedTypesByProvider.default;\n return content.map((item: t.ExtendedMessageContent | null) => {\n if (\n item &&\n typeof item === 'object' &&\n 'type' in item &&\n item.type != null &&\n item.type\n ) {\n let newType = item.type;\n if (newType.endsWith('_delta')) {\n newType = newType.replace('_delta', '');\n }\n if (!allowedTypes.includes(newType)) {\n newType = 'text';\n }\n\n /* Handle the edge case for empty object 'tool_use' input in AI messages */\n if (\n messageType === 'ai' &&\n newType === 'tool_use' &&\n 'input' in item &&\n item.input === ''\n ) {\n return { ...item, type: newType, input: '{}' };\n }\n\n return { ...item, type: newType };\n }\n return item;\n });\n};\n\ntype ContentBlock =\n | Partial<t.BedrockReasoningContentText>\n | t.MessageDeltaUpdate;\n\nfunction reduceBlocks(blocks: ContentBlock[]): ContentBlock[] {\n const reduced: ContentBlock[] = [];\n\n for (const block of blocks) {\n const lastBlock = reduced[reduced.length - 1] as ContentBlock | undefined;\n\n // Merge consecutive 'reasoning_content'\n if (\n block.type === 'reasoning_content' &&\n lastBlock?.type === 'reasoning_content'\n ) {\n // append text if exists\n if (block.reasoningText?.text != null && block.reasoningText.text) {\n (\n lastBlock.reasoningText as t.BedrockReasoningContentText['reasoningText']\n ).text =\n (lastBlock.reasoningText?.text ?? '') + block.reasoningText.text;\n }\n // preserve the signature if exists\n if (\n block.reasoningText?.signature != null &&\n block.reasoningText.signature\n ) {\n (\n lastBlock.reasoningText as t.BedrockReasoningContentText['reasoningText']\n ).signature = block.reasoningText.signature;\n }\n }\n // Merge consecutive 'text'\n else if (block.type === 'text' && lastBlock?.type === 'text') {\n lastBlock.text += block.text;\n }\n // add a new block as it's a different type or first element\n else {\n // deep copy to avoid mutation of original\n reduced.push(JSON.parse(JSON.stringify(block)));\n }\n }\n\n return reduced;\n}\n\nfunction getReasoningText(\n value: string | Partial<ReasoningSummary> | null | undefined\n): string | undefined {\n if (typeof value === 'string') {\n return value !== '' ? value : undefined;\n }\n const summaryText = value?.summary\n ?.map((summary) => summary.text ?? '')\n .filter((text) => text !== '')\n .join('');\n return summaryText != null && summaryText !== '' ? summaryText : undefined;\n}\n\nfunction getReasoningDetailsText(\n value: ReasoningDetail[] | null | undefined\n): string | undefined {\n if (!Array.isArray(value)) {\n return undefined;\n }\n const reasoningText = value\n .filter((detail) => detail.type === 'reasoning.text')\n .map((detail) => detail.text ?? '')\n .filter((text) => text !== '')\n .join('');\n return reasoningText !== '' ? reasoningText : undefined;\n}\n\nfunction getAdditionalReasoningContent(\n message: BaseMessage\n): string | undefined {\n const additionalKwargs =\n message.additional_kwargs as ReasoningAdditionalKwargs | undefined;\n if (additionalKwargs == null) {\n return undefined;\n }\n\n const reasoningContent = getReasoningText(\n additionalKwargs.reasoning_content\n );\n if (reasoningContent != null) {\n return reasoningContent;\n }\n\n const reasoning = getReasoningText(additionalKwargs.reasoning);\n if (reasoning != null) {\n return reasoning;\n }\n\n return getReasoningDetailsText(additionalKwargs.reasoning_details);\n}\n\nfunction hasReasoningContent(content: BaseMessage['content']): boolean {\n if (!Array.isArray(content)) {\n return false;\n }\n return content.some((item) => {\n if (typeof item !== 'object' || !('type' in item)) {\n return false;\n }\n return (\n item.type === ContentTypes.THINK ||\n item.type === ContentTypes.THINKING ||\n item.type === ContentTypes.REASONING ||\n item.type === ContentTypes.REASONING_CONTENT ||\n item.type === 'redacted_thinking'\n );\n });\n}\n\nexport function modifyDeltaProperties(\n provider: Providers,\n obj?: AIMessageChunk\n): AIMessageChunk | undefined {\n if (!obj || typeof obj !== 'object') return obj;\n\n const messageType = (obj as Partial<AIMessageChunk>)._getType\n ? obj._getType()\n : '';\n\n if (provider === Providers.BEDROCK && Array.isArray(obj.content)) {\n obj.content = toLangChainContent(\n reduceBlocks(obj.content as ContentBlock[])\n );\n }\n if (Array.isArray(obj.content)) {\n obj.content = toLangChainContent(\n modifyContent({\n provider,\n messageType,\n content: obj.content as t.ExtendedMessageContent[],\n }) as t.MessageContentComplex[]\n );\n }\n if (\n (obj as Partial<AIMessageChunk>).lc_kwargs &&\n Array.isArray(obj.lc_kwargs.content)\n ) {\n if (provider === Providers.BEDROCK) {\n obj.lc_kwargs.content = reduceBlocks(\n obj.lc_kwargs.content as ContentBlock[]\n );\n }\n obj.lc_kwargs.content = modifyContent({\n provider,\n messageType,\n content: obj.lc_kwargs.content,\n });\n }\n return obj;\n}\n\nexport function formatAnthropicMessage(message: AIMessageChunk): AIMessage {\n if (!message.tool_calls || message.tool_calls.length === 0) {\n return new AIMessage({ content: toLangChainContent(message.content) });\n }\n\n const toolCallMap = new Map(message.tool_calls.map((tc) => [tc.id, tc]));\n let formattedContent: string | t.ExtendedMessageContent[];\n\n if (Array.isArray(message.content)) {\n formattedContent = message.content.reduce<t.ExtendedMessageContent[]>(\n (acc, item) => {\n if (typeof item === 'object') {\n const extendedItem = item as t.ExtendedMessageContent;\n if (\n extendedItem.type === 'text' &&\n extendedItem.text != null &&\n extendedItem.text\n ) {\n acc.push({ type: 'text', text: extendedItem.text });\n } else if (\n extendedItem.type === 'tool_use' &&\n extendedItem.id != null &&\n extendedItem.id\n ) {\n const toolCall = toolCallMap.get(extendedItem.id);\n if (toolCall) {\n acc.push({\n type: 'tool_use',\n id: extendedItem.id,\n name: toolCall.name,\n input: toolCall.args as unknown as string,\n });\n }\n } else if (\n 'input' in extendedItem &&\n extendedItem.input != null &&\n extendedItem.input\n ) {\n try {\n const parsedInput = JSON.parse(extendedItem.input);\n const toolCall = message.tool_calls?.find(\n (tc) => tc.args.input === parsedInput.input\n );\n if (toolCall) {\n acc.push({\n type: 'tool_use',\n id: toolCall.id,\n name: toolCall.name,\n input: toolCall.args as unknown as string,\n });\n }\n } catch {\n if (extendedItem.input) {\n acc.push({ type: 'text', text: extendedItem.input });\n }\n }\n }\n } else if (typeof item === 'string') {\n acc.push({ type: 'text', text: item });\n }\n return acc;\n },\n []\n );\n } else if (typeof message.content === 'string') {\n formattedContent = message.content;\n } else {\n formattedContent = [];\n }\n\n // const formattedToolCalls: ToolCall[] = message.tool_calls.map(toolCall => ({\n // id: toolCall.id ?? '',\n // name: toolCall.name,\n // args: toolCall.args,\n // type: 'tool_call',\n // }));\n\n const formattedToolCalls: t.AgentToolCall[] = message.tool_calls.map(\n (toolCall) => ({\n id: toolCall.id ?? '',\n type: 'function',\n function: {\n name: toolCall.name,\n arguments: toolCall.args,\n },\n })\n );\n\n return new AIMessage({\n content: toLangChainContent(formattedContent),\n tool_calls: formattedToolCalls as ToolCall[],\n additional_kwargs: {\n ...message.additional_kwargs,\n },\n });\n}\n\nexport function convertMessagesToContent(\n messages: BaseMessage[]\n): t.MessageContentComplex[] {\n const processedContent: t.MessageContentComplex[] = [];\n\n const addToolCallBoundary = (): number => {\n processedContent.push({ type: ContentTypes.TEXT, text: '' });\n return processedContent.length - 1;\n };\n\n const addContentPart = (message: BaseMessage | null): number | undefined => {\n const content =\n message?.lc_kwargs.content != null\n ? message.lc_kwargs.content\n : message?.content;\n if (content === undefined) {\n return undefined;\n }\n const reasoningContent =\n message?._getType() === 'ai' && !hasReasoningContent(content)\n ? getAdditionalReasoningContent(message)\n : undefined;\n if (reasoningContent != null) {\n processedContent.push({\n type: ContentTypes.THINK,\n think: reasoningContent,\n });\n }\n if (typeof content === 'string') {\n if (content === '') {\n return undefined;\n }\n processedContent.push({\n type: ContentTypes.TEXT,\n text: content,\n });\n return processedContent.length - 1;\n } else if (Array.isArray(content)) {\n let textContentIndex: number | undefined;\n for (const item of content) {\n if (item == null || item.type === 'tool_use') {\n continue;\n }\n processedContent.push(item);\n if (item.type === ContentTypes.TEXT) {\n textContentIndex = processedContent.length - 1;\n }\n }\n return textContentIndex;\n }\n return undefined;\n };\n\n let currentAIMessageIndex = -1;\n const toolCallMap = new Map<string, t.CustomToolCall>();\n\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i] as BaseMessage | null;\n const messageType = message?._getType();\n\n if (\n messageType === 'ai' &&\n ((message as AIMessage).tool_calls?.length ?? 0) > 0\n ) {\n const tool_calls = (message as AIMessage).tool_calls || [];\n for (const tool_call of tool_calls) {\n if (tool_call.id == null || !tool_call.id) {\n continue;\n }\n\n toolCallMap.set(tool_call.id, tool_call);\n }\n\n currentAIMessageIndex =\n addContentPart(message) ?? addToolCallBoundary();\n continue;\n } else if (\n messageType === 'tool' &&\n (message as ToolMessage).tool_call_id\n ) {\n const id = (message as ToolMessage).tool_call_id;\n const output = (message as ToolMessage).content;\n const tool_call = toolCallMap.get(id);\n if (currentAIMessageIndex === -1) {\n processedContent.push({ type: 'text', text: '' });\n currentAIMessageIndex = processedContent.length - 1;\n }\n const contentPart = processedContent[currentAIMessageIndex];\n processedContent.push({\n type: 'tool_call',\n tool_call: Object.assign({}, tool_call, { output }),\n });\n const tool_call_ids = contentPart.tool_call_ids || [];\n tool_call_ids.push(id);\n contentPart.tool_call_ids = tool_call_ids;\n continue;\n } else if (messageType !== 'ai') {\n continue;\n }\n\n addContentPart(message);\n }\n\n return processedContent;\n}\n\nfunction stringifyToolMessageContent(\n content: ToolMessage['content'] | null | undefined\n): string {\n return content == null ? '' : String(content);\n}\n\nexport function formatAnthropicArtifactContent(messages: BaseMessage[]): void {\n const lastMessage = messages[messages.length - 1];\n if (!(lastMessage instanceof ToolMessage)) return;\n\n // Find the latest AIMessage with tool_calls that this tool message belongs to\n const latestAIParentIndex = findLastIndex(\n messages,\n (msg) =>\n (msg instanceof AIMessageChunk &&\n (msg.tool_calls?.length ?? 0) > 0 &&\n msg.tool_calls?.some((tc) => tc.id === lastMessage.tool_call_id)) ??\n false\n );\n\n if (latestAIParentIndex === -1) return;\n\n // Build tool call ID set and merge artifact content in a single forward pass.\n const message = messages[latestAIParentIndex] as AIMessageChunk;\n const toolCallIdSet = new Set<string>();\n if (message.tool_calls) {\n for (const tc of message.tool_calls) {\n if (tc.id != null) {\n toolCallIdSet.add(tc.id);\n }\n }\n }\n\n for (let j = latestAIParentIndex + 1; j < messages.length; j++) {\n const msg = messages[j];\n if (\n msg instanceof ToolMessage &&\n toolCallIdSet.has(msg.tool_call_id) &&\n msg.artifact != null &&\n Array.isArray(msg.artifact?.content)\n ) {\n const base = Array.isArray(msg.content)\n ? msg.content\n : [\n {\n type: ContentTypes.TEXT,\n text: stringifyToolMessageContent(msg.content),\n },\n ];\n msg.content = base.concat(msg.artifact.content);\n }\n }\n}\n\nexport function formatArtifactPayload(messages: BaseMessage[]): void {\n const lastMessageY = messages[messages.length - 1];\n if (!(lastMessageY instanceof ToolMessage)) return;\n\n // Find the latest AIMessage with tool_calls that this tool message belongs to\n const latestAIParentIndex = findLastIndex(\n messages,\n (msg) =>\n (msg instanceof AIMessageChunk &&\n (msg.tool_calls?.length ?? 0) > 0 &&\n msg.tool_calls?.some((tc) => tc.id === lastMessageY.tool_call_id)) ??\n false\n );\n\n if (latestAIParentIndex === -1) return;\n\n // Single pass: collect relevant tool messages with artifacts and aggregate\n const aggregatedContent: t.MessageContentComplex[] = [];\n\n for (let i = latestAIParentIndex + 1; i < messages.length; i++) {\n const msg = messages[i];\n if (\n !(msg instanceof ToolMessage) ||\n !Array.isArray(msg.artifact?.content)\n ) {\n continue;\n }\n let currentContent = msg.content;\n if (!Array.isArray(currentContent)) {\n currentContent = [{ type: 'text', text: msg.content }];\n }\n aggregatedContent.push(...(currentContent as t.MessageContentComplex[]));\n msg.content =\n 'Tool response is included in the next message as a Human message';\n aggregatedContent.push(...msg.artifact.content);\n }\n\n if (aggregatedContent.length > 0) {\n messages.push(\n new HumanMessage({ content: toLangChainContent(aggregatedContent) })\n );\n }\n}\n\nexport function findLastIndex<T>(\n array: T[],\n predicate: (value: T) => boolean\n): number {\n for (let i = array.length - 1; i >= 0; i--) {\n if (predicate(array[i])) {\n return i;\n }\n }\n return -1;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"core.cjs","names":["HumanMessage","toLangChainContent","AIMessage","compactToolContent","getBoundedCacheControlledTextToolContent","getBoundedSingleTextToolContent","serializeToolContentBounded","stripAnthropicCacheControl","ToolMessage","hasComputerCallOutputMarker","getComputerCallOutputScreenshot","cloneToolMessageWithContent","HARD_MAX_TOOL_RESULT_CHARS","AIMessageChunk","isComputerCallOutputMessage"],"sources":["../../../src/messages/core.ts"],"sourcesContent":["// src/messages.ts\nimport { isProxy } from 'node:util/types';\nimport {\n AIMessage,\n BaseMessage,\n ToolMessage,\n HumanMessage,\n AIMessageChunk,\n} from '@langchain/core/messages';\nimport type { ToolCall, ToolCallChunk } from '@langchain/core/messages/tool';\nimport type * as t from '@/types';\nimport {\n cloneToolMessageWithContent,\n compactToolContent,\n getBoundedCacheControlledTextToolContent,\n getBoundedSingleTextToolContent,\n getComputerCallOutputScreenshot,\n hasComputerCallOutputMarker,\n isComputerCallOutputMessage,\n serializeToolContentBounded,\n} from '@/utils/toolContent';\nimport { HARD_MAX_TOOL_RESULT_CHARS } from '@/utils/truncation';\nimport { stripAnthropicCacheControl } from './cache';\nimport { ContentTypes, Providers } from '@/common';\nimport { toLangChainContent } from './langchain';\n\ntype ReasoningSummary = { summary?: Array<{ text?: string }> };\ntype ReasoningDetail = { type?: string; text?: string };\ntype ReasoningAdditionalKwargs = {\n reasoning_content?: string | Partial<ReasoningSummary> | null;\n reasoning?: string | Partial<ReasoningSummary> | null;\n reasoning_details?: ReasoningDetail[] | null;\n};\n\nexport function getConverseOverrideMessage({\n userMessage,\n lastMessageX,\n lastMessageY,\n}: {\n userMessage: string[];\n lastMessageX: AIMessageChunk | null;\n lastMessageY: ToolMessage;\n}): HumanMessage {\n const content = `\nUser: ${userMessage[1]}\n\n---\n# YOU HAVE ALREADY RESPONDED TO THE LATEST USER MESSAGE:\n\n# Observations:\n- ${lastMessageX?.content}\n\n# Tool Calls:\n- ${lastMessageX?.tool_calls?.join('\\n- ')}\n\n# Tool Responses:\n- ${lastMessageY.content}\n`;\n\n return new HumanMessage(content);\n}\n\nconst _allowedTypes = ['image_url', 'text', 'tool_use', 'tool_result'];\nconst allowedTypesByProvider: Record<string, string[]> = {\n default: _allowedTypes,\n [Providers.ANTHROPIC]: [\n ..._allowedTypes,\n 'thinking',\n 'redacted_thinking',\n 'server_tool_use',\n 'web_search_tool_result',\n 'web_search_result',\n ],\n [Providers.BEDROCK]: [..._allowedTypes, 'reasoning_content'],\n [Providers.OPENAI]: _allowedTypes,\n};\n\nconst modifyContent = ({\n provider,\n messageType,\n content,\n}: {\n provider: Providers;\n messageType: string;\n content: t.ExtendedMessageContent[];\n}): (t.ExtendedMessageContent | null)[] => {\n const allowedTypes =\n allowedTypesByProvider[provider] ?? allowedTypesByProvider.default;\n return content.map((item: t.ExtendedMessageContent | null) => {\n if (\n item &&\n typeof item === 'object' &&\n 'type' in item &&\n item.type != null &&\n item.type\n ) {\n let newType = item.type;\n if (newType.endsWith('_delta')) {\n newType = newType.replace('_delta', '');\n }\n if (!allowedTypes.includes(newType)) {\n newType = 'text';\n }\n\n /* Handle the edge case for empty object 'tool_use' input in AI messages */\n if (\n messageType === 'ai' &&\n newType === 'tool_use' &&\n 'input' in item &&\n item.input === ''\n ) {\n return { ...item, type: newType, input: '{}' };\n }\n\n return { ...item, type: newType };\n }\n return item;\n });\n};\n\ntype ContentBlock =\n | Partial<t.BedrockReasoningContentText>\n | t.MessageDeltaUpdate;\n\nfunction reduceBlocks(blocks: ContentBlock[]): ContentBlock[] {\n const reduced: ContentBlock[] = [];\n\n for (const block of blocks) {\n const lastBlock = reduced[reduced.length - 1] as ContentBlock | undefined;\n\n // Merge consecutive 'reasoning_content'\n if (\n block.type === 'reasoning_content' &&\n lastBlock?.type === 'reasoning_content'\n ) {\n // append text if exists\n if (block.reasoningText?.text != null && block.reasoningText.text) {\n (\n lastBlock.reasoningText as t.BedrockReasoningContentText['reasoningText']\n ).text =\n (lastBlock.reasoningText?.text ?? '') + block.reasoningText.text;\n }\n // preserve the signature if exists\n if (\n block.reasoningText?.signature != null &&\n block.reasoningText.signature\n ) {\n (\n lastBlock.reasoningText as t.BedrockReasoningContentText['reasoningText']\n ).signature = block.reasoningText.signature;\n }\n }\n // Merge consecutive 'text'\n else if (block.type === 'text' && lastBlock?.type === 'text') {\n lastBlock.text += block.text;\n }\n // add a new block as it's a different type or first element\n else {\n // deep copy to avoid mutation of original\n reduced.push(JSON.parse(JSON.stringify(block)));\n }\n }\n\n return reduced;\n}\n\nfunction getReasoningText(\n value: string | Partial<ReasoningSummary> | null | undefined\n): string | undefined {\n if (typeof value === 'string') {\n return value !== '' ? value : undefined;\n }\n const summaryText = value?.summary\n ?.map((summary) => summary.text ?? '')\n .filter((text) => text !== '')\n .join('');\n return summaryText != null && summaryText !== '' ? summaryText : undefined;\n}\n\nfunction getReasoningDetailsText(\n value: ReasoningDetail[] | null | undefined\n): string | undefined {\n if (!Array.isArray(value)) {\n return undefined;\n }\n const reasoningText = value\n .filter((detail) => detail.type === 'reasoning.text')\n .map((detail) => detail.text ?? '')\n .filter((text) => text !== '')\n .join('');\n return reasoningText !== '' ? reasoningText : undefined;\n}\n\nfunction getAdditionalReasoningContent(\n message: BaseMessage\n): string | undefined {\n const additionalKwargs = message.additional_kwargs as\n | ReasoningAdditionalKwargs\n | undefined;\n if (additionalKwargs == null) {\n return undefined;\n }\n\n const reasoningContent = getReasoningText(additionalKwargs.reasoning_content);\n if (reasoningContent != null) {\n return reasoningContent;\n }\n\n const reasoning = getReasoningText(additionalKwargs.reasoning);\n if (reasoning != null) {\n return reasoning;\n }\n\n return getReasoningDetailsText(additionalKwargs.reasoning_details);\n}\n\nfunction hasReasoningContent(content: BaseMessage['content']): boolean {\n if (!Array.isArray(content)) {\n return false;\n }\n return content.some((item) => {\n if (typeof item !== 'object' || !('type' in item)) {\n return false;\n }\n return (\n item.type === ContentTypes.THINK ||\n item.type === ContentTypes.THINKING ||\n item.type === ContentTypes.REASONING ||\n item.type === ContentTypes.REASONING_CONTENT ||\n item.type === 'redacted_thinking'\n );\n });\n}\n\nexport function modifyDeltaProperties(\n provider: Providers,\n obj?: AIMessageChunk\n): AIMessageChunk | undefined {\n if (!obj || typeof obj !== 'object') return obj;\n\n const messageType = (obj as Partial<AIMessageChunk>)._getType\n ? obj._getType()\n : '';\n\n if (provider === Providers.BEDROCK && Array.isArray(obj.content)) {\n obj.content = toLangChainContent(\n reduceBlocks(obj.content as ContentBlock[])\n );\n }\n if (Array.isArray(obj.content)) {\n obj.content = toLangChainContent(\n modifyContent({\n provider,\n messageType,\n content: obj.content as t.ExtendedMessageContent[],\n }) as t.MessageContentComplex[]\n );\n }\n if (\n (obj as Partial<AIMessageChunk>).lc_kwargs &&\n Array.isArray(obj.lc_kwargs.content)\n ) {\n if (provider === Providers.BEDROCK) {\n obj.lc_kwargs.content = reduceBlocks(\n obj.lc_kwargs.content as ContentBlock[]\n );\n }\n obj.lc_kwargs.content = modifyContent({\n provider,\n messageType,\n content: obj.lc_kwargs.content,\n });\n }\n return obj;\n}\n\nexport function formatAnthropicMessage(message: AIMessageChunk): AIMessage {\n if (!message.tool_calls || message.tool_calls.length === 0) {\n return new AIMessage({ content: toLangChainContent(message.content) });\n }\n\n const toolCallMap = new Map(message.tool_calls.map((tc) => [tc.id, tc]));\n let formattedContent: string | t.ExtendedMessageContent[];\n\n if (Array.isArray(message.content)) {\n formattedContent = message.content.reduce<t.ExtendedMessageContent[]>(\n (acc, item) => {\n if (typeof item === 'object') {\n const extendedItem = item as t.ExtendedMessageContent;\n if (\n extendedItem.type === 'text' &&\n extendedItem.text != null &&\n extendedItem.text\n ) {\n acc.push({ type: 'text', text: extendedItem.text });\n } else if (\n extendedItem.type === 'tool_use' &&\n extendedItem.id != null &&\n extendedItem.id\n ) {\n const toolCall = toolCallMap.get(extendedItem.id);\n if (toolCall) {\n acc.push({\n type: 'tool_use',\n id: extendedItem.id,\n name: toolCall.name,\n input: toolCall.args as unknown as string,\n });\n }\n } else if (\n 'input' in extendedItem &&\n extendedItem.input != null &&\n extendedItem.input\n ) {\n try {\n const parsedInput = JSON.parse(extendedItem.input);\n const toolCall = message.tool_calls?.find(\n (tc) => tc.args.input === parsedInput.input\n );\n if (toolCall) {\n acc.push({\n type: 'tool_use',\n id: toolCall.id,\n name: toolCall.name,\n input: toolCall.args as unknown as string,\n });\n }\n } catch {\n if (extendedItem.input) {\n acc.push({ type: 'text', text: extendedItem.input });\n }\n }\n }\n } else if (typeof item === 'string') {\n acc.push({ type: 'text', text: item });\n }\n return acc;\n },\n []\n );\n } else if (typeof message.content === 'string') {\n formattedContent = message.content;\n } else {\n formattedContent = [];\n }\n\n // const formattedToolCalls: ToolCall[] = message.tool_calls.map(toolCall => ({\n // id: toolCall.id ?? '',\n // name: toolCall.name,\n // args: toolCall.args,\n // type: 'tool_call',\n // }));\n\n const formattedToolCalls: t.AgentToolCall[] = message.tool_calls.map(\n (toolCall) => ({\n id: toolCall.id ?? '',\n type: 'function',\n function: {\n name: toolCall.name,\n arguments: toolCall.args,\n },\n })\n );\n\n return new AIMessage({\n content: toLangChainContent(formattedContent),\n tool_calls: formattedToolCalls as ToolCall[],\n additional_kwargs: {\n ...message.additional_kwargs,\n },\n });\n}\n\nexport function convertMessagesToContent(\n messages: BaseMessage[]\n): t.MessageContentComplex[] {\n const processedContent: t.MessageContentComplex[] = [];\n\n const addToolCallBoundary = (): number => {\n processedContent.push({ type: ContentTypes.TEXT, text: '' });\n return processedContent.length - 1;\n };\n\n const addContentPart = (message: BaseMessage | null): number | undefined => {\n const content =\n message?.lc_kwargs.content != null\n ? message.lc_kwargs.content\n : message?.content;\n if (content === undefined) {\n return undefined;\n }\n const reasoningContent =\n message?._getType() === 'ai' && !hasReasoningContent(content)\n ? getAdditionalReasoningContent(message)\n : undefined;\n if (reasoningContent != null) {\n processedContent.push({\n type: ContentTypes.THINK,\n think: reasoningContent,\n });\n }\n if (typeof content === 'string') {\n if (content === '') {\n return undefined;\n }\n processedContent.push({\n type: ContentTypes.TEXT,\n text: content,\n });\n return processedContent.length - 1;\n } else if (Array.isArray(content)) {\n let textContentIndex: number | undefined;\n for (const item of content) {\n if (item == null || item.type === 'tool_use') {\n continue;\n }\n processedContent.push(item);\n if (item.type === ContentTypes.TEXT) {\n textContentIndex = processedContent.length - 1;\n }\n }\n return textContentIndex;\n }\n return undefined;\n };\n\n let currentAIMessageIndex = -1;\n const toolCallMap = new Map<string, t.CustomToolCall>();\n\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i] as BaseMessage | null;\n const messageType = message?._getType();\n\n if (\n messageType === 'ai' &&\n ((message as AIMessage).tool_calls?.length ?? 0) > 0\n ) {\n const tool_calls = (message as AIMessage).tool_calls || [];\n for (const tool_call of tool_calls) {\n if (tool_call.id == null || !tool_call.id) {\n continue;\n }\n\n toolCallMap.set(tool_call.id, tool_call);\n }\n\n currentAIMessageIndex = addContentPart(message) ?? addToolCallBoundary();\n continue;\n } else if (\n messageType === 'tool' &&\n (message as ToolMessage).tool_call_id\n ) {\n const id = (message as ToolMessage).tool_call_id;\n const output = (message as ToolMessage).content;\n const tool_call = toolCallMap.get(id);\n if (currentAIMessageIndex === -1) {\n processedContent.push({ type: 'text', text: '' });\n currentAIMessageIndex = processedContent.length - 1;\n }\n const contentPart = processedContent[currentAIMessageIndex];\n processedContent.push({\n type: 'tool_call',\n tool_call: Object.assign({}, tool_call, { output }),\n });\n const tool_call_ids = contentPart.tool_call_ids || [];\n tool_call_ids.push(id);\n contentPart.tool_call_ids = tool_call_ids;\n continue;\n } else if (messageType !== 'ai') {\n continue;\n }\n\n addContentPart(message);\n }\n\n return processedContent;\n}\n\nfunction stringifyToolMessageContent(\n content: ToolMessage['content'] | null | undefined\n): string {\n return content == null ? '' : String(content);\n}\n\nfunction appendContentBlocks(\n target: t.MessageContentComplex[],\n content: BaseMessage['content']\n): void {\n if (typeof content === 'string') {\n target.push({ type: ContentTypes.TEXT, text: content });\n return;\n }\n for (const block of content) {\n target.push(block as t.MessageContentComplex);\n }\n}\n\n/**\n * Appends one artifact/tool-content segment without retaining an unbounded\n * intermediate block array. Both operands are compacted before they are\n * combined, and the combined result is compacted again under the aggregate\n * cap.\n */\nfunction appendBoundedContent(\n current: BaseMessage['content'] | undefined,\n next: unknown,\n maxChars: number\n): BaseMessage['content'] {\n const boundedNext = compactToolContent(next, maxChars).content;\n if (current == null) {\n return boundedNext;\n }\n\n const combined: t.MessageContentComplex[] = [];\n appendContentBlocks(combined, current);\n appendContentBlocks(combined, boundedNext);\n return compactToolContent(toLangChainContent(combined), maxChars).content;\n}\n\nfunction cloneAIMessageWithToolCalls(\n message: AIMessage,\n toolCalls: ToolCall[],\n removedCallIds: ReadonlySet<string>\n): AIMessage {\n const descriptors = Object.getOwnPropertyDescriptors(message) as Record<\n string,\n PropertyDescriptor | undefined\n >;\n let descriptor = descriptors.tool_calls;\n descriptors.tool_calls = {\n configurable: descriptor?.configurable ?? true,\n enumerable: descriptor?.enumerable ?? true,\n value: toolCalls,\n writable: descriptor?.writable ?? true,\n };\n const toolCallChunks = descriptors.tool_call_chunks?.value as\n | ToolCallChunk[]\n | undefined;\n if (Array.isArray(toolCallChunks)) {\n descriptor = descriptors.tool_call_chunks;\n descriptors.tool_call_chunks = {\n configurable: descriptor?.configurable ?? true,\n enumerable: descriptor?.enumerable ?? true,\n value: toolCallChunks.filter(\n (chunk) => typeof chunk.id !== 'string' || !removedCallIds.has(chunk.id)\n ),\n writable: descriptor?.writable ?? true,\n };\n }\n return Object.create(\n Object.getPrototypeOf(message),\n descriptors as PropertyDescriptorMap\n ) as AIMessage;\n}\n\nfunction cloneAIMessageWithContent(\n message: AIMessage,\n content: AIMessage['content']\n): AIMessage {\n const descriptors = Object.getOwnPropertyDescriptors(message) as Record<\n string,\n PropertyDescriptor | undefined\n >;\n const descriptor = descriptors.content;\n descriptors.content = {\n configurable: descriptor?.configurable ?? true,\n enumerable: descriptor?.enumerable ?? true,\n value: content,\n writable: descriptor?.writable ?? true,\n };\n const lcKwargs = descriptors.lc_kwargs;\n if (\n lcKwargs != null &&\n 'value' in lcKwargs &&\n typeof lcKwargs.value === 'object' &&\n lcKwargs.value != null\n ) {\n descriptors.lc_kwargs = {\n ...lcKwargs,\n value: {\n ...(lcKwargs.value as Record<string, unknown>),\n content,\n },\n };\n }\n return Object.create(\n Object.getPrototypeOf(message),\n descriptors as PropertyDescriptorMap\n ) as AIMessage;\n}\n\n/**\n * Drops incomplete streamed text-input fragments that some providers retain\n * beside the assembled parsed tool call. They are neither user-visible text\n * nor valid content blocks for a subsequent provider.\n */\nexport function projectToolStreamContentForProvider(\n messages: BaseMessage[]\n): BaseMessage[] {\n let projected: BaseMessage[] | undefined;\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i];\n if (message.getType() !== 'ai' || !Array.isArray(message.content)) {\n continue;\n }\n const content = message.content.filter((block) => {\n if (block == null || typeof block !== 'object') {\n return true;\n }\n try {\n if (isProxy(block)) {\n return false;\n }\n const type = Object.getOwnPropertyDescriptor(block, 'type');\n if (type == null) {\n return true;\n }\n if (type.enumerable !== true || !('value' in type)) {\n return false;\n }\n if (type.value !== 'text') {\n return true;\n }\n const text = Object.getOwnPropertyDescriptor(block, 'text');\n return (\n text?.enumerable === true &&\n 'value' in text &&\n typeof text.value === 'string' &&\n text.value !== ''\n );\n } catch {\n return false;\n }\n });\n if (content.length === message.content.length) {\n continue;\n }\n projected ??= [...messages];\n projected[i] = cloneAIMessageWithContent(\n message as AIMessage,\n toLangChainContent(content)\n );\n }\n return projected ?? messages;\n}\n\ntype CacheControlledTextProjection = 'serialize' | 'preserve' | 'text';\n\nfunction projectStructuredOpenAIToolContent(\n content: ToolMessage['content'],\n maxChars: number,\n cacheControlledTextProjection: CacheControlledTextProjection\n): ToolMessage['content'] {\n if (cacheControlledTextProjection !== 'serialize') {\n const cacheControlledContent = getBoundedCacheControlledTextToolContent(\n content,\n maxChars\n );\n if (cacheControlledContent != null) {\n return cacheControlledTextProjection === 'preserve'\n ? cacheControlledContent\n : cacheControlledContent[0].text;\n }\n const singleTextContent = getBoundedSingleTextToolContent(\n content,\n maxChars\n );\n if (singleTextContent != null) {\n return singleTextContent;\n }\n }\n const serializableContent =\n cacheControlledTextProjection === 'preserve'\n ? stripAnthropicCacheControl([{ content }])[0].content\n : content;\n return serializeToolContentBounded(serializableContent, maxChars);\n}\n\n/**\n * OpenAI Chat tool messages only accept strings or text-only parts, while the\n * Responses API serializes any structured ToolMessage after graph accounting.\n * Project every non-string tool result to one bounded string before the final\n * provider payload is measured so both APIs receive the exact representation\n * the budget guard counted. Native Responses computer screenshots stay\n * structured because their dedicated converter sends the media block directly.\n */\nfunction projectOpenAIToolMessageContentInternal(\n messages: BaseMessage[],\n maxChars: number,\n deduplicateResponsesComputerCalls: boolean,\n cacheControlledTextProjection: CacheControlledTextProjection\n): BaseMessage[] {\n const pendingComputerCallIds: string[] = [];\n const seenComputerCallIds = new Set<string>();\n let projected: BaseMessage[] | undefined;\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i];\n const messageRole = (message as BaseMessage & { role?: unknown }).role;\n const isAssistant =\n message.getType() === 'ai' || messageRole === 'assistant';\n if (isAssistant) {\n const parsedComputerCallIds = new Set<string>();\n const toolCalls = (message as AIMessage).tool_calls;\n if (Array.isArray(toolCalls)) {\n for (const toolCall of toolCalls) {\n const record = toolCall as ToolCall & {\n isComputerTool?: unknown;\n };\n if (\n record.type !== 'tool_call' ||\n record.isComputerTool !== true ||\n typeof record.id !== 'string' ||\n record.id === ''\n ) {\n continue;\n }\n if (parsedComputerCallIds.has(record.id)) {\n throw new Error(`Duplicate computer call id \"${record.id}\"`);\n }\n parsedComputerCallIds.add(record.id);\n if (seenComputerCallIds.has(record.id)) {\n throw new Error(`Duplicate computer call id \"${record.id}\"`);\n }\n seenComputerCallIds.add(record.id);\n pendingComputerCallIds.push(record.id);\n }\n }\n\n const rawOutput = (\n message.response_metadata as {\n output?: unknown;\n }\n ).output;\n const fallbackOutput = (\n message.additional_kwargs as {\n tool_outputs?: unknown;\n }\n ).tool_outputs;\n let actualToolOutputs: unknown[] = [];\n if (Array.isArray(rawOutput) && rawOutput.length > 0) {\n actualToolOutputs = rawOutput;\n } else if (Array.isArray(fallbackOutput)) {\n actualToolOutputs = fallbackOutput;\n }\n const rawComputerCallIds = new Set<string>();\n for (const item of actualToolOutputs) {\n if (item == null || typeof item !== 'object') {\n continue;\n }\n const record = item as {\n type?: unknown;\n call_id?: unknown;\n };\n if (\n record.type !== 'computer_call' ||\n typeof record.call_id !== 'string' ||\n record.call_id === ''\n ) {\n continue;\n }\n if (rawComputerCallIds.has(record.call_id)) {\n throw new Error(`Duplicate computer call id \"${record.call_id}\"`);\n }\n rawComputerCallIds.add(record.call_id);\n // LangChain can retain the same call in parsed and raw forms. It sends\n // one logical call, so collapse that representation duplicate.\n if (parsedComputerCallIds.has(record.call_id)) {\n continue;\n }\n if (seenComputerCallIds.has(record.call_id)) {\n throw new Error(`Duplicate computer call id \"${record.call_id}\"`);\n }\n seenComputerCallIds.add(record.call_id);\n pendingComputerCallIds.push(record.call_id);\n }\n\n if (\n deduplicateResponsesComputerCalls &&\n Array.isArray(toolCalls) &&\n rawComputerCallIds.size > 0\n ) {\n /**\n * The non-streaming Responses converter marks parsed computer calls,\n * but the streaming converter currently emits the same call as an\n * ordinary parsed `computer_use` tool call. In both cases the raw\n * `computer_call` item is authoritative and is replayed by LangChain,\n * so remove every parsed representation with the same call id.\n */\n const projectedToolCalls = toolCalls.filter(\n (toolCall) =>\n typeof toolCall.id !== 'string' ||\n !rawComputerCallIds.has(toolCall.id)\n );\n if (projectedToolCalls.length !== toolCalls.length) {\n projected ??= [...messages];\n projected[i] = cloneAIMessageWithToolCalls(\n message as AIMessage,\n projectedToolCalls,\n rawComputerCallIds\n );\n }\n }\n }\n\n if (\n message instanceof ToolMessage &&\n hasComputerCallOutputMarker(message)\n ) {\n const screenshot = getComputerCallOutputScreenshot(message.content);\n if (screenshot == null) {\n throw new Error('Invalid computer call output screenshot');\n }\n if (pendingComputerCallIds[0] !== message.tool_call_id) {\n throw new Error(\n `Invalid computer call output pairing for \"${message.tool_call_id}\"`\n );\n }\n pendingComputerCallIds.shift();\n projected ??= [...messages];\n projected[i] = cloneToolMessageWithContent(message, [screenshot]);\n continue;\n }\n if (\n !(message instanceof ToolMessage) ||\n typeof message.content === 'string'\n ) {\n continue;\n }\n projected ??= [...messages];\n projected[i] = cloneToolMessageWithContent(\n message,\n projectStructuredOpenAIToolContent(\n message.content,\n maxChars,\n cacheControlledTextProjection\n )\n );\n }\n if (pendingComputerCallIds.length > 0) {\n throw new Error(\n `Missing computer call output for \"${pendingComputerCallIds[0]}\"`\n );\n }\n return projected ?? messages;\n}\n\n/** Projects OpenAI-compatible tool content without changing parsed call parents. */\nexport function projectOpenAIToolMessageContent(\n messages: BaseMessage[],\n maxChars = HARD_MAX_TOOL_RESULT_CHARS\n): BaseMessage[] {\n return projectOpenAIToolMessageContentInternal(\n messages,\n maxChars,\n false,\n 'serialize'\n );\n}\n\n/** Projects an actual OpenAI-compatible Chat attempt and removes cache metadata. */\nexport function projectOpenAIChatToolMessageContent(\n messages: BaseMessage[],\n maxChars = HARD_MAX_TOOL_RESULT_CHARS\n): BaseMessage[] {\n return projectOpenAIToolMessageContentInternal(\n messages,\n maxChars,\n false,\n 'text'\n );\n}\n\n/** Preserves OpenRouter's cache-decorated text blocks for a Chat attempt. */\nexport function projectOpenRouterToolMessageContent(\n messages: BaseMessage[],\n maxChars = HARD_MAX_TOOL_RESULT_CHARS\n): BaseMessage[] {\n return projectOpenAIToolMessageContentInternal(\n messages,\n maxChars,\n false,\n 'preserve'\n );\n}\n\n/** Projects Responses tool content and collapses parsed/raw computer-call mirrors. */\nexport function projectOpenAIResponsesToolMessageContent(\n messages: BaseMessage[],\n maxChars = HARD_MAX_TOOL_RESULT_CHARS\n): BaseMessage[] {\n return projectOpenAIToolMessageContentInternal(\n messages,\n maxChars,\n true,\n 'text'\n );\n}\n\n/** Removes Anthropic/OpenRouter cache metadata before unsupported providers run. */\nexport function projectCacheControlledToolOutputsToText(\n messages: BaseMessage[],\n maxChars = HARD_MAX_TOOL_RESULT_CHARS\n): BaseMessage[] {\n let projected: BaseMessage[] | undefined;\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i];\n if (\n !(message instanceof ToolMessage) ||\n typeof message.content === 'string'\n ) {\n continue;\n }\n const cacheControlledContent = getBoundedCacheControlledTextToolContent(\n message.content,\n maxChars\n );\n if (cacheControlledContent == null) {\n continue;\n }\n projected ??= [...messages];\n projected[i] = cloneToolMessageWithContent(\n message,\n cacheControlledContent[0].text\n );\n }\n return projected ?? messages;\n}\n\n/** Unwraps a canonical single text block after provider cache markers are removed. */\nexport function projectSingleTextToolOutputsToText(\n messages: BaseMessage[],\n maxChars = HARD_MAX_TOOL_RESULT_CHARS\n): BaseMessage[] {\n let projected: BaseMessage[] | undefined;\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i];\n if (\n !(message instanceof ToolMessage) ||\n typeof message.content === 'string'\n ) {\n continue;\n }\n const text = getBoundedSingleTextToolContent(message.content, maxChars);\n if (text == null) {\n continue;\n }\n projected ??= [...messages];\n projected[i] = cloneToolMessageWithContent(message, text);\n }\n return projected ?? messages;\n}\n\n/** Serializes provider-neutral structured tool outputs without media pairing. */\nexport function projectStructuredToolOutputsToText(\n messages: BaseMessage[],\n maxChars = HARD_MAX_TOOL_RESULT_CHARS\n): BaseMessage[] {\n let projected: BaseMessage[] | undefined;\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i];\n if (\n !(message instanceof ToolMessage) ||\n typeof message.content === 'string' ||\n hasComputerCallOutputMarker(message)\n ) {\n continue;\n }\n projected ??= [...messages];\n projected[i] = cloneToolMessageWithContent(\n message,\n serializeToolContentBounded(message.content, maxChars)\n );\n }\n return projected ?? messages;\n}\n\n/**\n * Non-Responses providers cannot consume native computer screenshots. Keep\n * the tool-call structure intact, but replace screenshot bytes with a bounded\n * text marker at the actual invocation boundary.\n */\nexport function projectComputerCallOutputsToText(\n messages: BaseMessage[]\n): BaseMessage[] {\n let projected: BaseMessage[] | undefined;\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i];\n if (\n !(message instanceof ToolMessage) ||\n !hasComputerCallOutputMarker(message)\n ) {\n continue;\n }\n projected ??= [...messages];\n projected[i] = cloneToolMessageWithContent(\n message,\n '[Computer screenshot omitted for this provider]'\n );\n }\n return projected ?? messages;\n}\n\nexport function projectAnthropicArtifactContent(\n messages: BaseMessage[],\n maxChars = HARD_MAX_TOOL_RESULT_CHARS\n): BaseMessage[] {\n const lastMessage = messages[messages.length - 1];\n if (!(lastMessage instanceof ToolMessage)) return messages;\n\n // Find the latest AIMessage with tool_calls that this tool message belongs to\n const latestAIParentIndex = findLastIndex(\n messages,\n (msg) =>\n ((msg instanceof AIMessage || msg instanceof AIMessageChunk) &&\n (msg.tool_calls?.length ?? 0) > 0 &&\n msg.tool_calls?.some((tc) => tc.id === lastMessage.tool_call_id)) ??\n false\n );\n\n if (latestAIParentIndex === -1) return messages;\n\n // Build tool call ID set and merge artifact content in a single forward pass.\n const message = messages[latestAIParentIndex] as AIMessage | AIMessageChunk;\n const toolCallIdSet = new Set<string>();\n if (message.tool_calls) {\n for (const tc of message.tool_calls) {\n if (tc.id != null) {\n toolCallIdSet.add(tc.id);\n }\n }\n }\n\n let formattedMessages: BaseMessage[] | undefined;\n for (let j = latestAIParentIndex + 1; j < messages.length; j++) {\n const msg = messages[j];\n if (\n msg instanceof ToolMessage &&\n !isComputerCallOutputMessage(msg) &&\n toolCallIdSet.has(msg.tool_call_id) &&\n msg.artifact != null &&\n ((typeof msg.artifact?.content === 'string' &&\n msg.artifact.content.length > 0) ||\n (Array.isArray(msg.artifact?.content) &&\n msg.artifact.content.length > 0))\n ) {\n const artifactContent =\n typeof msg.artifact.content === 'string'\n ? [\n {\n type: ContentTypes.TEXT,\n text: msg.artifact.content,\n },\n ]\n : msg.artifact.content;\n const baseContent = Array.isArray(msg.content)\n ? msg.content\n : stringifyToolMessageContent(msg.content);\n const content = appendBoundedContent(\n compactToolContent(baseContent, maxChars).content,\n artifactContent,\n maxChars\n );\n formattedMessages ??= [...messages];\n formattedMessages[j] = cloneToolMessageWithContent(msg, content, {\n ...msg.artifact,\n content: [],\n });\n }\n }\n return formattedMessages ?? messages;\n}\n\n/**\n * Mutating compatibility wrapper retained for existing package consumers.\n * New provider-call paths should use `projectAnthropicArtifactContent`.\n */\nexport function formatAnthropicArtifactContent(messages: BaseMessage[]): void {\n const projected = projectAnthropicArtifactContent(messages);\n if (projected === messages) {\n return;\n }\n for (let i = 0; i < messages.length; i++) {\n if (\n messages[i] instanceof ToolMessage &&\n projected[i] instanceof ToolMessage &&\n projected[i] !== messages[i]\n ) {\n messages[i].content = projected[i].content;\n }\n }\n}\n\nexport function projectArtifactPayload(\n messages: BaseMessage[],\n maxChars = HARD_MAX_TOOL_RESULT_CHARS\n): BaseMessage[] {\n const lastMessageY = messages[messages.length - 1];\n if (!(lastMessageY instanceof ToolMessage)) return messages;\n\n // Find the latest AIMessage with tool_calls that this tool message belongs to\n const latestAIParentIndex = findLastIndex(\n messages,\n (msg) =>\n ((msg instanceof AIMessage || msg instanceof AIMessageChunk) &&\n (msg.tool_calls?.length ?? 0) > 0 &&\n msg.tool_calls?.some((tc) => tc.id === lastMessageY.tool_call_id)) ??\n false\n );\n\n if (latestAIParentIndex === -1) return messages;\n\n // Single pass: collect relevant tool messages with artifacts and aggregate\n let aggregatedContent: BaseMessage['content'] | undefined;\n let formattedMessages: BaseMessage[] | undefined;\n\n for (let i = latestAIParentIndex + 1; i < messages.length; i++) {\n const msg = messages[i];\n if (\n !(msg instanceof ToolMessage) ||\n isComputerCallOutputMessage(msg) ||\n !(\n (typeof msg.artifact?.content === 'string' &&\n msg.artifact.content.length > 0) ||\n (Array.isArray(msg.artifact?.content) &&\n msg.artifact.content.length > 0)\n )\n ) {\n continue;\n }\n aggregatedContent = appendBoundedContent(\n aggregatedContent,\n msg.content,\n maxChars\n );\n formattedMessages ??= [...messages];\n formattedMessages[i] = cloneToolMessageWithContent(\n msg,\n 'Tool response is included in the next message as a Human message',\n {\n ...msg.artifact,\n content: [],\n }\n );\n aggregatedContent = appendBoundedContent(\n aggregatedContent,\n msg.artifact.content,\n maxChars\n );\n }\n\n if (aggregatedContent != null) {\n formattedMessages?.push(new HumanMessage({ content: aggregatedContent }));\n }\n return formattedMessages ?? messages;\n}\n\n/**\n * Mutating compatibility wrapper retained for existing package consumers.\n * New provider-call paths should use `projectArtifactPayload`.\n */\nexport function formatArtifactPayload(messages: BaseMessage[]): void {\n const originalLength = messages.length;\n const projected = projectArtifactPayload(messages);\n if (projected === messages) {\n return;\n }\n for (let i = 0; i < originalLength; i++) {\n if (\n messages[i] instanceof ToolMessage &&\n projected[i] instanceof ToolMessage &&\n projected[i] !== messages[i]\n ) {\n messages[i].content = projected[i].content;\n }\n }\n messages.push(...projected.slice(originalLength));\n}\n\nexport function findLastIndex<T>(\n array: T[],\n predicate: (value: T) => boolean\n): number {\n for (let i = array.length - 1; i >= 0; i--) {\n if (predicate(array[i])) {\n return i;\n }\n }\n return -1;\n}\n"],"mappings":"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"}
|