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.
Files changed (42) hide show
  1. package/dist/cjs/graphs/Graph.cjs +28 -2
  2. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  3. package/dist/cjs/graphs/MultiAgentGraph.cjs +108 -0
  4. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  5. package/dist/cjs/messages/format.cjs.map +1 -1
  6. package/dist/cjs/stream.cjs +27 -0
  7. package/dist/cjs/stream.cjs.map +1 -1
  8. package/dist/cjs/tools/BrowserTools.cjs +125 -113
  9. package/dist/cjs/tools/BrowserTools.cjs.map +1 -1
  10. package/dist/esm/graphs/Graph.mjs +28 -2
  11. package/dist/esm/graphs/Graph.mjs.map +1 -1
  12. package/dist/esm/graphs/MultiAgentGraph.mjs +108 -0
  13. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  14. package/dist/esm/messages/format.mjs.map +1 -1
  15. package/dist/esm/stream.mjs +27 -0
  16. package/dist/esm/stream.mjs.map +1 -1
  17. package/dist/esm/tools/BrowserTools.mjs +125 -113
  18. package/dist/esm/tools/BrowserTools.mjs.map +1 -1
  19. package/dist/types/graphs/Graph.d.ts +14 -0
  20. package/dist/types/graphs/MultiAgentGraph.d.ts +41 -0
  21. package/dist/types/messages/format.d.ts +1 -1
  22. package/dist/types/tools/BrowserTools.d.ts +45 -5
  23. package/dist/types/types/stream.d.ts +13 -0
  24. package/package.json +4 -2
  25. package/src/graphs/Graph.ts +30 -2
  26. package/src/graphs/MultiAgentGraph.ts +119 -0
  27. package/src/messages/format.ts +2 -2
  28. package/src/scripts/multi-agent-chain.ts +59 -6
  29. package/src/scripts/multi-agent-parallel-start.ts +265 -0
  30. package/src/scripts/multi-agent-parallel.ts +61 -10
  31. package/src/scripts/multi-agent-sequence.ts +6 -1
  32. package/src/scripts/parallel-asymmetric-tools-test.ts +274 -0
  33. package/src/scripts/parallel-full-metadata-test.ts +240 -0
  34. package/src/scripts/parallel-tools-test.ts +340 -0
  35. package/src/scripts/sequential-full-metadata-test.ts +197 -0
  36. package/src/scripts/single-agent-metadata-test.ts +198 -0
  37. package/src/scripts/test-thinking-handoff.ts +8 -0
  38. package/src/scripts/tools.ts +31 -11
  39. package/src/stream.ts +32 -0
  40. package/src/tools/BrowserTools.ts +356 -310
  41. package/src/tools/__tests__/BrowserTools.test.ts +263 -257
  42. package/src/types/stream.ts +15 -0
