@myagentroam/node 0.11.29 → 0.11.30

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.
@@ -30,10 +30,21 @@ export class MarAgentConversationNormalizer {
30
30
  #subagentDetails = new Map();
31
31
  #codeModeObservationIds = new Set();
32
32
  #codeModeSourceCallIds = new Set();
33
+ #toolOutputSnapshots = new Map();
34
+ #codeModeOutputCalls = new Map();
35
+ #codeModeOutputSnapshots = new Map();
36
+ #runningCodeModeCells = new Map();
37
+ #codeModeCellWaiters = new Map();
33
38
  messageItemId(nativeItemId) {
34
39
  return itemId('message', nativeItemId);
35
40
  }
36
41
  normalize(event, options = {}) {
42
+ if (event.type === 'tool.output')
43
+ return this.#toolOutput(event);
44
+ if (event.type === 'execution.started') {
45
+ this.#startExecution(event.executionId);
46
+ return [];
47
+ }
37
48
  if (event.type === 'input.received')
38
49
  return [this.input(event.entry)];
39
50
  if (event.type === 'execution.failed') {
@@ -93,15 +104,26 @@ export class MarAgentConversationNormalizer {
93
104
  if (event.type === 'tool.started' ||
94
105
  event.type === 'tool.completed' ||
95
106
  event.type === 'tool.failed') {
107
+ if (event.parentCallId !== undefined &&
108
+ (event.toolName === 'exec' || event.toolName === 'exec_wait')) {
109
+ if (event.type === 'tool.started')
110
+ this.#trackCodeModeOutputCall(event);
111
+ else
112
+ this.#finishCodeModeOutputCall(event.callId, event.parentCallId);
113
+ return [];
114
+ }
96
115
  // Read/web calls and generated artifacts stay visible independently of cell observations.
97
116
  if (event.parentCallId !== undefined &&
98
117
  event.toolName !== 'read' &&
99
118
  event.toolName !== 'web_search' &&
100
119
  event.toolName !== 'web_fetch' &&
101
- !isImageGenerationTool(event.toolName))
120
+ !isImageGenerationTool(event.toolName)) {
121
+ this.#finishCodeModeOutputCall(event.callId, event.parentCallId);
102
122
  return [];
123
+ }
103
124
  if (event.type === 'tool.started')
104
125
  return this.#toolStarted(event);
126
+ this.#finishToolCall(event);
105
127
  const permissionStop = permissionStopForToolEvent(event);
106
128
  const outerItems = event.type === 'tool.completed' ? this.#toolCompleted(event) : this.#toolFailed(event);
107
129
  return [
@@ -145,6 +167,10 @@ export class MarAgentConversationNormalizer {
145
167
  }
146
168
  #toolStarted(event) {
147
169
  const ownItemId = itemId('tool', event.callId);
170
+ this.#clearRetainedCodeModeCellsForOtherExecutions(event.executionId);
171
+ this.#toolOutputSnapshots.delete(event.callId);
172
+ this.#codeModeOutputCalls.delete(event.callId);
173
+ this.#clearCodeModeOutputSnapshots(event.callId);
148
174
  if (event.toolName === 'exec' || event.toolName === 'exec_wait') {
149
175
  const input = record(event.input) ?? {};
150
176
  const action = input.action ??
@@ -170,6 +196,9 @@ export class MarAgentConversationNormalizer {
170
196
  input: event.input,
171
197
  itemId: ownItemId,
172
198
  structured: true,
199
+ executionId: event.executionId,
200
+ ...(event.turnId === undefined ? {} : { turnId: event.turnId }),
201
+ active: true,
173
202
  commandOrigin: event.callId
174
203
  });
175
204
  return [commandItem(command, 'IN_PROGRESS')];
@@ -197,6 +226,9 @@ export class MarAgentConversationNormalizer {
197
226
  input: event.input,
198
227
  itemId: ownItemId,
199
228
  structured: true,
229
+ executionId: event.executionId,
230
+ ...(event.turnId === undefined ? {} : { turnId: event.turnId }),
231
+ active: true,
200
232
  commandOrigin: event.callId
201
233
  });
202
234
  return [];
@@ -206,6 +238,9 @@ export class MarAgentConversationNormalizer {
206
238
  input: event.input,
207
239
  itemId: ownItemId,
208
240
  structured: true,
241
+ executionId: event.executionId,
242
+ ...(event.turnId === undefined ? {} : { turnId: event.turnId }),
243
+ active: true,
209
244
  commandOrigin: origin
210
245
  });
211
246
  return [];
@@ -222,16 +257,228 @@ export class MarAgentConversationNormalizer {
222
257
  input: event.input,
223
258
  itemId: ownItemId,
224
259
  structured: 'input' in event,
260
+ executionId: event.executionId,
261
+ ...(event.turnId === undefined ? {} : { turnId: event.turnId }),
262
+ active: true,
225
263
  ...(event.data === undefined ? {} : { presentationData: event.data }),
226
264
  ...(subagentTitle === undefined ? {} : { subagentTitle }),
227
265
  ...(subagentDetails === undefined ? {} : { subagentDetails })
228
266
  });
267
+ if (event.toolName === 'code_exec_wait')
268
+ this.#trackCodeModeWait(event);
229
269
  if (event.toolName === 'apply_patch' && 'input' in event)
230
270
  return [fileChangeItem(ownItemId, 'IN_PROGRESS', [])];
231
271
  return [
232
272
  genericToolItem(ownItemId, event.toolName, 'IN_PROGRESS', event.input, null, null, event.truncated === true, event.data, subagentTitle, subagentDetails)
233
273
  ];
234
274
  }
275
+ #toolOutput(event) {
276
+ const { callId, toolName, executionId, turnId, parentCallId, output } = event;
277
+ const inputOutput = [output.stdout, output.stderr].filter(Boolean).join('\n');
278
+ const snapshot = {
279
+ outputPreview: compactRunnerText(inputOutput, 10_000),
280
+ truncated: output.truncated || inputOutput.length > 10_000
281
+ };
282
+ if (parentCallId !== undefined)
283
+ return this.#codeModeToolOutput(callId, parentCallId, toolName, executionId, turnId, output.processId, snapshot);
284
+ const state = this.#tools.get(callId);
285
+ if (state === undefined ||
286
+ !state.active ||
287
+ state.toolName !== toolName ||
288
+ state.executionId !== executionId ||
289
+ (state.turnId !== undefined && turnId !== undefined && state.turnId !== turnId) ||
290
+ state.commandOrigin === undefined)
291
+ return [];
292
+ const input = record(state.input);
293
+ if (typeof input?.processId === 'string' && input.processId !== output.processId)
294
+ return [];
295
+ const command = this.#commands.get(state.commandOrigin);
296
+ if (command === undefined || command.status !== 'IN_PROGRESS')
297
+ return [];
298
+ this.#toolOutputSnapshots.set(callId, {
299
+ commandOrigin: state.commandOrigin,
300
+ ...snapshot
301
+ });
302
+ return [
303
+ commandItem(commandWithOutputSnapshots(command, [...this.#toolOutputSnapshots.values()].filter((entry) => entry.commandOrigin === state.commandOrigin)), 'IN_PROGRESS')
304
+ ];
305
+ }
306
+ #codeModeToolOutput(callId, parentCallId, toolName, executionId, turnId, processId, snapshot) {
307
+ const parent = this.#tools.get(parentCallId);
308
+ const child = this.#codeModeOutputCalls.get(callId);
309
+ if (parent === undefined ||
310
+ (parent.toolName !== 'code_exec' && parent.toolName !== 'code_exec_wait') ||
311
+ parent.executionId !== executionId ||
312
+ (parent.turnId !== undefined && turnId !== undefined && parent.turnId !== turnId) ||
313
+ child === undefined ||
314
+ child.parentCallId !== parentCallId ||
315
+ child.toolName !== toolName ||
316
+ child.executionId !== executionId ||
317
+ (child.turnId !== undefined && turnId !== undefined && child.turnId !== turnId))
318
+ return [];
319
+ const target = parent.active
320
+ ? parent
321
+ : this.#runningCodeModeCells.get(parentCallId)?.executionId === executionId
322
+ ? this.#activeCodeModeWaiter(this.#runningCodeModeCells.get(parentCallId))
323
+ : undefined;
324
+ if (target === undefined)
325
+ return [];
326
+ const input = record(child.input);
327
+ if (typeof input?.processId === 'string' && input.processId !== processId)
328
+ return [];
329
+ const snapshots = this.#codeModeOutputSnapshots.get(parentCallId) ?? new Map();
330
+ snapshots.set(callId, snapshot);
331
+ this.#codeModeOutputSnapshots.set(parentCallId, snapshots);
332
+ const combined = [...snapshots.values()]
333
+ .map((entry) => entry.outputPreview)
334
+ .filter(Boolean)
335
+ .join('\n');
336
+ const truncated = [...snapshots.values()].some((entry) => entry.truncated) || combined.length > 10_000;
337
+ return [
338
+ genericToolItem(target.itemId, target.toolName, 'IN_PROGRESS', target.input, compactRunnerText(combined, 10_000), null, truncated)
339
+ ];
340
+ }
341
+ #trackCodeModeOutputCall(event) {
342
+ const parentCallId = event.parentCallId;
343
+ if (parentCallId === undefined || (event.toolName !== 'exec' && event.toolName !== 'exec_wait'))
344
+ return;
345
+ const parent = this.#tools.get(parentCallId);
346
+ const retainedCell = this.#runningCodeModeCells.get(parentCallId);
347
+ const canResumeRetainedCell = parent !== undefined && !parent.active && retainedCell?.executionId === event.executionId;
348
+ if (parent === undefined ||
349
+ (parent.toolName !== 'code_exec' && parent.toolName !== 'code_exec_wait') ||
350
+ parent.executionId !== event.executionId ||
351
+ (parent.turnId !== undefined && event.turnId !== undefined && parent.turnId !== event.turnId))
352
+ return;
353
+ if (!parent.active && !canResumeRetainedCell)
354
+ return;
355
+ this.#codeModeOutputCalls.delete(event.callId);
356
+ const snapshots = this.#codeModeOutputSnapshots.get(parentCallId);
357
+ snapshots?.delete(event.callId);
358
+ this.#codeModeOutputCalls.set(event.callId, {
359
+ parentCallId,
360
+ executionId: event.executionId,
361
+ ...(event.turnId === undefined ? {} : { turnId: event.turnId }),
362
+ toolName: event.toolName,
363
+ input: event.input
364
+ });
365
+ }
366
+ #finishCodeModeOutputCall(callId, parentCallId) {
367
+ const call = this.#codeModeOutputCalls.get(callId);
368
+ if (call?.parentCallId === parentCallId) {
369
+ this.#codeModeOutputCalls.delete(callId);
370
+ this.#codeModeOutputSnapshots.get(parentCallId)?.delete(callId);
371
+ }
372
+ }
373
+ #trackCodeModeWait(event) {
374
+ const cellId = record(event.input)?.cellId;
375
+ if (typeof cellId !== 'string' || cellId.length === 0)
376
+ return;
377
+ const cell = [...this.#runningCodeModeCells.values()].find((candidate) => candidate.cellId === cellId && candidate.executionId === event.executionId);
378
+ if (cell === undefined)
379
+ return;
380
+ const waiters = this.#codeModeCellWaiters.get(cellId) ?? new Set();
381
+ waiters.add(event.callId);
382
+ this.#codeModeCellWaiters.set(cellId, waiters);
383
+ }
384
+ #activeCodeModeWaiter(cell) {
385
+ const waiters = this.#codeModeCellWaiters.get(cell.cellId);
386
+ if (waiters === undefined)
387
+ return undefined;
388
+ for (const callId of [...waiters].reverse()) {
389
+ const state = this.#tools.get(callId);
390
+ const input = record(state?.input);
391
+ if (state?.active === true &&
392
+ state.toolName === 'code_exec_wait' &&
393
+ state.executionId === cell.executionId &&
394
+ input?.cellId === cell.cellId)
395
+ return state;
396
+ waiters.delete(callId);
397
+ }
398
+ if (waiters.size === 0)
399
+ this.#codeModeCellWaiters.delete(cell.cellId);
400
+ return undefined;
401
+ }
402
+ #finishToolCall(event) {
403
+ const state = this.#tools.get(event.callId);
404
+ if (state !== undefined)
405
+ state.active = false;
406
+ this.#toolOutputSnapshots.delete(event.callId);
407
+ const data = record(event.data);
408
+ const cellId = typeof data?.cellId === 'string' ? data.cellId : undefined;
409
+ const status = data?.status;
410
+ if (state?.toolName === 'code_exec') {
411
+ if (event.type === 'tool.completed' &&
412
+ event.toolName === 'code_exec' &&
413
+ status === 'running' &&
414
+ cellId !== undefined &&
415
+ cellId.length > 0) {
416
+ this.#runningCodeModeCells.set(event.callId, {
417
+ cellId,
418
+ executionId: event.executionId
419
+ });
420
+ return;
421
+ }
422
+ this.#clearRunningCodeModeCell(event.callId);
423
+ return;
424
+ }
425
+ if (state?.toolName === 'code_exec_wait') {
426
+ const inputCellId = record(state.input)?.cellId;
427
+ if (typeof inputCellId === 'string')
428
+ this.#removeCodeModeWaiter(inputCellId, event.callId);
429
+ if ((status === 'completed' || status === 'failed' || status === 'cancelled') &&
430
+ typeof (cellId ?? inputCellId) === 'string') {
431
+ const finishedCellId = (cellId ?? inputCellId);
432
+ for (const [sourceCallId, cell] of this.#runningCodeModeCells)
433
+ if (cell.cellId === finishedCellId && cell.executionId === event.executionId)
434
+ this.#clearRunningCodeModeCell(sourceCallId);
435
+ }
436
+ this.#clearCodeModeOutputSnapshots(event.callId);
437
+ return;
438
+ }
439
+ this.#clearCodeModeOutputSnapshots(event.callId);
440
+ }
441
+ #clearCodeModeOutputSnapshots(parentCallId) {
442
+ this.#codeModeOutputSnapshots.delete(parentCallId);
443
+ for (const [callId, state] of this.#codeModeOutputCalls)
444
+ if (state.parentCallId === parentCallId)
445
+ this.#codeModeOutputCalls.delete(callId);
446
+ }
447
+ #removeCodeModeWaiter(cellId, callId) {
448
+ const waiters = this.#codeModeCellWaiters.get(cellId);
449
+ waiters?.delete(callId);
450
+ if (waiters?.size === 0)
451
+ this.#codeModeCellWaiters.delete(cellId);
452
+ }
453
+ #clearRunningCodeModeCell(sourceCallId) {
454
+ const cell = this.#runningCodeModeCells.get(sourceCallId);
455
+ if (cell !== undefined) {
456
+ this.#runningCodeModeCells.delete(sourceCallId);
457
+ this.#codeModeCellWaiters.delete(cell.cellId);
458
+ }
459
+ this.#clearCodeModeOutputSnapshots(sourceCallId);
460
+ }
461
+ #startExecution(executionId) {
462
+ for (const [callId, state] of this.#tools)
463
+ if (state.executionId !== executionId) {
464
+ state.active = false;
465
+ this.#toolOutputSnapshots.delete(callId);
466
+ }
467
+ for (const [callId, state] of this.#codeModeOutputCalls)
468
+ if (state.executionId !== executionId)
469
+ this.#codeModeOutputCalls.delete(callId);
470
+ for (const [sourceCallId, cell] of this.#runningCodeModeCells)
471
+ if (cell.executionId !== executionId)
472
+ this.#clearRunningCodeModeCell(sourceCallId);
473
+ for (const parentCallId of this.#codeModeOutputSnapshots.keys())
474
+ if (this.#tools.get(parentCallId)?.executionId !== executionId)
475
+ this.#codeModeOutputSnapshots.delete(parentCallId);
476
+ }
477
+ #clearRetainedCodeModeCellsForOtherExecutions(executionId) {
478
+ for (const [sourceCallId, cell] of this.#runningCodeModeCells)
479
+ if (cell.executionId !== executionId)
480
+ this.#clearRunningCodeModeCell(sourceCallId);
481
+ }
235
482
  #compactAnchorItemId(event, publicItemIdPrefix) {
236
483
  const anchor = event.anchor;
237
484
  if (anchor === undefined || !validCompactAnchor(anchor.id))
@@ -730,6 +977,21 @@ function commandItem(command, status, title) {
730
977
  merge: true
731
978
  };
732
979
  }
980
+ function commandWithOutputSnapshots(command, snapshots) {
981
+ const outputPreview = [
982
+ command.outputPreview,
983
+ ...snapshots.map((snapshot) => snapshot.outputPreview)
984
+ ]
985
+ .filter(Boolean)
986
+ .join('\n');
987
+ return {
988
+ ...command,
989
+ outputPreview: compactRunnerText(outputPreview, 10_000),
990
+ truncated: command.truncated ||
991
+ snapshots.some((snapshot) => snapshot.truncated) ||
992
+ outputPreview.length > 10_000
993
+ };
994
+ }
733
995
  function applyCommandResult(command, result) {
734
996
  const output = [result.stdout, result.stderr].filter(Boolean).join('\n');
735
997
  if (output.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myagentroam/node",
3
- "version": "0.11.29",
3
+ "version": "0.11.30",
4
4
  "description": "MyAgentRoam Node runtime CLI.",
5
5
  "license": "Apache-2.0 AND GPL-2.0-or-later",
6
6
  "type": "module",
@@ -38,10 +38,10 @@
38
38
  "sharp": "0.35.5",
39
39
  "ws": "^8.21.3",
40
40
  "zod": "4.4.3",
41
- "@myagentroam/agent": "0.11.29",
41
+ "@myagentroam/agent": "0.11.30",
42
42
  "@myagentroam/code-navigation": "0.11.0",
43
- "@myagentroam/protocol": "0.11.29",
44
- "@myagentroam/marctl": "0.11.1"
43
+ "@myagentroam/marctl": "0.11.1",
44
+ "@myagentroam/protocol": "0.11.30"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/ws": "^8.18.1"