@librechat/agents 3.7.6 → 3.7.8
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 +23 -3
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/common/constants.cjs +10 -0
- package/dist/cjs/common/constants.cjs.map +1 -1
- package/dist/cjs/eventActor/EventActorExecutor.cjs +305 -11
- package/dist/cjs/eventActor/EventActorExecutor.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +16 -5
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/langfuseTraceShaping.cjs +75 -0
- package/dist/cjs/langfuseTraceShaping.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/toolCache.cjs +1 -1
- package/dist/cjs/llm/fake.cjs +9 -5
- package/dist/cjs/llm/fake.cjs.map +1 -1
- package/dist/cjs/llm/invoke.cjs +1 -1
- package/dist/cjs/llm/openrouter/toolCache.cjs +1 -1
- package/dist/cjs/llm/prepareProviderRequest.cjs +2 -2
- package/dist/cjs/llm/providers.cjs +1 -1
- package/dist/cjs/llm/truncation.cjs +1 -0
- package/dist/cjs/main.cjs +3 -2
- package/dist/cjs/messages/format.cjs +298 -3
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/prune.cjs +1 -1
- package/dist/cjs/run.cjs +25 -15
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/stream.cjs +1 -1
- package/dist/cjs/summarization/node.cjs +43 -9
- package/dist/cjs/summarization/node.cjs.map +1 -1
- package/dist/cjs/summarization/semanticIndex.cjs +362 -0
- package/dist/cjs/summarization/semanticIndex.cjs.map +1 -0
- package/dist/cjs/tools/subagent/childGraphConfig.cjs +2 -1
- package/dist/cjs/tools/subagent/childGraphConfig.cjs.map +1 -1
- package/dist/cjs/utils/index.cjs +1 -1
- package/dist/esm/agents/AgentContext.mjs +23 -3
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/common/constants.mjs +10 -1
- package/dist/esm/common/constants.mjs.map +1 -1
- package/dist/esm/eventActor/EventActorExecutor.mjs +305 -11
- package/dist/esm/eventActor/EventActorExecutor.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +16 -5
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/langfuseTraceShaping.mjs +75 -0
- package/dist/esm/langfuseTraceShaping.mjs.map +1 -1
- package/dist/esm/llm/bedrock/toolCache.mjs +1 -1
- package/dist/esm/llm/fake.mjs +9 -5
- package/dist/esm/llm/fake.mjs.map +1 -1
- package/dist/esm/llm/invoke.mjs +1 -1
- package/dist/esm/llm/openrouter/toolCache.mjs +1 -1
- package/dist/esm/llm/prepareProviderRequest.mjs +2 -2
- package/dist/esm/llm/providers.mjs +1 -1
- package/dist/esm/llm/truncation.mjs +1 -1
- package/dist/esm/main.mjs +4 -4
- package/dist/esm/messages/format.mjs +298 -3
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/prune.mjs +1 -1
- package/dist/esm/run.mjs +25 -15
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/stream.mjs +1 -1
- package/dist/esm/summarization/node.mjs +43 -9
- package/dist/esm/summarization/node.mjs.map +1 -1
- package/dist/esm/summarization/semanticIndex.mjs +360 -0
- package/dist/esm/summarization/semanticIndex.mjs.map +1 -0
- package/dist/esm/tools/subagent/childGraphConfig.mjs +2 -1
- package/dist/esm/tools/subagent/childGraphConfig.mjs.map +1 -1
- package/dist/esm/utils/index.mjs +1 -1
- package/dist/types/agents/AgentContext.d.ts +27 -1
- package/dist/types/common/constants.d.ts +10 -0
- package/dist/types/eventActor/EventActorExecutor.d.ts +3 -1
- package/dist/types/eventActor/index.d.ts +1 -1
- package/dist/types/eventActor/types.d.ts +149 -5
- package/dist/types/graphs/Graph.d.ts +15 -0
- package/dist/types/llm/fake.d.ts +12 -2
- package/dist/types/messages/format.d.ts +10 -1
- package/dist/types/run.d.ts +17 -5
- package/dist/types/summarization/semanticIndex.d.ts +19 -0
- package/dist/types/types/graph.d.ts +9 -1
- package/dist/types/types/summarize.d.ts +38 -0
- package/package.json +2 -1
- package/src/agents/AgentContext.ts +61 -1
- package/src/common/constants.ts +11 -0
- package/src/eventActor/EventActorExecutor.ts +545 -16
- package/src/eventActor/index.ts +17 -0
- package/src/eventActor/types.ts +182 -3
- package/src/graphs/Graph.ts +41 -8
- package/src/langfuseTraceShaping.ts +94 -0
- package/src/llm/fake.ts +35 -4
- package/src/messages/format.ts +652 -4
- package/src/run.ts +36 -10
- package/src/summarization/node.ts +90 -33
- package/src/summarization/semanticIndex.ts +653 -0
- package/src/tools/subagent/childGraphConfig.ts +3 -0
- package/src/types/graph.ts +9 -0
- package/src/types/summarize.ts +50 -0
package/src/messages/format.ts
CHANGED
|
@@ -28,6 +28,8 @@ import type {
|
|
|
28
28
|
TPayload,
|
|
29
29
|
TMessage,
|
|
30
30
|
ProviderName,
|
|
31
|
+
CompactionSemanticIndex,
|
|
32
|
+
CompactionSemanticIndexEntry,
|
|
31
33
|
} from '@/types';
|
|
32
34
|
import type {
|
|
33
35
|
ProviderMessageAttribution,
|
|
@@ -56,11 +58,17 @@ import {
|
|
|
56
58
|
isAtomicToolContentBlock,
|
|
57
59
|
serializeStructuredValueBounded,
|
|
58
60
|
} from '@/utils/toolContent';
|
|
61
|
+
import { setCompactionSemanticIndexProvidedEntryCount } from '@/summarization/semanticIndex';
|
|
59
62
|
import { normalizeAnthropicToolCallId } from '@/llm/anthropic/utils/message_inputs';
|
|
60
63
|
import { toLangChainContent, toLangChainMessageFields } from './langchain';
|
|
61
64
|
import { flattenLegacyContent, isLegacyConvertible } from './content';
|
|
62
65
|
import { HARD_MAX_TOOL_RESULT_CHARS } from '@/utils/truncation';
|
|
63
|
-
import {
|
|
66
|
+
import {
|
|
67
|
+
Providers,
|
|
68
|
+
ContentTypes,
|
|
69
|
+
Constants,
|
|
70
|
+
COMPACTION_SEMANTIC_INDEX_LIMITS,
|
|
71
|
+
} from '@/common';
|
|
64
72
|
import { emitAgentLog } from '@/utils/events';
|
|
65
73
|
|
|
66
74
|
interface MediaMessageParams {
|
|
@@ -367,9 +375,12 @@ export const formatFromLangChain = (
|
|
|
367
375
|
};
|
|
368
376
|
|
|
369
377
|
interface FormatAssistantMessageOptions {
|
|
378
|
+
compactionSemanticIndex?: DerivedCompactionSemanticIndexCollector;
|
|
379
|
+
intentToolNames?: ReadonlySet<string>;
|
|
370
380
|
preserveUnpairedServerToolUses?: boolean;
|
|
371
381
|
preserveReasoningContent?: boolean;
|
|
372
382
|
provider?: ProviderName;
|
|
383
|
+
retainedSourceContentEnd?: number;
|
|
373
384
|
sourceMessageId?: string;
|
|
374
385
|
sourceContentPartOffset?: number;
|
|
375
386
|
sourceContentPartIndices?: readonly SourceContentPartIndices[];
|
|
@@ -394,6 +405,13 @@ interface FormatAgentMessagesOptions {
|
|
|
394
405
|
* historical `skill` tool_calls are not reconstructed into a HumanMessage,
|
|
395
406
|
* so the same SKILL.md body is not injected twice in one request. */
|
|
396
407
|
skipSkillBodyNames?: Set<string>;
|
|
408
|
+
/** Derive bounded compaction guidance during the formatter's existing
|
|
409
|
+
* persisted-content analysis. Tool intents are accepted only for names
|
|
410
|
+
* the host identifies as semantic-label fields; business `intent`
|
|
411
|
+
* parameters must remain ordinary tool input. */
|
|
412
|
+
compactionSemanticIndex?: {
|
|
413
|
+
intentToolNames?: ReadonlySet<string>;
|
|
414
|
+
};
|
|
397
415
|
}
|
|
398
416
|
|
|
399
417
|
function extractReasoningContent(
|
|
@@ -476,6 +494,542 @@ function getToolUseId(part: MessageContentComplex): string | undefined {
|
|
|
476
494
|
return part.tool_use_id;
|
|
477
495
|
}
|
|
478
496
|
|
|
497
|
+
type CompactionSemanticContentPart = MessageContentComplex & {
|
|
498
|
+
activity_label?: string;
|
|
499
|
+
activity_label_type?: string;
|
|
500
|
+
activity_label_revision?: number;
|
|
501
|
+
activity_start_index?: number;
|
|
502
|
+
pending?: boolean;
|
|
503
|
+
reasoning_label?: string;
|
|
504
|
+
reasoning_label_revision?: number;
|
|
505
|
+
reasoning_label_status?: string;
|
|
506
|
+
reasoning_label_step_id?: string;
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
type OrderedCompactionSemanticIndexEntry = {
|
|
510
|
+
entry: CompactionSemanticIndexEntry;
|
|
511
|
+
identityHash: number;
|
|
512
|
+
order: number;
|
|
513
|
+
retentionCount: number;
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
type CompactionSemanticEntryRing = {
|
|
517
|
+
entries: OrderedCompactionSemanticIndexEntry[];
|
|
518
|
+
cursor: number;
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
type CompactionSemanticTypeCoverage = {
|
|
522
|
+
head: OrderedCompactionSemanticIndexEntry[];
|
|
523
|
+
tail: CompactionSemanticEntryRing;
|
|
524
|
+
};
|
|
525
|
+
|
|
526
|
+
type CompactionSemanticCoverageState = {
|
|
527
|
+
head: OrderedCompactionSemanticIndexEntry[];
|
|
528
|
+
tail: CompactionSemanticEntryRing;
|
|
529
|
+
latestByIdentityHash: Map<number, OrderedCompactionSemanticIndexEntry[]>;
|
|
530
|
+
typeCoverage: Map<
|
|
531
|
+
CompactionSemanticIndexEntry['type'],
|
|
532
|
+
CompactionSemanticTypeCoverage
|
|
533
|
+
>;
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
type DerivedCompactionSemanticIndexCollector = {
|
|
537
|
+
entries: CompactionSemanticIndexEntry[];
|
|
538
|
+
entryCount: number;
|
|
539
|
+
coverage?: CompactionSemanticCoverageState;
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
const DERIVED_SEMANTIC_HEAD_LIMIT =
|
|
543
|
+
COMPACTION_SEMANTIC_INDEX_LIMITS.maxInputEntries / 4;
|
|
544
|
+
const DERIVED_SEMANTIC_TAIL_LIMIT =
|
|
545
|
+
COMPACTION_SEMANTIC_INDEX_LIMITS.maxInputEntries / 2;
|
|
546
|
+
const DERIVED_SEMANTIC_TYPE_EDGE_LIMIT =
|
|
547
|
+
COMPACTION_SEMANTIC_INDEX_LIMITS.maxInputEntries / 32;
|
|
548
|
+
const DERIVED_SEMANTIC_TYPE_HASH: Readonly<
|
|
549
|
+
Record<CompactionSemanticIndexEntry['type'], number>
|
|
550
|
+
> = Object.freeze({
|
|
551
|
+
tool_intent: 1,
|
|
552
|
+
tool_outcome: 2,
|
|
553
|
+
activity_phase: 3,
|
|
554
|
+
reasoning_label: 4,
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
function createDerivedCompactionSemanticIndexCollector(): DerivedCompactionSemanticIndexCollector {
|
|
558
|
+
return {
|
|
559
|
+
entries: [],
|
|
560
|
+
entryCount: 0,
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
function createCompactionSemanticCoverageState(): CompactionSemanticCoverageState {
|
|
565
|
+
return {
|
|
566
|
+
head: [],
|
|
567
|
+
tail: { entries: [], cursor: 0 },
|
|
568
|
+
latestByIdentityHash: new Map(),
|
|
569
|
+
typeCoverage: new Map(),
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
function getDerivedCompactionSemanticLocalId(
|
|
574
|
+
entry: CompactionSemanticIndexEntry
|
|
575
|
+
): string {
|
|
576
|
+
if (entry.type === 'reasoning_label') {
|
|
577
|
+
return entry.reasoningStepId.trim();
|
|
578
|
+
}
|
|
579
|
+
if (entry.type !== 'activity_phase') {
|
|
580
|
+
return entry.toolCallId.trim();
|
|
581
|
+
}
|
|
582
|
+
return '';
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
function hashDerivedCompactionSemanticIdentityString(
|
|
586
|
+
initialHash: number,
|
|
587
|
+
value: string
|
|
588
|
+
): number {
|
|
589
|
+
let hash = initialHash;
|
|
590
|
+
for (let index = 0; index < value.length; index++) {
|
|
591
|
+
hash ^= value.charCodeAt(index);
|
|
592
|
+
hash = Math.imul(hash, 16_777_619);
|
|
593
|
+
}
|
|
594
|
+
return hash;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
function hashDerivedCompactionSemanticIdentity(
|
|
598
|
+
entry: CompactionSemanticIndexEntry
|
|
599
|
+
): number {
|
|
600
|
+
let hash = 2_166_136_261 ^ DERIVED_SEMANTIC_TYPE_HASH[entry.type];
|
|
601
|
+
hash = Math.imul(hash, 16_777_619);
|
|
602
|
+
hash = hashDerivedCompactionSemanticIdentityString(
|
|
603
|
+
hash,
|
|
604
|
+
entry.sourceMessageId.trim()
|
|
605
|
+
);
|
|
606
|
+
hash ^= entry.sourceContentIndex;
|
|
607
|
+
hash = Math.imul(hash, 16_777_619);
|
|
608
|
+
hash = hashDerivedCompactionSemanticIdentityString(
|
|
609
|
+
hash,
|
|
610
|
+
getDerivedCompactionSemanticLocalId(entry)
|
|
611
|
+
);
|
|
612
|
+
return hash >>> 0;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
function entriesShareDerivedCompactionSemanticIdentity(
|
|
616
|
+
left: CompactionSemanticIndexEntry,
|
|
617
|
+
right: CompactionSemanticIndexEntry
|
|
618
|
+
): boolean {
|
|
619
|
+
return (
|
|
620
|
+
left.type === right.type &&
|
|
621
|
+
left.sourceMessageId.trim() === right.sourceMessageId.trim() &&
|
|
622
|
+
left.sourceContentIndex === right.sourceContentIndex &&
|
|
623
|
+
getDerivedCompactionSemanticLocalId(left) ===
|
|
624
|
+
getDerivedCompactionSemanticLocalId(right)
|
|
625
|
+
);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
function entriesHaveConflictingSemanticState(
|
|
629
|
+
left: CompactionSemanticIndexEntry,
|
|
630
|
+
right: CompactionSemanticIndexEntry
|
|
631
|
+
): boolean {
|
|
632
|
+
return (
|
|
633
|
+
left.status !== right.status ||
|
|
634
|
+
(left.redacted === true) !== (right.redacted === true) ||
|
|
635
|
+
left.text.replace(/\s+/g, ' ').trim() !==
|
|
636
|
+
right.text.replace(/\s+/g, ' ').trim()
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
function retainCompactionSemanticEntry(
|
|
641
|
+
entry: OrderedCompactionSemanticIndexEntry
|
|
642
|
+
): void {
|
|
643
|
+
entry.retentionCount++;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
function releaseCompactionSemanticEntry(
|
|
647
|
+
coverage: CompactionSemanticCoverageState,
|
|
648
|
+
entry: OrderedCompactionSemanticIndexEntry
|
|
649
|
+
): void {
|
|
650
|
+
entry.retentionCount--;
|
|
651
|
+
if (
|
|
652
|
+
entry.retentionCount === 0 &&
|
|
653
|
+
coverage.latestByIdentityHash.has(entry.identityHash)
|
|
654
|
+
) {
|
|
655
|
+
const bucket = coverage.latestByIdentityHash.get(entry.identityHash);
|
|
656
|
+
if (bucket == null) {
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
const entryIndex = bucket.indexOf(entry);
|
|
660
|
+
if (entryIndex >= 0) {
|
|
661
|
+
bucket.splice(entryIndex, 1);
|
|
662
|
+
}
|
|
663
|
+
if (bucket.length === 0) {
|
|
664
|
+
coverage.latestByIdentityHash.delete(entry.identityHash);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
function appendCompactionSemanticEntryRing(
|
|
670
|
+
coverage: CompactionSemanticCoverageState,
|
|
671
|
+
ring: CompactionSemanticEntryRing,
|
|
672
|
+
entry: OrderedCompactionSemanticIndexEntry,
|
|
673
|
+
limit: number
|
|
674
|
+
): void {
|
|
675
|
+
if (ring.entries.length < limit) {
|
|
676
|
+
ring.entries.push(entry);
|
|
677
|
+
retainCompactionSemanticEntry(entry);
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
releaseCompactionSemanticEntry(coverage, ring.entries[ring.cursor]);
|
|
681
|
+
ring.entries[ring.cursor] = entry;
|
|
682
|
+
retainCompactionSemanticEntry(entry);
|
|
683
|
+
ring.cursor = (ring.cursor + 1) % limit;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
function renewCompactionSemanticEntryRing(
|
|
687
|
+
coverage: CompactionSemanticCoverageState,
|
|
688
|
+
ring: CompactionSemanticEntryRing,
|
|
689
|
+
entry: OrderedCompactionSemanticIndexEntry,
|
|
690
|
+
limit: number
|
|
691
|
+
): void {
|
|
692
|
+
const existingIndex = ring.entries.indexOf(entry);
|
|
693
|
+
if (existingIndex < 0) {
|
|
694
|
+
appendCompactionSemanticEntryRing(coverage, ring, entry, limit);
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
if (ring.entries.length < limit) {
|
|
698
|
+
ring.entries.splice(existingIndex, 1);
|
|
699
|
+
ring.entries.push(entry);
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
const newestIndex =
|
|
703
|
+
(ring.cursor + ring.entries.length - 1) % ring.entries.length;
|
|
704
|
+
let currentIndex = existingIndex;
|
|
705
|
+
for (
|
|
706
|
+
let offset = 0;
|
|
707
|
+
currentIndex !== newestIndex && offset < ring.entries.length;
|
|
708
|
+
offset++
|
|
709
|
+
) {
|
|
710
|
+
const nextIndex = (currentIndex + 1) % ring.entries.length;
|
|
711
|
+
ring.entries[currentIndex] = ring.entries[nextIndex];
|
|
712
|
+
currentIndex = nextIndex;
|
|
713
|
+
}
|
|
714
|
+
ring.entries[newestIndex] = entry;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
function renewCoverageBalancedCompactionSemanticEntry(
|
|
718
|
+
coverage: CompactionSemanticCoverageState,
|
|
719
|
+
entry: OrderedCompactionSemanticIndexEntry
|
|
720
|
+
): void {
|
|
721
|
+
renewCompactionSemanticEntryRing(
|
|
722
|
+
coverage,
|
|
723
|
+
coverage.tail,
|
|
724
|
+
entry,
|
|
725
|
+
DERIVED_SEMANTIC_TAIL_LIMIT
|
|
726
|
+
);
|
|
727
|
+
const typeCoverage = coverage.typeCoverage.get(entry.entry.type);
|
|
728
|
+
if (typeCoverage == null) {
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
renewCompactionSemanticEntryRing(
|
|
732
|
+
coverage,
|
|
733
|
+
typeCoverage.tail,
|
|
734
|
+
entry,
|
|
735
|
+
DERIVED_SEMANTIC_TYPE_EDGE_LIMIT
|
|
736
|
+
);
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
function appendDerivedCompactionSemanticEntry(
|
|
740
|
+
collector: DerivedCompactionSemanticIndexCollector,
|
|
741
|
+
entry: CompactionSemanticIndexEntry
|
|
742
|
+
): void {
|
|
743
|
+
let boundedEntry = entry;
|
|
744
|
+
if (entry.status === 'pending') {
|
|
745
|
+
boundedEntry = { ...entry, text: '' };
|
|
746
|
+
} else if (
|
|
747
|
+
entry.text.length > COMPACTION_SEMANTIC_INDEX_LIMITS.maxInputTextChars
|
|
748
|
+
) {
|
|
749
|
+
boundedEntry = { ...entry, text: '', redacted: true };
|
|
750
|
+
}
|
|
751
|
+
const order = collector.entryCount;
|
|
752
|
+
collector.entryCount++;
|
|
753
|
+
if (
|
|
754
|
+
collector.coverage == null &&
|
|
755
|
+
collector.entries.length < COMPACTION_SEMANTIC_INDEX_LIMITS.maxInputEntries
|
|
756
|
+
) {
|
|
757
|
+
collector.entries.push(boundedEntry);
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
const orderedEntry = {
|
|
761
|
+
entry: boundedEntry,
|
|
762
|
+
identityHash: hashDerivedCompactionSemanticIdentity(boundedEntry),
|
|
763
|
+
order,
|
|
764
|
+
retentionCount: 0,
|
|
765
|
+
};
|
|
766
|
+
if (collector.coverage == null) {
|
|
767
|
+
collector.coverage = createCompactionSemanticCoverageState();
|
|
768
|
+
for (let order = 0; order < collector.entries.length; order++) {
|
|
769
|
+
appendCoverageBalancedCompactionSemanticEntry(collector.coverage, {
|
|
770
|
+
entry: collector.entries[order],
|
|
771
|
+
identityHash: hashDerivedCompactionSemanticIdentity(
|
|
772
|
+
collector.entries[order]
|
|
773
|
+
),
|
|
774
|
+
order,
|
|
775
|
+
retentionCount: 0,
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
collector.entries = [];
|
|
779
|
+
}
|
|
780
|
+
appendCoverageBalancedCompactionSemanticEntry(
|
|
781
|
+
collector.coverage,
|
|
782
|
+
orderedEntry
|
|
783
|
+
);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
function appendCoverageBalancedCompactionSemanticEntry(
|
|
787
|
+
coverage: CompactionSemanticCoverageState,
|
|
788
|
+
orderedEntry: OrderedCompactionSemanticIndexEntry
|
|
789
|
+
): void {
|
|
790
|
+
const identityHash = orderedEntry.identityHash;
|
|
791
|
+
const identityBucket = coverage.latestByIdentityHash.get(identityHash);
|
|
792
|
+
const current = identityBucket?.find(({ entry }) =>
|
|
793
|
+
entriesShareDerivedCompactionSemanticIdentity(entry, orderedEntry.entry)
|
|
794
|
+
);
|
|
795
|
+
if (current != null) {
|
|
796
|
+
if (orderedEntry.entry.revision < current.entry.revision) {
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
if (orderedEntry.entry.revision === current.entry.revision) {
|
|
800
|
+
if (
|
|
801
|
+
entriesHaveConflictingSemanticState(current.entry, orderedEntry.entry)
|
|
802
|
+
) {
|
|
803
|
+
current.entry = { ...current.entry, text: '', redacted: true };
|
|
804
|
+
current.order = orderedEntry.order;
|
|
805
|
+
renewCoverageBalancedCompactionSemanticEntry(coverage, current);
|
|
806
|
+
}
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
current.entry = orderedEntry.entry;
|
|
810
|
+
current.order = orderedEntry.order;
|
|
811
|
+
renewCoverageBalancedCompactionSemanticEntry(coverage, current);
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
if (identityBucket == null) {
|
|
815
|
+
coverage.latestByIdentityHash.set(identityHash, [orderedEntry]);
|
|
816
|
+
} else {
|
|
817
|
+
identityBucket.push(orderedEntry);
|
|
818
|
+
}
|
|
819
|
+
if (coverage.head.length < DERIVED_SEMANTIC_HEAD_LIMIT) {
|
|
820
|
+
coverage.head.push(orderedEntry);
|
|
821
|
+
retainCompactionSemanticEntry(orderedEntry);
|
|
822
|
+
}
|
|
823
|
+
appendCompactionSemanticEntryRing(
|
|
824
|
+
coverage,
|
|
825
|
+
coverage.tail,
|
|
826
|
+
orderedEntry,
|
|
827
|
+
DERIVED_SEMANTIC_TAIL_LIMIT
|
|
828
|
+
);
|
|
829
|
+
let typeCoverage = coverage.typeCoverage.get(orderedEntry.entry.type);
|
|
830
|
+
if (typeCoverage == null) {
|
|
831
|
+
typeCoverage = { head: [], tail: { entries: [], cursor: 0 } };
|
|
832
|
+
coverage.typeCoverage.set(orderedEntry.entry.type, typeCoverage);
|
|
833
|
+
}
|
|
834
|
+
if (typeCoverage.head.length < DERIVED_SEMANTIC_TYPE_EDGE_LIMIT) {
|
|
835
|
+
typeCoverage.head.push(orderedEntry);
|
|
836
|
+
retainCompactionSemanticEntry(orderedEntry);
|
|
837
|
+
}
|
|
838
|
+
appendCompactionSemanticEntryRing(
|
|
839
|
+
coverage,
|
|
840
|
+
typeCoverage.tail,
|
|
841
|
+
orderedEntry,
|
|
842
|
+
DERIVED_SEMANTIC_TYPE_EDGE_LIMIT
|
|
843
|
+
);
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
function finalizeDerivedCompactionSemanticIndex(
|
|
847
|
+
collector: DerivedCompactionSemanticIndexCollector | undefined
|
|
848
|
+
): CompactionSemanticIndex | undefined {
|
|
849
|
+
if (collector == null || collector.entryCount === 0) {
|
|
850
|
+
return undefined;
|
|
851
|
+
}
|
|
852
|
+
if (collector.coverage == null) {
|
|
853
|
+
setCompactionSemanticIndexProvidedEntryCount(
|
|
854
|
+
collector.entries,
|
|
855
|
+
collector.entryCount
|
|
856
|
+
);
|
|
857
|
+
return collector.entries;
|
|
858
|
+
}
|
|
859
|
+
const retained = new Map<number, CompactionSemanticIndexEntry>();
|
|
860
|
+
const retain = (
|
|
861
|
+
entries: readonly OrderedCompactionSemanticIndexEntry[]
|
|
862
|
+
): void => {
|
|
863
|
+
for (const { entry, order } of entries) {
|
|
864
|
+
retained.set(order, entry);
|
|
865
|
+
}
|
|
866
|
+
};
|
|
867
|
+
retain(collector.coverage.head);
|
|
868
|
+
retain(collector.coverage.tail.entries);
|
|
869
|
+
for (const typeCoverage of collector.coverage.typeCoverage.values()) {
|
|
870
|
+
retain(typeCoverage.head);
|
|
871
|
+
retain(typeCoverage.tail.entries);
|
|
872
|
+
}
|
|
873
|
+
const result = [...retained.entries()]
|
|
874
|
+
.sort(([left], [right]) => left - right)
|
|
875
|
+
.map(([, entry]) => entry);
|
|
876
|
+
setCompactionSemanticIndexProvidedEntryCount(result, collector.entryCount);
|
|
877
|
+
return result;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
function collectCompactionSemanticEntriesFromPart(
|
|
881
|
+
collector: DerivedCompactionSemanticIndexCollector,
|
|
882
|
+
part: CompactionSemanticContentPart,
|
|
883
|
+
sourceMessageId: string,
|
|
884
|
+
sourceContentIndex: number,
|
|
885
|
+
retainedSourceContentStart: number,
|
|
886
|
+
retainedSourceContentEnd: number,
|
|
887
|
+
intentToolNames?: ReadonlySet<string>,
|
|
888
|
+
parsedToolInput?: ToolCallPart['args']
|
|
889
|
+
): void {
|
|
890
|
+
if (
|
|
891
|
+
sourceMessageId.length >
|
|
892
|
+
COMPACTION_SEMANTIC_INDEX_LIMITS.maxIdentityChars
|
|
893
|
+
) {
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
if (part.type === ContentTypes.TOOL_CALL) {
|
|
898
|
+
if (
|
|
899
|
+
sourceContentIndex < 0 ||
|
|
900
|
+
sourceContentIndex >
|
|
901
|
+
COMPACTION_SEMANTIC_INDEX_LIMITS.maxSourceContentIndex
|
|
902
|
+
) {
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
905
|
+
const toolCall = part.tool_call;
|
|
906
|
+
const toolCallId = toolCall?.id;
|
|
907
|
+
if (
|
|
908
|
+
typeof toolCallId !== 'string' ||
|
|
909
|
+
toolCallId === '' ||
|
|
910
|
+
toolCallId.length > COMPACTION_SEMANTIC_INDEX_LIMITS.maxIdentityChars
|
|
911
|
+
) {
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
if (
|
|
915
|
+
typeof toolCall.name === 'string' &&
|
|
916
|
+
intentToolNames?.has(toolCall.name) === true
|
|
917
|
+
) {
|
|
918
|
+
const intent =
|
|
919
|
+
parsedToolInput != null &&
|
|
920
|
+
typeof parsedToolInput === 'object' &&
|
|
921
|
+
!Array.isArray(parsedToolInput)
|
|
922
|
+
? parsedToolInput.intent
|
|
923
|
+
: undefined;
|
|
924
|
+
if (typeof intent === 'string' && intent !== '') {
|
|
925
|
+
appendDerivedCompactionSemanticEntry(collector, {
|
|
926
|
+
type: 'tool_intent',
|
|
927
|
+
sourceMessageId,
|
|
928
|
+
sourceContentIndex,
|
|
929
|
+
revision: 0,
|
|
930
|
+
status: 'committed',
|
|
931
|
+
text: intent,
|
|
932
|
+
toolCallId,
|
|
933
|
+
});
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
if (typeof toolCall.outcome === 'string' && toolCall.outcome !== '') {
|
|
937
|
+
appendDerivedCompactionSemanticEntry(collector, {
|
|
938
|
+
type: 'tool_outcome',
|
|
939
|
+
sourceMessageId,
|
|
940
|
+
sourceContentIndex,
|
|
941
|
+
revision: 0,
|
|
942
|
+
status: 'committed',
|
|
943
|
+
text: toolCall.outcome,
|
|
944
|
+
toolCallId,
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
if (part.type === ContentTypes.THINK) {
|
|
951
|
+
if (
|
|
952
|
+
sourceContentIndex < 0 ||
|
|
953
|
+
sourceContentIndex >
|
|
954
|
+
COMPACTION_SEMANTIC_INDEX_LIMITS.maxSourceContentIndex
|
|
955
|
+
) {
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
const reasoningStepId = part.reasoning_label_step_id;
|
|
959
|
+
const revision = part.reasoning_label_revision;
|
|
960
|
+
const status = part.reasoning_label_status;
|
|
961
|
+
const text = part.reasoning_label;
|
|
962
|
+
if (
|
|
963
|
+
typeof reasoningStepId !== 'string' ||
|
|
964
|
+
reasoningStepId === '' ||
|
|
965
|
+
reasoningStepId.length >
|
|
966
|
+
COMPACTION_SEMANTIC_INDEX_LIMITS.maxIdentityChars ||
|
|
967
|
+
typeof revision !== 'number' ||
|
|
968
|
+
!Number.isSafeInteger(revision) ||
|
|
969
|
+
revision < 0
|
|
970
|
+
) {
|
|
971
|
+
return;
|
|
972
|
+
}
|
|
973
|
+
const malformedState =
|
|
974
|
+
(status !== 'complete' && status !== 'streaming') ||
|
|
975
|
+
typeof text !== 'string';
|
|
976
|
+
appendDerivedCompactionSemanticEntry(collector, {
|
|
977
|
+
type: 'reasoning_label',
|
|
978
|
+
sourceMessageId,
|
|
979
|
+
sourceContentIndex,
|
|
980
|
+
revision,
|
|
981
|
+
status:
|
|
982
|
+
status === 'streaming' || malformedState ? 'pending' : 'committed',
|
|
983
|
+
text: typeof text === 'string' ? text : '',
|
|
984
|
+
reasoningStepId,
|
|
985
|
+
...(malformedState ? { redacted: true } : {}),
|
|
986
|
+
});
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
if (
|
|
991
|
+
part.type !== ContentTypes.ACTIVITY_LABEL ||
|
|
992
|
+
part.activity_label_type !== 'phase'
|
|
993
|
+
) {
|
|
994
|
+
return;
|
|
995
|
+
}
|
|
996
|
+
const activitySourceContentIndex = part.activity_start_index;
|
|
997
|
+
if (
|
|
998
|
+
typeof activitySourceContentIndex !== 'number' ||
|
|
999
|
+
!Number.isSafeInteger(activitySourceContentIndex) ||
|
|
1000
|
+
activitySourceContentIndex < retainedSourceContentStart ||
|
|
1001
|
+
activitySourceContentIndex >= retainedSourceContentEnd ||
|
|
1002
|
+
activitySourceContentIndex >
|
|
1003
|
+
COMPACTION_SEMANTIC_INDEX_LIMITS.maxSourceContentIndex
|
|
1004
|
+
) {
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
const revision = part.activity_label_revision;
|
|
1008
|
+
if (
|
|
1009
|
+
revision !== undefined &&
|
|
1010
|
+
(typeof revision !== 'number' ||
|
|
1011
|
+
!Number.isSafeInteger(revision) ||
|
|
1012
|
+
revision < 0)
|
|
1013
|
+
) {
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1016
|
+
const malformedPending =
|
|
1017
|
+
part.pending !== undefined && typeof part.pending !== 'boolean';
|
|
1018
|
+
const malformedText = typeof part.activity_label !== 'string';
|
|
1019
|
+
const malformedState = malformedPending || malformedText;
|
|
1020
|
+
const text = typeof part.activity_label === 'string' ? part.activity_label : '';
|
|
1021
|
+
appendDerivedCompactionSemanticEntry(collector, {
|
|
1022
|
+
type: 'activity_phase',
|
|
1023
|
+
sourceMessageId,
|
|
1024
|
+
sourceContentIndex: activitySourceContentIndex,
|
|
1025
|
+
revision: revision ?? 0,
|
|
1026
|
+
status:
|
|
1027
|
+
part.pending === true || malformedPending ? 'pending' : 'committed',
|
|
1028
|
+
text,
|
|
1029
|
+
...(malformedState ? { redacted: true } : {}),
|
|
1030
|
+
});
|
|
1031
|
+
}
|
|
1032
|
+
|
|
479
1033
|
function collectTrustedToolResultSourceContentPartIndices(
|
|
480
1034
|
content: readonly unknown[] | undefined,
|
|
481
1035
|
sourceContentPartOffset: number
|
|
@@ -868,6 +1422,17 @@ function formatAssistantMessage(
|
|
|
868
1422
|
>();
|
|
869
1423
|
const shouldPreserveReasoningContent =
|
|
870
1424
|
options?.preserveReasoningContent === true;
|
|
1425
|
+
const compactionSemanticIndex = options?.compactionSemanticIndex;
|
|
1426
|
+
const semanticSourceMessageId =
|
|
1427
|
+
compactionSemanticIndex != null &&
|
|
1428
|
+
options?.sourceMessageId != null &&
|
|
1429
|
+
options.sourceMessageId.length <=
|
|
1430
|
+
COMPACTION_SEMANTIC_INDEX_LIMITS.maxIdentityChars
|
|
1431
|
+
? options.sourceMessageId
|
|
1432
|
+
: undefined;
|
|
1433
|
+
const retainedSourceContentStart = options?.sourceContentPartOffset ?? 0;
|
|
1434
|
+
const retainedSourceContentEnd =
|
|
1435
|
+
options?.retainedSourceContentEnd ?? retainedSourceContentStart;
|
|
871
1436
|
const serverToolResultIds = new Set<string>();
|
|
872
1437
|
const preferredToolCallParts = new Map<string, MessageContentComplex>();
|
|
873
1438
|
|
|
@@ -976,6 +1541,9 @@ function formatAssistantMessage(
|
|
|
976
1541
|
if (part == null) {
|
|
977
1542
|
continue;
|
|
978
1543
|
}
|
|
1544
|
+
if (part.type === ContentTypes.ACTIVITY_LABEL) {
|
|
1545
|
+
continue;
|
|
1546
|
+
}
|
|
979
1547
|
const isTrustedResult = isTrustedServerToolResult(
|
|
980
1548
|
part,
|
|
981
1549
|
getSourcePartIndices(partIndex),
|
|
@@ -1011,6 +1579,24 @@ function formatAssistantMessage(
|
|
|
1011
1579
|
continue;
|
|
1012
1580
|
}
|
|
1013
1581
|
const sourcePartIndices = getSourcePartIndices(partIndex);
|
|
1582
|
+
if (part.type === ContentTypes.ACTIVITY_LABEL) {
|
|
1583
|
+
if (
|
|
1584
|
+
compactionSemanticIndex != null &&
|
|
1585
|
+
semanticSourceMessageId != null &&
|
|
1586
|
+
typeof sourcePartIndices === 'number'
|
|
1587
|
+
) {
|
|
1588
|
+
collectCompactionSemanticEntriesFromPart(
|
|
1589
|
+
compactionSemanticIndex,
|
|
1590
|
+
part,
|
|
1591
|
+
semanticSourceMessageId,
|
|
1592
|
+
sourcePartIndices,
|
|
1593
|
+
retainedSourceContentStart,
|
|
1594
|
+
retainedSourceContentEnd,
|
|
1595
|
+
options?.intentToolNames
|
|
1596
|
+
);
|
|
1597
|
+
}
|
|
1598
|
+
continue;
|
|
1599
|
+
}
|
|
1014
1600
|
const toolUseId = getToolUseId(part);
|
|
1015
1601
|
if (toolUseId != null) {
|
|
1016
1602
|
const isServerToolResult =
|
|
@@ -1117,12 +1703,29 @@ function formatAssistantMessage(
|
|
|
1117
1703
|
) {
|
|
1118
1704
|
continue;
|
|
1119
1705
|
}
|
|
1706
|
+
const serverToolInput = parseServerToolInput(_args);
|
|
1707
|
+
if (
|
|
1708
|
+
compactionSemanticIndex != null &&
|
|
1709
|
+
semanticSourceMessageId != null &&
|
|
1710
|
+
typeof sourcePartIndices === 'number'
|
|
1711
|
+
) {
|
|
1712
|
+
collectCompactionSemanticEntriesFromPart(
|
|
1713
|
+
compactionSemanticIndex,
|
|
1714
|
+
part,
|
|
1715
|
+
semanticSourceMessageId,
|
|
1716
|
+
sourcePartIndices,
|
|
1717
|
+
retainedSourceContentStart,
|
|
1718
|
+
retainedSourceContentEnd,
|
|
1719
|
+
options.intentToolNames,
|
|
1720
|
+
serverToolInput
|
|
1721
|
+
);
|
|
1722
|
+
}
|
|
1120
1723
|
pendingServerToolUses.set(_tool_call.id, {
|
|
1121
1724
|
content: {
|
|
1122
1725
|
type: 'server_tool_use',
|
|
1123
1726
|
id: _tool_call.id,
|
|
1124
1727
|
name: _tool_call.name,
|
|
1125
|
-
input:
|
|
1728
|
+
input: serverToolInput,
|
|
1126
1729
|
} as MessageContentComplex,
|
|
1127
1730
|
sourceContentPartIndices: sourcePartIndices,
|
|
1128
1731
|
});
|
|
@@ -1154,6 +1757,22 @@ function formatAssistantMessage(
|
|
|
1154
1757
|
}
|
|
1155
1758
|
|
|
1156
1759
|
tool_call.args = args;
|
|
1760
|
+
if (
|
|
1761
|
+
compactionSemanticIndex != null &&
|
|
1762
|
+
semanticSourceMessageId != null &&
|
|
1763
|
+
typeof sourcePartIndices === 'number'
|
|
1764
|
+
) {
|
|
1765
|
+
collectCompactionSemanticEntriesFromPart(
|
|
1766
|
+
compactionSemanticIndex,
|
|
1767
|
+
part,
|
|
1768
|
+
semanticSourceMessageId,
|
|
1769
|
+
sourcePartIndices,
|
|
1770
|
+
retainedSourceContentStart,
|
|
1771
|
+
retainedSourceContentEnd,
|
|
1772
|
+
options?.intentToolNames,
|
|
1773
|
+
args
|
|
1774
|
+
);
|
|
1775
|
+
}
|
|
1157
1776
|
if (
|
|
1158
1777
|
options?.provider === Providers.ANTHROPIC &&
|
|
1159
1778
|
Array.isArray(lastAIMessage.content)
|
|
@@ -1192,6 +1811,22 @@ function formatAssistantMessage(
|
|
|
1192
1811
|
part.type === ContentTypes.REASONING_CONTENT ||
|
|
1193
1812
|
part.type === 'redacted_thinking'
|
|
1194
1813
|
) {
|
|
1814
|
+
if (
|
|
1815
|
+
part.type === ContentTypes.THINK &&
|
|
1816
|
+
compactionSemanticIndex != null &&
|
|
1817
|
+
semanticSourceMessageId != null &&
|
|
1818
|
+
typeof sourcePartIndices === 'number'
|
|
1819
|
+
) {
|
|
1820
|
+
collectCompactionSemanticEntriesFromPart(
|
|
1821
|
+
compactionSemanticIndex,
|
|
1822
|
+
part,
|
|
1823
|
+
semanticSourceMessageId,
|
|
1824
|
+
sourcePartIndices,
|
|
1825
|
+
retainedSourceContentStart,
|
|
1826
|
+
retainedSourceContentEnd,
|
|
1827
|
+
options?.intentToolNames
|
|
1828
|
+
);
|
|
1829
|
+
}
|
|
1195
1830
|
hasReasoning = true;
|
|
1196
1831
|
pendingReasoningContent += extractReasoningContent(part);
|
|
1197
1832
|
appendSourceContentPartIndices(
|
|
@@ -1270,8 +1905,7 @@ function formatAssistantMessage(
|
|
|
1270
1905
|
} else if (
|
|
1271
1906
|
part.type === ContentTypes.ERROR ||
|
|
1272
1907
|
part.type === ContentTypes.AGENT_UPDATE ||
|
|
1273
|
-
part.type === ContentTypes.SUMMARY
|
|
1274
|
-
part.type === ContentTypes.ACTIVITY_LABEL
|
|
1908
|
+
part.type === ContentTypes.SUMMARY
|
|
1275
1909
|
) {
|
|
1276
1910
|
continue;
|
|
1277
1911
|
} else {
|
|
@@ -1991,6 +2625,8 @@ export const formatAgentMessages = (
|
|
|
1991
2625
|
/** When a positional summary boundary sliced content from a message, the token
|
|
1992
2626
|
* count was proportionally reduced. Returned so the caller can log it. */
|
|
1993
2627
|
boundaryTokenAdjustment?: SummaryTokenAdjustment;
|
|
2628
|
+
/** Bounded semantic guidance derived during persisted-content analysis. */
|
|
2629
|
+
compactionSemanticIndex?: CompactionSemanticIndex;
|
|
1994
2630
|
} => {
|
|
1995
2631
|
const messages: Array<
|
|
1996
2632
|
| RoleBearingMessage<HumanMessage>
|
|
@@ -2005,6 +2641,10 @@ export const formatAgentMessages = (
|
|
|
2005
2641
|
* nothing cannot leave the anchor stranded as the final turn.
|
|
2006
2642
|
*/
|
|
2007
2643
|
const legacyContentEnabled = options?.legacyContent === true;
|
|
2644
|
+
const compactionSemanticIndexCollector =
|
|
2645
|
+
options?.compactionSemanticIndex != null
|
|
2646
|
+
? createDerivedCompactionSemanticIndexCollector()
|
|
2647
|
+
: undefined;
|
|
2008
2648
|
/** Emission choke point: every formatted message enters the result here, so
|
|
2009
2649
|
* the legacy flatten happens once per message with no closing rescan. The
|
|
2010
2650
|
* summary boundary slices payload entries before formatting, and nothing
|
|
@@ -2334,11 +2974,16 @@ export const formatAgentMessages = (
|
|
|
2334
2974
|
}
|
|
2335
2975
|
|
|
2336
2976
|
const formattedMessages = formatAssistantMessage(processedMessage, {
|
|
2977
|
+
compactionSemanticIndex: compactionSemanticIndexCollector,
|
|
2978
|
+
intentToolNames: options?.compactionSemanticIndex?.intentToolNames,
|
|
2337
2979
|
preserveUnpairedServerToolUses: i === payload.length - 1,
|
|
2338
2980
|
preserveReasoningContent:
|
|
2339
2981
|
options?.preserveReasoningContent ??
|
|
2340
2982
|
options?.provider === Providers.DEEPSEEK,
|
|
2341
2983
|
provider: options?.provider,
|
|
2984
|
+
retainedSourceContentEnd:
|
|
2985
|
+
sourceContentPartOffset +
|
|
2986
|
+
(Array.isArray(message.content) ? message.content.length : 0),
|
|
2342
2987
|
sourceMessageId,
|
|
2343
2988
|
sourceContentPartOffset,
|
|
2344
2989
|
sourceContentPartIndices: processedSourceContentPartIndices,
|
|
@@ -2610,6 +3255,9 @@ export const formatAgentMessages = (
|
|
|
2610
3255
|
? { text: summaryBoundary.text, tokenCount: summaryBoundary.tokenCount }
|
|
2611
3256
|
: undefined,
|
|
2612
3257
|
boundaryTokenAdjustment,
|
|
3258
|
+
compactionSemanticIndex: finalizeDerivedCompactionSemanticIndex(
|
|
3259
|
+
compactionSemanticIndexCollector
|
|
3260
|
+
),
|
|
2613
3261
|
};
|
|
2614
3262
|
};
|
|
2615
3263
|
|