@librechat/agents 3.7.22 → 3.8.1
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 +13 -3
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +174 -53
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +15 -5
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/langfuse.cjs +48 -2
- package/dist/cjs/langfuse.cjs.map +1 -1
- package/dist/cjs/langfuseToolOutputTracing.cjs +42 -0
- package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
- package/dist/cjs/langfuseTraceShaping.cjs +7 -1
- package/dist/cjs/langfuseTraceShaping.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +5 -9
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +2 -7
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/contextPressureMeter.cjs +51 -10
- package/dist/cjs/llm/contextPressureMeter.cjs.map +1 -1
- package/dist/cjs/llm/init.cjs +1 -1
- package/dist/cjs/llm/invoke.cjs +2 -2
- package/dist/cjs/llm/openai/index.cjs +4 -3
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +5 -4
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/llm/preempt.cjs +3 -2
- package/dist/cjs/llm/preempt.cjs.map +1 -1
- package/dist/cjs/llm/prepareProviderRequest.cjs +9 -7
- package/dist/cjs/llm/prepareProviderRequest.cjs.map +1 -1
- package/dist/cjs/llm/providers.cjs +1 -1
- package/dist/cjs/main.cjs +11 -5
- package/dist/cjs/messages/alternation.cjs +1 -5
- package/dist/cjs/messages/alternation.cjs.map +1 -1
- package/dist/cjs/messages/budget.cjs +206 -7
- package/dist/cjs/messages/budget.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +3 -9
- package/dist/cjs/messages/cache.cjs.map +1 -1
- package/dist/cjs/messages/core.cjs +25 -37
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +131 -42
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/index.cjs +2 -0
- package/dist/cjs/messages/prune.cjs +12 -7
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/messages/reasoningTypes.cjs +21 -0
- package/dist/cjs/messages/reasoningTypes.cjs.map +1 -0
- package/dist/cjs/messages/recency.cjs +15 -94
- package/dist/cjs/messages/recency.cjs.map +1 -1
- package/dist/cjs/messages/toolHistoryProjection.cjs +243 -0
- package/dist/cjs/messages/toolHistoryProjection.cjs.map +1 -0
- package/dist/cjs/messages/toolResultTypes.cjs +145 -4
- package/dist/cjs/messages/toolResultTypes.cjs.map +1 -1
- package/dist/cjs/run.cjs +5 -4
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/session/AgentSession.cjs +6 -4
- package/dist/cjs/session/AgentSession.cjs.map +1 -1
- package/dist/cjs/session/JsonlSessionStore.cjs +3 -0
- package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -1
- package/dist/cjs/session/index.cjs +1 -1
- package/dist/cjs/session/sessionProjection.cjs +75 -0
- package/dist/cjs/session/sessionProjection.cjs.map +1 -0
- package/dist/cjs/stream.cjs +18 -17
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/summarization/index.cjs.map +1 -1
- package/dist/cjs/summarization/node.cjs +18 -8
- package/dist/cjs/summarization/node.cjs.map +1 -1
- package/dist/cjs/summarization/shared.cjs +9 -0
- package/dist/cjs/summarization/shared.cjs.map +1 -1
- package/dist/cjs/tools/ArtifactDelivery.cjs +27 -0
- package/dist/cjs/tools/ArtifactDelivery.cjs.map +1 -0
- package/dist/cjs/tools/BashExecutor.cjs +6 -1
- package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
- package/dist/cjs/tools/CodeExecutor.cjs +6 -1
- package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs +5 -1
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/local/CompileCheckTool.cjs +1 -1
- package/dist/cjs/tools/local/LocalCodingTools.cjs +1 -1
- package/dist/cjs/utils/events.cjs +13 -0
- package/dist/cjs/utils/events.cjs.map +1 -1
- package/dist/cjs/utils/tokens.cjs +105 -0
- package/dist/cjs/utils/tokens.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +13 -3
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +176 -55
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +15 -5
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/langfuse.mjs +49 -4
- package/dist/esm/langfuse.mjs.map +1 -1
- package/dist/esm/langfuseToolOutputTracing.mjs +41 -1
- package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
- package/dist/esm/langfuseTraceShaping.mjs +7 -1
- package/dist/esm/langfuseTraceShaping.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +5 -9
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs +2 -7
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/contextPressureMeter.mjs +52 -11
- package/dist/esm/llm/contextPressureMeter.mjs.map +1 -1
- package/dist/esm/llm/init.mjs +1 -1
- package/dist/esm/llm/invoke.mjs +2 -2
- package/dist/esm/llm/openai/index.mjs +2 -1
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +5 -4
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/llm/preempt.mjs +2 -1
- package/dist/esm/llm/preempt.mjs.map +1 -1
- package/dist/esm/llm/prepareProviderRequest.mjs +9 -7
- package/dist/esm/llm/prepareProviderRequest.mjs.map +1 -1
- package/dist/esm/llm/providers.mjs +1 -1
- package/dist/esm/main.mjs +10 -7
- package/dist/esm/messages/alternation.mjs +2 -6
- package/dist/esm/messages/alternation.mjs.map +1 -1
- package/dist/esm/messages/budget.mjs +206 -8
- package/dist/esm/messages/budget.mjs.map +1 -1
- package/dist/esm/messages/cache.mjs +3 -9
- package/dist/esm/messages/cache.mjs.map +1 -1
- package/dist/esm/messages/core.mjs +23 -33
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +132 -43
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/index.mjs +2 -0
- package/dist/esm/messages/prune.mjs +12 -7
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/messages/reasoningTypes.mjs +20 -0
- package/dist/esm/messages/reasoningTypes.mjs.map +1 -0
- package/dist/esm/messages/recency.mjs +16 -95
- package/dist/esm/messages/recency.mjs.map +1 -1
- package/dist/esm/messages/toolHistoryProjection.mjs +237 -0
- package/dist/esm/messages/toolHistoryProjection.mjs.map +1 -0
- package/dist/esm/messages/toolResultTypes.mjs +141 -4
- package/dist/esm/messages/toolResultTypes.mjs.map +1 -1
- package/dist/esm/run.mjs +5 -4
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/session/AgentSession.mjs +6 -4
- package/dist/esm/session/AgentSession.mjs.map +1 -1
- package/dist/esm/session/JsonlSessionStore.mjs +3 -0
- package/dist/esm/session/JsonlSessionStore.mjs.map +1 -1
- package/dist/esm/session/index.mjs +1 -1
- package/dist/esm/session/sessionProjection.mjs +72 -0
- package/dist/esm/session/sessionProjection.mjs.map +1 -0
- package/dist/esm/stream.mjs +15 -14
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/summarization/index.mjs.map +1 -1
- package/dist/esm/summarization/node.mjs +19 -9
- package/dist/esm/summarization/node.mjs.map +1 -1
- package/dist/esm/summarization/shared.mjs +9 -1
- package/dist/esm/summarization/shared.mjs.map +1 -1
- package/dist/esm/tools/ArtifactDelivery.mjs +26 -0
- package/dist/esm/tools/ArtifactDelivery.mjs.map +1 -0
- package/dist/esm/tools/BashExecutor.mjs +6 -1
- package/dist/esm/tools/BashExecutor.mjs.map +1 -1
- package/dist/esm/tools/CodeExecutor.mjs +6 -1
- package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
- package/dist/esm/tools/ProgrammaticToolCalling.mjs +5 -1
- package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/local/CompileCheckTool.mjs +1 -1
- package/dist/esm/tools/local/LocalCodingTools.mjs +1 -1
- package/dist/esm/utils/events.mjs +13 -0
- package/dist/esm/utils/events.mjs.map +1 -1
- package/dist/esm/utils/tokens.mjs +105 -1
- package/dist/esm/utils/tokens.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +13 -1
- package/dist/types/graphs/Graph.d.ts +27 -0
- package/dist/types/hooks/types.d.ts +4 -2
- package/dist/types/index.d.ts +1 -0
- package/dist/types/langfuse.d.ts +10 -0
- package/dist/types/langfuseToolOutputTracing.d.ts +2 -0
- package/dist/types/llm/contextPressureMeter.d.ts +2 -1
- package/dist/types/llm/prepareProviderRequest.d.ts +7 -1
- package/dist/types/messages/budget.d.ts +15 -10
- package/dist/types/messages/core.d.ts +8 -17
- package/dist/types/messages/format.d.ts +3 -2
- package/dist/types/messages/index.d.ts +1 -1
- package/dist/types/messages/prune.d.ts +1 -1
- package/dist/types/messages/reasoningTypes.d.ts +7 -0
- package/dist/types/messages/recency.d.ts +3 -0
- package/dist/types/messages/toolHistoryProjection.d.ts +65 -0
- package/dist/types/messages/toolResultTypes.d.ts +31 -1
- package/dist/types/session/sessionProjection.d.ts +10 -0
- package/dist/types/summarization/index.d.ts +2 -1
- package/dist/types/summarization/node.d.ts +1 -0
- package/dist/types/summarization/shared.d.ts +12 -0
- package/dist/types/tools/ArtifactDelivery.d.ts +4 -0
- package/dist/types/types/graph.d.ts +28 -0
- package/dist/types/types/run.d.ts +4 -0
- package/dist/types/types/summarize.d.ts +4 -1
- package/dist/types/types/tools.d.ts +11 -0
- package/dist/types/utils/tokens.d.ts +2 -1
- package/package.json +1 -1
- package/src/agents/AgentContext.ts +34 -3
- package/src/graphs/Graph.ts +465 -147
- package/src/graphs/MultiAgentGraph.ts +28 -6
- package/src/hooks/types.ts +4 -1
- package/src/index.ts +1 -0
- package/src/langfuse.ts +84 -11
- package/src/langfuseToolOutputTracing.ts +91 -0
- package/src/langfuseTraceShaping.ts +17 -4
- package/src/llm/anthropic/utils/message_inputs.ts +5 -10
- package/src/llm/bedrock/utils/message_inputs.ts +2 -8
- package/src/llm/contextPressureMeter.ts +80 -12
- package/src/llm/openai/utils/index.ts +5 -4
- package/src/llm/prepareProviderRequest.ts +21 -16
- package/src/messages/alternation.ts +2 -15
- package/src/messages/budget.ts +439 -23
- package/src/messages/cache.ts +8 -9
- package/src/messages/core.ts +65 -95
- package/src/messages/format.ts +262 -78
- package/src/messages/index.ts +1 -1
- package/src/messages/prune.ts +31 -12
- package/src/messages/reasoningTypes.ts +23 -0
- package/src/messages/recency.ts +35 -179
- package/src/messages/toolHistoryProjection.ts +460 -0
- package/src/messages/toolResultTypes.ts +331 -100
- package/src/run.ts +10 -2
- package/src/session/AgentSession.ts +33 -16
- package/src/session/JsonlSessionStore.ts +6 -0
- package/src/session/sessionProjection.ts +126 -0
- package/src/stream.ts +14 -19
- package/src/summarization/index.ts +2 -0
- package/src/summarization/node.ts +62 -13
- package/src/summarization/shared.ts +23 -0
- package/src/tools/ArtifactDelivery.ts +50 -0
- package/src/tools/BashExecutor.ts +18 -1
- package/src/tools/CodeExecutor.ts +18 -1
- package/src/tools/ProgrammaticToolCalling.ts +15 -1
- package/src/types/graph.ts +28 -0
- package/src/types/run.ts +4 -0
- package/src/types/summarize.ts +4 -1
- package/src/types/tools.ts +12 -0
- package/src/utils/events.ts +19 -0
- package/src/utils/tokens.ts +183 -0
package/src/messages/format.ts
CHANGED
|
@@ -13,6 +13,11 @@ import type {
|
|
|
13
13
|
} from '@langchain/core/messages';
|
|
14
14
|
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
15
15
|
import type { ToolCall } from '@langchain/core/messages/tool';
|
|
16
|
+
import type {
|
|
17
|
+
OrderedToolHistoryProjection,
|
|
18
|
+
ToolHistoryPreparation,
|
|
19
|
+
ToolHistoryCallMirrors,
|
|
20
|
+
} from './toolHistoryProjection';
|
|
16
21
|
import type {
|
|
17
22
|
BedrockReasoningContentText,
|
|
18
23
|
ExtendedMessageContent,
|
|
@@ -44,6 +49,7 @@ import {
|
|
|
44
49
|
getProviderToolCallPartDescriptor,
|
|
45
50
|
getProviderToolResultPartDescriptor,
|
|
46
51
|
hasStructurallyValidAnthropicWebSearchResultContent,
|
|
52
|
+
isProviderToolContentPart,
|
|
47
53
|
} from './toolResultTypes';
|
|
48
54
|
import {
|
|
49
55
|
hasBijectiveProviderContentPartMapping,
|
|
@@ -72,9 +78,15 @@ import {
|
|
|
72
78
|
} from '@/common';
|
|
73
79
|
import { normalizeAnthropicToolCallId } from '@/llm/anthropic/utils/message_inputs';
|
|
74
80
|
import { toLangChainContent, toLangChainMessageFields } from './langchain';
|
|
81
|
+
import { isReasoningContentBlock } from './reasoningTypes';
|
|
75
82
|
import { flattenLegacyContent, isLegacyConvertible } from './content';
|
|
76
83
|
import { HARD_MAX_TOOL_RESULT_CHARS } from '@/utils/truncation';
|
|
77
84
|
import { emitAgentLog } from '@/utils/events';
|
|
85
|
+
import {
|
|
86
|
+
createToolHistoryPreparation,
|
|
87
|
+
isToolHistoryCallMirror,
|
|
88
|
+
recordToolHistoryCallMirror,
|
|
89
|
+
} from './toolHistoryProjection';
|
|
78
90
|
|
|
79
91
|
interface MediaMessageParams {
|
|
80
92
|
message: {
|
|
@@ -437,10 +449,18 @@ function extractReasoningContent(
|
|
|
437
449
|
const thinking = (part as ThinkingContentText).thinking;
|
|
438
450
|
return typeof thinking === 'string' ? thinking : '';
|
|
439
451
|
}
|
|
452
|
+
if (part.type === 'thinking_delta') {
|
|
453
|
+
const thinking = readFoldedDataProperty(part, 'thinking');
|
|
454
|
+
return typeof thinking === 'string' ? thinking : '';
|
|
455
|
+
}
|
|
440
456
|
if (part.type === ContentTypes.REASONING) {
|
|
441
457
|
const reasoning = (part as GoogleReasoningContentText).reasoning;
|
|
442
458
|
return typeof reasoning === 'string' ? reasoning : '';
|
|
443
459
|
}
|
|
460
|
+
if (part.type === 'reasoning-delta') {
|
|
461
|
+
const reasoning = readFoldedDataProperty(part, 'reasoning');
|
|
462
|
+
return typeof reasoning === 'string' ? reasoning : '';
|
|
463
|
+
}
|
|
444
464
|
if (part.type === ContentTypes.REASONING_CONTENT) {
|
|
445
465
|
const reasoningText = (part as BedrockReasoningContentText).reasoningText;
|
|
446
466
|
return typeof reasoningText.text === 'string' ? reasoningText.text : '';
|
|
@@ -484,13 +504,7 @@ function hasMeaningfulAssistantContent(part: MessageContentComplex): boolean {
|
|
|
484
504
|
) {
|
|
485
505
|
return false;
|
|
486
506
|
}
|
|
487
|
-
if (
|
|
488
|
-
part.type === ContentTypes.THINK ||
|
|
489
|
-
part.type === ContentTypes.THINKING ||
|
|
490
|
-
part.type === ContentTypes.REASONING ||
|
|
491
|
-
part.type === ContentTypes.REASONING_CONTENT ||
|
|
492
|
-
part.type === 'redacted_thinking'
|
|
493
|
-
) {
|
|
507
|
+
if (isReasoningContentBlock(part)) {
|
|
494
508
|
return extractReasoningContent(part).trim().length > 0;
|
|
495
509
|
}
|
|
496
510
|
return part.type != null && part.type !== '';
|
|
@@ -599,8 +613,7 @@ function createDerivedCompactionSemanticIndexCollector(
|
|
|
599
613
|
Number.isSafeInteger(serializedProvidedEntryCount) &&
|
|
600
614
|
serializedProvidedEntryCount >= snapshotProvidedEntryCount;
|
|
601
615
|
const providedEntryCount =
|
|
602
|
-
validSerializedProvidedEntryCount &&
|
|
603
|
-
serializedProvidedEntryCount != null
|
|
616
|
+
validSerializedProvidedEntryCount && serializedProvidedEntryCount != null
|
|
604
617
|
? serializedProvidedEntryCount
|
|
605
618
|
: snapshotProvidedEntryCount;
|
|
606
619
|
collector.omittedBaseEntryCount = Math.max(
|
|
@@ -1983,13 +1996,7 @@ function formatAssistantMessage(
|
|
|
1983
1996
|
'tool',
|
|
1984
1997
|
sourcePartIndices
|
|
1985
1998
|
);
|
|
1986
|
-
} else if (
|
|
1987
|
-
part.type === ContentTypes.THINK ||
|
|
1988
|
-
part.type === ContentTypes.THINKING ||
|
|
1989
|
-
part.type === ContentTypes.REASONING ||
|
|
1990
|
-
part.type === ContentTypes.REASONING_CONTENT ||
|
|
1991
|
-
part.type === 'redacted_thinking'
|
|
1992
|
-
) {
|
|
1999
|
+
} else if (isReasoningContentBlock(part)) {
|
|
1993
2000
|
if (
|
|
1994
2001
|
part.type === ContentTypes.THINK &&
|
|
1995
2002
|
compactionSemanticIndex != null &&
|
|
@@ -3037,10 +3044,7 @@ export const formatAgentMessages = (
|
|
|
3037
3044
|
}
|
|
3038
3045
|
}
|
|
3039
3046
|
|
|
3040
|
-
if (
|
|
3041
|
-
discoveredTools.has(toolName) ||
|
|
3042
|
-
isSdkManagedToolName(toolName)
|
|
3043
|
-
) {
|
|
3047
|
+
if (discoveredTools.has(toolName) || isSdkManagedToolName(toolName)) {
|
|
3044
3048
|
filteredContent.push(part);
|
|
3045
3049
|
filteredSourceContentPartIndices.push(partSourceContentIndices);
|
|
3046
3050
|
if (
|
|
@@ -3547,6 +3551,7 @@ interface FoldedSourceMessage {
|
|
|
3547
3551
|
* string content or tool-call metadata contributed as a whole. */
|
|
3548
3552
|
readonly retainedContentPartIndices?: ReadonlySet<number>;
|
|
3549
3553
|
readonly mappingAmbiguous?: boolean;
|
|
3554
|
+
readonly additionalAttributions?: readonly ProviderMessageAttribution[];
|
|
3550
3555
|
}
|
|
3551
3556
|
|
|
3552
3557
|
function getFoldedSourceAttribution(
|
|
@@ -3668,6 +3673,22 @@ function getSyntheticProviderContextProvenanceParts(
|
|
|
3668
3673
|
if (parts.length === sourcePartStart) {
|
|
3669
3674
|
parts.push({ attribution: fallbackAttribution });
|
|
3670
3675
|
}
|
|
3676
|
+
for (const attribution of source.additionalAttributions ?? []) {
|
|
3677
|
+
const sourceMessageId =
|
|
3678
|
+
sourceMessageIds.length === 1
|
|
3679
|
+
? sourceMessageIds[0]
|
|
3680
|
+
: undefined;
|
|
3681
|
+
const retainedSourceId =
|
|
3682
|
+
retainedSourceIds.size === 1
|
|
3683
|
+
? retainedSourceIds.values().next().value
|
|
3684
|
+
: undefined;
|
|
3685
|
+
parts.push({
|
|
3686
|
+
attribution,
|
|
3687
|
+
...((sourceMessageId ?? retainedSourceId) != null && {
|
|
3688
|
+
sourceMessageId: sourceMessageId ?? retainedSourceId,
|
|
3689
|
+
}),
|
|
3690
|
+
});
|
|
3691
|
+
}
|
|
3671
3692
|
}
|
|
3672
3693
|
return mergeAdjacentProviderProvenanceParts(parts);
|
|
3673
3694
|
}
|
|
@@ -3763,6 +3784,78 @@ function flushTextChunks(
|
|
|
3763
3784
|
textChunks.length = 0;
|
|
3764
3785
|
}
|
|
3765
3786
|
|
|
3787
|
+
function getAuthoritativeResponsesToolOutput(
|
|
3788
|
+
message: BaseMessage,
|
|
3789
|
+
preparation: ToolHistoryPreparation
|
|
3790
|
+
): OrderedToolHistoryProjection | undefined {
|
|
3791
|
+
const projection = preparation.get(message);
|
|
3792
|
+
return projection?.hasToolContent === true ? projection : undefined;
|
|
3793
|
+
}
|
|
3794
|
+
|
|
3795
|
+
function appendOrderedResponsesOutput(
|
|
3796
|
+
projection: OrderedToolHistoryProjection,
|
|
3797
|
+
textChunks: string[],
|
|
3798
|
+
parts: MessageContentComplex[],
|
|
3799
|
+
budget: FoldContextBudget,
|
|
3800
|
+
omitText = false
|
|
3801
|
+
): { contributed: boolean; complete: boolean; hasTool: boolean } {
|
|
3802
|
+
let contributed = false;
|
|
3803
|
+
let hasTool = false;
|
|
3804
|
+
for (const contribution of projection.contributions) {
|
|
3805
|
+
if (!consumeFoldedWork(textChunks, budget)) {
|
|
3806
|
+
break;
|
|
3807
|
+
}
|
|
3808
|
+
const remainingCharsBefore = budget.remainingChars;
|
|
3809
|
+
if (contribution.kind === 'image') {
|
|
3810
|
+
const chars = getToolContentCharLength([contribution.image]);
|
|
3811
|
+
if (chars > budget.remainingChars) {
|
|
3812
|
+
appendFoldedLine(textChunks, budget, [
|
|
3813
|
+
'Tool: [image omitted: folded context limit]',
|
|
3814
|
+
]);
|
|
3815
|
+
contributed = true;
|
|
3816
|
+
hasTool = true;
|
|
3817
|
+
continue;
|
|
3818
|
+
}
|
|
3819
|
+
flushTextChunks(textChunks, parts);
|
|
3820
|
+
parts.push(contribution.image as MessageContentComplex);
|
|
3821
|
+
budget.remainingChars -= chars;
|
|
3822
|
+
contributed = true;
|
|
3823
|
+
hasTool = true;
|
|
3824
|
+
continue;
|
|
3825
|
+
}
|
|
3826
|
+
if (contribution.kind === 'text') {
|
|
3827
|
+
if (omitText) {
|
|
3828
|
+
continue;
|
|
3829
|
+
}
|
|
3830
|
+
appendFoldedLine(textChunks, budget, ['AI: ', contribution.text]);
|
|
3831
|
+
} else if (contribution.kind === 'call') {
|
|
3832
|
+
appendFoldedLine(textChunks, budget, [
|
|
3833
|
+
`AI: [tool_call] ${contribution.name}(`,
|
|
3834
|
+
serializeFoldedValue(contribution.arguments),
|
|
3835
|
+
')',
|
|
3836
|
+
]);
|
|
3837
|
+
} else if (contribution.providerType !== 'reasoning') {
|
|
3838
|
+
appendFoldedLine(textChunks, budget, [
|
|
3839
|
+
'AI: [server_tool_output] ',
|
|
3840
|
+
serializeFoldedValue(contribution.value),
|
|
3841
|
+
]);
|
|
3842
|
+
}
|
|
3843
|
+
const retained = budget.remainingChars < remainingCharsBefore;
|
|
3844
|
+
contributed ||= retained;
|
|
3845
|
+
hasTool ||= retained && contribution.actor === 'tool';
|
|
3846
|
+
}
|
|
3847
|
+
if (projection.truncated) {
|
|
3848
|
+
const before = budget.remainingChars;
|
|
3849
|
+
appendFoldedLine(textChunks, budget, [FOLDED_CONTEXT_TRUNCATION_NOTICE]);
|
|
3850
|
+
contributed ||= budget.remainingChars < before;
|
|
3851
|
+
}
|
|
3852
|
+
return {
|
|
3853
|
+
contributed,
|
|
3854
|
+
complete: !budget.truncated && !projection.truncated,
|
|
3855
|
+
hasTool,
|
|
3856
|
+
};
|
|
3857
|
+
}
|
|
3858
|
+
|
|
3766
3859
|
/**
|
|
3767
3860
|
* Appends a single message's content to the running `textChunks` / `parts`
|
|
3768
3861
|
* accumulators. Portable image blocks are shallow-copied into `parts` so
|
|
@@ -3770,18 +3863,49 @@ function flushTextChunks(
|
|
|
3770
3863
|
* blocks are retained as bounded text so a folded cross-provider history
|
|
3771
3864
|
* cannot contain an unsupported native block or JSON-expand without limit.
|
|
3772
3865
|
*
|
|
3773
|
-
*
|
|
3774
|
-
*
|
|
3775
|
-
* a fallback when `content` is a plain string or an array with no tool_use.
|
|
3866
|
+
* Parsed calls are omitted only when identity, name, and complete arguments
|
|
3867
|
+
* establish an equivalent content representation.
|
|
3776
3868
|
*/
|
|
3777
3869
|
function appendMessageContent(
|
|
3778
3870
|
msg: BaseMessage,
|
|
3779
3871
|
role: string,
|
|
3780
3872
|
textChunks: string[],
|
|
3781
3873
|
parts: MessageContentComplex[],
|
|
3782
|
-
budget: FoldContextBudget
|
|
3874
|
+
budget: FoldContextBudget,
|
|
3875
|
+
preparation: ToolHistoryPreparation = createToolHistoryPreparation()
|
|
3783
3876
|
): FoldedSourceMessage | undefined {
|
|
3784
3877
|
const { content } = msg;
|
|
3878
|
+
const responsesOutput = getAuthoritativeResponsesToolOutput(msg, preparation);
|
|
3879
|
+
if (
|
|
3880
|
+
responsesOutput != null &&
|
|
3881
|
+
(responsesOutput.source.coverage === 'complete-output' ||
|
|
3882
|
+
typeof content === 'string' ||
|
|
3883
|
+
(Array.isArray(content) &&
|
|
3884
|
+
content.length <= MAX_FOLDED_CONTEXT_WORK &&
|
|
3885
|
+
content.every(
|
|
3886
|
+
(block) => readFoldedDataProperty(block, 'type') === 'text'
|
|
3887
|
+
)))
|
|
3888
|
+
) {
|
|
3889
|
+
const orderedOutput = appendOrderedResponsesOutput(
|
|
3890
|
+
responsesOutput,
|
|
3891
|
+
textChunks,
|
|
3892
|
+
parts,
|
|
3893
|
+
budget
|
|
3894
|
+
);
|
|
3895
|
+
const toolCalls =
|
|
3896
|
+
responsesOutput.source.coverage === 'tool-sidecar'
|
|
3897
|
+
? appendToolCalls(msg, role, textChunks, budget)
|
|
3898
|
+
: { contributed: false, complete: true };
|
|
3899
|
+
return orderedOutput.contributed || toolCalls.contributed
|
|
3900
|
+
? {
|
|
3901
|
+
message: msg,
|
|
3902
|
+
mappingAmbiguous: true,
|
|
3903
|
+
...(orderedOutput.hasTool && {
|
|
3904
|
+
additionalAttributions: ['tool'] as const,
|
|
3905
|
+
}),
|
|
3906
|
+
}
|
|
3907
|
+
: undefined;
|
|
3908
|
+
}
|
|
3785
3909
|
|
|
3786
3910
|
if (typeof content === 'string') {
|
|
3787
3911
|
const remainingCharsBefore = budget.remainingChars;
|
|
@@ -3812,13 +3936,12 @@ function appendMessageContent(
|
|
|
3812
3936
|
: undefined;
|
|
3813
3937
|
}
|
|
3814
3938
|
|
|
3815
|
-
|
|
3939
|
+
const representedToolCalls: ToolHistoryCallMirrors = new Map();
|
|
3816
3940
|
const retainedContentPartIndices = new Set<number>();
|
|
3817
3941
|
|
|
3818
3942
|
for (let blockIndex = 0; blockIndex < content.length; blockIndex++) {
|
|
3819
3943
|
const block = content[blockIndex] as ExtendedMessageContent;
|
|
3820
3944
|
if (!consumeFoldedWork(textChunks, budget)) {
|
|
3821
|
-
hasToolUseBlock = true;
|
|
3822
3945
|
break;
|
|
3823
3946
|
}
|
|
3824
3947
|
const remainingCharsBefore = budget.remainingChars;
|
|
@@ -3830,7 +3953,12 @@ function appendMessageContent(
|
|
|
3830
3953
|
const blockTypeValue = readFoldedDataProperty(block, 'type');
|
|
3831
3954
|
const blockType =
|
|
3832
3955
|
typeof blockTypeValue === 'string' ? blockTypeValue : undefined;
|
|
3833
|
-
|
|
3956
|
+
const blockRole =
|
|
3957
|
+
getProviderToolResultPartDescriptor(block) != null ? 'Tool' : role;
|
|
3958
|
+
const callDescriptor = getProviderToolCallPartDescriptor(block);
|
|
3959
|
+
if (callDescriptor != null) {
|
|
3960
|
+
recordToolHistoryCallMirror(representedToolCalls, block);
|
|
3961
|
+
}
|
|
3834
3962
|
if (
|
|
3835
3963
|
blockType !== 'tool_use' &&
|
|
3836
3964
|
blockType !== 'tool_call' &&
|
|
@@ -3841,7 +3969,7 @@ function appendMessageContent(
|
|
|
3841
3969
|
const blockChars = getToolContentCharLength([block]);
|
|
3842
3970
|
if (blockChars > budget.remainingChars) {
|
|
3843
3971
|
appendFoldedLine(textChunks, budget, [
|
|
3844
|
-
`${
|
|
3972
|
+
`${blockRole}: [${blockType ?? 'media'} omitted: folded context limit]`,
|
|
3845
3973
|
]);
|
|
3846
3974
|
markBlockRetained();
|
|
3847
3975
|
continue;
|
|
@@ -3851,7 +3979,7 @@ function appendMessageContent(
|
|
|
3851
3979
|
budget.remainingChars -= blockChars;
|
|
3852
3980
|
} else {
|
|
3853
3981
|
appendFoldedLine(textChunks, budget, [
|
|
3854
|
-
`${
|
|
3982
|
+
`${blockRole}: [${blockType ?? 'media'}] `,
|
|
3855
3983
|
serializeFoldedValue(block),
|
|
3856
3984
|
]);
|
|
3857
3985
|
}
|
|
@@ -3860,7 +3988,6 @@ function appendMessageContent(
|
|
|
3860
3988
|
}
|
|
3861
3989
|
|
|
3862
3990
|
if (blockType === 'tool_use') {
|
|
3863
|
-
hasToolUseBlock = true;
|
|
3864
3991
|
const name = readFoldedDataProperty(block, 'name');
|
|
3865
3992
|
const input = readFoldedDataProperty(block, 'input');
|
|
3866
3993
|
appendFoldedLine(textChunks, budget, [
|
|
@@ -3877,7 +4004,6 @@ function appendMessageContent(
|
|
|
3877
4004
|
// output } }`, from `convertMessagesToContent` / persisted history). Handle
|
|
3878
4005
|
// both, and emit any embedded output, so the name/args/result survive.
|
|
3879
4006
|
if (blockType === 'tool_call') {
|
|
3880
|
-
hasToolUseBlock = true;
|
|
3881
4007
|
const nested = readFoldedDataProperty(block, 'tool_call');
|
|
3882
4008
|
const nestedName = readFoldedDataProperty(nested, 'name');
|
|
3883
4009
|
const topLevelName = readFoldedDataProperty(block, 'name');
|
|
@@ -3911,16 +4037,12 @@ function appendMessageContent(
|
|
|
3911
4037
|
// user message carrying the result). Preserve nested image blocks as-is
|
|
3912
4038
|
// instead of JSON-stringifying them through the generic fallback.
|
|
3913
4039
|
if (blockType === 'tool_result') {
|
|
3914
|
-
hasToolUseBlock = true;
|
|
3915
4040
|
const inner = readFoldedDataProperty(block, 'content') as
|
|
3916
4041
|
| ToolResultContent['content']
|
|
3917
4042
|
| undefined;
|
|
3918
4043
|
if (typeof inner === 'string') {
|
|
3919
4044
|
if (inner) {
|
|
3920
|
-
appendFoldedLine(textChunks, budget, [
|
|
3921
|
-
`${role}: [tool_result] `,
|
|
3922
|
-
inner,
|
|
3923
|
-
]);
|
|
4045
|
+
appendFoldedLine(textChunks, budget, ['Tool: [tool_result] ', inner]);
|
|
3924
4046
|
}
|
|
3925
4047
|
} else if (Array.isArray(inner)) {
|
|
3926
4048
|
for (const innerBlock of inner as Array<
|
|
@@ -3932,7 +4054,7 @@ function appendMessageContent(
|
|
|
3932
4054
|
if (typeof innerBlock === 'string') {
|
|
3933
4055
|
if (innerBlock) {
|
|
3934
4056
|
appendFoldedLine(textChunks, budget, [
|
|
3935
|
-
|
|
4057
|
+
'Tool: [tool_result] ',
|
|
3936
4058
|
innerBlock,
|
|
3937
4059
|
]);
|
|
3938
4060
|
}
|
|
@@ -3951,7 +4073,7 @@ function appendMessageContent(
|
|
|
3951
4073
|
budget.remainingChars -= blockChars;
|
|
3952
4074
|
} else {
|
|
3953
4075
|
appendFoldedLine(textChunks, budget, [
|
|
3954
|
-
|
|
4076
|
+
`Tool: [${innerType ?? 'media'} omitted: folded context limit]`,
|
|
3955
4077
|
]);
|
|
3956
4078
|
}
|
|
3957
4079
|
} else {
|
|
@@ -3959,7 +4081,7 @@ function appendMessageContent(
|
|
|
3959
4081
|
const inputValue = readFoldedDataProperty(innerBlock, 'input');
|
|
3960
4082
|
const innerText = textValue ?? inputValue;
|
|
3961
4083
|
appendFoldedLine(textChunks, budget, [
|
|
3962
|
-
|
|
4084
|
+
'Tool: [tool_result] ',
|
|
3963
4085
|
typeof innerText === 'string' && innerText
|
|
3964
4086
|
? innerText
|
|
3965
4087
|
: serializeFoldedValue(innerBlock),
|
|
@@ -3969,7 +4091,7 @@ function appendMessageContent(
|
|
|
3969
4091
|
}
|
|
3970
4092
|
} else if (inner != null) {
|
|
3971
4093
|
appendFoldedLine(textChunks, budget, [
|
|
3972
|
-
|
|
4094
|
+
'Tool: [tool_result] ',
|
|
3973
4095
|
serializeFoldedValue(inner),
|
|
3974
4096
|
]);
|
|
3975
4097
|
}
|
|
@@ -3989,22 +4111,39 @@ function appendMessageContent(
|
|
|
3989
4111
|
// Fallback: serialize unrecognized block types to preserve context
|
|
3990
4112
|
if (blockType != null && blockType !== '') {
|
|
3991
4113
|
appendFoldedLine(textChunks, budget, [
|
|
3992
|
-
`${
|
|
4114
|
+
`${blockRole}: [${blockType}] `,
|
|
3993
4115
|
serializeFoldedValue(block),
|
|
3994
4116
|
]);
|
|
3995
4117
|
}
|
|
3996
4118
|
markBlockRetained();
|
|
3997
4119
|
}
|
|
3998
4120
|
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4121
|
+
const responsesOutputContributed =
|
|
4122
|
+
responsesOutput != null &&
|
|
4123
|
+
appendOrderedResponsesOutput(
|
|
4124
|
+
responsesOutput,
|
|
4125
|
+
textChunks,
|
|
4126
|
+
parts,
|
|
4127
|
+
budget,
|
|
4128
|
+
true
|
|
4129
|
+
).contributed;
|
|
4130
|
+
|
|
4131
|
+
const toolCalls = appendToolCalls(
|
|
4132
|
+
msg,
|
|
4133
|
+
role,
|
|
4134
|
+
textChunks,
|
|
4135
|
+
budget,
|
|
4136
|
+
representedToolCalls
|
|
4137
|
+
);
|
|
4138
|
+
if (toolCalls.contributed || responsesOutputContributed) {
|
|
4005
4139
|
return {
|
|
4006
4140
|
message: msg,
|
|
4007
|
-
...(!toolCalls.complete && {
|
|
4141
|
+
...((responsesOutputContributed || !toolCalls.complete) && {
|
|
4142
|
+
mappingAmbiguous: true,
|
|
4143
|
+
}),
|
|
4144
|
+
...(responsesOutputContributed && {
|
|
4145
|
+
additionalAttributions: ['tool'] as const,
|
|
4146
|
+
}),
|
|
4008
4147
|
};
|
|
4009
4148
|
}
|
|
4010
4149
|
return retainedContentPartIndices.size > 0
|
|
@@ -4016,7 +4155,8 @@ function appendToolCalls(
|
|
|
4016
4155
|
msg: BaseMessage,
|
|
4017
4156
|
role: string,
|
|
4018
4157
|
textChunks: string[],
|
|
4019
|
-
budget: FoldContextBudget
|
|
4158
|
+
budget: FoldContextBudget,
|
|
4159
|
+
representedToolCalls?: ToolHistoryCallMirrors
|
|
4020
4160
|
): { contributed: boolean; complete: boolean } {
|
|
4021
4161
|
if (role !== 'AI') {
|
|
4022
4162
|
return { contributed: false, complete: true };
|
|
@@ -4052,6 +4192,16 @@ function appendToolCalls(
|
|
|
4052
4192
|
}
|
|
4053
4193
|
const name = readFoldedDataProperty(tc, 'name');
|
|
4054
4194
|
const args = readFoldedDataProperty(tc, 'args');
|
|
4195
|
+
if (
|
|
4196
|
+
isToolHistoryCallMirror(
|
|
4197
|
+
representedToolCalls,
|
|
4198
|
+
readFoldedDataProperty(tc, 'id'),
|
|
4199
|
+
name,
|
|
4200
|
+
args
|
|
4201
|
+
)
|
|
4202
|
+
) {
|
|
4203
|
+
continue;
|
|
4204
|
+
}
|
|
4055
4205
|
appendFoldedLine(textChunks, budget, [
|
|
4056
4206
|
`AI: [tool_call] ${typeof name === 'string' ? name : ''}(`,
|
|
4057
4207
|
serializeFoldedValue(args),
|
|
@@ -4082,7 +4232,7 @@ function appendToolCalls(
|
|
|
4082
4232
|
const args = readFoldedDataProperty(fn, 'arguments');
|
|
4083
4233
|
appendFoldedLine(textChunks, budget, [
|
|
4084
4234
|
`AI: [tool_call] ${typeof name === 'string' ? name : ''}(`,
|
|
4085
|
-
typeof args === 'string' ? args : '',
|
|
4235
|
+
serializeFoldedValue(typeof args === 'string' ? args : ''),
|
|
4086
4236
|
')',
|
|
4087
4237
|
]);
|
|
4088
4238
|
}
|
|
@@ -4122,7 +4272,8 @@ export function ensureThinkingBlockInMessages(
|
|
|
4122
4272
|
messages: BaseMessage[],
|
|
4123
4273
|
_provider: ProviderName,
|
|
4124
4274
|
config?: RunnableConfig,
|
|
4125
|
-
runStartIndex?: number
|
|
4275
|
+
runStartIndex?: number,
|
|
4276
|
+
preparation: ToolHistoryPreparation = createToolHistoryPreparation()
|
|
4126
4277
|
): BaseMessage[] {
|
|
4127
4278
|
if (messages.length === 0) {
|
|
4128
4279
|
return messages;
|
|
@@ -4182,12 +4333,7 @@ export function ensureThinkingBlockInMessages(
|
|
|
4182
4333
|
const type = readFoldedDataProperty(c, 'type');
|
|
4183
4334
|
if (type === 'tool_use') {
|
|
4184
4335
|
hasToolUse = true;
|
|
4185
|
-
} else if (
|
|
4186
|
-
type === ContentTypes.THINKING ||
|
|
4187
|
-
type === ContentTypes.REASONING_CONTENT ||
|
|
4188
|
-
type === ContentTypes.REASONING ||
|
|
4189
|
-
type === 'redacted_thinking'
|
|
4190
|
-
) {
|
|
4336
|
+
} else if (isReasoningContentBlock({ type })) {
|
|
4191
4337
|
hasThinkingBlock = true;
|
|
4192
4338
|
}
|
|
4193
4339
|
if (hasToolUse && hasThinkingBlock) {
|
|
@@ -4250,7 +4396,8 @@ export function ensureThinkingBlockInMessages(
|
|
|
4250
4396
|
'AI',
|
|
4251
4397
|
textChunks,
|
|
4252
4398
|
parts,
|
|
4253
|
-
foldBudget
|
|
4399
|
+
foldBudget,
|
|
4400
|
+
preparation
|
|
4254
4401
|
);
|
|
4255
4402
|
if (aiSource != null) {
|
|
4256
4403
|
foldedSourceMessages.push(aiSource);
|
|
@@ -4263,7 +4410,8 @@ export function ensureThinkingBlockInMessages(
|
|
|
4263
4410
|
'Tool',
|
|
4264
4411
|
textChunks,
|
|
4265
4412
|
parts,
|
|
4266
|
-
foldBudget
|
|
4413
|
+
foldBudget,
|
|
4414
|
+
preparation
|
|
4267
4415
|
);
|
|
4268
4416
|
if (toolSource != null) {
|
|
4269
4417
|
foldedSourceMessages.push(toolSource);
|
|
@@ -4307,7 +4455,11 @@ export function ensureThinkingBlockInMessages(
|
|
|
4307
4455
|
* `toolUse` / `toolResult`). Missing the parent AI message is not just a
|
|
4308
4456
|
* passthrough: folding its ToolMessage alone would leave an orphan
|
|
4309
4457
|
* `assistant(tool_calls) -> user(...)` sequence. */
|
|
4310
|
-
function messageHasToolContent(
|
|
4458
|
+
function messageHasToolContent(
|
|
4459
|
+
msg: BaseMessage,
|
|
4460
|
+
preserveNativeOpenAIResponses = false,
|
|
4461
|
+
preparation: ToolHistoryPreparation = createToolHistoryPreparation()
|
|
4462
|
+
): boolean {
|
|
4311
4463
|
if (isToolMessage(msg)) {
|
|
4312
4464
|
return true;
|
|
4313
4465
|
}
|
|
@@ -4320,15 +4472,33 @@ function messageHasToolContent(msg: BaseMessage): boolean {
|
|
|
4320
4472
|
return true;
|
|
4321
4473
|
}
|
|
4322
4474
|
if (Array.isArray(msg.content)) {
|
|
4475
|
+
let hasOpenAINativeServerContent = false;
|
|
4323
4476
|
for (const block of msg.content as ExtendedMessageContent[]) {
|
|
4324
4477
|
const type = readFoldedDataProperty(block, 'type');
|
|
4478
|
+
const isNativeOpenAIServerContent =
|
|
4479
|
+
preserveNativeOpenAIResponses &&
|
|
4480
|
+
(type === 'server_tool_call' ||
|
|
4481
|
+
type === 'server_tool_call_result' ||
|
|
4482
|
+
type === 'server_tool_result');
|
|
4483
|
+
hasOpenAINativeServerContent ||= isNativeOpenAIServerContent;
|
|
4325
4484
|
if (
|
|
4326
4485
|
typeof block === 'object' &&
|
|
4327
|
-
|
|
4486
|
+
!isNativeOpenAIServerContent &&
|
|
4487
|
+
(isProviderToolContentPart(block) ||
|
|
4488
|
+
readFoldedDataProperty(block, 'tool_call') != null)
|
|
4328
4489
|
) {
|
|
4329
4490
|
return true;
|
|
4330
4491
|
}
|
|
4331
4492
|
}
|
|
4493
|
+
if (hasOpenAINativeServerContent) {
|
|
4494
|
+
return false;
|
|
4495
|
+
}
|
|
4496
|
+
}
|
|
4497
|
+
if (
|
|
4498
|
+
!preserveNativeOpenAIResponses &&
|
|
4499
|
+
getAuthoritativeResponsesToolOutput(msg, preparation) != null
|
|
4500
|
+
) {
|
|
4501
|
+
return true;
|
|
4332
4502
|
}
|
|
4333
4503
|
return false;
|
|
4334
4504
|
}
|
|
@@ -4346,12 +4516,29 @@ function isToolResultMessage(msg: BaseMessage): boolean {
|
|
|
4346
4516
|
return (msg.content as ExtendedMessageContent[]).some(
|
|
4347
4517
|
(block) =>
|
|
4348
4518
|
typeof block === 'object' &&
|
|
4349
|
-
|
|
4519
|
+
getProviderToolResultPartDescriptor(block) != null
|
|
4350
4520
|
);
|
|
4351
4521
|
}
|
|
4352
4522
|
return false;
|
|
4353
4523
|
}
|
|
4354
4524
|
|
|
4525
|
+
function getFoldedMessageRole(msg: BaseMessage): 'AI' | 'Tool' | 'User' {
|
|
4526
|
+
if (isToolMessage(msg)) {
|
|
4527
|
+
return 'Tool';
|
|
4528
|
+
}
|
|
4529
|
+
if (
|
|
4530
|
+
msg instanceof AIMessage ||
|
|
4531
|
+
msg instanceof AIMessageChunk ||
|
|
4532
|
+
('role' in msg && msg.role === 'assistant')
|
|
4533
|
+
) {
|
|
4534
|
+
return 'AI';
|
|
4535
|
+
}
|
|
4536
|
+
if (msg instanceof HumanMessage || ('role' in msg && msg.role === 'user')) {
|
|
4537
|
+
return 'User';
|
|
4538
|
+
}
|
|
4539
|
+
return isToolResultMessage(msg) ? 'Tool' : 'AI';
|
|
4540
|
+
}
|
|
4541
|
+
|
|
4355
4542
|
/**
|
|
4356
4543
|
* Folds tool_use / tool_result content into plain text for an agent that binds
|
|
4357
4544
|
* no tools.
|
|
@@ -4375,7 +4562,9 @@ function isToolResultMessage(msg: BaseMessage): boolean {
|
|
|
4375
4562
|
*/
|
|
4376
4563
|
export function foldToolBlocksForToollessAgent(
|
|
4377
4564
|
messages: BaseMessage[],
|
|
4378
|
-
config?: RunnableConfig
|
|
4565
|
+
config?: RunnableConfig,
|
|
4566
|
+
preserveNativeOpenAIResponses = false,
|
|
4567
|
+
preparation: ToolHistoryPreparation = createToolHistoryPreparation()
|
|
4379
4568
|
): BaseMessage[] {
|
|
4380
4569
|
let result: BaseMessage[] | null = null;
|
|
4381
4570
|
let foldedCount = 0;
|
|
@@ -4383,7 +4572,9 @@ export function foldToolBlocksForToollessAgent(
|
|
|
4383
4572
|
let i = 0;
|
|
4384
4573
|
while (i < messages.length) {
|
|
4385
4574
|
const msg = messages[i];
|
|
4386
|
-
if (
|
|
4575
|
+
if (
|
|
4576
|
+
!messageHasToolContent(msg, preserveNativeOpenAIResponses, preparation)
|
|
4577
|
+
) {
|
|
4387
4578
|
result?.push(msg);
|
|
4388
4579
|
i++;
|
|
4389
4580
|
continue;
|
|
@@ -4400,10 +4591,11 @@ export function foldToolBlocksForToollessAgent(
|
|
|
4400
4591
|
appendFoldedLine(textChunks, foldBudget, ['[Previous tool interaction]']);
|
|
4401
4592
|
const initialSource = appendMessageContent(
|
|
4402
4593
|
msg,
|
|
4403
|
-
|
|
4594
|
+
getFoldedMessageRole(msg),
|
|
4404
4595
|
textChunks,
|
|
4405
4596
|
parts,
|
|
4406
|
-
foldBudget
|
|
4597
|
+
foldBudget,
|
|
4598
|
+
preparation
|
|
4407
4599
|
);
|
|
4408
4600
|
if (initialSource != null) {
|
|
4409
4601
|
foldedSourceMessages.push(initialSource);
|
|
@@ -4414,10 +4606,11 @@ export function foldToolBlocksForToollessAgent(
|
|
|
4414
4606
|
while (j < messages.length && isToolResultMessage(messages[j])) {
|
|
4415
4607
|
const toolSource = appendMessageContent(
|
|
4416
4608
|
messages[j],
|
|
4417
|
-
|
|
4609
|
+
getFoldedMessageRole(messages[j]),
|
|
4418
4610
|
textChunks,
|
|
4419
4611
|
parts,
|
|
4420
|
-
foldBudget
|
|
4612
|
+
foldBudget,
|
|
4613
|
+
preparation
|
|
4421
4614
|
);
|
|
4422
4615
|
if (toolSource != null) {
|
|
4423
4616
|
foldedSourceMessages.push(toolSource);
|
|
@@ -4482,16 +4675,7 @@ function chainHasThinkingBlock(
|
|
|
4482
4675
|
|
|
4483
4676
|
if (Array.isArray(prevAiMsg.content) && prevAiMsg.content.length > 0) {
|
|
4484
4677
|
const content = prevAiMsg.content as ExtendedMessageContent[];
|
|
4485
|
-
if (
|
|
4486
|
-
content.some(
|
|
4487
|
-
(c) =>
|
|
4488
|
-
typeof c === 'object' &&
|
|
4489
|
-
(c.type === ContentTypes.THINKING ||
|
|
4490
|
-
c.type === ContentTypes.REASONING_CONTENT ||
|
|
4491
|
-
c.type === ContentTypes.REASONING ||
|
|
4492
|
-
c.type === 'redacted_thinking')
|
|
4493
|
-
)
|
|
4494
|
-
) {
|
|
4678
|
+
if (content.some((c) => isReasoningContentBlock(c))) {
|
|
4495
4679
|
return true;
|
|
4496
4680
|
}
|
|
4497
4681
|
}
|
package/src/messages/index.ts
CHANGED