@myagentroam/node 0.11.43 → 0.11.45
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/application/node-lifecycle.js +30 -7
- package/dist/connector.js +5 -1
- package/dist/main.js +10 -3
- package/dist/runner/claude/managed-run-controller.js +3 -10
- package/dist/runner/claude/native-transcript.js +1 -1
- package/dist/runner/claude/tool-normalizer.js +16 -11
- package/dist/runner/codex/conversation-parser.js +29 -38
- package/dist/runner/codex/managed-run-controller.js +4 -4
- package/dist/runner/codex/native-transcript.js +5 -3
- package/dist/runner/codex/tool-normalizer.js +13 -17
- package/dist/runner/execution-presentation.js +8 -51
- package/dist/runner/mar-agent/agent-network-extension.js +43 -13
- package/dist/runner/mar-agent/agent-operation-presentation.js +167 -0
- package/dist/runner/mar-agent/conversation-normalizer.js +118 -107
- package/dist/runner/mar-agent/session-runtime-registry.js +22 -12
- package/dist/runner/mar-agent/session-runtime.js +16 -11
- package/dist/runner/normalization.js +5 -0
- package/dist/runner/opencode/tool-normalizer.js +10 -10
- package/dist/service/agent-network-bindings.js +10 -49
- package/dist/service/agent-network-invoke.js +4 -19
- package/dist/service/agent-network-service.js +0 -16
- package/dist/service/marctl-caller.js +17 -9
- package/dist/session/runtime/conversation-projection.js +10 -3
- package/dist/workspace/git.js +44 -1
- package/dist/workspace/workspace-change-service.js +39 -1
- package/dist/workspace/workspace-workbench-service.js +8 -0
- package/package.json +4 -4
|
@@ -7,8 +7,9 @@ export function normalizeMarAgentUsage(usage) {
|
|
|
7
7
|
import { boundedConversationItemId, compactRunnerText, compactRunnerValue } from '../normalization.js';
|
|
8
8
|
import { runnerErrorProjection } from '../runner-error.js';
|
|
9
9
|
import { toolPresentationSchema } from '@myagentroam/protocol';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { publicOutputSnapshot, publicToolOutput } from '../normalization.js';
|
|
11
|
+
import { boundToolOutput } from '@myagentroam/protocol';
|
|
12
|
+
import { agentOperationAction, agentOperationPresentation } from './agent-operation-presentation.js';
|
|
12
13
|
function boundCodeOutputSnapshots(sources) {
|
|
13
14
|
for (const channel of ['outputPreview', 'stdout', 'stderr']) {
|
|
14
15
|
const text = (entry) => channel === 'outputPreview' ? entry.outputPreview : entry.displayOutput[channel];
|
|
@@ -147,15 +148,18 @@ export class MarAgentConversationNormalizer {
|
|
|
147
148
|
this.#finishCodeModeOutputCall(event.callId, event.parentCallId);
|
|
148
149
|
return [];
|
|
149
150
|
}
|
|
150
|
-
//
|
|
151
|
+
// Public Agent calls, read/web calls and artifacts do not depend on model observations.
|
|
151
152
|
if (event.parentCallId !== undefined &&
|
|
152
153
|
event.toolName !== 'read' &&
|
|
153
154
|
event.toolName !== 'web_search' &&
|
|
154
155
|
event.toolName !== 'web_fetch' &&
|
|
156
|
+
agentOperationAction(event.toolName) === undefined &&
|
|
155
157
|
!isImageGenerationTool(event.toolName)) {
|
|
156
158
|
this.#finishCodeModeOutputCall(event.callId, event.parentCallId);
|
|
157
159
|
return [];
|
|
158
160
|
}
|
|
161
|
+
if (event.parentCallId !== undefined && agentOperationAction(event.toolName) !== undefined)
|
|
162
|
+
this.#codeModeSourceCallIds.add(event.callId);
|
|
159
163
|
if (event.type === 'tool.started')
|
|
160
164
|
return this.#toolStarted(event);
|
|
161
165
|
this.#finishToolCall(event);
|
|
@@ -252,6 +256,7 @@ export class MarAgentConversationNormalizer {
|
|
|
252
256
|
input: event.input,
|
|
253
257
|
itemId: ownItemId,
|
|
254
258
|
structured: 'input' in event,
|
|
259
|
+
inputTruncated: event.truncated === true,
|
|
255
260
|
executionId: event.executionId,
|
|
256
261
|
...(event.turnId === undefined ? {} : { turnId: event.turnId }),
|
|
257
262
|
active: true,
|
|
@@ -264,7 +269,7 @@ export class MarAgentConversationNormalizer {
|
|
|
264
269
|
if (event.toolName === 'apply_patch' && 'input' in event)
|
|
265
270
|
return [fileChangeItem(ownItemId, 'IN_PROGRESS', [])];
|
|
266
271
|
return [
|
|
267
|
-
genericToolItem(ownItemId, event.toolName, 'IN_PROGRESS', event.input, null, null, event.truncated === true, event.data, subagentTitle, subagentDetails)
|
|
272
|
+
genericToolItem(ownItemId, event.toolName, 'IN_PROGRESS', event.input, null, null, event.truncated === true, event.data, subagentTitle, subagentDetails, undefined, undefined, event.truncated === true)
|
|
268
273
|
];
|
|
269
274
|
}
|
|
270
275
|
#toolOutput(event) {
|
|
@@ -279,14 +284,13 @@ export class MarAgentConversationNormalizer {
|
|
|
279
284
|
stderrDroppedBytes: 0
|
|
280
285
|
};
|
|
281
286
|
const displayed = [displayOutput.stdout, displayOutput.stderr].filter(Boolean).join('\n');
|
|
282
|
-
const bounded = publicOutputSnapshot(displayed,
|
|
283
|
-
displayOutput.stdoutDroppedBytes > 0 ||
|
|
284
|
-
displayOutput.stderrDroppedBytes > 0);
|
|
287
|
+
const bounded = publicOutputSnapshot(displayed, event.outputTruncation !== undefined);
|
|
285
288
|
const snapshot = {
|
|
286
289
|
outputPreview: bounded.text,
|
|
287
290
|
truncated: bounded.truncated || inputOutput.length > 10_000,
|
|
288
291
|
displayOutput,
|
|
289
|
-
processId: output.processId
|
|
292
|
+
processId: output.processId,
|
|
293
|
+
...(event.outputTruncation ? { outputTruncation: event.outputTruncation } : {})
|
|
290
294
|
};
|
|
291
295
|
if (parentCallId !== undefined && (toolName === 'exec' || toolName === 'exec_wait'))
|
|
292
296
|
return this.#codeModeToolOutput(callId, parentCallId, toolName, executionId, turnId, output.processId, snapshot);
|
|
@@ -309,7 +313,7 @@ export class MarAgentConversationNormalizer {
|
|
|
309
313
|
displayOutput: snapshot.displayOutput,
|
|
310
314
|
outputHeadTruncated: snapshot.displayOutput.stdoutDroppedBytes > 0 ||
|
|
311
315
|
snapshot.displayOutput.stderrDroppedBytes > 0
|
|
312
|
-
})
|
|
316
|
+
}, undefined, undefined, undefined, event.outputTruncation, state.inputTruncated)
|
|
313
317
|
];
|
|
314
318
|
}
|
|
315
319
|
const command = this.#commands.get(state.commandOrigin);
|
|
@@ -320,6 +324,10 @@ export class MarAgentConversationNormalizer {
|
|
|
320
324
|
command.displayOutput = display;
|
|
321
325
|
command.outputPreview = snapshot.outputPreview;
|
|
322
326
|
command.truncated = snapshot.truncated;
|
|
327
|
+
if (event.outputTruncation)
|
|
328
|
+
command.outputTruncation = event.outputTruncation;
|
|
329
|
+
else
|
|
330
|
+
delete command.outputTruncation;
|
|
323
331
|
return [commandItem(command, 'IN_PROGRESS')];
|
|
324
332
|
}
|
|
325
333
|
#toolOutputDelta(event) {
|
|
@@ -375,26 +383,11 @@ export class MarAgentConversationNormalizer {
|
|
|
375
383
|
const command = target.commandOrigin === undefined ? undefined : this.#commands.get(target.commandOrigin);
|
|
376
384
|
const item = command
|
|
377
385
|
? commandItem(command, 'IN_PROGRESS')
|
|
378
|
-
: genericToolItem(target.itemId, target.toolName, 'IN_PROGRESS', target.input, null, null);
|
|
379
|
-
const original = record(record(item.payload.toolPresentation)?.execution);
|
|
386
|
+
: genericToolItem(target.itemId, target.toolName, 'IN_PROGRESS', target.input, null, null, false, undefined, undefined, undefined, undefined, undefined, target.inputTruncated);
|
|
380
387
|
const blocks = [
|
|
381
388
|
...(output.stdout ? [{ channel: 'STDOUT', text: output.stdout }] : []),
|
|
382
389
|
...(output.stderr ? [{ channel: 'STDERR', text: output.stderr }] : [])
|
|
383
390
|
];
|
|
384
|
-
const text = [output.stdout, output.stderr].filter(Boolean).join('\n');
|
|
385
|
-
const boundedText = publicOutputSnapshot(text, output.truncated);
|
|
386
|
-
const bounded = boundExecutionPresentation({
|
|
387
|
-
kind: parentCallId !== undefined
|
|
388
|
-
? target.toolName === 'code_exec'
|
|
389
|
-
? 'CODE'
|
|
390
|
-
: 'CONTROL'
|
|
391
|
-
: toolName === 'exec'
|
|
392
|
-
? 'SHELL'
|
|
393
|
-
: 'CONTROL',
|
|
394
|
-
...(typeof original?.toolName === 'string' ? { toolName: original.toolName } : {}),
|
|
395
|
-
output: blocks,
|
|
396
|
-
...(output.truncated ? { truncation: { output: 'HEAD' } } : {})
|
|
397
|
-
});
|
|
398
391
|
return [
|
|
399
392
|
{
|
|
400
393
|
...item,
|
|
@@ -402,9 +395,7 @@ export class MarAgentConversationNormalizer {
|
|
|
402
395
|
merge: true,
|
|
403
396
|
payload: {
|
|
404
397
|
...item.payload,
|
|
405
|
-
|
|
406
|
-
output: boundedText,
|
|
407
|
-
toolPresentation: bounded.presentation
|
|
398
|
+
output: boundToolOutput(blocks, event.outputTruncation)
|
|
408
399
|
}
|
|
409
400
|
}
|
|
410
401
|
];
|
|
@@ -458,7 +449,13 @@ export class MarAgentConversationNormalizer {
|
|
|
458
449
|
.filter(Boolean)
|
|
459
450
|
.join('')
|
|
460
451
|
}
|
|
461
|
-
})
|
|
452
|
+
}, undefined, undefined, undefined, entries.some((entry) => entry.outputTruncation === 'SOURCE')
|
|
453
|
+
? 'SOURCE'
|
|
454
|
+
: entries.some((entry) => entry.outputTruncation === 'HEAD' ||
|
|
455
|
+
entry.displayOutput.stdoutDroppedBytes > 0 ||
|
|
456
|
+
entry.displayOutput.stderrDroppedBytes > 0)
|
|
457
|
+
? 'HEAD'
|
|
458
|
+
: undefined, target.inputTruncated)
|
|
462
459
|
];
|
|
463
460
|
}
|
|
464
461
|
#trackCodeModeOutputCall(event) {
|
|
@@ -626,9 +623,13 @@ export class MarAgentConversationNormalizer {
|
|
|
626
623
|
const state = this.#tools.get(event.callId);
|
|
627
624
|
if (event.toolName === 'exec' && state?.commandOrigin !== undefined) {
|
|
628
625
|
const command = this.#commands.get(state.commandOrigin);
|
|
629
|
-
const result = execResult(event.data, event.summary, event.
|
|
626
|
+
const result = execResult(event.data, event.summary, event.outputTruncation !== undefined);
|
|
630
627
|
if (command !== undefined && result !== undefined) {
|
|
631
628
|
applyCommandResult(command, result);
|
|
629
|
+
if (event.outputTruncation)
|
|
630
|
+
command.outputTruncation = event.outputTruncation;
|
|
631
|
+
else
|
|
632
|
+
delete command.outputTruncation;
|
|
632
633
|
const data = record(event.data);
|
|
633
634
|
const display = execDisplayOutput(data?.displayOutput);
|
|
634
635
|
if (display !== undefined)
|
|
@@ -672,7 +673,7 @@ export class MarAgentConversationNormalizer {
|
|
|
672
673
|
}
|
|
673
674
|
const item = genericToolItem(state?.itemId ?? itemId('tool', event.callId), event.toolName, 'COMPLETED', state?.input, generatedImages.length === 0
|
|
674
675
|
? event.summary
|
|
675
|
-
: generatedImages.map((image) => image.name).join(', '), null, event.
|
|
676
|
+
: generatedImages.map((image) => image.name).join(', '), null, event.outputTruncation !== undefined, event.data, agentId === undefined ? state?.subagentTitle : this.#subagentTitles.get(agentId), details, state?.sleepStartedAt, event.outputTruncation, state?.inputTruncated, event.summaryTruncated === true);
|
|
676
677
|
return [
|
|
677
678
|
{
|
|
678
679
|
...item,
|
|
@@ -703,7 +704,7 @@ export class MarAgentConversationNormalizer {
|
|
|
703
704
|
return [
|
|
704
705
|
genericToolItem(state?.itemId ?? itemId('tool', event.callId), event.toolName, event.code === 'MAR_AGENT_CANCELLED' || event.code === 'MAR_AGENT_EXECUTION_CANCELLED'
|
|
705
706
|
? 'CANCELLED'
|
|
706
|
-
: 'FAILED', state?.input, event.message ?? event.code, event.code, event.truncated === true, state?.presentationData, state?.subagentTitle, state?.subagentDetails, state?.sleepStartedAt)
|
|
707
|
+
: 'FAILED', state?.input, event.message ?? event.code, event.code, event.truncated === true, state?.presentationData, state?.subagentTitle, state?.subagentDetails, state?.sleepStartedAt, event.outputTruncation, state?.inputTruncated)
|
|
707
708
|
];
|
|
708
709
|
}
|
|
709
710
|
#codeModeToolResults(event) {
|
|
@@ -1026,33 +1027,30 @@ function codeExecutionError(data) {
|
|
|
1026
1027
|
message: compactRunnerText(error.message, 1000)
|
|
1027
1028
|
};
|
|
1028
1029
|
}
|
|
1029
|
-
function genericToolItem(id, toolName, status, input, outputSummary = null, errorCode = null, truncated = false, output, subagentTitle, knownSubagentDetails, sleepStartedAt) {
|
|
1030
|
+
function genericToolItem(id, toolName, status, input, outputSummary = null, errorCode = null, truncated = false, output, subagentTitle, knownSubagentDetails, sleepStartedAt, outputTruncation, inputTruncated = false, summaryTruncated = false) {
|
|
1030
1031
|
if (toolName === 'code_exec') {
|
|
1031
1032
|
const code = typeof input === 'string' ? input : record(input)?.code;
|
|
1032
1033
|
const source = typeof code === 'string' ? code : compactRunnerValue(input, 10_000).text || toolName;
|
|
1033
1034
|
const resultData = record(output);
|
|
1034
|
-
const codeOutput = codeObservationOutput(resultData,
|
|
1035
|
+
const codeOutput = codeObservationOutput(resultData, null);
|
|
1035
1036
|
const resultError = codeExecutionError(resultData);
|
|
1036
1037
|
const preview = errorCode === null
|
|
1037
1038
|
? (outputSummary ?? '')
|
|
1038
1039
|
: [errorCode, outputSummary].filter(Boolean).join(': ');
|
|
1039
|
-
|
|
1040
|
+
const item = commandItem({
|
|
1040
1041
|
itemId: id,
|
|
1041
1042
|
command: compactRunnerText(source, 10_000),
|
|
1042
1043
|
cwd: null,
|
|
1043
|
-
outputPreview:
|
|
1044
|
+
outputPreview: '',
|
|
1044
1045
|
exitCode: null,
|
|
1045
|
-
truncated: truncated ||
|
|
1046
|
-
resultData?.truncated === true ||
|
|
1047
|
-
source.length > 10_000 ||
|
|
1048
|
-
preview.length > 10_000
|
|
1046
|
+
truncated: truncated || source.length > 10_000 || preview.length > 10_000
|
|
1049
1047
|
}, status, 'Code execution', {
|
|
1050
1048
|
kind: 'CODE',
|
|
1051
|
-
...(source.length > 10_000 ||
|
|
1049
|
+
...(source.length > 10_000 || inputTruncated || outputTruncation !== undefined
|
|
1052
1050
|
? {
|
|
1053
1051
|
truncation: {
|
|
1054
|
-
...(source.length > 10_000 ? { input: true } : {}),
|
|
1055
|
-
...(
|
|
1052
|
+
...(source.length > 10_000 || inputTruncated ? { input: true } : {}),
|
|
1053
|
+
...(outputTruncation === undefined ? {} : { output: outputTruncation })
|
|
1056
1054
|
}
|
|
1057
1055
|
}
|
|
1058
1056
|
: {}),
|
|
@@ -1068,6 +1066,12 @@ function genericToolItem(id, toolName, status, input, outputSummary = null, erro
|
|
|
1068
1066
|
}),
|
|
1069
1067
|
...(codeOutput === undefined ? {} : { output: codeOutput })
|
|
1070
1068
|
}, toolName);
|
|
1069
|
+
if (codeOutput === undefined && errorCode === null && outputSummary !== null) {
|
|
1070
|
+
item.payload.outputSummary = compactRunnerText(outputSummary, 10_000);
|
|
1071
|
+
if (summaryTruncated || outputSummary.length > 10_000)
|
|
1072
|
+
item.payload.outputSummaryTruncated = true;
|
|
1073
|
+
}
|
|
1074
|
+
return item;
|
|
1071
1075
|
}
|
|
1072
1076
|
if (toolName === 'code_exec_wait' || toolName === 'exec_wait') {
|
|
1073
1077
|
const inputRecord = record(input);
|
|
@@ -1081,40 +1085,17 @@ function genericToolItem(id, toolName, status, input, outputSummary = null, erro
|
|
|
1081
1085
|
? [{ channel: 'STDERR', text: resultData.stderr }]
|
|
1082
1086
|
: [])
|
|
1083
1087
|
];
|
|
1084
|
-
const codeOutput = toolName === 'code_exec_wait' ? codeObservationOutput(resultData,
|
|
1088
|
+
const codeOutput = toolName === 'code_exec_wait' ? codeObservationOutput(resultData, null) : undefined;
|
|
1085
1089
|
const resultError = toolName === 'code_exec_wait' ? codeExecutionError(resultData) : undefined;
|
|
1086
1090
|
const action = typeof inputRecord?.action === 'string' ? inputRecord.action : 'poll';
|
|
1087
1091
|
const inputSummary = compactRunnerValue(input, 10_000);
|
|
1088
|
-
const
|
|
1089
|
-
const resultSummary = [outputSummary, result?.text]
|
|
1090
|
-
.filter((value, index, values) => typeof value === 'string' && value.length > 0 && values.indexOf(value) === index)
|
|
1091
|
-
.join('\n');
|
|
1092
|
-
const details = [
|
|
1093
|
-
`Action: ${compactRunnerText(action, 128)}`,
|
|
1094
|
-
`Input: ${inputSummary.text || '{}'}`,
|
|
1095
|
-
resultSummary.length === 0 ? '' : `Result: ${compactRunnerText(resultSummary, 10_000)}`,
|
|
1096
|
-
errorCode === null ? '' : `Error: ${compactRunnerText(errorCode, 80)}`
|
|
1097
|
-
]
|
|
1098
|
-
.filter(Boolean)
|
|
1099
|
-
.join('\n');
|
|
1100
|
-
return commandItem({
|
|
1092
|
+
const item = commandItem({
|
|
1101
1093
|
itemId: id,
|
|
1102
1094
|
command: '',
|
|
1103
1095
|
cwd: null,
|
|
1104
|
-
outputPreview:
|
|
1105
|
-
? outputSummary
|
|
1106
|
-
: legacyBlocks.length > 0
|
|
1107
|
-
? legacyBlocks
|
|
1108
|
-
.map((block) => block.text)
|
|
1109
|
-
.filter(Boolean)
|
|
1110
|
-
.join('\n')
|
|
1111
|
-
: details,
|
|
1096
|
+
outputPreview: '',
|
|
1112
1097
|
exitCode: typeof resultData?.exitCode === 'number' ? resultData.exitCode : null,
|
|
1113
|
-
truncated: truncated ||
|
|
1114
|
-
resultData?.truncated === true ||
|
|
1115
|
-
inputSummary.truncated ||
|
|
1116
|
-
result?.truncated === true ||
|
|
1117
|
-
resultSummary.length > 10_000
|
|
1098
|
+
truncated: truncated || inputSummary.truncated
|
|
1118
1099
|
}, status, toolName === 'code_exec_wait' ? 'Code execution wait' : 'Command wait', {
|
|
1119
1100
|
kind: 'CONTROL',
|
|
1120
1101
|
toolName,
|
|
@@ -1135,21 +1116,21 @@ function genericToolItem(id, toolName, status, input, outputSummary = null, erro
|
|
|
1135
1116
|
}),
|
|
1136
1117
|
...(display === undefined && legacyBlocks.length > 0 ? { output: legacyBlocks } : {}),
|
|
1137
1118
|
...(codeOutput === undefined ? {} : { output: codeOutput }),
|
|
1138
|
-
...(
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
(display
|
|
1119
|
+
...(inputTruncated ||
|
|
1120
|
+
(typeof inputRecord?.data === 'string' && inputRecord.data.length > 10_000) ||
|
|
1121
|
+
outputTruncation !== undefined ||
|
|
1122
|
+
(display !== undefined && (display.stdoutDroppedBytes || display.stderrDroppedBytes))
|
|
1142
1123
|
? {
|
|
1143
1124
|
truncation: {
|
|
1144
|
-
...(
|
|
1125
|
+
...(inputTruncated ||
|
|
1126
|
+
(typeof inputRecord?.data === 'string' && inputRecord.data.length > 10_000)
|
|
1145
1127
|
? { input: true }
|
|
1146
1128
|
: {}),
|
|
1147
|
-
...(
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
? { output: 'SOURCE' }
|
|
1129
|
+
...(outputTruncation !== undefined
|
|
1130
|
+
? { output: outputTruncation }
|
|
1131
|
+
: display !== undefined &&
|
|
1132
|
+
(display.stdoutDroppedBytes || display.stderrDroppedBytes)
|
|
1133
|
+
? { output: 'HEAD' }
|
|
1153
1134
|
: {})
|
|
1154
1135
|
}
|
|
1155
1136
|
}
|
|
@@ -1165,8 +1146,32 @@ function genericToolItem(id, toolName, status, input, outputSummary = null, erro
|
|
|
1165
1146
|
}
|
|
1166
1147
|
})
|
|
1167
1148
|
});
|
|
1149
|
+
if (display === undefined &&
|
|
1150
|
+
legacyBlocks.length === 0 &&
|
|
1151
|
+
codeOutput === undefined &&
|
|
1152
|
+
errorCode === null &&
|
|
1153
|
+
outputSummary !== null) {
|
|
1154
|
+
item.payload.outputSummary = compactRunnerText(outputSummary, 10_000);
|
|
1155
|
+
if (summaryTruncated || outputSummary.length > 10_000)
|
|
1156
|
+
item.payload.outputSummaryTruncated = true;
|
|
1157
|
+
}
|
|
1158
|
+
return item;
|
|
1168
1159
|
}
|
|
1169
1160
|
const subagent = marAgentSubagentProjection(toolName, input, output, subagentTitle, knownSubagentDetails);
|
|
1161
|
+
const agentOperation = agentOperationPresentation(toolName, input, output);
|
|
1162
|
+
if (agentOperation &&
|
|
1163
|
+
record(output)?.agentOperation === undefined &&
|
|
1164
|
+
typeof subagent?.subagentId === 'string') {
|
|
1165
|
+
agentOperation.targets = [
|
|
1166
|
+
{
|
|
1167
|
+
agentId: subagent.subagentId,
|
|
1168
|
+
...(typeof subagent.subagentSessionId === 'string'
|
|
1169
|
+
? { sessionId: subagent.subagentSessionId }
|
|
1170
|
+
: {}),
|
|
1171
|
+
...(typeof subagent.title === 'string' ? { title: subagent.title } : {})
|
|
1172
|
+
}
|
|
1173
|
+
];
|
|
1174
|
+
}
|
|
1170
1175
|
const toolCategory = isImageGenerationTool(toolName) ? 'IMAGE_GENERATION' : undefined;
|
|
1171
1176
|
const presentation = projectToolPresentation(toolName, input, output, sleepStartedAt);
|
|
1172
1177
|
const inputSummary = compactRunnerValue(input, 10_000);
|
|
@@ -1179,13 +1184,20 @@ function genericToolItem(id, toolName, status, input, outputSummary = null, erro
|
|
|
1179
1184
|
toolName: compactRunnerText(toolName, 128) || 'unknown',
|
|
1180
1185
|
title: compactRunnerText(toolName, 500) || 'unknown',
|
|
1181
1186
|
inputSummary: inputSummary.text || null,
|
|
1182
|
-
outputSummary:
|
|
1183
|
-
...(
|
|
1187
|
+
outputSummary: typeof output === 'string' || errorCode !== null ? null : outputSummary,
|
|
1188
|
+
...(typeof output === 'string' ? { output: publicToolOutput(output, outputTruncation) } : {}),
|
|
1189
|
+
...(typeof output !== 'string' && outputSummary !== null && summaryTruncated
|
|
1190
|
+
? { outputSummaryTruncated: true }
|
|
1191
|
+
: {}),
|
|
1184
1192
|
progressLabel: status === 'IN_PROGRESS' ? 'Running' : null,
|
|
1185
1193
|
errorCode: errorCode === null ? null : compactRunnerText(errorCode, 80),
|
|
1186
|
-
|
|
1194
|
+
...(errorCode !== null && outputSummary
|
|
1195
|
+
? { errorMessage: compactRunnerText(outputSummary, 1000) }
|
|
1196
|
+
: {}),
|
|
1197
|
+
...(inputTruncated || inputSummary.truncated ? { inputTruncated: true } : {}),
|
|
1187
1198
|
...(toolCategory === undefined ? {} : { toolCategory }),
|
|
1188
1199
|
...(presentation === undefined ? {} : { toolPresentation: presentation }),
|
|
1200
|
+
...(agentOperation === undefined ? {} : { agentOperation }),
|
|
1189
1201
|
...subagent
|
|
1190
1202
|
},
|
|
1191
1203
|
merge: true
|
|
@@ -1294,7 +1306,14 @@ function commandItem(command, status, title, execution, toolName = 'exec') {
|
|
|
1294
1306
|
]
|
|
1295
1307
|
})
|
|
1296
1308
|
};
|
|
1297
|
-
const
|
|
1309
|
+
const { output: detailOutput, truncation, ...executionMetadata } = detail;
|
|
1310
|
+
const blocks = detailOutput ??
|
|
1311
|
+
(!detail.error && command.outputPreview
|
|
1312
|
+
? [{ channel: 'COMBINED', text: command.outputPreview }]
|
|
1313
|
+
: undefined);
|
|
1314
|
+
const output = blocks === undefined
|
|
1315
|
+
? undefined
|
|
1316
|
+
: boundToolOutput(blocks, command.outputTruncation ?? truncation?.output);
|
|
1298
1317
|
return {
|
|
1299
1318
|
itemId: command.itemId,
|
|
1300
1319
|
kind: 'command_execution',
|
|
@@ -1303,22 +1322,17 @@ function commandItem(command, status, title, execution, toolName = 'exec') {
|
|
|
1303
1322
|
...(title === undefined ? {} : { title }),
|
|
1304
1323
|
command: command.command,
|
|
1305
1324
|
cwd: command.cwd,
|
|
1306
|
-
|
|
1307
|
-
output: {
|
|
1308
|
-
text: publicOutputSnapshot(bounded.presentation.execution.output
|
|
1309
|
-
?.map((block) => block.text)
|
|
1310
|
-
.filter(Boolean)
|
|
1311
|
-
.join('\n') ?? command.outputPreview).text,
|
|
1312
|
-
truncated: command.truncated || bounded.truncated
|
|
1313
|
-
},
|
|
1325
|
+
...(output === undefined ? {} : { output }),
|
|
1314
1326
|
exitCode: command.exitCode,
|
|
1315
1327
|
durationMs: null,
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1328
|
+
toolPresentation: {
|
|
1329
|
+
kind: 'EXECUTION',
|
|
1330
|
+
execution: {
|
|
1331
|
+
toolName,
|
|
1332
|
+
...executionMetadata,
|
|
1333
|
+
...(truncation?.input ? { truncation: { input: true } } : {})
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1322
1336
|
},
|
|
1323
1337
|
merge: true
|
|
1324
1338
|
};
|
|
@@ -1421,8 +1435,8 @@ function execResult(value, summary, eventTruncated = false) {
|
|
|
1421
1435
|
...(exitCode === undefined ? {} : { exitCode }),
|
|
1422
1436
|
...(data?.cached === true || summaryData?.cached === true ? { cached: true } : {}),
|
|
1423
1437
|
truncated: eventTruncated ||
|
|
1424
|
-
data?.truncated === true ||
|
|
1425
|
-
summaryData?.truncated === true ||
|
|
1438
|
+
(execDisplayOutput(data?.displayOutput) === undefined && data?.truncated === true) ||
|
|
1439
|
+
(data === undefined && summaryData?.truncated === true) ||
|
|
1426
1440
|
structuredSummaryIncomplete
|
|
1427
1441
|
};
|
|
1428
1442
|
}
|
|
@@ -1458,14 +1472,11 @@ function marAgentSubagentProjection(toolName, input, output, knownTitle, knownDe
|
|
|
1458
1472
|
...(title.length === 0 ? {} : { title }),
|
|
1459
1473
|
...subagentPayload(details),
|
|
1460
1474
|
...(typeof details.latestMessage?.text === 'string'
|
|
1461
|
-
? {
|
|
1462
|
-
outputSummary: boundedToolSummary(details.latestMessage.text),
|
|
1463
|
-
output: publicOutputSnapshot(details.latestMessage.text, details.latestMessage.truncated === true)
|
|
1464
|
-
}
|
|
1475
|
+
? { outputSummary: null, output: undefined }
|
|
1465
1476
|
: typeof outputData?.errorMessage === 'string'
|
|
1466
1477
|
? {
|
|
1467
|
-
outputSummary:
|
|
1468
|
-
output:
|
|
1478
|
+
outputSummary: null,
|
|
1479
|
+
output: publicToolOutput(outputData.errorMessage)
|
|
1469
1480
|
}
|
|
1470
1481
|
: {}),
|
|
1471
1482
|
...(typeof outputData?.errorCode === 'string'
|
|
@@ -240,19 +240,24 @@ export class MarAgentSessionRuntimeRegistry {
|
|
|
240
240
|
throw failure.reason;
|
|
241
241
|
}
|
|
242
242
|
async #destroyRuntime(runtime, aliases, reason, runId, changedCategories = []) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
243
|
+
try {
|
|
244
|
+
nodeLog('runner.mar-agent.runtime.releasing', {
|
|
245
|
+
runtimeId: runtime.runtimeId,
|
|
246
|
+
sessionId: runtime.session.id,
|
|
247
|
+
reason,
|
|
248
|
+
...(runId === undefined ? {} : { runId }),
|
|
249
|
+
...(changedCategories.length === 0 ? {} : { changedCategories })
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
// Resource release must not depend on a writable diagnostic sink.
|
|
254
|
+
}
|
|
250
255
|
const results = await Promise.allSettled([
|
|
251
256
|
this.#releaseComputerAliases(new Set([...aliases, runtime.session.id]))
|
|
252
257
|
]);
|
|
253
258
|
results.push(...(await Promise.allSettled([releaseSessionRuntime(runtime)])));
|
|
254
259
|
const failures = results.filter((result) => result.status === 'rejected');
|
|
255
|
-
if (failures.length >
|
|
260
|
+
if (failures.length > 0)
|
|
256
261
|
this.#logCleanupFailure(runtime.session.id);
|
|
257
262
|
if (failures[0]?.status === 'rejected')
|
|
258
263
|
throw failures[0].reason;
|
|
@@ -263,9 +268,14 @@ export class MarAgentSessionRuntimeRegistry {
|
|
|
263
268
|
this.#entries.delete(alias);
|
|
264
269
|
}
|
|
265
270
|
#logCleanupFailure(sessionId) {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
271
|
+
try {
|
|
272
|
+
nodeLog('runner.mar-agent.runtime.cleanup_failed', {
|
|
273
|
+
sessionId,
|
|
274
|
+
code: 'MAR_AGENT_RUNTIME_CLEANUP_FAILED'
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
// Keep the original cleanup error when the diagnostic sink is unavailable.
|
|
279
|
+
}
|
|
270
280
|
}
|
|
271
281
|
}
|
|
@@ -185,25 +185,30 @@ export async function reconfigureSessionRuntime(existing, input, modelFactory) {
|
|
|
185
185
|
}
|
|
186
186
|
export async function releaseSessionRuntime(runtime) {
|
|
187
187
|
const failures = [];
|
|
188
|
-
for (const cleanup of [
|
|
189
|
-
() => runtime.agent.dispose(),
|
|
190
|
-
() => runtime.releaseNetworkContext?.(),
|
|
191
|
-
() => runtime.mcpLease.release(),
|
|
192
|
-
() => runtime.releaseEnvironment?.()
|
|
188
|
+
for (const [resource, cleanup] of [
|
|
189
|
+
['agent', () => runtime.agent.dispose()],
|
|
190
|
+
['network', () => runtime.releaseNetworkContext?.()],
|
|
191
|
+
['mcp', () => runtime.mcpLease.release()],
|
|
192
|
+
['environment', () => runtime.releaseEnvironment?.()]
|
|
193
193
|
]) {
|
|
194
194
|
try {
|
|
195
195
|
await cleanup();
|
|
196
196
|
}
|
|
197
197
|
catch (error) {
|
|
198
198
|
failures.push(error);
|
|
199
|
+
try {
|
|
200
|
+
nodeLog('runner.mar-agent.runtime.cleanup_failed', {
|
|
201
|
+
sessionId: runtime.session.id,
|
|
202
|
+
code: 'MAR_AGENT_RUNTIME_CLEANUP_FAILED',
|
|
203
|
+
stage: 'resource_release',
|
|
204
|
+
resource
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
// Keep releasing resources even when the diagnostic sink is unavailable.
|
|
209
|
+
}
|
|
199
210
|
}
|
|
200
211
|
}
|
|
201
|
-
if (failures.length > 1)
|
|
202
|
-
nodeLog('runner.mar-agent.runtime.cleanup_failed', {
|
|
203
|
-
sessionId: runtime.session.id,
|
|
204
|
-
code: 'MAR_AGENT_RUNTIME_CLEANUP_FAILED',
|
|
205
|
-
stage: 'resource_release'
|
|
206
|
-
});
|
|
207
212
|
if (failures.length > 0)
|
|
208
213
|
throw failures[0];
|
|
209
214
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { boundToolOutput } from '@myagentroam/protocol';
|
|
1
2
|
export function compactRunnerText(value, limit) {
|
|
2
3
|
return value.length <= limit ? value : `${value.slice(0, Math.max(0, limit - 1))}…`;
|
|
3
4
|
}
|
|
@@ -9,6 +10,10 @@ export function publicOutputSnapshot(value, truncated = false) {
|
|
|
9
10
|
bounded = bounded.slice(1);
|
|
10
11
|
return { text: bounded, truncated: truncated || text.length > 10_000 };
|
|
11
12
|
}
|
|
13
|
+
export function publicToolOutput(value, truncation, channel = 'TEXT') {
|
|
14
|
+
const text = typeof value === 'string' ? value : compactRunnerValue(value, Number.MAX_SAFE_INTEGER).text;
|
|
15
|
+
return boundToolOutput(text ? [{ channel, text }] : [], truncation);
|
|
16
|
+
}
|
|
12
17
|
export function compactRunnerValue(value, limit) {
|
|
13
18
|
if (value === undefined || value === null)
|
|
14
19
|
return { text: '', truncated: false };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { compactRunnerText, compactRunnerValue,
|
|
1
|
+
import { compactRunnerText, compactRunnerValue, publicToolOutput } from '../normalization.js';
|
|
2
2
|
import { shellExecution } from '../execution-presentation.js';
|
|
3
3
|
export function normalizeOpenCodeTool(toolName, state) {
|
|
4
4
|
const status = state?.status === 'completed'
|
|
@@ -21,14 +21,14 @@ export function normalizeOpenCodeTool(toolName, state) {
|
|
|
21
21
|
? input.cmd
|
|
22
22
|
: publicToolName, 10_000),
|
|
23
23
|
cwd: typeof input?.cwd === 'string' ? compactRunnerText(input.cwd, 4_096) : null,
|
|
24
|
-
outputPreview: typeof state?.output === 'string' ? compactRunnerText(state.output, 10_000) : '',
|
|
25
24
|
exitCode: typeof state?.exitCode === 'number' ? state.exitCode : null,
|
|
26
25
|
durationMs: null,
|
|
27
|
-
truncated: typeof state?.output === 'string' && state.output.length > 10_000,
|
|
28
26
|
...(typeof state?.output === 'string'
|
|
29
|
-
? { output:
|
|
27
|
+
? { output: publicToolOutput(state.output, undefined, 'COMBINED') }
|
|
30
28
|
: {}),
|
|
31
|
-
toolPresentation: shellExecution(typeof
|
|
29
|
+
toolPresentation: shellExecution((typeof input?.command === 'string' && input.command.length > 10_000) ||
|
|
30
|
+
(typeof input?.cmd === 'string' && input.cmd.length > 10_000) ||
|
|
31
|
+
(typeof input?.cwd === 'string' && input.cwd.length > 4_096))
|
|
32
32
|
}
|
|
33
33
|
};
|
|
34
34
|
return {
|
|
@@ -39,10 +39,10 @@ export function normalizeOpenCodeTool(toolName, state) {
|
|
|
39
39
|
title: compactRunnerText(typeof state?.title === 'string' ? state.title : toolName, 500) ||
|
|
40
40
|
publicToolName,
|
|
41
41
|
inputSummary: compactRunnerValue(state?.input, 10_000).text || null,
|
|
42
|
-
outputSummary:
|
|
42
|
+
outputSummary: null,
|
|
43
43
|
progressLabel: null,
|
|
44
44
|
errorCode: status === 'FAILED' ? 'OPENCODE_TOOL_FAILED' : null,
|
|
45
|
-
truncated:
|
|
45
|
+
...(compactRunnerValue(state?.input, 10_000).truncated ? { inputTruncated: true } : {}),
|
|
46
46
|
...(normalizedName === 'read'
|
|
47
47
|
? {
|
|
48
48
|
toolPresentation: {
|
|
@@ -53,7 +53,7 @@ export function normalizeOpenCodeTool(toolName, state) {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
: {}),
|
|
56
|
-
...(typeof state?.output === 'string' ? { output:
|
|
56
|
+
...(typeof state?.output === 'string' ? { output: publicToolOutput(state.output) } : {}),
|
|
57
57
|
...subagent
|
|
58
58
|
}
|
|
59
59
|
};
|
|
@@ -77,8 +77,8 @@ function openCodeSubagentProjection(toolName, input, output) {
|
|
|
77
77
|
...(nativeResult === undefined
|
|
78
78
|
? {}
|
|
79
79
|
: {
|
|
80
|
-
outputSummary:
|
|
81
|
-
output:
|
|
80
|
+
outputSummary: null,
|
|
81
|
+
output: publicToolOutput(nativeResult.result)
|
|
82
82
|
})
|
|
83
83
|
};
|
|
84
84
|
}
|