@@ -1,257 +1,263 @@
1
- import { describe, it, expect, beforeEach, jest } from '@jest/globals';
2
- import {
3
- createBrowserTools,
4
- hasBrowserCapability,
5
- EBrowserTools,
6
- type BrowserToolResponse,
7
- } from '../BrowserTools';
8
-
9
- describe('BrowserTools', () => {
10
- describe('EBrowserTools enum', () => {
11
- it('should have all expected browser tool names', () => {
12
- expect(EBrowserTools.CLICK).toBe('browser_click');
13
- expect(EBrowserTools.TYPE).toBe('browser_type');
14
- expect(EBrowserTools.NAVIGATE).toBe('browser_navigate');
15
- expect(EBrowserTools.SCROLL).toBe('browser_scroll');
16
- expect(EBrowserTools.EXTRACT).toBe('browser_extract');
17
- expect(EBrowserTools.HOVER).toBe('browser_hover');
18
- expect(EBrowserTools.WAIT).toBe('browser_wait');
19
- expect(EBrowserTools.BACK).toBe('browser_back');
20
- expect(EBrowserTools.SCREENSHOT).toBe('browser_screenshot');
21
- expect(EBrowserTools.GET_PAGE_STATE).toBe('browser_get_page_state');
22
- });
23
-
24
- it('should have exactly 10 browser tools', () => {
25
- expect(Object.keys(EBrowserTools).length).toBe(10);
26
- });
27
- });
28
-
29
- describe('hasBrowserCapability', () => {
30
- it('should return false when no request is provided', () => {
31
- expect(hasBrowserCapability()).toBe(false);
32
- expect(hasBrowserCapability(undefined)).toBe(false);
33
- });
34
-
35
- it('should return false when request has no headers', () => {
36
- expect(hasBrowserCapability({})).toBe(false);
37
- expect(hasBrowserCapability({ headers: undefined })).toBe(false);
38
- });
39
-
40
- it('should return true when X-Ranger-Browser-Extension header is true', () => {
41
- const req = {
42
- headers: {
43
- 'x-ranger-browser-extension': 'true',
44
- },
45
- };
46
- expect(hasBrowserCapability(req)).toBe(true);
47
- });
48
-
49
- it('should return true when X-Ranger-Browser-Capable header is true', () => {
50
- const req = {
51
- headers: {
52
- 'x-ranger-browser-capable': 'true',
53
- },
54
- };
55
- expect(hasBrowserCapability(req)).toBe(true);
56
- });
57
-
58
- it('should return false when browser headers are not true', () => {
59
- const req = {
60
- headers: {
61
- 'x-ranger-browser-extension': 'false',
62
- 'x-ranger-browser-capable': 'false',
63
- },
64
- };
65
- expect(hasBrowserCapability(req)).toBe(false);
66
- });
67
-
68
- it('should return false when browser headers are missing', () => {
69
- const req = {
70
- headers: {
71
- 'content-type': 'application/json',
72
- },
73
- };
74
- expect(hasBrowserCapability(req)).toBe(false);
75
- });
76
- });
77
-
78
- describe('createBrowserTools', () => {
79
- let tools: ReturnType<typeof createBrowserTools>;
80
-
81
- beforeEach(() => {
82
- tools = createBrowserTools();
83
- });
84
-
85
- it('should create exactly 10 browser tools', () => {
86
- expect(tools.length).toBe(10);
87
- });
88
-
89
- it('should create tools with correct names', () => {
90
- const toolNames = tools.map(t => t.name);
91
- expect(toolNames).toContain('browser_click');
92
- expect(toolNames).toContain('browser_type');
93
- expect(toolNames).toContain('browser_navigate');
94
- expect(toolNames).toContain('browser_scroll');
95
- expect(toolNames).toContain('browser_extract');
96
- expect(toolNames).toContain('browser_hover');
97
- expect(toolNames).toContain('browser_wait');
98
- expect(toolNames).toContain('browser_back');
99
- expect(toolNames).toContain('browser_screenshot');
100
- expect(toolNames).toContain('browser_get_page_state');
101
- });
102
-
103
- it('should have descriptions for all tools', () => {
104
- for (const tool of tools) {
105
- expect(tool.description).toBeDefined();
106
- expect(tool.description.length).toBeGreaterThan(0);
107
- }
108
- });
109
-
110
- describe('browser_click tool', () => {
111
- it('should return requiresBrowserExecution marker', async () => {
112
- const clickTool = tools.find(t => t.name === 'browser_click');
113
- expect(clickTool).toBeDefined();
114
-
115
- const result = await clickTool!.invoke({ index: 5 });
116
- const parsed: BrowserToolResponse = JSON.parse(result);
117
-
118
- expect(parsed.requiresBrowserExecution).toBe(true);
119
- expect(parsed.action).toBe('click');
120
- expect(parsed.args).toEqual({ index: 5 });
121
- });
122
- });
123
-
124
- describe('browser_type tool', () => {
125
- it('should return requiresBrowserExecution marker with all args', async () => {
126
- const typeTool = tools.find(t => t.name === 'browser_type');
127
- expect(typeTool).toBeDefined();
128
-
129
- const result = await typeTool!.invoke({
130
- index: 3,
131
- text: 'Hello World',
132
- pressEnter: true
133
- });
134
- const parsed: BrowserToolResponse = JSON.parse(result);
135
-
136
- expect(parsed.requiresBrowserExecution).toBe(true);
137
- expect(parsed.action).toBe('type');
138
- expect(parsed.args.index).toBe(3);
139
- expect(parsed.args.text).toBe('Hello World');
140
- expect(parsed.args.pressEnter).toBe(true);
141
- });
142
- });
143
-
144
- describe('browser_navigate tool', () => {
145
- it('should return requiresBrowserExecution marker with URL', async () => {
146
- const navigateTool = tools.find(t => t.name === 'browser_navigate');
147
- expect(navigateTool).toBeDefined();
148
-
149
- const result = await navigateTool!.invoke({ url: 'https://example.com' });
150
- const parsed: BrowserToolResponse = JSON.parse(result);
151
-
152
- expect(parsed.requiresBrowserExecution).toBe(true);
153
- expect(parsed.action).toBe('navigate');
154
- expect(parsed.args.url).toBe('https://example.com');
155
- });
156
- });
157
-
158
- describe('browser_scroll tool', () => {
159
- it('should return requiresBrowserExecution marker with direction', async () => {
160
- const scrollTool = tools.find(t => t.name === 'browser_scroll');
161
- expect(scrollTool).toBeDefined();
162
-
163
- const result = await scrollTool!.invoke({
164
- direction: 'down',
165
- amount: 500
166
- });
167
- const parsed: BrowserToolResponse = JSON.parse(result);
168
-
169
- expect(parsed.requiresBrowserExecution).toBe(true);
170
- expect(parsed.action).toBe('scroll');
171
- expect(parsed.args.direction).toBe('down');
172
- expect(parsed.args.amount).toBe(500);
173
- });
174
- });
175
-
176
- describe('browser_hover tool', () => {
177
- it('should return requiresBrowserExecution marker with index', async () => {
178
- const hoverTool = tools.find(t => t.name === 'browser_hover');
179
- expect(hoverTool).toBeDefined();
180
-
181
- const result = await hoverTool!.invoke({ index: 2 });
182
- const parsed: BrowserToolResponse = JSON.parse(result);
183
-
184
- expect(parsed.requiresBrowserExecution).toBe(true);
185
- expect(parsed.action).toBe('hover');
186
- expect(parsed.args.index).toBe(2);
187
- });
188
- });
189
-
190
- describe('browser_wait tool', () => {
191
- it('should return requiresBrowserExecution marker with duration', async () => {
192
- const waitTool = tools.find(t => t.name === 'browser_wait');
193
- expect(waitTool).toBeDefined();
194
-
195
- const result = await waitTool!.invoke({ duration: 2000 });
196
- const parsed: BrowserToolResponse = JSON.parse(result);
197
-
198
- expect(parsed.requiresBrowserExecution).toBe(true);
199
- expect(parsed.action).toBe('wait');
200
- expect(parsed.args.duration).toBe(2000);
201
- });
202
- });
203
-
204
- describe('browser_back tool', () => {
205
- it('should return requiresBrowserExecution marker', async () => {
206
- const backTool = tools.find(t => t.name === 'browser_back');
207
- expect(backTool).toBeDefined();
208
-
209
- const result = await backTool!.invoke({});
210
- const parsed: BrowserToolResponse = JSON.parse(result);
211
-
212
- expect(parsed.requiresBrowserExecution).toBe(true);
213
- expect(parsed.action).toBe('back');
214
- });
215
- });
216
-
217
- describe('browser_screenshot tool', () => {
218
- it('should return requiresBrowserExecution marker', async () => {
219
- const screenshotTool = tools.find(t => t.name === 'browser_screenshot');
220
- expect(screenshotTool).toBeDefined();
221
-
222
- const result = await screenshotTool!.invoke({});
223
- const parsed: BrowserToolResponse = JSON.parse(result);
224
-
225
- expect(parsed.requiresBrowserExecution).toBe(true);
226
- expect(parsed.action).toBe('screenshot');
227
- });
228
- });
229
-
230
- describe('browser_get_page_state tool', () => {
231
- it('should return requiresBrowserExecution marker', async () => {
232
- const pageStateTool = tools.find(t => t.name === 'browser_get_page_state');
233
- expect(pageStateTool).toBeDefined();
234
-
235
- const result = await pageStateTool!.invoke({});
236
- const parsed: BrowserToolResponse = JSON.parse(result);
237
-
238
- expect(parsed.requiresBrowserExecution).toBe(true);
239
- expect(parsed.action).toBe('get_page_state');
240
- });
241
- });
242
-
243
- describe('browser_extract tool', () => {
244
- it('should return requiresBrowserExecution marker', async () => {
245
- const extractTool = tools.find(t => t.name === 'browser_extract');
246
- expect(extractTool).toBeDefined();
247
-
248
- const result = await extractTool!.invoke({ query: 'main content' });
249
- const parsed: BrowserToolResponse = JSON.parse(result);
250
-
251
- expect(parsed.requiresBrowserExecution).toBe(true);
252
- expect(parsed.action).toBe('extract');
253
- expect(parsed.args.query).toBe('main content');
254
- });
255
- });
256
- });
257
- });
1
+ import { describe, it, expect, beforeEach, jest as _jest } from '@jest/globals';
2
+ import {
3
+ createBrowserTools,
4
+ hasBrowserCapability,
5
+ EBrowserTools,
6
+ type BrowserToolResponse,
7
+ } from '../BrowserTools';
8
+
9
+ describe('BrowserTools', () => {
10
+ describe('EBrowserTools enum', () => {
11
+ it('should have all expected browser tool names', () => {
12
+ expect(EBrowserTools.CLICK).toBe('browser_click');
13
+ expect(EBrowserTools.TYPE).toBe('browser_type');
14
+ expect(EBrowserTools.NAVIGATE).toBe('browser_navigate');
15
+ expect(EBrowserTools.SCROLL).toBe('browser_scroll');
16
+ expect(EBrowserTools.EXTRACT).toBe('browser_extract');
17
+ expect(EBrowserTools.HOVER).toBe('browser_hover');
18
+ expect(EBrowserTools.WAIT).toBe('browser_wait');
19
+ expect(EBrowserTools.BACK).toBe('browser_back');
20
+ expect(EBrowserTools.SCREENSHOT).toBe('browser_screenshot');
21
+ expect(EBrowserTools.GET_PAGE_STATE).toBe('browser_get_page_state');
22
+ });
23
+
24
+ it('should have exactly 10 browser tools', () => {
25
+ expect(Object.keys(EBrowserTools).length).toBe(10);
26
+ });
27
+ });
28
+
29
+ describe('hasBrowserCapability', () => {
30
+ it('should return false when no request is provided', () => {
31
+ expect(hasBrowserCapability()).toBe(false);
32
+ expect(hasBrowserCapability(undefined)).toBe(false);
33
+ });
34
+
35
+ it('should return false when request has no headers', () => {
36
+ expect(hasBrowserCapability({})).toBe(false);
37
+ expect(hasBrowserCapability({ headers: undefined })).toBe(false);
38
+ });
39
+
40
+ it('should return true when X-Ranger-Browser-Extension header is true', () => {
41
+ const req = {
42
+ headers: {
43
+ 'x-ranger-browser-extension': 'true',
44
+ },
45
+ };
46
+ expect(hasBrowserCapability(req)).toBe(true);
47
+ });
48
+
49
+ it('should return true when X-Ranger-Browser-Capable header is true', () => {
50
+ const req = {
51
+ headers: {
52
+ 'x-ranger-browser-capable': 'true',
53
+ },
54
+ };
55
+ expect(hasBrowserCapability(req)).toBe(true);
56
+ });
57
+
58
+ it('should return false when browser headers are not true', () => {
59
+ const req = {
60
+ headers: {
61
+ 'x-ranger-browser-extension': 'false',
62
+ 'x-ranger-browser-capable': 'false',
63
+ },
64
+ };
65
+ expect(hasBrowserCapability(req)).toBe(false);
66
+ });
67
+
68
+ it('should return false when browser headers are missing', () => {
69
+ const req = {
70
+ headers: {
71
+ 'content-type': 'application/json',
72
+ },
73
+ };
74
+ expect(hasBrowserCapability(req)).toBe(false);
75
+ });
76
+ });
77
+
78
+ describe('createBrowserTools', () => {
79
+ let tools: ReturnType<typeof createBrowserTools>;
80
+
81
+ beforeEach(() => {
82
+ tools = createBrowserTools();
83
+ });
84
+
85
+ it('should create exactly 10 browser tools', () => {
86
+ expect(tools.length).toBe(10);
87
+ });
88
+
89
+ it('should create tools with correct names', () => {
90
+ const toolNames = tools.map((t) => t.name);
91
+ expect(toolNames).toContain('browser_click');
92
+ expect(toolNames).toContain('browser_type');
93
+ expect(toolNames).toContain('browser_navigate');
94
+ expect(toolNames).toContain('browser_scroll');
95
+ expect(toolNames).toContain('browser_extract');
96
+ expect(toolNames).toContain('browser_hover');
97
+ expect(toolNames).toContain('browser_wait');
98
+ expect(toolNames).toContain('browser_back');
99
+ expect(toolNames).toContain('browser_screenshot');
100
+ expect(toolNames).toContain('browser_get_page_state');
101
+ });
102
+
103
+ it('should have descriptions for all tools', () => {
104
+ for (const tool of tools) {
105
+ expect(tool.description).toBeDefined();
106
+ expect(tool.description.length).toBeGreaterThan(0);
107
+ }
108
+ });
109
+
110
+ describe('browser_click tool', () => {
111
+ it('should return requiresBrowserExecution marker', async () => {
112
+ const clickTool = tools.find((t) => t.name === 'browser_click');
113
+ expect(clickTool).toBeDefined();
114
+
115
+ const result = await clickTool!.invoke({ index: 5 });
116
+ const parsed: BrowserToolResponse = JSON.parse(result);
117
+
118
+ expect(parsed.requiresBrowserExecution).toBe(true);
119
+ expect(parsed.action).toBe('click');
120
+ expect(parsed.args).toEqual({ index: 5 });
121
+ });
122
+ });
123
+
124
+ describe('browser_type tool', () => {
125
+ it('should return requiresBrowserExecution marker with all args', async () => {
126
+ const typeTool = tools.find((t) => t.name === 'browser_type');
127
+ expect(typeTool).toBeDefined();
128
+
129
+ const result = await typeTool!.invoke({
130
+ index: 3,
131
+ text: 'Hello World',
132
+ pressEnter: true,
133
+ });
134
+ const parsed: BrowserToolResponse = JSON.parse(result);
135
+
136
+ expect(parsed.requiresBrowserExecution).toBe(true);
137
+ expect(parsed.action).toBe('type');
138
+ expect(parsed.args.index).toBe(3);
139
+ expect(parsed.args.text).toBe('Hello World');
140
+ expect(parsed.args.pressEnter).toBe(true);
141
+ });
142
+ });
143
+
144
+ describe('browser_navigate tool', () => {
145
+ it('should return requiresBrowserExecution marker with URL', async () => {
146
+ const navigateTool = tools.find((t) => t.name === 'browser_navigate');
147
+ expect(navigateTool).toBeDefined();
148
+
149
+ const result = await navigateTool!.invoke({
150
+ url: 'https://example.com',
151
+ });
152
+ const parsed: BrowserToolResponse = JSON.parse(result);
153
+
154
+ expect(parsed.requiresBrowserExecution).toBe(true);
155
+ expect(parsed.action).toBe('navigate');
156
+ expect(parsed.args.url).toBe('https://example.com');
157
+ });
158
+ });
159
+
160
+ describe('browser_scroll tool', () => {
161
+ it('should return requiresBrowserExecution marker with direction', async () => {
162
+ const scrollTool = tools.find((t) => t.name === 'browser_scroll');
163
+ expect(scrollTool).toBeDefined();
164
+
165
+ const result = await scrollTool!.invoke({
166
+ direction: 'down',
167
+ amount: 500,
168
+ });
169
+ const parsed: BrowserToolResponse = JSON.parse(result);
170
+
171
+ expect(parsed.requiresBrowserExecution).toBe(true);
172
+ expect(parsed.action).toBe('scroll');
173
+ expect(parsed.args.direction).toBe('down');
174
+ expect(parsed.args.amount).toBe(500);
175
+ });
176
+ });
177
+
178
+ describe('browser_hover tool', () => {
179
+ it('should return requiresBrowserExecution marker with index', async () => {
180
+ const hoverTool = tools.find((t) => t.name === 'browser_hover');
181
+ expect(hoverTool).toBeDefined();
182
+
183
+ const result = await hoverTool!.invoke({ index: 2 });
184
+ const parsed: BrowserToolResponse = JSON.parse(result);
185
+
186
+ expect(parsed.requiresBrowserExecution).toBe(true);
187
+ expect(parsed.action).toBe('hover');
188
+ expect(parsed.args.index).toBe(2);
189
+ });
190
+ });
191
+
192
+ describe('browser_wait tool', () => {
193
+ it('should return requiresBrowserExecution marker with duration', async () => {
194
+ const waitTool = tools.find((t) => t.name === 'browser_wait');
195
+ expect(waitTool).toBeDefined();
196
+
197
+ const result = await waitTool!.invoke({ duration: 2000 });
198
+ const parsed: BrowserToolResponse = JSON.parse(result);
199
+
200
+ expect(parsed.requiresBrowserExecution).toBe(true);
201
+ expect(parsed.action).toBe('wait');
202
+ expect(parsed.args.duration).toBe(2000);
203
+ });
204
+ });
205
+
206
+ describe('browser_back tool', () => {
207
+ it('should return requiresBrowserExecution marker', async () => {
208
+ const backTool = tools.find((t) => t.name === 'browser_back');
209
+ expect(backTool).toBeDefined();
210
+
211
+ const result = await backTool!.invoke({});
212
+ const parsed: BrowserToolResponse = JSON.parse(result);
213
+
214
+ expect(parsed.requiresBrowserExecution).toBe(true);
215
+ expect(parsed.action).toBe('back');
216
+ });
217
+ });
218
+
219
+ describe('browser_screenshot tool', () => {
220
+ it('should return requiresBrowserExecution marker', async () => {
221
+ const screenshotTool = tools.find(
222
+ (t) => t.name === 'browser_screenshot'
223
+ );
224
+ expect(screenshotTool).toBeDefined();
225
+
226
+ const result = await screenshotTool!.invoke({});
227
+ const parsed: BrowserToolResponse = JSON.parse(result);
228
+
229
+ expect(parsed.requiresBrowserExecution).toBe(true);
230
+ expect(parsed.action).toBe('screenshot');
231
+ });
232
+ });
233
+
234
+ describe('browser_get_page_state tool', () => {
235
+ it('should return requiresBrowserExecution marker', async () => {
236
+ const pageStateTool = tools.find(
237
+ (t) => t.name === 'browser_get_page_state'
238
+ );
239
+ expect(pageStateTool).toBeDefined();
240
+
241
+ const result = await pageStateTool!.invoke({});
242
+ const parsed: BrowserToolResponse = JSON.parse(result);
243
+
244
+ expect(parsed.requiresBrowserExecution).toBe(true);
245
+ expect(parsed.action).toBe('get_page_state');
246
+ });
247
+ });
248
+
249
+ describe('browser_extract tool', () => {
250
+ it('should return requiresBrowserExecution marker', async () => {
251
+ const extractTool = tools.find((t) => t.name === 'browser_extract');
252
+ expect(extractTool).toBeDefined();
253
+
254
+ const result = await extractTool!.invoke({ query: 'main content' });
255
+ const parsed: BrowserToolResponse = JSON.parse(result);
256
+
257
+ expect(parsed.requiresBrowserExecution).toBe(true);
258
+ expect(parsed.action).toBe('extract');
259
+ expect(parsed.args.query).toBe('main content');
260
+ });
261
+ });
262
+ });
263
+ });
@@ -66,6 +66,17 @@ export type RunStep = {
66
66
  id: string; // #new
67
67
  runId?: string; // #new
68
68
  agentId?: string; // #new - tracks which agent this step belongs to
69
+ /**
70
+ * Group ID - incrementing number (1, 2, 3...) reflecting execution order.
71
+ * Agents with the same groupId run in parallel and should be rendered together.
72
+ * undefined means the agent runs sequentially (not part of any parallel group).
73
+ *
74
+ * Example for: researcher -> [analyst1, analyst2, analyst3] -> summarizer
75
+ * - researcher: undefined (sequential)
76
+ * - analyst1, analyst2, analyst3: 1 (first parallel group)
77
+ * - summarizer: undefined (sequential)
78
+ */
79
+ groupId?: number; // #new
69
80
  index: number; // #new
70
81
  stepIndex?: number; // #new
71
82
  stepDetails: StepDetails;
@@ -332,6 +343,10 @@ export type MessageContentComplex = (
332
343
  })
333
344
  ) & {
334
345
  tool_call_ids?: string[];
346
+ // Optional agentId for parallel execution attribution
347
+ agentId?: string;
348
+ // Optional groupId for parallel group attribution
349
+ groupId?: number;
335
350
  };
336
351
 
337
352
  export interface TMessage {