@librechat/agents 3.6.8 → 3.6.10
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 +46 -39
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/agents/projection.cjs +2 -2
- package/dist/cjs/agents/projection.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +28 -18
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +87 -16
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +10 -0
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +14 -0
- package/dist/cjs/messages/alternation.cjs +125 -20
- package/dist/cjs/messages/alternation.cjs.map +1 -1
- package/dist/cjs/messages/core.cjs +195 -18
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +488 -118
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/handoffCue.cjs +3 -2
- package/dist/cjs/messages/handoffCue.cjs.map +1 -1
- package/dist/cjs/messages/index.cjs +1 -0
- package/dist/cjs/messages/injected.cjs +5 -2
- package/dist/cjs/messages/injected.cjs.map +1 -1
- package/dist/cjs/messages/provenance.cjs +411 -0
- package/dist/cjs/messages/provenance.cjs.map +1 -0
- package/dist/cjs/messages/prune.cjs +18 -13
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/messages/toolResultTypes.cjs +663 -0
- package/dist/cjs/messages/toolResultTypes.cjs.map +1 -0
- package/dist/cjs/run.cjs +7 -4
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +21 -4
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/CallerCapabilities.cjs +48 -0
- package/dist/cjs/tools/CallerCapabilities.cjs.map +1 -0
- package/dist/cjs/tools/ProgrammaticCallerPolicy.cjs +34 -0
- package/dist/cjs/tools/ProgrammaticCallerPolicy.cjs.map +1 -0
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs +21 -4
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +25 -24
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs +12 -4
- package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +13 -4
- package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +47 -11
- package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
- package/dist/cjs/tools/ptcTimeout.cjs.map +1 -1
- package/dist/cjs/tools/search/search.cjs +19 -9
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/tool.cjs +2 -1
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
- package/dist/cjs/utils/toolContent.cjs +2 -2
- package/dist/cjs/utils/toolContent.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +46 -39
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/agents/projection.mjs +2 -2
- package/dist/esm/agents/projection.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +30 -20
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +87 -16
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +10 -0
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +4 -3
- package/dist/esm/messages/alternation.mjs +125 -20
- package/dist/esm/messages/alternation.mjs.map +1 -1
- package/dist/esm/messages/core.mjs +196 -19
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +488 -119
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/handoffCue.mjs +3 -2
- package/dist/esm/messages/handoffCue.mjs.map +1 -1
- package/dist/esm/messages/index.mjs +1 -0
- package/dist/esm/messages/injected.mjs +5 -2
- package/dist/esm/messages/injected.mjs.map +1 -1
- package/dist/esm/messages/provenance.mjs +401 -0
- package/dist/esm/messages/provenance.mjs.map +1 -0
- package/dist/esm/messages/prune.mjs +18 -13
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/messages/toolResultTypes.mjs +657 -0
- package/dist/esm/messages/toolResultTypes.mjs.map +1 -0
- package/dist/esm/run.mjs +7 -4
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs +21 -4
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/CallerCapabilities.mjs +45 -0
- package/dist/esm/tools/CallerCapabilities.mjs.map +1 -0
- package/dist/esm/tools/ProgrammaticCallerPolicy.mjs +32 -0
- package/dist/esm/tools/ProgrammaticCallerPolicy.mjs.map +1 -0
- package/dist/esm/tools/ProgrammaticToolCalling.mjs +21 -4
- package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +25 -24
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs +14 -6
- package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +15 -6
- package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +47 -12
- package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
- package/dist/esm/tools/ptcTimeout.mjs.map +1 -1
- package/dist/esm/tools/search/search.mjs +19 -9
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/tool.mjs +2 -1
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
- package/dist/esm/utils/toolContent.mjs +2 -2
- package/dist/esm/utils/toolContent.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +8 -13
- package/dist/types/agents/projection.d.ts +3 -1
- package/dist/types/graphs/Graph.d.ts +1 -1
- package/dist/types/llm/openai/index.d.ts +20 -0
- package/dist/types/messages/format.d.ts +5 -0
- package/dist/types/messages/index.d.ts +1 -0
- package/dist/types/messages/provenance.d.ts +85 -0
- package/dist/types/messages/toolResultTypes.d.ts +33 -0
- package/dist/types/tools/CallerCapabilities.d.ts +12 -0
- package/dist/types/tools/ProgrammaticCallerPolicy.d.ts +20 -0
- package/dist/types/tools/ToolNode.d.ts +4 -7
- package/dist/types/tools/local/resolveLocalExecutionTools.d.ts +4 -0
- package/dist/types/tools/ptcTimeout.d.ts +8 -0
- package/dist/types/tools/search/types.d.ts +15 -0
- package/dist/types/types/graph.d.ts +3 -1
- package/dist/types/types/tools.d.ts +13 -2
- package/package.json +1 -1
- package/src/agents/AgentContext.ts +109 -67
- package/src/agents/projection.ts +9 -1
- package/src/graphs/Graph.ts +56 -23
- package/src/graphs/MultiAgentGraph.ts +175 -33
- package/src/llm/openai/index.ts +43 -0
- package/src/messages/alternation.ts +217 -34
- package/src/messages/core.ts +358 -38
- package/src/messages/format.ts +958 -137
- package/src/messages/handoffCue.ts +7 -4
- package/src/messages/index.ts +1 -0
- package/src/messages/injected.ts +9 -6
- package/src/messages/provenance.ts +897 -0
- package/src/messages/prune.ts +28 -10
- package/src/messages/toolResultTypes.ts +1174 -0
- package/src/run.ts +9 -4
- package/src/tools/BashProgrammaticToolCalling.ts +46 -12
- package/src/tools/CallerCapabilities.ts +78 -0
- package/src/tools/ProgrammaticCallerPolicy.ts +97 -0
- package/src/tools/ProgrammaticToolCalling.ts +41 -7
- package/src/tools/ToolNode.ts +70 -52
- package/src/tools/cloudflare/CloudflareProgrammaticToolCalling.ts +24 -26
- package/src/tools/local/LocalProgrammaticToolCalling.ts +28 -23
- package/src/tools/local/resolveLocalExecutionTools.ts +132 -13
- package/src/tools/ptcTimeout.ts +6 -0
- package/src/tools/search/search.ts +25 -8
- package/src/tools/search/tool.ts +2 -0
- package/src/tools/search/types.ts +16 -0
- package/src/tools/subagent/SubagentExecutor.ts +8 -4
- package/src/types/graph.ts +3 -0
- package/src/types/tools.ts +14 -3
- package/src/utils/toolContent.ts +2 -2
package/src/messages/core.ts
CHANGED
|
@@ -9,10 +9,12 @@ import {
|
|
|
9
9
|
} from '@langchain/core/messages';
|
|
10
10
|
import type { ContentBlock as LangChainContentBlock } from '@langchain/core/messages';
|
|
11
11
|
import type { ToolCall, ToolCallChunk } from '@langchain/core/messages/tool';
|
|
12
|
+
import type { ProviderMessageProvenancePart } from './provenance';
|
|
12
13
|
import type * as t from '@/types';
|
|
13
14
|
import {
|
|
14
15
|
cloneToolMessageWithContent,
|
|
15
16
|
compactToolContent,
|
|
17
|
+
getToolContentCharLength,
|
|
16
18
|
getBoundedCacheControlledTextToolContent,
|
|
17
19
|
getBoundedSingleTextToolContent,
|
|
18
20
|
getComputerCallOutputScreenshot,
|
|
@@ -20,6 +22,13 @@ import {
|
|
|
20
22
|
isComputerCallOutputMessage,
|
|
21
23
|
serializeToolContentBounded,
|
|
22
24
|
} from '@/utils/toolContent';
|
|
25
|
+
import {
|
|
26
|
+
getProviderMessageProvenance,
|
|
27
|
+
getProviderSourceMessageIds,
|
|
28
|
+
hasBijectiveProviderContentPartMapping,
|
|
29
|
+
setProviderMessageProvenance,
|
|
30
|
+
stampSyntheticProviderMessage,
|
|
31
|
+
} from './provenance';
|
|
23
32
|
import { HARD_MAX_TOOL_RESULT_CHARS } from '@/utils/truncation';
|
|
24
33
|
import { stripAnthropicCacheControl } from './cache';
|
|
25
34
|
import { ContentTypes, Providers } from '@/common';
|
|
@@ -496,26 +505,177 @@ function appendContentBlocks(
|
|
|
496
505
|
}
|
|
497
506
|
}
|
|
498
507
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
function
|
|
506
|
-
current: BaseMessage['content'] | undefined,
|
|
507
|
-
next: unknown,
|
|
508
|
+
interface BoundedContentAccumulator {
|
|
509
|
+
readonly blocks: t.MessageContentComplex[];
|
|
510
|
+
hasContent: boolean;
|
|
511
|
+
remainingChars: number;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
function createBoundedContentAccumulator(
|
|
508
515
|
maxChars: number
|
|
509
|
-
):
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
516
|
+
): BoundedContentAccumulator {
|
|
517
|
+
return {
|
|
518
|
+
blocks: [],
|
|
519
|
+
hasContent: false,
|
|
520
|
+
remainingChars: Number.isFinite(maxChars)
|
|
521
|
+
? Math.max(0, Math.floor(maxChars))
|
|
522
|
+
: Number.MAX_SAFE_INTEGER,
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/** Appends a segment only when at least one of its provider-visible bytes fits.
|
|
527
|
+
* Each segment is compacted against the remaining budget before combination,
|
|
528
|
+
* so a later segment cannot be credited merely because recompression replaced
|
|
529
|
+
* earlier bytes with a truncation notice. */
|
|
530
|
+
function appendBoundedContentSegment(
|
|
531
|
+
accumulator: BoundedContentAccumulator,
|
|
532
|
+
next: unknown
|
|
533
|
+
): { contributed: boolean; complete: boolean } {
|
|
534
|
+
const separatorChars = accumulator.hasContent ? 1 : 0;
|
|
535
|
+
const availableChars = accumulator.remainingChars - separatorChars;
|
|
536
|
+
const originalChars = getToolContentCharLength(next);
|
|
537
|
+
if (originalChars <= 0) {
|
|
538
|
+
return { contributed: false, complete: true };
|
|
539
|
+
}
|
|
540
|
+
if (availableChars <= 0) {
|
|
541
|
+
return { contributed: false, complete: false };
|
|
542
|
+
}
|
|
543
|
+
const compactedNext = compactToolContent(next, availableChars);
|
|
544
|
+
const boundedNext = compactedNext.content;
|
|
545
|
+
const appendedChars = Math.min(
|
|
546
|
+
availableChars,
|
|
547
|
+
getToolContentCharLength(boundedNext)
|
|
548
|
+
);
|
|
549
|
+
if (appendedChars <= 0) {
|
|
550
|
+
return { contributed: false, complete: false };
|
|
551
|
+
}
|
|
552
|
+
appendContentBlocks(accumulator.blocks, boundedNext);
|
|
553
|
+
accumulator.hasContent = true;
|
|
554
|
+
accumulator.remainingChars -= separatorChars + appendedChars;
|
|
555
|
+
return {
|
|
556
|
+
contributed: true,
|
|
557
|
+
complete: !compactedNext.changed && originalChars <= availableChars,
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
function appendBoundedContentContribution(
|
|
562
|
+
accumulator: BoundedContentAccumulator,
|
|
563
|
+
next: unknown
|
|
564
|
+
): {
|
|
565
|
+
contributed: boolean;
|
|
566
|
+
complete: boolean;
|
|
567
|
+
retainedContentPartIndices?: ReadonlySet<number>;
|
|
568
|
+
} {
|
|
569
|
+
if (!Array.isArray(next)) {
|
|
570
|
+
return appendBoundedContentSegment(accumulator, next);
|
|
571
|
+
}
|
|
572
|
+
const retainedContentPartIndices = new Set<number>();
|
|
573
|
+
let complete = true;
|
|
574
|
+
for (let index = 0; index < next.length; index++) {
|
|
575
|
+
const projection = appendBoundedContentSegment(accumulator, [next[index]]);
|
|
576
|
+
if (!projection.complete) {
|
|
577
|
+
complete = false;
|
|
578
|
+
}
|
|
579
|
+
if (!projection.contributed) {
|
|
580
|
+
const separatorChars = accumulator.hasContent ? 1 : 0;
|
|
581
|
+
if (accumulator.remainingChars <= separatorChars) {
|
|
582
|
+
if (index < next.length - 1) {
|
|
583
|
+
complete = false;
|
|
584
|
+
}
|
|
585
|
+
break;
|
|
586
|
+
}
|
|
587
|
+
continue;
|
|
588
|
+
}
|
|
589
|
+
retainedContentPartIndices.add(index);
|
|
513
590
|
}
|
|
591
|
+
return {
|
|
592
|
+
contributed: retainedContentPartIndices.size > 0,
|
|
593
|
+
complete,
|
|
594
|
+
retainedContentPartIndices,
|
|
595
|
+
};
|
|
596
|
+
}
|
|
514
597
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
598
|
+
function retainProjectedContentPartProvenance(
|
|
599
|
+
message: BaseMessage,
|
|
600
|
+
parts: readonly ProviderMessageProvenancePart[],
|
|
601
|
+
retainedContentPartIndices: ReadonlySet<number> | undefined,
|
|
602
|
+
complete: boolean
|
|
603
|
+
): ProviderMessageProvenancePart[] {
|
|
604
|
+
if (
|
|
605
|
+
complete &&
|
|
606
|
+
(retainedContentPartIndices == null ||
|
|
607
|
+
!Array.isArray(message.content) ||
|
|
608
|
+
retainedContentPartIndices.size === message.content.length)
|
|
609
|
+
) {
|
|
610
|
+
return [...parts];
|
|
611
|
+
}
|
|
612
|
+
const mapsOneToOne = hasBijectiveProviderContentPartMapping(
|
|
613
|
+
parts,
|
|
614
|
+
message.content.length
|
|
615
|
+
);
|
|
616
|
+
const distinctSourceMessageIds = new Set<string>();
|
|
617
|
+
for (const part of parts) {
|
|
618
|
+
if (part.sourceMessageId != null) {
|
|
619
|
+
distinctSourceMessageIds.add(part.sourceMessageId);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
if (!Array.isArray(message.content)) {
|
|
623
|
+
const soleSourceMessageId =
|
|
624
|
+
distinctSourceMessageIds.size === 1
|
|
625
|
+
? distinctSourceMessageIds.values().next().value
|
|
626
|
+
: undefined;
|
|
627
|
+
return [
|
|
628
|
+
{
|
|
629
|
+
attribution: parts[0]?.attribution ?? 'tool',
|
|
630
|
+
...(soleSourceMessageId != null && {
|
|
631
|
+
sourceMessageId: soleSourceMessageId,
|
|
632
|
+
}),
|
|
633
|
+
},
|
|
634
|
+
];
|
|
635
|
+
}
|
|
636
|
+
const retained: ProviderMessageProvenancePart[] = [];
|
|
637
|
+
const appendUnindexedAttribution = (
|
|
638
|
+
part: ProviderMessageProvenancePart
|
|
639
|
+
): void => {
|
|
640
|
+
const sourceMessageId =
|
|
641
|
+
distinctSourceMessageIds.size <= 1 ? part.sourceMessageId : undefined;
|
|
642
|
+
if (retained.length > 0) {
|
|
643
|
+
const previous = retained[retained.length - 1];
|
|
644
|
+
if (
|
|
645
|
+
previous.attribution === part.attribution &&
|
|
646
|
+
previous.sourceMessageId === sourceMessageId &&
|
|
647
|
+
previous.sourceContentPartIndices == null
|
|
648
|
+
) {
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
retained.push({
|
|
653
|
+
attribution: part.attribution,
|
|
654
|
+
...(sourceMessageId != null && { sourceMessageId }),
|
|
655
|
+
});
|
|
656
|
+
};
|
|
657
|
+
for (const part of parts) {
|
|
658
|
+
if (part.sourceContentPartIndices == null) {
|
|
659
|
+
appendUnindexedAttribution(part);
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
if (!mapsOneToOne || retainedContentPartIndices == null) {
|
|
663
|
+
appendUnindexedAttribution(part);
|
|
664
|
+
continue;
|
|
665
|
+
}
|
|
666
|
+
const sourceContentPartIndices: number[] = [];
|
|
667
|
+
for (const sourceContentPartIndex of part.sourceContentPartIndices) {
|
|
668
|
+
if (retainedContentPartIndices.has(sourceContentPartIndex)) {
|
|
669
|
+
sourceContentPartIndices.push(sourceContentPartIndex);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
if (sourceContentPartIndices.length > 0) {
|
|
673
|
+
retained.push({ ...part, sourceContentPartIndices });
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
return retained.length > 0
|
|
677
|
+
? retained
|
|
678
|
+
: [{ attribution: parts[0]?.attribution ?? 'tool' }];
|
|
519
679
|
}
|
|
520
680
|
|
|
521
681
|
function cloneAIMessageWithToolCalls(
|
|
@@ -2245,9 +2405,11 @@ export function projectComputerCallOutputsToText(
|
|
|
2245
2405
|
continue;
|
|
2246
2406
|
}
|
|
2247
2407
|
projected ??= [...messages];
|
|
2248
|
-
projected[i] =
|
|
2249
|
-
|
|
2250
|
-
|
|
2408
|
+
projected[i] = stampSyntheticProviderMessage(
|
|
2409
|
+
cloneToolMessageWithContent(
|
|
2410
|
+
message,
|
|
2411
|
+
'[Computer screenshot omitted for this provider]'
|
|
2412
|
+
)
|
|
2251
2413
|
);
|
|
2252
2414
|
}
|
|
2253
2415
|
return projected ?? messages;
|
|
@@ -2308,21 +2470,130 @@ export function projectAnthropicArtifactContent(
|
|
|
2308
2470
|
const baseContent = Array.isArray(msg.content)
|
|
2309
2471
|
? msg.content
|
|
2310
2472
|
: stringifyToolMessageContent(msg.content);
|
|
2311
|
-
const
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2473
|
+
const aggregate = createBoundedContentAccumulator(maxChars);
|
|
2474
|
+
let contentProjection: ReturnType<
|
|
2475
|
+
typeof appendBoundedContentContribution
|
|
2476
|
+
> = { contributed: false, complete: true };
|
|
2477
|
+
/** Preserve the established empty-result text block shape without
|
|
2478
|
+
* crediting it as a provider-visible source contribution. */
|
|
2479
|
+
if (baseContent === '') {
|
|
2480
|
+
aggregate.blocks.push({ type: ContentTypes.TEXT, text: '' });
|
|
2481
|
+
aggregate.hasContent = true;
|
|
2482
|
+
} else {
|
|
2483
|
+
contentProjection = appendBoundedContentContribution(
|
|
2484
|
+
aggregate,
|
|
2485
|
+
baseContent
|
|
2486
|
+
);
|
|
2487
|
+
}
|
|
2488
|
+
const artifactProjection = appendBoundedContentContribution(
|
|
2489
|
+
aggregate,
|
|
2490
|
+
artifactContent
|
|
2315
2491
|
);
|
|
2492
|
+
const content = toLangChainContent(aggregate.blocks);
|
|
2316
2493
|
formattedMessages ??= [...messages];
|
|
2317
|
-
|
|
2494
|
+
const projectedMessage = cloneToolMessageWithContent(msg, content, {
|
|
2318
2495
|
...msg.artifact,
|
|
2319
2496
|
content: [],
|
|
2320
2497
|
});
|
|
2498
|
+
const toolProvenanceParts = projectProviderMessageAttribution(
|
|
2499
|
+
msg,
|
|
2500
|
+
'tool'
|
|
2501
|
+
);
|
|
2502
|
+
const projectedProvenanceParts: ProviderMessageProvenancePart[] = [];
|
|
2503
|
+
if (contentProjection.contributed) {
|
|
2504
|
+
const retainedParts = retainProjectedContentPartProvenance(
|
|
2505
|
+
msg,
|
|
2506
|
+
toolProvenanceParts,
|
|
2507
|
+
contentProjection.retainedContentPartIndices,
|
|
2508
|
+
contentProjection.complete
|
|
2509
|
+
);
|
|
2510
|
+
for (const part of retainedParts) {
|
|
2511
|
+
projectedProvenanceParts.push(part);
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
if (artifactProjection.contributed) {
|
|
2515
|
+
const artifactPart = projectUnindexedProviderMessageAttribution(
|
|
2516
|
+
msg,
|
|
2517
|
+
'tool'
|
|
2518
|
+
);
|
|
2519
|
+
const previousPart =
|
|
2520
|
+
projectedProvenanceParts[projectedProvenanceParts.length - 1];
|
|
2521
|
+
if (
|
|
2522
|
+
projectedProvenanceParts.length === 0 ||
|
|
2523
|
+
previousPart.attribution !== artifactPart.attribution ||
|
|
2524
|
+
previousPart.sourceMessageId !== artifactPart.sourceMessageId ||
|
|
2525
|
+
previousPart.sourceContentPartIndices != null
|
|
2526
|
+
) {
|
|
2527
|
+
projectedProvenanceParts.push(artifactPart);
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
if (projectedProvenanceParts.length > 0) {
|
|
2531
|
+
setProviderMessageProvenance(
|
|
2532
|
+
projectedMessage,
|
|
2533
|
+
projectedProvenanceParts
|
|
2534
|
+
);
|
|
2535
|
+
}
|
|
2536
|
+
formattedMessages[j] = projectedMessage;
|
|
2321
2537
|
}
|
|
2322
2538
|
}
|
|
2323
2539
|
return formattedMessages ?? messages;
|
|
2324
2540
|
}
|
|
2325
2541
|
|
|
2542
|
+
function projectProviderMessageAttribution(
|
|
2543
|
+
message: BaseMessage,
|
|
2544
|
+
attribution: ProviderMessageProvenancePart['attribution']
|
|
2545
|
+
): ProviderMessageProvenancePart[] {
|
|
2546
|
+
const explicit = getProviderMessageProvenance(message);
|
|
2547
|
+
const sourceMessageIds = getProviderSourceMessageIds(message);
|
|
2548
|
+
const explicitSourceIds = new Set<string>();
|
|
2549
|
+
for (const part of explicit?.parts ?? []) {
|
|
2550
|
+
if (part.sourceMessageId != null) {
|
|
2551
|
+
explicitSourceIds.add(part.sourceMessageId);
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
const soleSourceFallback =
|
|
2555
|
+
explicitSourceIds.size === 0 && sourceMessageIds.length === 1
|
|
2556
|
+
? sourceMessageIds[0]
|
|
2557
|
+
: undefined;
|
|
2558
|
+
const parts: ProviderMessageProvenancePart[] = [];
|
|
2559
|
+
const representedSourceIds = new Set<string>();
|
|
2560
|
+
for (const part of explicit?.parts ?? []) {
|
|
2561
|
+
const sourceMessageId = part.sourceMessageId ?? soleSourceFallback;
|
|
2562
|
+
if (sourceMessageId != null) {
|
|
2563
|
+
representedSourceIds.add(sourceMessageId);
|
|
2564
|
+
}
|
|
2565
|
+
parts.push({
|
|
2566
|
+
attribution,
|
|
2567
|
+
...(sourceMessageId != null && { sourceMessageId }),
|
|
2568
|
+
...(part.sourceContentPartIndices != null && {
|
|
2569
|
+
sourceContentPartIndices: part.sourceContentPartIndices,
|
|
2570
|
+
}),
|
|
2571
|
+
});
|
|
2572
|
+
}
|
|
2573
|
+
for (const sourceMessageId of sourceMessageIds) {
|
|
2574
|
+
if (!representedSourceIds.has(sourceMessageId)) {
|
|
2575
|
+
parts.push({ attribution, sourceMessageId });
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
return parts.length > 0 ? parts : [{ attribution }];
|
|
2579
|
+
}
|
|
2580
|
+
|
|
2581
|
+
/** Artifacts are attached to a tool message rather than one of its content
|
|
2582
|
+
* positions. Retain the source row only when it is unambiguous, but never
|
|
2583
|
+
* claim a raw content-part index for artifact-only bytes. */
|
|
2584
|
+
function projectUnindexedProviderMessageAttribution(
|
|
2585
|
+
message: BaseMessage,
|
|
2586
|
+
attribution: ProviderMessageProvenancePart['attribution']
|
|
2587
|
+
): ProviderMessageProvenancePart {
|
|
2588
|
+
const sourceMessageIds = getProviderSourceMessageIds(message);
|
|
2589
|
+
return {
|
|
2590
|
+
attribution,
|
|
2591
|
+
...(sourceMessageIds.length === 1 && {
|
|
2592
|
+
sourceMessageId: sourceMessageIds[0],
|
|
2593
|
+
}),
|
|
2594
|
+
};
|
|
2595
|
+
}
|
|
2596
|
+
|
|
2326
2597
|
/**
|
|
2327
2598
|
* Mutating compatibility wrapper retained for existing package consumers.
|
|
2328
2599
|
* New provider-call paths should use `projectAnthropicArtifactContent`.
|
|
@@ -2339,6 +2610,10 @@ export function formatAnthropicArtifactContent(messages: BaseMessage[]): void {
|
|
|
2339
2610
|
projected[i] !== messages[i]
|
|
2340
2611
|
) {
|
|
2341
2612
|
messages[i].content = projected[i].content;
|
|
2613
|
+
const provenance = getProviderMessageProvenance(projected[i]);
|
|
2614
|
+
if (provenance != null) {
|
|
2615
|
+
setProviderMessageProvenance(messages[i], provenance.parts);
|
|
2616
|
+
}
|
|
2342
2617
|
}
|
|
2343
2618
|
}
|
|
2344
2619
|
}
|
|
@@ -2363,8 +2638,9 @@ export function projectArtifactPayload(
|
|
|
2363
2638
|
if (latestAIParentIndex === -1) return messages;
|
|
2364
2639
|
|
|
2365
2640
|
// Single pass: collect relevant tool messages with artifacts and aggregate
|
|
2366
|
-
|
|
2641
|
+
const aggregate = createBoundedContentAccumulator(maxChars);
|
|
2367
2642
|
let formattedMessages: BaseMessage[] | undefined;
|
|
2643
|
+
const artifactProvenanceParts: ProviderMessageProvenancePart[] = [];
|
|
2368
2644
|
|
|
2369
2645
|
for (let i = latestAIParentIndex + 1; i < messages.length; i++) {
|
|
2370
2646
|
const msg = messages[i];
|
|
@@ -2380,13 +2656,12 @@ export function projectArtifactPayload(
|
|
|
2380
2656
|
) {
|
|
2381
2657
|
continue;
|
|
2382
2658
|
}
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
msg.content
|
|
2386
|
-
maxChars
|
|
2659
|
+
const contentProjection = appendBoundedContentContribution(
|
|
2660
|
+
aggregate,
|
|
2661
|
+
msg.content
|
|
2387
2662
|
);
|
|
2388
2663
|
formattedMessages ??= [...messages];
|
|
2389
|
-
|
|
2664
|
+
const placeholder = cloneToolMessageWithContent(
|
|
2390
2665
|
msg,
|
|
2391
2666
|
'Tool response is included in the next message as a Human message',
|
|
2392
2667
|
{
|
|
@@ -2394,15 +2669,54 @@ export function projectArtifactPayload(
|
|
|
2394
2669
|
content: [],
|
|
2395
2670
|
}
|
|
2396
2671
|
);
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2672
|
+
const toolProvenanceParts = projectProviderMessageAttribution(msg, 'tool');
|
|
2673
|
+
setProviderMessageProvenance(
|
|
2674
|
+
placeholder,
|
|
2675
|
+
toolProvenanceParts.map((part) => ({
|
|
2676
|
+
...part,
|
|
2677
|
+
attribution: 'synthetic',
|
|
2678
|
+
}))
|
|
2679
|
+
);
|
|
2680
|
+
formattedMessages[i] = placeholder;
|
|
2681
|
+
const artifactProjection = appendBoundedContentContribution(
|
|
2682
|
+
aggregate,
|
|
2683
|
+
msg.artifact.content
|
|
2401
2684
|
);
|
|
2685
|
+
if (contentProjection.contributed) {
|
|
2686
|
+
const retainedParts = retainProjectedContentPartProvenance(
|
|
2687
|
+
msg,
|
|
2688
|
+
toolProvenanceParts,
|
|
2689
|
+
contentProjection.retainedContentPartIndices,
|
|
2690
|
+
contentProjection.complete
|
|
2691
|
+
);
|
|
2692
|
+
for (const part of retainedParts) {
|
|
2693
|
+
artifactProvenanceParts.push(part);
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
if (artifactProjection.contributed) {
|
|
2697
|
+
const artifactPart = projectUnindexedProviderMessageAttribution(
|
|
2698
|
+
msg,
|
|
2699
|
+
'tool'
|
|
2700
|
+
);
|
|
2701
|
+
const previousPart =
|
|
2702
|
+
artifactProvenanceParts[artifactProvenanceParts.length - 1];
|
|
2703
|
+
if (
|
|
2704
|
+
artifactProvenanceParts.length === 0 ||
|
|
2705
|
+
previousPart.attribution !== artifactPart.attribution ||
|
|
2706
|
+
previousPart.sourceMessageId !== artifactPart.sourceMessageId ||
|
|
2707
|
+
previousPart.sourceContentPartIndices != null
|
|
2708
|
+
) {
|
|
2709
|
+
artifactProvenanceParts.push(artifactPart);
|
|
2710
|
+
}
|
|
2711
|
+
}
|
|
2402
2712
|
}
|
|
2403
2713
|
|
|
2404
|
-
if (
|
|
2405
|
-
|
|
2714
|
+
if (aggregate.hasContent && artifactProvenanceParts.length > 0) {
|
|
2715
|
+
const artifactPayload = new HumanMessage({
|
|
2716
|
+
content: toLangChainContent(aggregate.blocks),
|
|
2717
|
+
});
|
|
2718
|
+
setProviderMessageProvenance(artifactPayload, artifactProvenanceParts);
|
|
2719
|
+
formattedMessages?.push(artifactPayload);
|
|
2406
2720
|
}
|
|
2407
2721
|
return formattedMessages ?? messages;
|
|
2408
2722
|
}
|
|
@@ -2424,9 +2738,15 @@ export function formatArtifactPayload(messages: BaseMessage[]): void {
|
|
|
2424
2738
|
projected[i] !== messages[i]
|
|
2425
2739
|
) {
|
|
2426
2740
|
messages[i].content = projected[i].content;
|
|
2741
|
+
const provenance = getProviderMessageProvenance(projected[i]);
|
|
2742
|
+
if (provenance != null) {
|
|
2743
|
+
setProviderMessageProvenance(messages[i], provenance.parts);
|
|
2744
|
+
}
|
|
2427
2745
|
}
|
|
2428
2746
|
}
|
|
2429
|
-
|
|
2747
|
+
for (let i = originalLength; i < projected.length; i++) {
|
|
2748
|
+
messages.push(projected[i]);
|
|
2749
|
+
}
|
|
2430
2750
|
}
|
|
2431
2751
|
|
|
2432
2752
|
export function findLastIndex<T>(
|