@librechat/agents 3.3.0 → 3.3.2
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 +116 -2
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/common/enum.cjs +2 -0
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +229 -48
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +102 -27
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/index.cjs +11 -2
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
- package/dist/cjs/llm/contextOverflowRecovery.cjs +132 -0
- package/dist/cjs/llm/contextOverflowRecovery.cjs.map +1 -0
- package/dist/cjs/llm/google/index.cjs +1 -1
- package/dist/cjs/llm/invoke.cjs +60 -3
- package/dist/cjs/llm/invoke.cjs.map +1 -1
- package/dist/cjs/main.cjs +20 -7
- package/dist/cjs/messages/prune.cjs +16 -5
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/messages/recency.cjs +2 -0
- package/dist/cjs/messages/recency.cjs.map +1 -1
- package/dist/cjs/run.cjs +15 -2
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/stream.cjs +205 -49
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/summarization/node.cjs +55 -7
- package/dist/cjs/summarization/node.cjs.map +1 -1
- package/dist/cjs/tools/BashExecutor.cjs +2 -2
- package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +2 -2
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/CodeExecutor.cjs +69 -8
- package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs +19 -15
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +32 -3
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/utils/errors.cjs +317 -52
- package/dist/cjs/utils/errors.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +117 -3
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/common/enum.mjs +2 -0
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +227 -46
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +102 -27
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/llm/bedrock/index.mjs +11 -2
- package/dist/esm/llm/bedrock/index.mjs.map +1 -1
- package/dist/esm/llm/contextOverflowRecovery.mjs +130 -0
- package/dist/esm/llm/contextOverflowRecovery.mjs.map +1 -0
- package/dist/esm/llm/google/index.mjs +1 -1
- package/dist/esm/llm/invoke.mjs +59 -4
- package/dist/esm/llm/invoke.mjs.map +1 -1
- package/dist/esm/main.mjs +9 -9
- package/dist/esm/messages/prune.mjs +14 -6
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/messages/recency.mjs +2 -1
- package/dist/esm/messages/recency.mjs.map +1 -1
- package/dist/esm/run.mjs +15 -2
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/stream.mjs +205 -49
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/summarization/node.mjs +55 -7
- package/dist/esm/summarization/node.mjs.map +1 -1
- package/dist/esm/tools/BashExecutor.mjs +3 -3
- package/dist/esm/tools/BashExecutor.mjs.map +1 -1
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs +3 -3
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/CodeExecutor.mjs +62 -9
- package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
- package/dist/esm/tools/ProgrammaticToolCalling.mjs +20 -16
- package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +32 -3
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/utils/errors.mjs +317 -53
- package/dist/esm/utils/errors.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +62 -3
- package/dist/types/common/enum.d.ts +2 -0
- package/dist/types/graphs/Graph.d.ts +16 -2
- package/dist/types/graphs/MultiAgentGraph.d.ts +1 -0
- package/dist/types/llm/contextOverflowRecovery.d.ts +85 -0
- package/dist/types/llm/invoke.d.ts +35 -6
- package/dist/types/messages/prune.d.ts +10 -2
- package/dist/types/messages/recency.d.ts +1 -0
- package/dist/types/run.d.ts +2 -0
- package/dist/types/tools/CodeExecutor.d.ts +14 -1
- package/dist/types/types/llm.d.ts +7 -4
- package/dist/types/types/stream.d.ts +5 -4
- package/dist/types/types/summarize.d.ts +22 -0
- package/dist/types/utils/__tests__/fixtures/contextOverflowSignatures.d.ts +40 -0
- package/dist/types/utils/errors.d.ts +65 -16
- package/dist/types/utils/redactSecrets.d.ts +3 -0
- package/package.json +10 -11
- package/src/agents/AgentContext.ts +188 -7
- package/src/agents/__tests__/AgentContext.overflow.test.ts +205 -0
- package/src/common/enum.ts +2 -0
- package/src/graphs/Graph.ts +389 -58
- package/src/graphs/MultiAgentGraph.ts +184 -46
- package/src/graphs/__tests__/Graph.contextOverflow.test.ts +631 -0
- package/src/llm/__tests__/contextOverflowRecovery.test.ts +401 -0
- package/src/llm/__tests__/fallbackOverflow.test.ts +287 -0
- package/src/llm/anthropic/llm.spec.ts +8 -0
- package/src/llm/bedrock/index.ts +25 -12
- package/src/llm/contextOverflowRecovery.ts +292 -0
- package/src/llm/invoke.ts +119 -4
- package/src/messages/prune.ts +24 -11
- package/src/messages/recency.ts +3 -1
- package/src/run.ts +24 -1
- package/src/scripts/context-overflow-probe.ts +997 -0
- package/src/specs/agent-handoffs.test.ts +903 -1
- package/src/specs/context-overflow-recovery.live.test.ts +213 -0
- package/src/splitStream.test.ts +882 -0
- package/src/stream.ts +315 -51
- package/src/summarization/__tests__/aggregator.test.ts +83 -0
- package/src/summarization/__tests__/node.test.ts +139 -0
- package/src/summarization/node.ts +99 -14
- package/src/tools/BashExecutor.ts +4 -2
- package/src/tools/BashProgrammaticToolCalling.ts +4 -7
- package/src/tools/CodeExecutor.ts +119 -8
- package/src/tools/ProgrammaticToolCalling.ts +29 -27
- package/src/tools/ToolNode.ts +50 -8
- package/src/tools/__tests__/CodeApiAuthHeaders.test.ts +297 -3
- package/src/types/llm.ts +8 -1
- package/src/types/stream.ts +5 -4
- package/src/types/summarize.ts +22 -0
- package/src/utils/__tests__/errors.test.ts +270 -0
- package/src/utils/__tests__/fixtures/contextOverflowSignatures.ts +336 -0
- package/src/utils/__tests__/redactSecrets.test.ts +56 -0
- package/src/utils/errors.ts +484 -66
- package/src/utils/redactSecrets.ts +61 -0
|
@@ -23,6 +23,63 @@ import { Constants } from '@/common';
|
|
|
23
23
|
|
|
24
24
|
/** Pattern to extract instructions from transfer ToolMessage content */
|
|
25
25
|
const HANDOFF_INSTRUCTIONS_PATTERN = /(?:Instructions?|Context):\s*(.+)/is;
|
|
26
|
+
const HANDOFF_INSTRUCTIONS_KEY = 'handoff_instructions';
|
|
27
|
+
|
|
28
|
+
function getHandoffInstructions(
|
|
29
|
+
input: Record<string, unknown>,
|
|
30
|
+
promptKey: string,
|
|
31
|
+
hasHandoffInput: boolean
|
|
32
|
+
): string | null {
|
|
33
|
+
if (
|
|
34
|
+
!hasHandoffInput ||
|
|
35
|
+
!Object.prototype.hasOwnProperty.call(input, promptKey)
|
|
36
|
+
) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const value = input[promptKey];
|
|
40
|
+
return typeof value === 'string' ? value : null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function formatHandoffPromptLabel(promptKey: string): string {
|
|
44
|
+
return promptKey.charAt(0).toUpperCase() + promptKey.slice(1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function extractLegacyHandoffInstructions(
|
|
48
|
+
content: string,
|
|
49
|
+
promptLabels: Set<string> | undefined
|
|
50
|
+
): string | null {
|
|
51
|
+
let markerIndex = -1;
|
|
52
|
+
let markerLength = 0;
|
|
53
|
+
for (const label of promptLabels ?? []) {
|
|
54
|
+
const marker = `\n\n${label}:`;
|
|
55
|
+
const index = content.indexOf(marker);
|
|
56
|
+
if (index >= 0 && (markerIndex < 0 || index < markerIndex)) {
|
|
57
|
+
markerIndex = index;
|
|
58
|
+
markerLength = marker.length;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (markerIndex >= 0) {
|
|
62
|
+
return content.slice(markerIndex + markerLength).trim();
|
|
63
|
+
}
|
|
64
|
+
return content.match(HANDOFF_INSTRUCTIONS_PATTERN)?.[1]?.trim() ?? null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function isValidHandoffGroupId(value: unknown): value is number {
|
|
68
|
+
return typeof value === 'number' && Number.isSafeInteger(value) && value > 0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function withHandoffGroupMetadata(
|
|
72
|
+
config: LangGraphRunnableConfig | undefined,
|
|
73
|
+
groupId: number | undefined
|
|
74
|
+
): LangGraphRunnableConfig {
|
|
75
|
+
return {
|
|
76
|
+
...config,
|
|
77
|
+
metadata: {
|
|
78
|
+
...config?.metadata,
|
|
79
|
+
[Constants.HANDOFF_GROUP_ID]: groupId ?? null,
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
26
83
|
|
|
27
84
|
/**
|
|
28
85
|
* MultiAgentGraph extends StandardGraph to support dynamic multi-agent workflows
|
|
@@ -43,6 +100,7 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
43
100
|
private startingNodes: Set<string> = new Set();
|
|
44
101
|
private directEdges: t.GraphEdge[] = [];
|
|
45
102
|
private handoffEdges: t.GraphEdge[] = [];
|
|
103
|
+
private handoffPromptLabels: Map<string, Set<string>> = new Map();
|
|
46
104
|
/**
|
|
47
105
|
* Map of agentId to parallel group info.
|
|
48
106
|
* Contains groupId (incrementing number reflecting execution order) for agents in parallel groups.
|
|
@@ -271,6 +329,18 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
271
329
|
|
|
272
330
|
// Only process handoff edges for tool creation
|
|
273
331
|
for (const edge of this.handoffEdges) {
|
|
332
|
+
if (typeof edge.prompt === 'string') {
|
|
333
|
+
const label = formatHandoffPromptLabel(
|
|
334
|
+
edge.promptKey ?? 'instructions'
|
|
335
|
+
);
|
|
336
|
+
const destinations = Array.isArray(edge.to) ? edge.to : [edge.to];
|
|
337
|
+
for (const destination of destinations) {
|
|
338
|
+
const labels =
|
|
339
|
+
this.handoffPromptLabels.get(destination) ?? new Set<string>();
|
|
340
|
+
labels.add(label);
|
|
341
|
+
this.handoffPromptLabels.set(destination, labels);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
274
344
|
const sources = Array.isArray(edge.from) ? edge.from : [edge.from];
|
|
275
345
|
sources.forEach((source) => {
|
|
276
346
|
if (!handoffsByAgent.has(source)) {
|
|
@@ -349,13 +419,14 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
349
419
|
destination = Array.isArray(result) ? result[0] : destinations[0];
|
|
350
420
|
}
|
|
351
421
|
|
|
422
|
+
const handoffInstructions = getHandoffInstructions(
|
|
423
|
+
input,
|
|
424
|
+
promptKey,
|
|
425
|
+
hasHandoffInput
|
|
426
|
+
);
|
|
352
427
|
let content = `Conditionally transferred to ${destination}`;
|
|
353
|
-
if (
|
|
354
|
-
|
|
355
|
-
promptKey in input &&
|
|
356
|
-
input[promptKey] != null
|
|
357
|
-
) {
|
|
358
|
-
content += `\n\n${promptKey.charAt(0).toUpperCase() + promptKey.slice(1)}: ${input[promptKey]}`;
|
|
428
|
+
if (handoffInstructions !== null) {
|
|
429
|
+
content += `\n\n${formatHandoffPromptLabel(promptKey)}: ${handoffInstructions}`;
|
|
359
430
|
}
|
|
360
431
|
|
|
361
432
|
const toolMessage = new ToolMessage({
|
|
@@ -367,6 +438,9 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
367
438
|
handoff_destination: destination,
|
|
368
439
|
/** Store source agent name for receiving agent to know who handed off */
|
|
369
440
|
handoff_source_name: sourceAgentName,
|
|
441
|
+
...(handoffInstructions !== null && {
|
|
442
|
+
[HANDOFF_INSTRUCTIONS_KEY]: handoffInstructions,
|
|
443
|
+
}),
|
|
370
444
|
},
|
|
371
445
|
});
|
|
372
446
|
|
|
@@ -415,13 +489,14 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
415
489
|
const input = rawInput as Record<string, unknown>;
|
|
416
490
|
const toolCallId = runtime.toolCall?.id ?? 'unknown';
|
|
417
491
|
|
|
492
|
+
const handoffInstructions = getHandoffInstructions(
|
|
493
|
+
input,
|
|
494
|
+
promptKey,
|
|
495
|
+
hasHandoffInput
|
|
496
|
+
);
|
|
418
497
|
let content = `Successfully transferred to ${destination}`;
|
|
419
|
-
if (
|
|
420
|
-
|
|
421
|
-
promptKey in input &&
|
|
422
|
-
input[promptKey] != null
|
|
423
|
-
) {
|
|
424
|
-
content += `\n\n${promptKey.charAt(0).toUpperCase() + promptKey.slice(1)}: ${input[promptKey]}`;
|
|
498
|
+
if (handoffInstructions !== null) {
|
|
499
|
+
content += `\n\n${formatHandoffPromptLabel(promptKey)}: ${handoffInstructions}`;
|
|
425
500
|
}
|
|
426
501
|
|
|
427
502
|
const toolMessage = new ToolMessage({
|
|
@@ -431,6 +506,9 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
431
506
|
additional_kwargs: {
|
|
432
507
|
/** Store source agent name for receiving agent to know who handed off */
|
|
433
508
|
handoff_source_name: sourceAgentName,
|
|
509
|
+
...(handoffInstructions !== null && {
|
|
510
|
+
[HANDOFF_INSTRUCTIONS_KEY]: handoffInstructions,
|
|
511
|
+
}),
|
|
434
512
|
},
|
|
435
513
|
});
|
|
436
514
|
|
|
@@ -558,9 +636,40 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
558
636
|
instructions: string | null;
|
|
559
637
|
sourceAgentName: string | null;
|
|
560
638
|
parallelSiblings: string[];
|
|
639
|
+
parallelGroupId?: number;
|
|
561
640
|
} | null {
|
|
562
641
|
if (messages.length === 0) return null;
|
|
563
642
|
|
|
643
|
+
/**
|
|
644
|
+
* A handoff is active only while resolving the most recent assistant
|
|
645
|
+
* tool-call round. Older transfer results remain in conversation history,
|
|
646
|
+
* but must not be reused when this agent is reached later through a direct
|
|
647
|
+
* edge or cycle.
|
|
648
|
+
*/
|
|
649
|
+
const activeTransferToolCallIds = new Set<string>();
|
|
650
|
+
let activeToolMessageStartIndex = messages.length;
|
|
651
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
652
|
+
const msg = messages[i];
|
|
653
|
+
if (msg.getType() === 'tool') continue;
|
|
654
|
+
|
|
655
|
+
if (msg.getType() === 'ai') {
|
|
656
|
+
const aiMsg = msg as AIMessage | AIMessageChunk;
|
|
657
|
+
for (const toolCall of aiMsg.tool_calls ?? []) {
|
|
658
|
+
if (
|
|
659
|
+
toolCall.id != null &&
|
|
660
|
+
(toolCall.name.startsWith(Constants.LC_TRANSFER_TO_) ||
|
|
661
|
+
toolCall.name === 'conditional_transfer')
|
|
662
|
+
) {
|
|
663
|
+
activeTransferToolCallIds.add(toolCall.id);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
activeToolMessageStartIndex = i + 1;
|
|
667
|
+
}
|
|
668
|
+
break;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
if (activeTransferToolCallIds.size === 0) return null;
|
|
672
|
+
|
|
564
673
|
/**
|
|
565
674
|
* Search for a transfer ToolMessage targeting this agent.
|
|
566
675
|
* For parallel handoffs, multiple transfer messages may exist - find ours.
|
|
@@ -569,14 +678,19 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
569
678
|
let toolMessage: ToolMessage | null = null;
|
|
570
679
|
let toolMessageIndex = -1;
|
|
571
680
|
|
|
572
|
-
for (let i = messages.length - 1; i >=
|
|
681
|
+
for (let i = messages.length - 1; i >= activeToolMessageStartIndex; i--) {
|
|
573
682
|
const msg = messages[i];
|
|
574
683
|
if (msg.getType() !== 'tool') continue;
|
|
575
684
|
|
|
576
685
|
const candidateMsg = msg as ToolMessage;
|
|
577
686
|
const toolName = candidateMsg.name;
|
|
578
687
|
|
|
579
|
-
if (
|
|
688
|
+
if (
|
|
689
|
+
typeof toolName !== 'string' ||
|
|
690
|
+
!activeTransferToolCallIds.has(candidateMsg.tool_call_id)
|
|
691
|
+
) {
|
|
692
|
+
continue;
|
|
693
|
+
}
|
|
580
694
|
|
|
581
695
|
/** Check for standard transfer pattern */
|
|
582
696
|
const isTransferMessage = toolName.startsWith(Constants.LC_TRANSFER_TO_);
|
|
@@ -611,8 +725,15 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
611
725
|
? toolMessage.content
|
|
612
726
|
: JSON.stringify(toolMessage.content);
|
|
613
727
|
|
|
614
|
-
const
|
|
615
|
-
|
|
728
|
+
const structuredInstructions =
|
|
729
|
+
toolMessage.additional_kwargs[HANDOFF_INSTRUCTIONS_KEY];
|
|
730
|
+
const instructions =
|
|
731
|
+
typeof structuredInstructions === 'string'
|
|
732
|
+
? structuredInstructions.trim()
|
|
733
|
+
: extractLegacyHandoffInstructions(
|
|
734
|
+
contentStr,
|
|
735
|
+
this.handoffPromptLabels.get(agentId)
|
|
736
|
+
);
|
|
616
737
|
|
|
617
738
|
/** Extract source agent name from additional_kwargs */
|
|
618
739
|
const handoffSourceName = toolMessage.additional_kwargs.handoff_source_name;
|
|
@@ -629,6 +750,11 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
629
750
|
const ctx = this.agentContexts.get(id);
|
|
630
751
|
return ctx?.name ?? id;
|
|
631
752
|
});
|
|
753
|
+
const storedParallelGroupId =
|
|
754
|
+
toolMessage.additional_kwargs[Constants.HANDOFF_GROUP_ID];
|
|
755
|
+
const parallelGroupId = isValidHandoffGroupId(storedParallelGroupId)
|
|
756
|
+
? storedParallelGroupId
|
|
757
|
+
: undefined;
|
|
632
758
|
|
|
633
759
|
/** Get the tool_call_id to find and filter the AI message's tool call */
|
|
634
760
|
const toolCallId = toolMessage.tool_call_id;
|
|
@@ -640,15 +766,27 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
640
766
|
*/
|
|
641
767
|
const transferToolCallIds = new Set<string>([toolCallId]);
|
|
642
768
|
for (const msg of messages) {
|
|
643
|
-
if (msg.getType()
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
769
|
+
if (msg.getType() === 'tool') {
|
|
770
|
+
const tm = msg as ToolMessage;
|
|
771
|
+
const tName = tm.name;
|
|
772
|
+
if (
|
|
773
|
+
typeof tName === 'string' &&
|
|
774
|
+
(tName.startsWith(Constants.LC_TRANSFER_TO_) ||
|
|
775
|
+
tName === 'conditional_transfer')
|
|
776
|
+
) {
|
|
777
|
+
transferToolCallIds.add(tm.tool_call_id);
|
|
778
|
+
}
|
|
779
|
+
} else if (msg.getType() === 'ai') {
|
|
780
|
+
const aiMsg = msg as AIMessage | AIMessageChunk;
|
|
781
|
+
for (const toolCall of aiMsg.tool_calls ?? []) {
|
|
782
|
+
if (
|
|
783
|
+
toolCall.id != null &&
|
|
784
|
+
(toolCall.name.startsWith(Constants.LC_TRANSFER_TO_) ||
|
|
785
|
+
toolCall.name === 'conditional_transfer')
|
|
786
|
+
) {
|
|
787
|
+
transferToolCallIds.add(toolCall.id);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
652
790
|
}
|
|
653
791
|
}
|
|
654
792
|
|
|
@@ -708,6 +846,7 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
708
846
|
instructions,
|
|
709
847
|
sourceAgentName,
|
|
710
848
|
parallelSiblings,
|
|
849
|
+
parallelGroupId,
|
|
711
850
|
};
|
|
712
851
|
}
|
|
713
852
|
|
|
@@ -715,6 +854,7 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
715
854
|
* Create the multi-agent workflow with dynamic handoffs
|
|
716
855
|
*/
|
|
717
856
|
override createWorkflow(): t.CompiledMultiAgentWorkflow {
|
|
857
|
+
this.hasCompiledCheckpointer = this.compileOptions?.checkpointer != null;
|
|
718
858
|
const StateAnnotation = Annotation.Root({
|
|
719
859
|
messages: Annotation<BaseMessage[]>({
|
|
720
860
|
reducer: (a, b) => {
|
|
@@ -795,27 +935,23 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
795
935
|
state.messages,
|
|
796
936
|
agentId
|
|
797
937
|
);
|
|
938
|
+
const agentContext = this.agentContexts.get(agentId);
|
|
798
939
|
|
|
799
|
-
if (
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
940
|
+
if (
|
|
941
|
+
handoffContext?.sourceAgentName != null &&
|
|
942
|
+
handoffContext.sourceAgentName !== ''
|
|
943
|
+
) {
|
|
944
|
+
agentContext?.setHandoffContext(
|
|
945
|
+
handoffContext.sourceAgentName,
|
|
946
|
+
handoffContext.parallelSiblings
|
|
947
|
+
);
|
|
948
|
+
} else {
|
|
949
|
+
agentContext?.clearHandoffContext();
|
|
950
|
+
}
|
|
806
951
|
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
*/
|
|
811
|
-
const agentContext = this.agentContexts.get(agentId);
|
|
812
|
-
if (
|
|
813
|
-
agentContext &&
|
|
814
|
-
sourceAgentName != null &&
|
|
815
|
-
sourceAgentName !== ''
|
|
816
|
-
) {
|
|
817
|
-
agentContext.setHandoffContext(sourceAgentName, parallelSiblings);
|
|
818
|
-
}
|
|
952
|
+
if (handoffContext !== null) {
|
|
953
|
+
const { filteredMessages, instructions, parallelGroupId } =
|
|
954
|
+
handoffContext;
|
|
819
955
|
|
|
820
956
|
/** Build messages for the receiving agent */
|
|
821
957
|
let messagesForAgent = filteredMessages;
|
|
@@ -883,7 +1019,10 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
883
1019
|
...state,
|
|
884
1020
|
messages: messagesForAgent,
|
|
885
1021
|
};
|
|
886
|
-
result = await agentSubgraph.invoke(
|
|
1022
|
+
result = await agentSubgraph.invoke(
|
|
1023
|
+
transformedState,
|
|
1024
|
+
withHandoffGroupMetadata(config, parallelGroupId)
|
|
1025
|
+
);
|
|
887
1026
|
result = {
|
|
888
1027
|
...result,
|
|
889
1028
|
agentMessages: [],
|
|
@@ -896,7 +1035,6 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
896
1035
|
* When using agentMessages (excludeResults=true), we need to update
|
|
897
1036
|
* the token map to account for the new prompt message
|
|
898
1037
|
*/
|
|
899
|
-
const agentContext = this.agentContexts.get(agentId);
|
|
900
1038
|
if (agentContext && agentContext.tokenCounter) {
|
|
901
1039
|
/** The agentMessages contains:
|
|
902
1040
|
* 1. Filtered messages (0 to startIndex) - already have token counts
|