@myagentroam/node 0.11.39 → 0.11.41
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/connector.js +176 -21
- package/dist/database.js +35 -11
- package/dist/main.js +12 -1
- package/dist/marctl-guidance.js +18 -27
- package/dist/migrations/v022.js +58 -0
- package/dist/runner/abstract-runner.js +14 -0
- package/dist/runner/claude/tool-normalizer.js +6 -1
- package/dist/runner/codex/conversation-parser.js +23 -4
- package/dist/runner/codex/managed-run-controller.js +4 -2
- package/dist/runner/codex/tool-normalizer.js +9 -0
- package/dist/runner/execution-presentation.js +56 -0
- package/dist/runner/mar-agent/agent-network-extension.js +168 -0
- package/dist/runner/mar-agent/agent-network-wait-output.js +72 -0
- package/dist/runner/mar-agent/conversation-normalizer.js +232 -118
- package/dist/runner/mar-agent/managed-run-controller.js +5 -0
- package/dist/runner/mar-agent/marctl-skill.js +3 -3
- package/dist/runner/mar-agent/runtime-model-factory.js +1 -0
- package/dist/runner/mar-agent/session-runtime.js +34 -1
- package/dist/runner/mar-agent-runner.js +36 -0
- package/dist/runner/opencode/tool-normalizer.js +6 -1
- package/dist/runtime-state.js +57 -0
- package/dist/service/agent-network-bindings.js +483 -0
- package/dist/service/agent-network-goal.js +19 -0
- package/dist/service/agent-network-invoke.js +179 -0
- package/dist/service/agent-network-observations.js +377 -0
- package/dist/service/agent-network-service.js +315 -0
- package/dist/service/agent-network-wait.js +130 -0
- package/dist/service/composer-message-input.js +9 -2
- package/dist/service/continuous-run-coordinator.js +24 -1
- package/dist/service/goal-continuation-coordinator.js +12 -2
- package/dist/service/marctl-caller.js +80 -0
- package/dist/service/marctl-execution-credential-control.js +65 -0
- package/dist/service/model-usage-service.js +9 -0
- package/dist/service/node-control-message-service.js +10 -0
- package/dist/service/node-request-service.js +52 -7
- package/dist/service/node-upgrade-coordinator.js +79 -8
- package/dist/service/node-upgrade-credential-control.js +57 -0
- package/dist/service/node-upgrade-reporter.js +108 -0
- package/dist/service/run-event-service.js +8 -0
- package/dist/service/run-workbench-service.js +11 -0
- package/dist/service/supervised-node-child.js +153 -0
- package/dist/service/supervisor-upgrade-handoff.js +104 -0
- package/dist/session/native-session-projection-service.js +69 -6
- package/dist/session/operation-admission.js +7 -0
- package/dist/session/runtime/conversation-projection.js +25 -3
- package/dist/session/session-catalog-service.js +156 -32
- package/dist/session/session-lifecycle-service.js +68 -42
- package/dist/session/session-message-service.js +16 -6
- package/dist/supervisor.js +209 -20
- package/dist/terminal.js +41 -21
- package/package.json +5 -5
|
@@ -7,6 +7,7 @@ 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 { boundExecutionPresentation, publicOutputSnapshot } from '../execution-presentation.js';
|
|
10
11
|
export class MarAgentConversationNormalizer {
|
|
11
12
|
input(entry) {
|
|
12
13
|
return {
|
|
@@ -25,12 +26,10 @@ export class MarAgentConversationNormalizer {
|
|
|
25
26
|
}
|
|
26
27
|
#tools = new Map();
|
|
27
28
|
#commands = new Map();
|
|
28
|
-
#processOrigins = new Map();
|
|
29
29
|
#subagentTitles = new Map();
|
|
30
30
|
#subagentDetails = new Map();
|
|
31
31
|
#codeModeObservationIds = new Set();
|
|
32
32
|
#codeModeSourceCallIds = new Set();
|
|
33
|
-
#toolOutputSnapshots = new Map();
|
|
34
33
|
#codeModeOutputCalls = new Map();
|
|
35
34
|
#codeModeOutputSnapshots = new Map();
|
|
36
35
|
#runningCodeModeCells = new Map();
|
|
@@ -69,7 +68,8 @@ export class MarAgentConversationNormalizer {
|
|
|
69
68
|
const payload = {
|
|
70
69
|
text: event.type === 'message.completed' ? event.text : '',
|
|
71
70
|
format: 'markdown',
|
|
72
|
-
model: typeof modelName === 'string' ? modelName : null
|
|
71
|
+
model: typeof modelName === 'string' ? modelName : null,
|
|
72
|
+
phase: event.phase
|
|
73
73
|
};
|
|
74
74
|
return [
|
|
75
75
|
{
|
|
@@ -168,7 +168,6 @@ export class MarAgentConversationNormalizer {
|
|
|
168
168
|
#toolStarted(event) {
|
|
169
169
|
const ownItemId = itemId('tool', event.callId);
|
|
170
170
|
this.#clearRetainedCodeModeCellsForOtherExecutions(event.executionId);
|
|
171
|
-
this.#toolOutputSnapshots.delete(event.callId);
|
|
172
171
|
this.#codeModeOutputCalls.delete(event.callId);
|
|
173
172
|
this.#clearCodeModeOutputSnapshots(event.callId);
|
|
174
173
|
if (event.toolName === 'exec' || event.toolName === 'exec_wait') {
|
|
@@ -182,13 +181,17 @@ export class MarAgentConversationNormalizer {
|
|
|
182
181
|
if (action === 'start' && typeof input.command === 'string') {
|
|
183
182
|
const command = {
|
|
184
183
|
itemId: ownItemId,
|
|
185
|
-
turnKey: event.turnId ?? event.executionId,
|
|
186
184
|
command: compactRunnerText(input.command, 10_000),
|
|
187
185
|
cwd: typeof input.cwd === 'string' ? compactRunnerText(input.cwd, 4_096) : null,
|
|
188
186
|
status: 'IN_PROGRESS',
|
|
189
187
|
outputPreview: '',
|
|
190
188
|
exitCode: null,
|
|
191
|
-
truncated:
|
|
189
|
+
truncated: event.truncated === true ||
|
|
190
|
+
input.command.length > 10_000 ||
|
|
191
|
+
(typeof input.cwd === 'string' && input.cwd.length > 4096),
|
|
192
|
+
inputTruncated: event.truncated === true ||
|
|
193
|
+
input.command.length > 10_000 ||
|
|
194
|
+
(typeof input.cwd === 'string' && input.cwd.length > 4096)
|
|
192
195
|
};
|
|
193
196
|
this.#commands.set(event.callId, command);
|
|
194
197
|
this.#tools.set(event.callId, {
|
|
@@ -203,49 +206,6 @@ export class MarAgentConversationNormalizer {
|
|
|
203
206
|
});
|
|
204
207
|
return [commandItem(command, 'IN_PROGRESS')];
|
|
205
208
|
}
|
|
206
|
-
if ((action === 'poll' || action === 'write' || action === 'cancel') &&
|
|
207
|
-
typeof input.processId === 'string') {
|
|
208
|
-
const origin = this.#processOrigins.get(input.processId);
|
|
209
|
-
if (origin !== undefined) {
|
|
210
|
-
const previous = this.#commands.get(origin);
|
|
211
|
-
const sameTurn = previous?.turnKey === (event.turnId ?? event.executionId);
|
|
212
|
-
if (previous !== undefined && !sameTurn) {
|
|
213
|
-
const command = {
|
|
214
|
-
itemId: ownItemId,
|
|
215
|
-
turnKey: event.turnId ?? event.executionId,
|
|
216
|
-
command: previous.command,
|
|
217
|
-
cwd: previous.cwd,
|
|
218
|
-
status: 'IN_PROGRESS',
|
|
219
|
-
outputPreview: '',
|
|
220
|
-
exitCode: null,
|
|
221
|
-
truncated: false
|
|
222
|
-
};
|
|
223
|
-
this.#commands.set(event.callId, command);
|
|
224
|
-
this.#tools.set(event.callId, {
|
|
225
|
-
toolName: event.toolName,
|
|
226
|
-
input: event.input,
|
|
227
|
-
itemId: ownItemId,
|
|
228
|
-
structured: true,
|
|
229
|
-
executionId: event.executionId,
|
|
230
|
-
...(event.turnId === undefined ? {} : { turnId: event.turnId }),
|
|
231
|
-
active: true,
|
|
232
|
-
commandOrigin: event.callId
|
|
233
|
-
});
|
|
234
|
-
return [];
|
|
235
|
-
}
|
|
236
|
-
this.#tools.set(event.callId, {
|
|
237
|
-
toolName: event.toolName,
|
|
238
|
-
input: event.input,
|
|
239
|
-
itemId: ownItemId,
|
|
240
|
-
structured: true,
|
|
241
|
-
executionId: event.executionId,
|
|
242
|
-
...(event.turnId === undefined ? {} : { turnId: event.turnId }),
|
|
243
|
-
active: true,
|
|
244
|
-
commandOrigin: origin
|
|
245
|
-
});
|
|
246
|
-
return [];
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
209
|
}
|
|
250
210
|
const agentId = isMarAgentControlTool(event.toolName)
|
|
251
211
|
? marAgentAgentId(event.input)
|
|
@@ -275,9 +235,20 @@ export class MarAgentConversationNormalizer {
|
|
|
275
235
|
#toolOutput(event) {
|
|
276
236
|
const { callId, toolName, executionId, turnId, parentCallId, output } = event;
|
|
277
237
|
const inputOutput = [output.stdout, output.stderr].filter(Boolean).join('\n');
|
|
238
|
+
const displayOutput = execDisplayOutput(output.displayOutput) ?? {
|
|
239
|
+
stdout: output.stdout,
|
|
240
|
+
stderr: output.stderr,
|
|
241
|
+
stdoutDroppedBytes: 0,
|
|
242
|
+
stderrDroppedBytes: 0
|
|
243
|
+
};
|
|
244
|
+
const displayed = [displayOutput.stdout, displayOutput.stderr].filter(Boolean).join('\n');
|
|
245
|
+
const bounded = publicOutputSnapshot(displayed, output.truncated ||
|
|
246
|
+
displayOutput.stdoutDroppedBytes > 0 ||
|
|
247
|
+
displayOutput.stderrDroppedBytes > 0);
|
|
278
248
|
const snapshot = {
|
|
279
|
-
outputPreview:
|
|
280
|
-
truncated:
|
|
249
|
+
outputPreview: bounded.text,
|
|
250
|
+
truncated: bounded.truncated || inputOutput.length > 10_000,
|
|
251
|
+
displayOutput
|
|
281
252
|
};
|
|
282
253
|
if (parentCallId !== undefined)
|
|
283
254
|
return this.#codeModeToolOutput(callId, parentCallId, toolName, executionId, turnId, output.processId, snapshot);
|
|
@@ -295,19 +266,18 @@ export class MarAgentConversationNormalizer {
|
|
|
295
266
|
if (toolName !== 'exec_wait')
|
|
296
267
|
return [];
|
|
297
268
|
return [
|
|
298
|
-
genericToolItem(state.itemId, toolName, 'IN_PROGRESS', state.input, snapshot.outputPreview, null, snapshot.truncated)
|
|
269
|
+
genericToolItem(state.itemId, toolName, 'IN_PROGRESS', state.input, snapshot.outputPreview, null, snapshot.truncated, { processId: output.processId, displayOutput: snapshot.displayOutput })
|
|
299
270
|
];
|
|
300
271
|
}
|
|
301
272
|
const command = this.#commands.get(state.commandOrigin);
|
|
302
273
|
if (command === undefined || command.status !== 'IN_PROGRESS')
|
|
303
274
|
return [];
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
];
|
|
275
|
+
const display = snapshot.displayOutput;
|
|
276
|
+
if (display !== undefined)
|
|
277
|
+
command.displayOutput = display;
|
|
278
|
+
command.outputPreview = snapshot.outputPreview;
|
|
279
|
+
command.truncated = snapshot.truncated;
|
|
280
|
+
return [commandItem(command, 'IN_PROGRESS')];
|
|
311
281
|
}
|
|
312
282
|
#codeModeToolOutput(callId, parentCallId, toolName, executionId, turnId, processId, snapshot) {
|
|
313
283
|
const parent = this.#tools.get(parentCallId);
|
|
@@ -339,9 +309,9 @@ export class MarAgentConversationNormalizer {
|
|
|
339
309
|
.map((entry) => entry.outputPreview)
|
|
340
310
|
.filter(Boolean)
|
|
341
311
|
.join('\n');
|
|
342
|
-
const
|
|
312
|
+
const bounded = publicOutputSnapshot(combined, [...snapshots.values()].some((entry) => entry.truncated));
|
|
343
313
|
return [
|
|
344
|
-
genericToolItem(target.itemId, target.toolName, 'IN_PROGRESS', target.input,
|
|
314
|
+
genericToolItem(target.itemId, target.toolName, 'IN_PROGRESS', target.input, bounded.text, null, bounded.truncated)
|
|
345
315
|
];
|
|
346
316
|
}
|
|
347
317
|
#trackCodeModeOutputCall(event) {
|
|
@@ -409,7 +379,6 @@ export class MarAgentConversationNormalizer {
|
|
|
409
379
|
const state = this.#tools.get(event.callId);
|
|
410
380
|
if (state !== undefined)
|
|
411
381
|
state.active = false;
|
|
412
|
-
this.#toolOutputSnapshots.delete(event.callId);
|
|
413
382
|
const data = record(event.data);
|
|
414
383
|
const cellId = typeof data?.cellId === 'string' ? data.cellId : undefined;
|
|
415
384
|
const status = data?.status;
|
|
@@ -468,7 +437,6 @@ export class MarAgentConversationNormalizer {
|
|
|
468
437
|
for (const [callId, state] of this.#tools)
|
|
469
438
|
if (state.executionId !== executionId) {
|
|
470
439
|
state.active = false;
|
|
471
|
-
this.#toolOutputSnapshots.delete(callId);
|
|
472
440
|
}
|
|
473
441
|
for (const [callId, state] of this.#codeModeOutputCalls)
|
|
474
442
|
if (state.executionId !== executionId)
|
|
@@ -499,21 +467,19 @@ export class MarAgentConversationNormalizer {
|
|
|
499
467
|
}
|
|
500
468
|
#toolCompleted(event) {
|
|
501
469
|
const state = this.#tools.get(event.callId);
|
|
502
|
-
if (
|
|
503
|
-
state?.commandOrigin !== undefined) {
|
|
470
|
+
if (event.toolName === 'exec' && state?.commandOrigin !== undefined) {
|
|
504
471
|
const command = this.#commands.get(state.commandOrigin);
|
|
505
472
|
const result = execResult(event.data, event.summary, event.truncated === true);
|
|
506
473
|
if (command !== undefined && result !== undefined) {
|
|
507
|
-
if (result.processId !== undefined)
|
|
508
|
-
this.#processOrigins.set(result.processId, state.commandOrigin);
|
|
509
474
|
applyCommandResult(command, result);
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
475
|
+
const data = record(event.data);
|
|
476
|
+
const display = execDisplayOutput(data?.displayOutput);
|
|
477
|
+
if (display !== undefined)
|
|
478
|
+
command.displayOutput = display;
|
|
479
|
+
else
|
|
480
|
+
delete command.displayOutput;
|
|
481
|
+
command.status = 'COMPLETED';
|
|
482
|
+
return [commandItem(command, 'COMPLETED')];
|
|
517
483
|
}
|
|
518
484
|
}
|
|
519
485
|
if (event.toolName === 'apply_patch' &&
|
|
@@ -559,16 +525,17 @@ export class MarAgentConversationNormalizer {
|
|
|
559
525
|
}
|
|
560
526
|
#toolFailed(event) {
|
|
561
527
|
const state = this.#tools.get(event.callId);
|
|
562
|
-
if (
|
|
563
|
-
state?.commandOrigin !== undefined) {
|
|
528
|
+
if (event.toolName === 'exec' && state?.commandOrigin !== undefined) {
|
|
564
529
|
const command = this.#commands.get(state.commandOrigin);
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
(input?.action == null && typeof input?.command === 'string'))) {
|
|
530
|
+
if (command !== undefined) {
|
|
531
|
+
const error = {
|
|
532
|
+
code: compactRunnerText(event.code, 80) || 'UNKNOWN',
|
|
533
|
+
message: compactRunnerText(event.message ?? event.code, 1000)
|
|
534
|
+
};
|
|
571
535
|
command.status = 'FAILED';
|
|
536
|
+
command.error = error;
|
|
537
|
+
delete command.displayOutput;
|
|
538
|
+
command.outputPreview = '';
|
|
572
539
|
return [commandItem(command, 'FAILED')];
|
|
573
540
|
}
|
|
574
541
|
}
|
|
@@ -854,24 +821,89 @@ function normalizeContextCompaction(event, anchorItemId) {
|
|
|
854
821
|
function validCompactAnchor(value) {
|
|
855
822
|
return value !== undefined && value.length > 0 && value.length <= 128 ? value : undefined;
|
|
856
823
|
}
|
|
824
|
+
function codeObservationOutput(data, summary) {
|
|
825
|
+
if (Array.isArray(data?.observations)) {
|
|
826
|
+
return data.observations
|
|
827
|
+
.flatMap((entry) => {
|
|
828
|
+
const observation = record(entry);
|
|
829
|
+
if (observation?.type === 'value' && typeof observation.value === 'string')
|
|
830
|
+
return [observation.value];
|
|
831
|
+
const result = record(observation?.result);
|
|
832
|
+
const source = record(observation?.source);
|
|
833
|
+
if (observation?.type === 'tool_result' &&
|
|
834
|
+
(source?.toolName === 'exec' || source?.toolName === 'exec_wait')) {
|
|
835
|
+
const resultData = record(result?.data);
|
|
836
|
+
const display = record(resultData?.displayOutput) ?? resultData;
|
|
837
|
+
if (typeof display?.stdout === 'string' || typeof display?.stderr === 'string')
|
|
838
|
+
return [display?.stdout, display?.stderr].filter((value) => typeof value === 'string' && value.length > 0);
|
|
839
|
+
}
|
|
840
|
+
return observation?.type === 'tool_result' && typeof result?.content === 'string'
|
|
841
|
+
? [result.content]
|
|
842
|
+
: [];
|
|
843
|
+
})
|
|
844
|
+
.join('\n');
|
|
845
|
+
}
|
|
846
|
+
return summary ?? undefined;
|
|
847
|
+
}
|
|
848
|
+
function codeExecutionError(data) {
|
|
849
|
+
const error = record(data?.error);
|
|
850
|
+
if (typeof error?.code !== 'string' || !error.code || typeof error.message !== 'string')
|
|
851
|
+
return undefined;
|
|
852
|
+
return {
|
|
853
|
+
code: compactRunnerText(error.code, 80),
|
|
854
|
+
message: compactRunnerText(error.message, 1000)
|
|
855
|
+
};
|
|
856
|
+
}
|
|
857
857
|
function genericToolItem(id, toolName, status, input, outputSummary = null, errorCode = null, truncated = false, output, subagentTitle, knownSubagentDetails, sleepStartedAt) {
|
|
858
858
|
if (toolName === 'code_exec') {
|
|
859
859
|
const code = typeof input === 'string' ? input : record(input)?.code;
|
|
860
860
|
const source = typeof code === 'string' ? code : compactRunnerValue(input, 10_000).text || toolName;
|
|
861
|
-
const
|
|
861
|
+
const resultData = record(output);
|
|
862
|
+
const codeOutput = codeObservationOutput(resultData, outputSummary);
|
|
863
|
+
const resultError = codeExecutionError(resultData);
|
|
864
|
+
const preview = errorCode === null
|
|
862
865
|
? (outputSummary ?? '')
|
|
863
866
|
: [errorCode, outputSummary].filter(Boolean).join(': ');
|
|
864
867
|
return commandItem({
|
|
865
868
|
itemId: id,
|
|
866
869
|
command: compactRunnerText(source, 10_000),
|
|
867
870
|
cwd: null,
|
|
868
|
-
outputPreview: compactRunnerText(
|
|
871
|
+
outputPreview: compactRunnerText(preview, 10_000),
|
|
869
872
|
exitCode: null,
|
|
870
|
-
truncated: truncated ||
|
|
871
|
-
|
|
873
|
+
truncated: truncated ||
|
|
874
|
+
resultData?.truncated === true ||
|
|
875
|
+
source.length > 10_000 ||
|
|
876
|
+
preview.length > 10_000
|
|
877
|
+
}, status, 'Code execution', {
|
|
878
|
+
kind: 'CODE',
|
|
879
|
+
...(source.length > 10_000 ? { truncation: { input: true } } : {}),
|
|
880
|
+
...(errorCode === null
|
|
881
|
+
? resultError === undefined
|
|
882
|
+
? {}
|
|
883
|
+
: { error: resultError }
|
|
884
|
+
: {
|
|
885
|
+
error: {
|
|
886
|
+
code: compactRunnerText(errorCode, 80),
|
|
887
|
+
message: compactRunnerText(outputSummary ?? '', 1000)
|
|
888
|
+
}
|
|
889
|
+
}),
|
|
890
|
+
...(codeOutput === undefined ? {} : { output: [{ channel: 'TEXT', text: codeOutput }] })
|
|
891
|
+
});
|
|
872
892
|
}
|
|
873
893
|
if (toolName === 'code_exec_wait' || toolName === 'exec_wait') {
|
|
874
894
|
const inputRecord = record(input);
|
|
895
|
+
const resultData = record(output);
|
|
896
|
+
const display = execDisplayOutput(resultData?.displayOutput);
|
|
897
|
+
const legacyBlocks = [
|
|
898
|
+
...(typeof resultData?.stdout === 'string'
|
|
899
|
+
? [{ channel: 'STDOUT', text: resultData.stdout }]
|
|
900
|
+
: []),
|
|
901
|
+
...(typeof resultData?.stderr === 'string'
|
|
902
|
+
? [{ channel: 'STDERR', text: resultData.stderr }]
|
|
903
|
+
: [])
|
|
904
|
+
];
|
|
905
|
+
const codeOutput = toolName === 'code_exec_wait' ? codeObservationOutput(resultData, outputSummary) : undefined;
|
|
906
|
+
const resultError = toolName === 'code_exec_wait' ? codeExecutionError(resultData) : undefined;
|
|
875
907
|
const action = typeof inputRecord?.action === 'string' ? inputRecord.action : 'poll';
|
|
876
908
|
const inputSummary = compactRunnerValue(input, 10_000);
|
|
877
909
|
const result = output === undefined ? null : compactRunnerValue(output, 10_000);
|
|
@@ -890,13 +922,62 @@ function genericToolItem(id, toolName, status, input, outputSummary = null, erro
|
|
|
890
922
|
itemId: id,
|
|
891
923
|
command: toolName,
|
|
892
924
|
cwd: null,
|
|
893
|
-
outputPreview:
|
|
894
|
-
|
|
925
|
+
outputPreview: status === 'IN_PROGRESS' && outputSummary !== null
|
|
926
|
+
? outputSummary
|
|
927
|
+
: legacyBlocks.length > 0
|
|
928
|
+
? legacyBlocks
|
|
929
|
+
.map((block) => block.text)
|
|
930
|
+
.filter(Boolean)
|
|
931
|
+
.join('\n')
|
|
932
|
+
: details,
|
|
933
|
+
exitCode: typeof resultData?.exitCode === 'number' ? resultData.exitCode : null,
|
|
895
934
|
truncated: truncated ||
|
|
935
|
+
resultData?.truncated === true ||
|
|
896
936
|
inputSummary.truncated ||
|
|
897
937
|
result?.truncated === true ||
|
|
898
938
|
resultSummary.length > 10_000
|
|
899
|
-
}, status, toolName === 'code_exec_wait' ? 'Code execution wait' : 'Command wait'
|
|
939
|
+
}, status, toolName === 'code_exec_wait' ? 'Code execution wait' : 'Command wait', {
|
|
940
|
+
kind: 'CONTROL',
|
|
941
|
+
...(display === undefined
|
|
942
|
+
? {}
|
|
943
|
+
: {
|
|
944
|
+
output: [
|
|
945
|
+
{ channel: 'STDOUT', text: display.stdout },
|
|
946
|
+
{ channel: 'STDERR', text: display.stderr }
|
|
947
|
+
]
|
|
948
|
+
}),
|
|
949
|
+
...(display === undefined && legacyBlocks.length > 0 ? { output: legacyBlocks } : {}),
|
|
950
|
+
...(codeOutput === undefined
|
|
951
|
+
? {}
|
|
952
|
+
: { output: [{ channel: 'TEXT', text: codeOutput }] }),
|
|
953
|
+
...((typeof inputRecord?.data === 'string' && inputRecord.data.length > 10_000) ||
|
|
954
|
+
(display !== undefined && (display.stdoutDroppedBytes || display.stderrDroppedBytes)) ||
|
|
955
|
+
(display === undefined && legacyBlocks.length > 0 && truncated)
|
|
956
|
+
? {
|
|
957
|
+
truncation: {
|
|
958
|
+
...(typeof inputRecord?.data === 'string' && inputRecord.data.length > 10_000
|
|
959
|
+
? { input: true }
|
|
960
|
+
: {}),
|
|
961
|
+
...(display !== undefined &&
|
|
962
|
+
(display.stdoutDroppedBytes || display.stderrDroppedBytes)
|
|
963
|
+
? { output: 'HEAD' }
|
|
964
|
+
: display === undefined && legacyBlocks.length > 0 && truncated
|
|
965
|
+
? { output: 'SOURCE' }
|
|
966
|
+
: {})
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
: {}),
|
|
970
|
+
...(errorCode === null
|
|
971
|
+
? resultError === undefined
|
|
972
|
+
? {}
|
|
973
|
+
: { error: resultError }
|
|
974
|
+
: {
|
|
975
|
+
error: {
|
|
976
|
+
code: compactRunnerText(errorCode, 80),
|
|
977
|
+
message: compactRunnerText(outputSummary ?? '', 1000)
|
|
978
|
+
}
|
|
979
|
+
})
|
|
980
|
+
});
|
|
900
981
|
}
|
|
901
982
|
const subagent = marAgentSubagentProjection(toolName, input, output, subagentTitle, knownSubagentDetails);
|
|
902
983
|
const toolCategory = isImageGenerationTool(toolName) ? 'IMAGE_GENERATION' : undefined;
|
|
@@ -965,7 +1046,50 @@ function projectToolPresentation(toolName, input, output, startedAt) {
|
|
|
965
1046
|
const parsed = toolPresentationSchema.safeParse(candidate);
|
|
966
1047
|
return parsed.success ? parsed.data : { kind };
|
|
967
1048
|
}
|
|
968
|
-
function
|
|
1049
|
+
function execDisplayOutput(value) {
|
|
1050
|
+
const data = record(value);
|
|
1051
|
+
if (typeof data?.stdout !== 'string' ||
|
|
1052
|
+
typeof data.stderr !== 'string' ||
|
|
1053
|
+
typeof data.stdoutDroppedBytes !== 'number' ||
|
|
1054
|
+
!Number.isSafeInteger(data.stdoutDroppedBytes) ||
|
|
1055
|
+
data.stdoutDroppedBytes < 0 ||
|
|
1056
|
+
typeof data.stderrDroppedBytes !== 'number' ||
|
|
1057
|
+
!Number.isSafeInteger(data.stderrDroppedBytes) ||
|
|
1058
|
+
data.stderrDroppedBytes < 0)
|
|
1059
|
+
return undefined;
|
|
1060
|
+
return {
|
|
1061
|
+
stdout: data.stdout,
|
|
1062
|
+
stderr: data.stderr,
|
|
1063
|
+
stdoutDroppedBytes: data.stdoutDroppedBytes,
|
|
1064
|
+
stderrDroppedBytes: data.stderrDroppedBytes
|
|
1065
|
+
};
|
|
1066
|
+
}
|
|
1067
|
+
function commandItem(command, status, title, execution) {
|
|
1068
|
+
const display = command.displayOutput;
|
|
1069
|
+
const detail = execution ?? {
|
|
1070
|
+
kind: 'SHELL',
|
|
1071
|
+
...(command.error === undefined ? {} : { error: command.error }),
|
|
1072
|
+
...(!command.inputTruncated &&
|
|
1073
|
+
!(display && (display.stdoutDroppedBytes > 0 || display.stderrDroppedBytes > 0))
|
|
1074
|
+
? {}
|
|
1075
|
+
: {
|
|
1076
|
+
truncation: {
|
|
1077
|
+
...(command.inputTruncated ? { input: true } : {}),
|
|
1078
|
+
...(display && (display.stdoutDroppedBytes > 0 || display.stderrDroppedBytes > 0)
|
|
1079
|
+
? { output: 'HEAD' }
|
|
1080
|
+
: {})
|
|
1081
|
+
}
|
|
1082
|
+
}),
|
|
1083
|
+
...(display === undefined
|
|
1084
|
+
? {}
|
|
1085
|
+
: {
|
|
1086
|
+
output: [
|
|
1087
|
+
{ channel: 'STDOUT', text: display.stdout },
|
|
1088
|
+
{ channel: 'STDERR', text: display.stderr }
|
|
1089
|
+
]
|
|
1090
|
+
})
|
|
1091
|
+
};
|
|
1092
|
+
const bounded = boundExecutionPresentation(detail);
|
|
969
1093
|
return {
|
|
970
1094
|
itemId: command.itemId,
|
|
971
1095
|
kind: 'command_execution',
|
|
@@ -978,37 +1102,21 @@ function commandItem(command, status, title) {
|
|
|
978
1102
|
outputRef: null,
|
|
979
1103
|
exitCode: command.exitCode,
|
|
980
1104
|
durationMs: null,
|
|
981
|
-
truncated: command.truncated
|
|
1105
|
+
truncated: command.truncated ||
|
|
1106
|
+
command.inputTruncated === true ||
|
|
1107
|
+
bounded.truncated ||
|
|
1108
|
+
(display !== undefined &&
|
|
1109
|
+
(display.stdoutDroppedBytes > 0 || display.stderrDroppedBytes > 0)),
|
|
1110
|
+
toolPresentation: bounded.presentation
|
|
982
1111
|
},
|
|
983
1112
|
merge: true
|
|
984
1113
|
};
|
|
985
1114
|
}
|
|
986
|
-
function commandWithOutputSnapshots(command, snapshots) {
|
|
987
|
-
const outputPreview = [
|
|
988
|
-
command.outputPreview,
|
|
989
|
-
...snapshots.map((snapshot) => snapshot.outputPreview)
|
|
990
|
-
]
|
|
991
|
-
.filter(Boolean)
|
|
992
|
-
.join('\n');
|
|
993
|
-
return {
|
|
994
|
-
...command,
|
|
995
|
-
outputPreview: compactRunnerText(outputPreview, 10_000),
|
|
996
|
-
truncated: command.truncated ||
|
|
997
|
-
snapshots.some((snapshot) => snapshot.truncated) ||
|
|
998
|
-
outputPreview.length > 10_000
|
|
999
|
-
};
|
|
1000
|
-
}
|
|
1001
1115
|
function applyCommandResult(command, result) {
|
|
1002
1116
|
const output = [result.stdout, result.stderr].filter(Boolean).join('\n');
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
: [command.outputPreview, output].filter(Boolean).join('\n');
|
|
1007
|
-
command.truncated ||= combined.length > 10_000;
|
|
1008
|
-
command.outputPreview = compactRunnerText(combined, 10_000);
|
|
1009
|
-
}
|
|
1010
|
-
command.exitCode = result.exitCode ?? command.exitCode;
|
|
1011
|
-
command.truncated ||= result.truncated;
|
|
1117
|
+
command.outputPreview = compactRunnerText(output, 10_000);
|
|
1118
|
+
command.truncated = result.truncated || output.length > 10_000;
|
|
1119
|
+
command.exitCode = result.exitCode ?? null;
|
|
1012
1120
|
}
|
|
1013
1121
|
function fileChangeItem(id, status, changes) {
|
|
1014
1122
|
return { itemId: id, kind: 'file_change', status, payload: { changes }, merge: true };
|
|
@@ -1126,11 +1234,17 @@ function marAgentSubagentProjection(toolName, input, output, knownTitle, knownDe
|
|
|
1126
1234
|
? outputData.description
|
|
1127
1235
|
: operation === 'START' && typeof inputData?.description === 'string'
|
|
1128
1236
|
? inputData.description
|
|
1129
|
-
: ''
|
|
1237
|
+
: operation === 'START' && typeof inputData?.title === 'string'
|
|
1238
|
+
? inputData.title
|
|
1239
|
+
: ''), 500);
|
|
1130
1240
|
return {
|
|
1131
1241
|
subagentOperation: operation,
|
|
1132
1242
|
...(operation === 'STATUS' ? { subagentWait: inputData?.waitMs !== 0 } : {}),
|
|
1133
1243
|
subagentId: marAgentAgentId(input) ?? marAgentAgentId(controlOutput) ?? null,
|
|
1244
|
+
...(typeof outputData?.productSessionId === 'string' &&
|
|
1245
|
+
outputData.productSessionId === marAgentAgentId(controlOutput)
|
|
1246
|
+
? { subagentSessionId: outputData.productSessionId }
|
|
1247
|
+
: {}),
|
|
1134
1248
|
...(title.length === 0 ? {} : { title }),
|
|
1135
1249
|
...subagentPayload(details),
|
|
1136
1250
|
...(typeof details.latestMessage?.text === 'string'
|
|
@@ -1171,9 +1285,9 @@ function marAgentSubagentOperation(toolName) {
|
|
|
1171
1285
|
return 'START';
|
|
1172
1286
|
if (toolName === 'agent_wait')
|
|
1173
1287
|
return 'STATUS';
|
|
1174
|
-
if (toolName === 'agent_message')
|
|
1288
|
+
if (toolName === 'agent_send' || toolName === 'agent_message')
|
|
1175
1289
|
return 'MESSAGE';
|
|
1176
|
-
if (toolName === 'agent_cancel')
|
|
1290
|
+
if (toolName === 'agent_stop' || toolName === 'agent_cancel')
|
|
1177
1291
|
return 'CANCEL';
|
|
1178
1292
|
return undefined;
|
|
1179
1293
|
}
|
|
@@ -51,6 +51,11 @@ export class MarAgentManagedRunController {
|
|
|
51
51
|
}
|
|
52
52
|
}),
|
|
53
53
|
customTitle: (sessionId) => this.host.customTitle?.(sessionId) ?? undefined,
|
|
54
|
+
...(options.attachNetworkContext === undefined
|
|
55
|
+
? {}
|
|
56
|
+
: {
|
|
57
|
+
attachNetworkContext: options.attachNetworkContext
|
|
58
|
+
}),
|
|
54
59
|
modelUsage: (runId, usage) => this.host.emit(runId, 'run.usage', normalizeMarAgentUsage(usage)),
|
|
55
60
|
publishModelResource: options.publishModelResource,
|
|
56
61
|
question: (runId, request, signal) => this.requestQuestion(runId, request, signal),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { hasMarctlContext,
|
|
1
|
+
import { hasMarctlContext, marctlManagementDescription, marctlManagementInstructions } from '../../marctl-guidance.js';
|
|
2
2
|
export function marctlExecutionEnvironment(environment = {}) {
|
|
3
3
|
return Object.fromEntries(Object.entries(environment).filter(([key]) => key.startsWith('MAR_CTL_')));
|
|
4
4
|
}
|
|
@@ -7,8 +7,8 @@ export function marctlHostSkill(environment = {}) {
|
|
|
7
7
|
return undefined;
|
|
8
8
|
return {
|
|
9
9
|
name: 'marctl',
|
|
10
|
-
description:
|
|
10
|
+
description: marctlManagementDescription,
|
|
11
11
|
requiredTools: ['exec'],
|
|
12
|
-
load: async () =>
|
|
12
|
+
load: async () => marctlManagementInstructions
|
|
13
13
|
};
|
|
14
14
|
}
|
|
@@ -63,6 +63,7 @@ export class MarAgentRuntimeModelFactory {
|
|
|
63
63
|
reasoningEfforts: configuration.reasoningEfforts,
|
|
64
64
|
defaultReasoningEffort: resolveMarAgentDefaultReasoningEffort(configuration.defaultReasoningEffort, configuration.reasoningEfforts),
|
|
65
65
|
conversationModel: configuration.conversationModel ?? true,
|
|
66
|
+
subagentModel: configuration.subagentModel ?? false,
|
|
66
67
|
titleGeneration: configuration.titleGeneration,
|
|
67
68
|
codeMode: configuration.codeMode,
|
|
68
69
|
...(configuration.serviceTier === undefined
|
|
@@ -2,6 +2,8 @@ import { createHash, randomUUID } from 'node:crypto';
|
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
3
|
import { access, constants } from 'node:fs/promises';
|
|
4
4
|
import { LocalAgentHost } from '@myagentroam/agent/host';
|
|
5
|
+
import { SESSION_CONTEXT_PROVIDER } from '@myagentroam/agent/extensions';
|
|
6
|
+
import { agentNetworkExtension } from './agent-network-extension.js';
|
|
5
7
|
import { marAgentRuntimeCompactConfigurationSchema } from '@myagentroam/protocol';
|
|
6
8
|
import { nodeExecutionEnvironment } from '../../node-execution-environment.js';
|
|
7
9
|
import { nodeLog } from '../../operational.js';
|
|
@@ -26,8 +28,10 @@ export async function createSessionRuntime(input, sessionKey, fingerprint, hostC
|
|
|
26
28
|
let agent;
|
|
27
29
|
let models = [];
|
|
28
30
|
let releaseEnvironment;
|
|
31
|
+
let networkContext;
|
|
29
32
|
try {
|
|
30
33
|
releaseEnvironment = dependencies.retainEnvironment?.(input.secretEnvironment ?? {});
|
|
34
|
+
networkContext = dependencies.attachNetworkContext?.(input.sessionId);
|
|
31
35
|
const mcp = mcpLease.pool;
|
|
32
36
|
const localHost = new LocalAgentHost({
|
|
33
37
|
publishModelResource: dependencies.publishModelResource === undefined
|
|
@@ -68,12 +72,36 @@ export async function createSessionRuntime(input, sessionKey, fingerprint, hostC
|
|
|
68
72
|
});
|
|
69
73
|
const compactState = { revision: 0 };
|
|
70
74
|
updateMarAgentCompactState(compactState, input.compact, models, input.models.map((model) => model.id));
|
|
75
|
+
const compactSource = marAgentCompactExtensionSource(compactState);
|
|
76
|
+
const networkProvider = networkContext;
|
|
71
77
|
agent = await dependencies.createAgent({
|
|
72
78
|
mode: 'node',
|
|
73
79
|
host: localHost,
|
|
74
80
|
models: sdkModelConfigurations(models.filter((model) => input.models.some((candidate) => candidate.id === model.id))),
|
|
75
81
|
defaultModelId: input.model.id,
|
|
76
|
-
extensions:
|
|
82
|
+
extensions: networkProvider === undefined
|
|
83
|
+
? compactSource
|
|
84
|
+
: {
|
|
85
|
+
async resolve(request) {
|
|
86
|
+
const snapshot = await compactSource.resolve(request);
|
|
87
|
+
return {
|
|
88
|
+
...snapshot,
|
|
89
|
+
extensions: [
|
|
90
|
+
...snapshot.extensions,
|
|
91
|
+
{
|
|
92
|
+
id: 'mar.node.agent-network-context',
|
|
93
|
+
apiVersion: '1.0',
|
|
94
|
+
attachSession(context) {
|
|
95
|
+
context.services.provide(SESSION_CONTEXT_PROVIDER, networkProvider);
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
...(networkProvider.invoke === undefined
|
|
99
|
+
? []
|
|
100
|
+
: [agentNetworkExtension(networkProvider.invoke, currentRunId)])
|
|
101
|
+
]
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
},
|
|
77
105
|
...(input.personalInstructions ? { systemInstruction: input.personalInstructions } : {})
|
|
78
106
|
});
|
|
79
107
|
const customTitle = dependencies.customTitle(input.sessionId) ?? undefined;
|
|
@@ -92,6 +120,9 @@ export async function createSessionRuntime(input, sessionKey, fingerprint, hostC
|
|
|
92
120
|
normalizer: new MarAgentConversationNormalizer(),
|
|
93
121
|
mcpLease,
|
|
94
122
|
releaseEnvironment,
|
|
123
|
+
...(networkContext === undefined
|
|
124
|
+
? {}
|
|
125
|
+
: { releaseNetworkContext: () => networkContext?.close() }),
|
|
95
126
|
automaticTitleEnabled: input.externalSessionId === undefined,
|
|
96
127
|
models,
|
|
97
128
|
compactState,
|
|
@@ -103,6 +134,7 @@ export async function createSessionRuntime(input, sessionKey, fingerprint, hostC
|
|
|
103
134
|
catch (error) {
|
|
104
135
|
for (const cleanup of [
|
|
105
136
|
() => agent?.dispose(),
|
|
137
|
+
() => networkContext?.close(),
|
|
106
138
|
() => closeModelCredentialProviders(models),
|
|
107
139
|
() => mcpLease.release(),
|
|
108
140
|
() => releaseEnvironment?.()
|
|
@@ -155,6 +187,7 @@ export async function releaseSessionRuntime(runtime) {
|
|
|
155
187
|
const failures = [];
|
|
156
188
|
for (const cleanup of [
|
|
157
189
|
() => runtime.agent.dispose(),
|
|
190
|
+
() => runtime.releaseNetworkContext?.(),
|
|
158
191
|
() => runtime.mcpLease.release(),
|
|
159
192
|
() => runtime.releaseEnvironment?.()
|
|
160
193
|
]) {
|