@illuma-ai/agents 1.1.14 → 1.1.16
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/common/enum.cjs +14 -3
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +304 -106
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/main.cjs +2 -0
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/types/graph.cjs.map +1 -1
- package/dist/esm/common/enum.mjs +12 -4
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +306 -108
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/main.mjs +1 -1
- package/dist/esm/types/graph.mjs.map +1 -1
- package/dist/types/common/enum.d.ts +11 -3
- package/dist/types/graphs/MultiAgentGraph.d.ts +72 -18
- package/dist/types/types/graph.d.ts +17 -5
- package/package.json +1 -1
- package/src/common/__tests__/enum.test.ts +15 -7
- package/src/common/enum.ts +13 -3
- package/src/graphs/MultiAgentGraph.ts +385 -107
- package/src/graphs/__tests__/multi-agent-delegate.test.ts +208 -0
- package/src/graphs/__tests__/multi-agent-edges.test.ts +98 -61
- package/src/scripts/multi-agent-chain.js +1 -1
- package/src/scripts/multi-agent-chain.ts +1 -1
- package/src/scripts/multi-agent-document-review-chain.js +1 -1
- package/src/scripts/multi-agent-document-review-chain.ts +1 -1
- package/src/scripts/multi-agent-hybrid-flow.js +3 -3
- package/src/scripts/multi-agent-hybrid-flow.ts +3 -3
- package/src/scripts/multi-agent-parallel.js +2 -2
- package/src/scripts/multi-agent-parallel.ts +2 -2
- package/src/scripts/multi-agent-sequence.js +2 -2
- package/src/scripts/multi-agent-sequence.ts +2 -2
- package/src/scripts/multi-agent-supervisor.js +5 -5
- package/src/scripts/multi-agent-supervisor.ts +5 -5
- package/src/scripts/poc-multi-agent-comprehensive.ts +7 -7
- package/src/scripts/sequential-full-metadata-test.js +1 -1
- package/src/scripts/sequential-full-metadata-test.ts +1 -1
- package/src/scripts/test-custom-prompt-key.js +3 -3
- package/src/scripts/test-custom-prompt-key.ts +3 -3
- package/src/scripts/test-handoff-input.js +1 -1
- package/src/scripts/test-handoff-input.ts +1 -1
- package/src/scripts/test-handoff-preamble.js +1 -1
- package/src/scripts/test-handoff-preamble.ts +1 -1
- package/src/scripts/test-handoff-steering.js +3 -3
- package/src/scripts/test-handoff-steering.ts +3 -3
- package/src/scripts/test-multi-agent-list-handoff.js +1 -1
- package/src/scripts/test-multi-agent-list-handoff.ts +1 -1
- package/src/scripts/test-parallel-agent-labeling.js +2 -2
- package/src/scripts/test-parallel-agent-labeling.ts +2 -2
- package/src/scripts/test-parallel-handoffs.js +2 -2
- package/src/scripts/test-parallel-handoffs.ts +2 -2
- package/src/scripts/test-thinking-handoff-bedrock.js +1 -1
- package/src/scripts/test-thinking-handoff-bedrock.ts +1 -1
- package/src/scripts/test-thinking-handoff.js +1 -1
- package/src/scripts/test-thinking-handoff.ts +1 -1
- package/src/scripts/test-thinking-to-thinking-handoff-bedrock.js +1 -1
- package/src/scripts/test-thinking-to-thinking-handoff-bedrock.ts +1 -1
- package/src/scripts/test-tool-before-handoff-role-order.js +1 -1
- package/src/scripts/test-tool-before-handoff-role-order.ts +1 -1
- package/src/scripts/test-tools-before-handoff.js +1 -1
- package/src/scripts/test-tools-before-handoff.ts +1 -1
- package/src/specs/agent-handoffs-bedrock.integration.test.ts +6 -6
- package/src/specs/agent-handoffs.test.ts +35 -35
- package/src/specs/thinking-handoff.test.ts +9 -9
- package/src/tools/search/search.test.ts +173 -0
- package/src/types/graph.ts +17 -5
|
@@ -75,10 +75,12 @@ export declare enum Providers {
|
|
|
75
75
|
MOONSHOT = "moonshot"
|
|
76
76
|
}
|
|
77
77
|
export declare enum EdgeType {
|
|
78
|
-
/**
|
|
78
|
+
/** True agent handoff — parent calls child agent inline, gets result back, continues orchestrating */
|
|
79
79
|
HANDOFF = "handoff",
|
|
80
|
-
/**
|
|
81
|
-
|
|
80
|
+
/** One-way transfer — parent exits, child takes over and responds directly to user */
|
|
81
|
+
TRANSFER = "transfer",
|
|
82
|
+
/** Fixed graph edges for automatic sequential/parallel transitions */
|
|
83
|
+
SEQUENCE = "sequence"
|
|
82
84
|
}
|
|
83
85
|
export declare enum GraphNodeKeys {
|
|
84
86
|
TOOLS = "tools=",
|
|
@@ -136,6 +138,8 @@ export declare enum Constants {
|
|
|
136
138
|
WEB_SEARCH = "web_search",
|
|
137
139
|
CONTENT_AND_ARTIFACT = "content_and_artifact",
|
|
138
140
|
LC_TRANSFER_TO_ = "lc_transfer_to_",
|
|
141
|
+
/** Prefix for handoff tool names: lc_handoff_to_{agentId} */
|
|
142
|
+
LC_HANDOFF_TO_ = "lc_handoff_to_",
|
|
139
143
|
/** Tool name for the AskUser structured question tool */
|
|
140
144
|
ASK_USER = "ask_user",
|
|
141
145
|
/** Delimiter for MCP tools: toolName_mcp_serverName */
|
|
@@ -183,3 +187,7 @@ export declare enum MessageTypes {
|
|
|
183
187
|
DEVELOPER = "developer",
|
|
184
188
|
REMOVE = "remove"
|
|
185
189
|
}
|
|
190
|
+
/** Default max characters for handoff results returned to parent (~8192 tokens at ~4 chars/token) */
|
|
191
|
+
export declare const DEFAULT_HANDOFF_MAX_RESULT_CHARS = 32768;
|
|
192
|
+
/** Default timeout for handoff sub-agent execution in milliseconds (5 minutes) */
|
|
193
|
+
export declare const HANDOFF_TIMEOUT_MS = 300000;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BaseMessage } from '@langchain/core/messages';
|
|
1
2
|
import type * as t from '@/types';
|
|
2
3
|
import { StandardGraph } from './Graph';
|
|
3
4
|
/**
|
|
@@ -5,20 +6,29 @@ import { StandardGraph } from './Graph';
|
|
|
5
6
|
* with handoffs, fan-in/fan-out, and other composable patterns.
|
|
6
7
|
*
|
|
7
8
|
* Key behavior:
|
|
8
|
-
* - Agents with ONLY
|
|
9
|
-
* - Agents with ONLY
|
|
10
|
-
* - Agents with BOTH: Use Command for exclusive routing (
|
|
11
|
-
* - If
|
|
12
|
-
* - If no
|
|
9
|
+
* - Agents with ONLY transfer edges: Can dynamically route to any transfer destination
|
|
10
|
+
* - Agents with ONLY sequence edges: Always follow their sequence edges
|
|
11
|
+
* - Agents with BOTH: Use Command for exclusive routing (transfer OR sequence, not both)
|
|
12
|
+
* - If transfer occurs: Only the transfer destination executes
|
|
13
|
+
* - If no transfer: Sequence edges execute (potentially in parallel)
|
|
13
14
|
*
|
|
14
|
-
* This enables the common pattern where an agent either
|
|
15
|
-
* OR continues its workflow (
|
|
15
|
+
* This enables the common pattern where an agent either transfers (one-way)
|
|
16
|
+
* OR continues its workflow (sequence edges), but not both simultaneously.
|
|
16
17
|
*/
|
|
17
18
|
export declare class MultiAgentGraph extends StandardGraph {
|
|
18
19
|
private edges;
|
|
19
20
|
private startingNodes;
|
|
20
|
-
private
|
|
21
|
+
private sequenceEdges;
|
|
22
|
+
private transferEdges;
|
|
21
23
|
private handoffEdges;
|
|
24
|
+
/**
|
|
25
|
+
* Lazily populated registry of compiled subgraphs, keyed by agentId.
|
|
26
|
+
* Handoff tools are created in the constructor but reference subgraphs
|
|
27
|
+
* that are only created in createWorkflow(). This Map bridges that gap —
|
|
28
|
+
* tools capture the Map reference in their closure, and createWorkflow()
|
|
29
|
+
* populates it before any tool invocation occurs.
|
|
30
|
+
*/
|
|
31
|
+
private subgraphRegistry;
|
|
22
32
|
/**
|
|
23
33
|
* Map of agentId to parallel group info.
|
|
24
34
|
* Contains groupId (incrementing number reflecting execution order) for agents in parallel groups.
|
|
@@ -37,7 +47,7 @@ export declare class MultiAgentGraph extends StandardGraph {
|
|
|
37
47
|
private lastActiveAgentId;
|
|
38
48
|
constructor(input: t.MultiAgentGraphInput);
|
|
39
49
|
/**
|
|
40
|
-
* Categorize edges into handoff and
|
|
50
|
+
* Categorize edges into handoff, transfer, and sequence types
|
|
41
51
|
*/
|
|
42
52
|
private categorizeEdges;
|
|
43
53
|
/**
|
|
@@ -81,23 +91,67 @@ export declare class MultiAgentGraph extends StandardGraph {
|
|
|
81
91
|
*/
|
|
82
92
|
protected getParallelGroupIdForAgent(agentId: string): number | undefined;
|
|
83
93
|
/**
|
|
84
|
-
* Create
|
|
94
|
+
* Create transfer tools for agents based on transfer edges only.
|
|
95
|
+
* Transfer tools return Command for one-way routing — parent exits, child takes over.
|
|
85
96
|
*/
|
|
86
|
-
private
|
|
97
|
+
private createTransferTools;
|
|
87
98
|
/**
|
|
88
|
-
* Create
|
|
89
|
-
*
|
|
90
|
-
* @param
|
|
99
|
+
* Create transfer tools for an edge (handles multiple destinations).
|
|
100
|
+
* Transfer tools return Command for one-way routing — parent exits, child takes over.
|
|
101
|
+
* @param edge - The graph edge defining the transfer
|
|
102
|
+
* @param sourceAgentId - The ID of the agent that will perform the transfer
|
|
91
103
|
* @param sourceAgentName - The human-readable name of the source agent
|
|
92
104
|
*/
|
|
93
|
-
private
|
|
105
|
+
private createTransferToolsForEdge;
|
|
94
106
|
/**
|
|
95
|
-
* Builds a meaningful default description for a
|
|
107
|
+
* Builds a meaningful default description for a transfer tool when no explicit
|
|
96
108
|
* edge.description is provided. Uses the destination agent's name and description
|
|
97
109
|
* so the LLM can make informed routing decisions.
|
|
98
110
|
* @param destContext - AgentContext of the destination agent (may be undefined)
|
|
99
111
|
* @param destinationId - Raw agent ID (fallback when context unavailable)
|
|
100
112
|
*/
|
|
113
|
+
private buildDefaultTransferDescription;
|
|
114
|
+
/**
|
|
115
|
+
* Create handoff tools for agents based on handoff edges.
|
|
116
|
+
* Handoff tools invoke child agent subgraphs inline and return the result
|
|
117
|
+
* as a string to the parent agent's context. Unlike transfer tools (which
|
|
118
|
+
* return Command for one-way routing), handoff tools execute the child,
|
|
119
|
+
* extract the final text, and return it within the parent's agent loop.
|
|
120
|
+
*
|
|
121
|
+
* This enables the supervisor pattern: parent calls child → gets result → thinks → calls another.
|
|
122
|
+
*/
|
|
123
|
+
private createHandoffTools;
|
|
124
|
+
/**
|
|
125
|
+
* Create handoff tools for an edge (handles multiple destinations).
|
|
126
|
+
* Each handoff tool invokes the child agent's compiled subgraph inline,
|
|
127
|
+
* extracts the final AI message text, truncates it, and returns it as
|
|
128
|
+
* a string (which becomes a ToolMessage in the parent's context).
|
|
129
|
+
*
|
|
130
|
+
* @param edge - The graph edge defining the handoff
|
|
131
|
+
* @param sourceAgentId - The ID of the parent/supervisor agent
|
|
132
|
+
*/
|
|
133
|
+
private createHandoffToolsForEdge;
|
|
134
|
+
/**
|
|
135
|
+
* Extract the final text result from a child agent's output messages.
|
|
136
|
+
* Walks backwards to find the last AIMessage with text content.
|
|
137
|
+
* Handles both string content and array content (multi-modal messages).
|
|
138
|
+
* @param messages - The child agent's output messages
|
|
139
|
+
* @param agentId - The child agent ID (for fallback message)
|
|
140
|
+
*/
|
|
141
|
+
static extractHandoffResult(messages: BaseMessage[], agentId: string): string;
|
|
142
|
+
/**
|
|
143
|
+
* Truncate handoff result using head/tail strategy (60/40 split).
|
|
144
|
+
* Preserves the beginning (key findings) and end (conclusions).
|
|
145
|
+
* Matches the TaskTool.truncateResult pattern from Ranger.
|
|
146
|
+
* @param result - The full result text
|
|
147
|
+
* @param maxChars - Maximum allowed characters
|
|
148
|
+
*/
|
|
149
|
+
static truncateHandoffResult(result: string, maxChars: number): string;
|
|
150
|
+
/**
|
|
151
|
+
* Build a meaningful default description for a handoff tool.
|
|
152
|
+
* @param destContext - AgentContext of the destination agent
|
|
153
|
+
* @param destinationId - Raw agent ID (fallback)
|
|
154
|
+
*/
|
|
101
155
|
private buildDefaultHandoffDescription;
|
|
102
156
|
/**
|
|
103
157
|
* Create a complete agent subgraph (similar to createReactAgent)
|
|
@@ -115,9 +169,9 @@ export declare class MultiAgentGraph extends StandardGraph {
|
|
|
115
169
|
* @param agentId - The agent ID to check for handoff reception
|
|
116
170
|
* @returns Object with filtered messages, extracted instructions, source agent, and parallel siblings
|
|
117
171
|
*/
|
|
118
|
-
private
|
|
172
|
+
private processTransferReception;
|
|
119
173
|
/**
|
|
120
|
-
* Create the multi-agent workflow with
|
|
174
|
+
* Create the multi-agent workflow with handoffs, transfers, and sequences
|
|
121
175
|
*/
|
|
122
176
|
createWorkflow(): t.CompiledMultiAgentWorkflow;
|
|
123
177
|
}
|
|
@@ -220,14 +220,18 @@ export type GraphEdge = {
|
|
|
220
220
|
description?: string;
|
|
221
221
|
/** Can return boolean or specific destination(s) */
|
|
222
222
|
condition?: (state: BaseGraphState) => boolean | string | string[];
|
|
223
|
-
/**
|
|
223
|
+
/**
|
|
224
|
+
* EdgeType.HANDOFF — true agent handoff, parent calls child inline and gets result back.
|
|
225
|
+
* EdgeType.TRANSFER — one-way transfer, parent exits and child takes over.
|
|
226
|
+
* EdgeType.SEQUENCE — fixed graph edges for sequential/parallel transitions.
|
|
227
|
+
*/
|
|
224
228
|
edgeType?: import('@/common').EdgeType;
|
|
225
229
|
/**
|
|
226
|
-
* For
|
|
230
|
+
* For sequence edges: Optional prompt to add when transitioning through this edge.
|
|
227
231
|
* String prompts can include variables like {results} which will be replaced with
|
|
228
232
|
* messages from startIndex onwards. When {results} is used, excludeResults defaults to true.
|
|
229
233
|
*
|
|
230
|
-
* For
|
|
234
|
+
* For transfer edges: Description for the input parameter that the transfer tool accepts,
|
|
231
235
|
* allowing the supervisor to pass specific instructions/context to the transferred agent.
|
|
232
236
|
*/
|
|
233
237
|
prompt?: string | ((messages: BaseMessage[], runStartIndex: number) => string | Promise<string> | undefined);
|
|
@@ -237,11 +241,19 @@ export type GraphEdge = {
|
|
|
237
241
|
*/
|
|
238
242
|
excludeResults?: boolean;
|
|
239
243
|
/**
|
|
240
|
-
* For
|
|
244
|
+
* For transfer edges: Customizes the parameter name for the transfer input.
|
|
241
245
|
* Defaults to "instructions" if not specified.
|
|
242
|
-
* Only applies when prompt is provided for
|
|
246
|
+
* Only applies when prompt is provided for transfer edges.
|
|
247
|
+
*
|
|
248
|
+
* For handoff edges: Customizes the parameter name for the handoff instruction input.
|
|
243
249
|
*/
|
|
244
250
|
promptKey?: string;
|
|
251
|
+
/**
|
|
252
|
+
* For handoff edges: Maximum characters for the result returned to the parent.
|
|
253
|
+
* Uses head/tail truncation (60/40 split) to preserve key findings and conclusions.
|
|
254
|
+
* Defaults to DEFAULT_HANDOFF_MAX_RESULT_CHARS (32768 chars, ~8192 tokens).
|
|
255
|
+
*/
|
|
256
|
+
maxResultChars?: number;
|
|
245
257
|
};
|
|
246
258
|
export type MultiAgentGraphInput = StandardGraphInput & {
|
|
247
259
|
edges: GraphEdge[];
|
package/package.json
CHANGED
|
@@ -18,18 +18,22 @@ import {
|
|
|
18
18
|
} from '@/common';
|
|
19
19
|
|
|
20
20
|
describe('EdgeType enum', () => {
|
|
21
|
-
it('has correct HANDOFF value', () => {
|
|
21
|
+
it('has correct HANDOFF value (supervisor pattern)', () => {
|
|
22
22
|
expect(EdgeType.HANDOFF).toBe('handoff');
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
-
it('has correct
|
|
26
|
-
expect(EdgeType.
|
|
25
|
+
it('has correct TRANSFER value (one-way fire-and-forget)', () => {
|
|
26
|
+
expect(EdgeType.TRANSFER).toBe('transfer');
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
-
it('
|
|
29
|
+
it('has correct SEQUENCE value (fixed graph edges)', () => {
|
|
30
|
+
expect(EdgeType.SEQUENCE).toBe('sequence');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('has three members: handoff, transfer, sequence', () => {
|
|
30
34
|
const values = Object.values(EdgeType);
|
|
31
|
-
expect(values).toHaveLength(
|
|
32
|
-
expect(values).toEqual(expect.arrayContaining(['handoff', '
|
|
35
|
+
expect(values).toHaveLength(3);
|
|
36
|
+
expect(values).toEqual(expect.arrayContaining(['handoff', 'transfer', 'sequence']));
|
|
33
37
|
});
|
|
34
38
|
});
|
|
35
39
|
|
|
@@ -42,10 +46,14 @@ describe('Constants enum', () => {
|
|
|
42
46
|
expect(Constants.EXECUTE_CODE).toBe('execute_code');
|
|
43
47
|
});
|
|
44
48
|
|
|
45
|
-
it('has LC_TRANSFER_TO_ prefix for LangChain
|
|
49
|
+
it('has LC_TRANSFER_TO_ prefix for LangChain transfer tools', () => {
|
|
46
50
|
expect(Constants.LC_TRANSFER_TO_).toBe('lc_transfer_to_');
|
|
47
51
|
});
|
|
48
52
|
|
|
53
|
+
it('has LC_HANDOFF_TO_ prefix for LangChain handoff tools', () => {
|
|
54
|
+
expect(Constants.LC_HANDOFF_TO_).toBe('lc_handoff_to_');
|
|
55
|
+
});
|
|
56
|
+
|
|
49
57
|
it('has MCP_DELIMITER for MCP tool naming', () => {
|
|
50
58
|
expect(Constants.MCP_DELIMITER).toBe('_mcp_');
|
|
51
59
|
});
|
package/src/common/enum.ts
CHANGED
|
@@ -96,10 +96,12 @@ export enum Providers {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
export enum EdgeType {
|
|
99
|
-
/**
|
|
99
|
+
/** True agent handoff — parent calls child agent inline, gets result back, continues orchestrating */
|
|
100
100
|
HANDOFF = 'handoff',
|
|
101
|
-
/**
|
|
102
|
-
|
|
101
|
+
/** One-way transfer — parent exits, child takes over and responds directly to user */
|
|
102
|
+
TRANSFER = 'transfer',
|
|
103
|
+
/** Fixed graph edges for automatic sequential/parallel transitions */
|
|
104
|
+
SEQUENCE = 'sequence',
|
|
103
105
|
}
|
|
104
106
|
|
|
105
107
|
export enum GraphNodeKeys {
|
|
@@ -182,6 +184,8 @@ export enum Constants {
|
|
|
182
184
|
WEB_SEARCH = 'web_search',
|
|
183
185
|
CONTENT_AND_ARTIFACT = 'content_and_artifact',
|
|
184
186
|
LC_TRANSFER_TO_ = 'lc_transfer_to_',
|
|
187
|
+
/** Prefix for handoff tool names: lc_handoff_to_{agentId} */
|
|
188
|
+
LC_HANDOFF_TO_ = 'lc_handoff_to_',
|
|
185
189
|
/** Tool name for the AskUser structured question tool */
|
|
186
190
|
ASK_USER = 'ask_user',
|
|
187
191
|
/** Delimiter for MCP tools: toolName_mcp_serverName */
|
|
@@ -233,3 +237,9 @@ export enum MessageTypes {
|
|
|
233
237
|
DEVELOPER = 'developer',
|
|
234
238
|
REMOVE = 'remove',
|
|
235
239
|
}
|
|
240
|
+
|
|
241
|
+
/** Default max characters for handoff results returned to parent (~8192 tokens at ~4 chars/token) */
|
|
242
|
+
export const DEFAULT_HANDOFF_MAX_RESULT_CHARS = 32768;
|
|
243
|
+
|
|
244
|
+
/** Default timeout for handoff sub-agent execution in milliseconds (5 minutes) */
|
|
245
|
+
export const HANDOFF_TIMEOUT_MS = 300_000;
|