illuma-agents 1.0.26 → 1.0.28
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/graphs/Graph.cjs +28 -2
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +108 -0
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/stream.cjs +27 -0
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/BrowserTools.cjs +125 -113
- package/dist/cjs/tools/BrowserTools.cjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +28 -2
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +108 -0
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/stream.mjs +27 -0
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/BrowserTools.mjs +125 -113
- package/dist/esm/tools/BrowserTools.mjs.map +1 -1
- package/dist/types/graphs/Graph.d.ts +14 -0
- package/dist/types/graphs/MultiAgentGraph.d.ts +41 -0
- package/dist/types/messages/format.d.ts +1 -1
- package/dist/types/tools/BrowserTools.d.ts +45 -5
- package/dist/types/types/stream.d.ts +13 -0
- package/package.json +4 -2
- package/src/graphs/Graph.ts +30 -2
- package/src/graphs/MultiAgentGraph.ts +119 -0
- package/src/messages/format.ts +2 -2
- package/src/scripts/multi-agent-chain.ts +59 -6
- package/src/scripts/multi-agent-parallel-start.ts +265 -0
- package/src/scripts/multi-agent-parallel.ts +61 -10
- package/src/scripts/multi-agent-sequence.ts +6 -1
- package/src/scripts/parallel-asymmetric-tools-test.ts +274 -0
- package/src/scripts/parallel-full-metadata-test.ts +240 -0
- package/src/scripts/parallel-tools-test.ts +340 -0
- package/src/scripts/sequential-full-metadata-test.ts +197 -0
- package/src/scripts/single-agent-metadata-test.ts +198 -0
- package/src/scripts/test-thinking-handoff.ts +8 -0
- package/src/scripts/tools.ts +31 -11
- package/src/stream.ts +32 -0
- package/src/tools/BrowserTools.ts +356 -310
- package/src/tools/__tests__/BrowserTools.test.ts +263 -257
- package/src/types/stream.ts +15 -0
|
@@ -19,6 +19,17 @@ export declare class MultiAgentGraph extends StandardGraph {
|
|
|
19
19
|
private startingNodes;
|
|
20
20
|
private directEdges;
|
|
21
21
|
private handoffEdges;
|
|
22
|
+
/**
|
|
23
|
+
* Map of agentId to parallel group info.
|
|
24
|
+
* Contains groupId (incrementing number reflecting execution order) for agents in parallel groups.
|
|
25
|
+
* Sequential agents (not in any parallel group) have undefined entry.
|
|
26
|
+
*
|
|
27
|
+
* Example for: researcher -> [analyst1, analyst2, analyst3] -> summarizer
|
|
28
|
+
* - researcher: undefined (sequential, order 0)
|
|
29
|
+
* - analyst1, analyst2, analyst3: { groupId: 1 } (parallel group, order 1)
|
|
30
|
+
* - summarizer: undefined (sequential, order 2)
|
|
31
|
+
*/
|
|
32
|
+
private agentParallelGroups;
|
|
22
33
|
constructor(input: t.MultiAgentGraphInput);
|
|
23
34
|
/**
|
|
24
35
|
* Categorize edges into handoff and direct types
|
|
@@ -28,6 +39,36 @@ export declare class MultiAgentGraph extends StandardGraph {
|
|
|
28
39
|
* Analyze graph structure to determine starting nodes and connections
|
|
29
40
|
*/
|
|
30
41
|
private analyzeGraph;
|
|
42
|
+
/**
|
|
43
|
+
* Compute parallel groups by traversing the graph in execution order.
|
|
44
|
+
* Assigns incrementing group IDs that reflect the sequential order of execution.
|
|
45
|
+
*
|
|
46
|
+
* For: researcher -> [analyst1, analyst2, analyst3] -> summarizer
|
|
47
|
+
* - researcher: no group (first sequential node)
|
|
48
|
+
* - analyst1, analyst2, analyst3: groupId 1 (first parallel group)
|
|
49
|
+
* - summarizer: no group (next sequential node)
|
|
50
|
+
*
|
|
51
|
+
* This allows frontend to render in order:
|
|
52
|
+
* Row 0: researcher
|
|
53
|
+
* Row 1: [analyst1, analyst2, analyst3] (grouped)
|
|
54
|
+
* Row 2: summarizer
|
|
55
|
+
*/
|
|
56
|
+
private computeParallelCapability;
|
|
57
|
+
/**
|
|
58
|
+
* Get the parallel group ID for an agent, if any.
|
|
59
|
+
* Returns undefined if the agent is not part of a parallel group.
|
|
60
|
+
* Group IDs are incrementing numbers reflecting execution order.
|
|
61
|
+
*/
|
|
62
|
+
getParallelGroupId(agentId: string): number | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Override to indicate this is a multi-agent graph.
|
|
65
|
+
* Enables agentId to be included in RunStep for frontend agent labeling.
|
|
66
|
+
*/
|
|
67
|
+
protected isMultiAgentGraph(): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Override base class method to provide parallel group IDs for run steps.
|
|
70
|
+
*/
|
|
71
|
+
protected getParallelGroupIdForAgent(agentId: string): number | undefined;
|
|
31
72
|
/**
|
|
32
73
|
* Create handoff tools for agents based on handoff edges only
|
|
33
74
|
*/
|
|
@@ -105,7 +105,7 @@ export declare const labelContentByAgent: (contentParts: MessageContentComplex[]
|
|
|
105
105
|
* @param tools - Optional set of tool names that are allowed in the request.
|
|
106
106
|
* @returns - Object containing formatted messages and updated indexTokenCountMap if provided.
|
|
107
107
|
*/
|
|
108
|
-
export declare const formatAgentMessages: (payload: TPayload, indexTokenCountMap?: Record<number, number>, tools?: Set<string>) => {
|
|
108
|
+
export declare const formatAgentMessages: (payload: TPayload, indexTokenCountMap?: Record<number, number | undefined>, tools?: Set<string>) => {
|
|
109
109
|
messages: Array<HumanMessage | AIMessage | SystemMessage | ToolMessage>;
|
|
110
110
|
indexTokenCountMap?: Record<number, number>;
|
|
111
111
|
};
|
|
@@ -15,7 +15,29 @@ export declare const EBrowserTools: {
|
|
|
15
15
|
readonly SCREENSHOT: "browser_screenshot";
|
|
16
16
|
readonly GET_PAGE_STATE: "browser_get_page_state";
|
|
17
17
|
};
|
|
18
|
-
export type BrowserToolName = typeof EBrowserTools[keyof typeof EBrowserTools];
|
|
18
|
+
export type BrowserToolName = (typeof EBrowserTools)[keyof typeof EBrowserTools];
|
|
19
|
+
/**
|
|
20
|
+
* Callback function type for waiting on browser action results
|
|
21
|
+
* This allows the server (Ranger) to provide a callback that waits for the extension
|
|
22
|
+
* to POST results back to the server before returning to the LLM.
|
|
23
|
+
*
|
|
24
|
+
* @param action - The browser action (click, type, navigate, etc.)
|
|
25
|
+
* @param args - Arguments for the action
|
|
26
|
+
* @param toolCallId - Unique ID for this tool call (from config.toolCall.id)
|
|
27
|
+
* @returns Promise that resolves with the actual browser result (page state, etc.)
|
|
28
|
+
*/
|
|
29
|
+
export type BrowserToolCallback = (action: string, args: Record<string, unknown>, toolCallId: string) => Promise<BrowserActionResult>;
|
|
30
|
+
/**
|
|
31
|
+
* Result returned from browser action execution
|
|
32
|
+
*/
|
|
33
|
+
export interface BrowserActionResult {
|
|
34
|
+
success: boolean;
|
|
35
|
+
url?: string;
|
|
36
|
+
title?: string;
|
|
37
|
+
elementList?: string;
|
|
38
|
+
error?: string;
|
|
39
|
+
screenshot?: string;
|
|
40
|
+
}
|
|
19
41
|
/**
|
|
20
42
|
* Check if browser capability is available based on request headers or context
|
|
21
43
|
* The browser extension sets these headers when connected:
|
|
@@ -33,13 +55,31 @@ export interface BrowserToolResponse {
|
|
|
33
55
|
requiresBrowserExecution: true;
|
|
34
56
|
action: string;
|
|
35
57
|
args: Record<string, unknown>;
|
|
58
|
+
toolCallId?: string;
|
|
36
59
|
}
|
|
37
60
|
/**
|
|
38
|
-
*
|
|
39
|
-
|
|
40
|
-
|
|
61
|
+
* Options for creating browser tools
|
|
62
|
+
*/
|
|
63
|
+
export interface CreateBrowserToolsOptions {
|
|
64
|
+
/**
|
|
65
|
+
* Optional callback that waits for browser action results.
|
|
66
|
+
* When provided, tools will await this callback to get actual results from the extension.
|
|
67
|
+
* When not provided, tools return markers immediately (for non-server contexts).
|
|
68
|
+
*/
|
|
69
|
+
waitForResult?: BrowserToolCallback;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Create browser tools with optional callback for waiting on results
|
|
73
|
+
*
|
|
74
|
+
* When waitForResult callback is provided:
|
|
75
|
+
* 1. Tool returns marker that triggers extension
|
|
76
|
+
* 2. Tool then awaits callback to get actual results
|
|
77
|
+
* 3. Returns real page state to LLM
|
|
78
|
+
*
|
|
79
|
+
* When no callback:
|
|
80
|
+
* 1. Tool returns marker only (for non-server contexts)
|
|
41
81
|
*
|
|
42
82
|
* NOTE: These tools use TEXT-BASED element lists, NOT screenshots
|
|
43
83
|
* Screenshots would be 100K+ tokens each - element lists are ~100 tokens
|
|
44
84
|
*/
|
|
45
|
-
export declare function createBrowserTools(): DynamicStructuredTool[];
|
|
85
|
+
export declare function createBrowserTools(options?: CreateBrowserToolsOptions): DynamicStructuredTool[];
|
|
@@ -38,6 +38,17 @@ export type RunStep = {
|
|
|
38
38
|
id: string;
|
|
39
39
|
runId?: string;
|
|
40
40
|
agentId?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Group ID - incrementing number (1, 2, 3...) reflecting execution order.
|
|
43
|
+
* Agents with the same groupId run in parallel and should be rendered together.
|
|
44
|
+
* undefined means the agent runs sequentially (not part of any parallel group).
|
|
45
|
+
*
|
|
46
|
+
* Example for: researcher -> [analyst1, analyst2, analyst3] -> summarizer
|
|
47
|
+
* - researcher: undefined (sequential)
|
|
48
|
+
* - analyst1, analyst2, analyst3: 1 (first parallel group)
|
|
49
|
+
* - summarizer: undefined (sequential)
|
|
50
|
+
*/
|
|
51
|
+
groupId?: number;
|
|
41
52
|
index: number;
|
|
42
53
|
stepIndex?: number;
|
|
43
54
|
stepDetails: StepDetails;
|
|
@@ -251,6 +262,8 @@ export type MessageContentComplex = (ToolResultContent | ThinkingContentText | A
|
|
|
251
262
|
type?: never;
|
|
252
263
|
})) & {
|
|
253
264
|
tool_call_ids?: string[];
|
|
265
|
+
agentId?: string;
|
|
266
|
+
groupId?: number;
|
|
254
267
|
};
|
|
255
268
|
export interface TMessage {
|
|
256
269
|
role?: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "illuma-agents",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.28",
|
|
4
4
|
"main": "./dist/cjs/main.cjs",
|
|
5
5
|
"module": "./dist/esm/main.mjs",
|
|
6
6
|
"types": "./dist/types/index.d.ts",
|
|
@@ -63,6 +63,8 @@
|
|
|
63
63
|
"multi-agent-test": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/multi-agent-test.ts",
|
|
64
64
|
"test-tools-before-handoff": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/test-tools-before-handoff.ts",
|
|
65
65
|
"multi-agent-parallel": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/multi-agent-parallel.ts",
|
|
66
|
+
"multi-agent-parallel-start": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/multi-agent-parallel-start.ts",
|
|
67
|
+
"single-agent-metadata-test": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/single-agent-metadata-test.ts",
|
|
66
68
|
"multi-agent-chain": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/multi-agent-chain.ts",
|
|
67
69
|
"multi-agent-sequence": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/multi-agent-sequence.ts",
|
|
68
70
|
"multi-agent-conditional": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/multi-agent-conditional.ts",
|
|
@@ -102,7 +104,7 @@
|
|
|
102
104
|
"dependencies": {
|
|
103
105
|
"@langchain/anthropic": "^0.3.26",
|
|
104
106
|
"@langchain/aws": "^0.1.15",
|
|
105
|
-
"@langchain/core": "^0.3.
|
|
107
|
+
"@langchain/core": "^0.3.80",
|
|
106
108
|
"@langchain/deepseek": "^0.0.2",
|
|
107
109
|
"@langchain/google-genai": "^0.2.18",
|
|
108
110
|
"@langchain/google-vertexai": "^0.2.18",
|
package/src/graphs/Graph.ts
CHANGED
|
@@ -1246,6 +1246,26 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
|
|
|
1246
1246
|
return workflow;
|
|
1247
1247
|
}
|
|
1248
1248
|
|
|
1249
|
+
/**
|
|
1250
|
+
* Indicates if this is a multi-agent graph.
|
|
1251
|
+
* Override in MultiAgentGraph to return true.
|
|
1252
|
+
* Used to conditionally include agentId in RunStep for frontend rendering.
|
|
1253
|
+
*/
|
|
1254
|
+
protected isMultiAgentGraph(): boolean {
|
|
1255
|
+
return false;
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
/**
|
|
1259
|
+
* Get the parallel group ID for an agent, if any.
|
|
1260
|
+
* Override in MultiAgentGraph to provide actual group IDs.
|
|
1261
|
+
* Group IDs are incrementing numbers (1, 2, 3...) reflecting execution order.
|
|
1262
|
+
* @param _agentId - The agent ID to look up
|
|
1263
|
+
* @returns undefined for StandardGraph (no parallel groups), or group number for MultiAgentGraph
|
|
1264
|
+
*/
|
|
1265
|
+
protected getParallelGroupIdForAgent(_agentId: string): number | undefined {
|
|
1266
|
+
return undefined;
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1249
1269
|
/* Dispatchers */
|
|
1250
1270
|
|
|
1251
1271
|
/**
|
|
@@ -1286,13 +1306,21 @@ If I seem to be missing something we discussed earlier, just give me a quick rem
|
|
|
1286
1306
|
}
|
|
1287
1307
|
|
|
1288
1308
|
/**
|
|
1289
|
-
* Extract and
|
|
1309
|
+
* Extract agentId and parallelGroupId from metadata
|
|
1310
|
+
* Only set agentId for MultiAgentGraph (so frontend knows when to show agent labels)
|
|
1290
1311
|
*/
|
|
1291
1312
|
if (metadata) {
|
|
1292
1313
|
try {
|
|
1293
1314
|
const agentContext = this.getAgentContext(metadata);
|
|
1294
|
-
if (agentContext.agentId) {
|
|
1315
|
+
if (this.isMultiAgentGraph() && agentContext.agentId) {
|
|
1316
|
+
// Only include agentId for MultiAgentGraph - enables frontend to show agent labels
|
|
1295
1317
|
runStep.agentId = agentContext.agentId;
|
|
1318
|
+
// Set group ID if this agent is part of a parallel group
|
|
1319
|
+
// Group IDs are incrementing numbers (1, 2, 3...) reflecting execution order
|
|
1320
|
+
const groupId = this.getParallelGroupIdForAgent(agentContext.agentId);
|
|
1321
|
+
if (groupId != null) {
|
|
1322
|
+
runStep.groupId = groupId;
|
|
1323
|
+
}
|
|
1296
1324
|
}
|
|
1297
1325
|
} catch (_e) {
|
|
1298
1326
|
/** If we can't get agent context, that's okay - agentId remains undefined */
|
|
@@ -40,6 +40,17 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
40
40
|
private startingNodes: Set<string> = new Set();
|
|
41
41
|
private directEdges: t.GraphEdge[] = [];
|
|
42
42
|
private handoffEdges: t.GraphEdge[] = [];
|
|
43
|
+
/**
|
|
44
|
+
* Map of agentId to parallel group info.
|
|
45
|
+
* Contains groupId (incrementing number reflecting execution order) for agents in parallel groups.
|
|
46
|
+
* Sequential agents (not in any parallel group) have undefined entry.
|
|
47
|
+
*
|
|
48
|
+
* Example for: researcher -> [analyst1, analyst2, analyst3] -> summarizer
|
|
49
|
+
* - researcher: undefined (sequential, order 0)
|
|
50
|
+
* - analyst1, analyst2, analyst3: { groupId: 1 } (parallel group, order 1)
|
|
51
|
+
* - summarizer: undefined (sequential, order 2)
|
|
52
|
+
*/
|
|
53
|
+
private agentParallelGroups: Map<string, number> = new Map();
|
|
43
54
|
|
|
44
55
|
constructor(input: t.MultiAgentGraphInput) {
|
|
45
56
|
super(input);
|
|
@@ -99,6 +110,114 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
99
110
|
if (this.startingNodes.size === 0 && this.agentContexts.size > 0) {
|
|
100
111
|
this.startingNodes.add(this.agentContexts.keys().next().value!);
|
|
101
112
|
}
|
|
113
|
+
|
|
114
|
+
// Determine if graph has parallel execution capability
|
|
115
|
+
this.computeParallelCapability();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Compute parallel groups by traversing the graph in execution order.
|
|
120
|
+
* Assigns incrementing group IDs that reflect the sequential order of execution.
|
|
121
|
+
*
|
|
122
|
+
* For: researcher -> [analyst1, analyst2, analyst3] -> summarizer
|
|
123
|
+
* - researcher: no group (first sequential node)
|
|
124
|
+
* - analyst1, analyst2, analyst3: groupId 1 (first parallel group)
|
|
125
|
+
* - summarizer: no group (next sequential node)
|
|
126
|
+
*
|
|
127
|
+
* This allows frontend to render in order:
|
|
128
|
+
* Row 0: researcher
|
|
129
|
+
* Row 1: [analyst1, analyst2, analyst3] (grouped)
|
|
130
|
+
* Row 2: summarizer
|
|
131
|
+
*/
|
|
132
|
+
private computeParallelCapability(): void {
|
|
133
|
+
let groupCounter = 1; // Start at 1, 0 reserved for "no group"
|
|
134
|
+
|
|
135
|
+
// Check 1: Multiple starting nodes means parallel from the start (group 1)
|
|
136
|
+
if (this.startingNodes.size > 1) {
|
|
137
|
+
for (const agentId of this.startingNodes) {
|
|
138
|
+
this.agentParallelGroups.set(agentId, groupCounter);
|
|
139
|
+
}
|
|
140
|
+
groupCounter++;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Check 2: Traverse direct edges in order to find fan-out patterns
|
|
144
|
+
// Build a simple execution order by following edges from starting nodes
|
|
145
|
+
const visited = new Set<string>();
|
|
146
|
+
const queue: string[] = [...this.startingNodes];
|
|
147
|
+
|
|
148
|
+
while (queue.length > 0) {
|
|
149
|
+
const current = queue.shift()!;
|
|
150
|
+
if (visited.has(current)) continue;
|
|
151
|
+
visited.add(current);
|
|
152
|
+
|
|
153
|
+
// Find direct edges from this node
|
|
154
|
+
for (const edge of this.directEdges) {
|
|
155
|
+
const sources = Array.isArray(edge.from) ? edge.from : [edge.from];
|
|
156
|
+
if (!sources.includes(current)) continue;
|
|
157
|
+
|
|
158
|
+
const destinations = Array.isArray(edge.to) ? edge.to : [edge.to];
|
|
159
|
+
|
|
160
|
+
// Fan-out: multiple destinations = parallel group
|
|
161
|
+
if (destinations.length > 1) {
|
|
162
|
+
for (const dest of destinations) {
|
|
163
|
+
// Only set if not already in a group (first group wins)
|
|
164
|
+
if (!this.agentParallelGroups.has(dest)) {
|
|
165
|
+
this.agentParallelGroups.set(dest, groupCounter);
|
|
166
|
+
}
|
|
167
|
+
if (!visited.has(dest)) {
|
|
168
|
+
queue.push(dest);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
groupCounter++;
|
|
172
|
+
} else {
|
|
173
|
+
// Single destination - add to queue for traversal
|
|
174
|
+
for (const dest of destinations) {
|
|
175
|
+
if (!visited.has(dest)) {
|
|
176
|
+
queue.push(dest);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Also follow handoff edges for traversal (but they don't create parallel groups)
|
|
183
|
+
for (const edge of this.handoffEdges) {
|
|
184
|
+
const sources = Array.isArray(edge.from) ? edge.from : [edge.from];
|
|
185
|
+
if (!sources.includes(current)) continue;
|
|
186
|
+
|
|
187
|
+
const destinations = Array.isArray(edge.to) ? edge.to : [edge.to];
|
|
188
|
+
for (const dest of destinations) {
|
|
189
|
+
if (!visited.has(dest)) {
|
|
190
|
+
queue.push(dest);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Get the parallel group ID for an agent, if any.
|
|
199
|
+
* Returns undefined if the agent is not part of a parallel group.
|
|
200
|
+
* Group IDs are incrementing numbers reflecting execution order.
|
|
201
|
+
*/
|
|
202
|
+
getParallelGroupId(agentId: string): number | undefined {
|
|
203
|
+
return this.agentParallelGroups.get(agentId);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Override to indicate this is a multi-agent graph.
|
|
208
|
+
* Enables agentId to be included in RunStep for frontend agent labeling.
|
|
209
|
+
*/
|
|
210
|
+
protected override isMultiAgentGraph(): boolean {
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Override base class method to provide parallel group IDs for run steps.
|
|
216
|
+
*/
|
|
217
|
+
protected override getParallelGroupIdForAgent(
|
|
218
|
+
agentId: string
|
|
219
|
+
): number | undefined {
|
|
220
|
+
return this.agentParallelGroups.get(agentId);
|
|
102
221
|
}
|
|
103
222
|
|
|
104
223
|
/**
|
package/src/messages/format.ts
CHANGED
|
@@ -636,7 +636,7 @@ export const labelContentByAgent = (
|
|
|
636
636
|
*/
|
|
637
637
|
export const formatAgentMessages = (
|
|
638
638
|
payload: TPayload,
|
|
639
|
-
indexTokenCountMap?: Record<number, number>,
|
|
639
|
+
indexTokenCountMap?: Record<number, number | undefined>,
|
|
640
640
|
tools?: Set<string>
|
|
641
641
|
): {
|
|
642
642
|
messages: Array<HumanMessage | AIMessage | SystemMessage | ToolMessage>;
|
|
@@ -648,7 +648,7 @@ export const formatAgentMessages = (
|
|
|
648
648
|
// If indexTokenCountMap is provided, create a new map to track the updated indices
|
|
649
649
|
const updatedIndexTokenCountMap: Record<number, number> = {};
|
|
650
650
|
// Keep track of the mapping from original payload indices to result indices
|
|
651
|
-
const indexMapping: Record<number, number[]> = {};
|
|
651
|
+
const indexMapping: Record<number, number[] | undefined> = {};
|
|
652
652
|
|
|
653
653
|
// Process messages with tool conversion if tools set is provided
|
|
654
654
|
for (let i = 0; i < payload.length; i++) {
|
|
@@ -143,18 +143,49 @@ async function testSequentialAgentChain() {
|
|
|
143
143
|
|
|
144
144
|
// Track agent progression
|
|
145
145
|
let currentAgent = '';
|
|
146
|
+
const startTime = Date.now();
|
|
147
|
+
let messageCount = 0;
|
|
146
148
|
|
|
147
|
-
// Create custom handlers
|
|
149
|
+
// Create custom handlers with extensive metadata logging
|
|
148
150
|
const customHandlers = {
|
|
149
151
|
[GraphEvents.TOOL_END]: new ToolEndHandler(),
|
|
150
|
-
[GraphEvents.CHAT_MODEL_END]:
|
|
152
|
+
[GraphEvents.CHAT_MODEL_END]: {
|
|
153
|
+
handle: (
|
|
154
|
+
_event: string,
|
|
155
|
+
_data: t.StreamEventData,
|
|
156
|
+
metadata?: Record<string, unknown>
|
|
157
|
+
): void => {
|
|
158
|
+
console.log('\n====== CHAT_MODEL_END METADATA ======');
|
|
159
|
+
console.dir(metadata, { depth: null });
|
|
160
|
+
const elapsed = Date.now() - startTime;
|
|
161
|
+
console.log(`⏱️ COMPLETED at ${elapsed}ms`);
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
[GraphEvents.CHAT_MODEL_START]: {
|
|
165
|
+
handle: (
|
|
166
|
+
_event: string,
|
|
167
|
+
_data: t.StreamEventData,
|
|
168
|
+
metadata?: Record<string, unknown>
|
|
169
|
+
): void => {
|
|
170
|
+
console.log('\n====== CHAT_MODEL_START METADATA ======');
|
|
171
|
+
console.dir(metadata, { depth: null });
|
|
172
|
+
const elapsed = Date.now() - startTime;
|
|
173
|
+
console.log(`⏱️ STARTED at ${elapsed}ms`);
|
|
174
|
+
},
|
|
175
|
+
},
|
|
151
176
|
[GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
|
|
152
177
|
[GraphEvents.ON_RUN_STEP]: {
|
|
153
178
|
handle: (
|
|
154
179
|
event: GraphEvents.ON_RUN_STEP,
|
|
155
|
-
data: t.StreamEventData
|
|
180
|
+
data: t.StreamEventData,
|
|
181
|
+
metadata?: Record<string, unknown>
|
|
156
182
|
): void => {
|
|
157
183
|
const runStepData = data as any;
|
|
184
|
+
console.log('\n====== ON_RUN_STEP ======');
|
|
185
|
+
console.log('DATA:');
|
|
186
|
+
console.dir(data, { depth: null });
|
|
187
|
+
console.log('METADATA:');
|
|
188
|
+
console.dir(metadata, { depth: null });
|
|
158
189
|
if (runStepData?.name) {
|
|
159
190
|
currentAgent = runStepData.name;
|
|
160
191
|
console.log(`\n→ ${currentAgent} is processing...`);
|
|
@@ -165,9 +196,15 @@ async function testSequentialAgentChain() {
|
|
|
165
196
|
[GraphEvents.ON_RUN_STEP_COMPLETED]: {
|
|
166
197
|
handle: (
|
|
167
198
|
event: GraphEvents.ON_RUN_STEP_COMPLETED,
|
|
168
|
-
data: t.StreamEventData
|
|
199
|
+
data: t.StreamEventData,
|
|
200
|
+
metadata?: Record<string, unknown>
|
|
169
201
|
): void => {
|
|
170
202
|
const runStepData = data as any;
|
|
203
|
+
console.log('\n====== ON_RUN_STEP_COMPLETED ======');
|
|
204
|
+
console.log('DATA:');
|
|
205
|
+
console.dir(data, { depth: null });
|
|
206
|
+
console.log('METADATA:');
|
|
207
|
+
console.dir(metadata, { depth: null });
|
|
171
208
|
if (runStepData?.name) {
|
|
172
209
|
console.log(`✓ ${runStepData.name} completed`);
|
|
173
210
|
}
|
|
@@ -180,16 +217,32 @@ async function testSequentialAgentChain() {
|
|
|
180
217
|
[GraphEvents.ON_RUN_STEP_DELTA]: {
|
|
181
218
|
handle: (
|
|
182
219
|
event: GraphEvents.ON_RUN_STEP_DELTA,
|
|
183
|
-
data: t.StreamEventData
|
|
220
|
+
data: t.StreamEventData,
|
|
221
|
+
metadata?: Record<string, unknown>
|
|
184
222
|
): void => {
|
|
223
|
+
console.log('\n====== ON_RUN_STEP_DELTA ======');
|
|
224
|
+
console.log('DATA:');
|
|
225
|
+
console.dir(data, { depth: null });
|
|
226
|
+
console.log('METADATA:');
|
|
227
|
+
console.dir(metadata, { depth: null });
|
|
185
228
|
aggregateContent({ event, data: data as t.RunStepDeltaEvent });
|
|
186
229
|
},
|
|
187
230
|
},
|
|
188
231
|
[GraphEvents.ON_MESSAGE_DELTA]: {
|
|
189
232
|
handle: (
|
|
190
233
|
event: GraphEvents.ON_MESSAGE_DELTA,
|
|
191
|
-
data: t.StreamEventData
|
|
234
|
+
data: t.StreamEventData,
|
|
235
|
+
metadata?: Record<string, unknown>
|
|
192
236
|
): void => {
|
|
237
|
+
messageCount++;
|
|
238
|
+
// Only log first few message deltas to avoid spam
|
|
239
|
+
if (messageCount <= 3) {
|
|
240
|
+
console.log('\n====== ON_MESSAGE_DELTA ======');
|
|
241
|
+
console.log('DATA:');
|
|
242
|
+
console.dir(data, { depth: null });
|
|
243
|
+
console.log('METADATA:');
|
|
244
|
+
console.dir(metadata, { depth: null });
|
|
245
|
+
}
|
|
193
246
|
aggregateContent({ event, data: data as t.MessageDeltaEvent });
|
|
194
247
|
},
|
|
195
248
|
},
|