@myagentroam/node 0.11.42 → 0.11.44
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 +14 -3
- package/dist/hosting/hosted-conversation-node-service.js +1 -2
- package/dist/main.js +10 -3
- package/dist/marctl-guidance.js +3 -1
- package/dist/runner/abstract-runner.js +2 -2
- package/dist/runner/claude/managed-run-controller.js +1 -1
- package/dist/runner/claude/native-transcript.js +1 -1
- package/dist/runner/claude/tool-normalizer.js +21 -12
- package/dist/runner/codex/conversation-parser.js +17 -9
- package/dist/runner/codex/managed-run-controller.js +1 -1
- package/dist/runner/codex/tool-normalizer.js +17 -9
- package/dist/runner/execution-presentation.js +0 -3
- package/dist/runner/mar-agent/agent-network-extension.js +2 -2
- package/dist/runner/mar-agent/conversation-normalizer.js +259 -43
- package/dist/runner/mar-agent/managed-run-controller.js +2 -1
- package/dist/runner/mar-agent/runtime-model-factory.js +2 -4
- package/dist/runner/mar-agent/session-runtime-registry.js +22 -12
- package/dist/runner/mar-agent/session-runtime.js +16 -11
- package/dist/runner/mar-agent-runner.js +32 -8
- package/dist/runner/normalization.js +8 -0
- package/dist/runner/opencode/tool-normalizer.js +8 -4
- package/dist/runtime-state.js +0 -1
- package/dist/service/agent-network-bindings.js +9 -50
- package/dist/service/agent-network-invoke.js +9 -21
- package/dist/service/agent-network-observations.js +15 -13
- package/dist/service/agent-network-service.js +39 -31
- package/dist/service/goal-continuation-coordinator.js +5 -0
- package/dist/service/marctl-caller.js +17 -9
- package/dist/service/runner-service.js +7 -3
- package/dist/session/runtime/conversation-projection.js +3 -1
- package/dist/session/session-lifecycle-service.js +7 -4
- package/dist/session/session-message-service.js +4 -2
- package/package.json +5 -5
|
@@ -75,30 +75,53 @@ export class NodeLifecycle {
|
|
|
75
75
|
async stopResources(handoff) {
|
|
76
76
|
let snapshot;
|
|
77
77
|
let failure;
|
|
78
|
+
let stage = 'waitForRecovery';
|
|
79
|
+
const failed = (error) => {
|
|
80
|
+
failure ??= { error };
|
|
81
|
+
try {
|
|
82
|
+
this.shutdown.diagnose(stage, error);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Diagnostics must not replace the shutdown failure or prevent cleanup.
|
|
86
|
+
}
|
|
87
|
+
};
|
|
78
88
|
try {
|
|
79
89
|
await this.shutdown.waitForRecovery();
|
|
90
|
+
stage = 'drainInput';
|
|
80
91
|
await this.shutdown.drainInput();
|
|
81
92
|
}
|
|
82
93
|
catch (error) {
|
|
83
|
-
|
|
94
|
+
failed(error);
|
|
84
95
|
}
|
|
85
96
|
try {
|
|
97
|
+
stage = 'closeResume';
|
|
86
98
|
await this.shutdown.closeResume();
|
|
87
|
-
if (failure === undefined && handoff)
|
|
99
|
+
if (failure === undefined && handoff) {
|
|
100
|
+
stage = 'capture';
|
|
88
101
|
snapshot = this.shutdown.capture();
|
|
102
|
+
}
|
|
89
103
|
}
|
|
90
104
|
catch (error) {
|
|
91
|
-
|
|
105
|
+
failed(error);
|
|
92
106
|
}
|
|
93
107
|
try {
|
|
108
|
+
stage = 'dispose';
|
|
94
109
|
await this.shutdown.dispose();
|
|
95
110
|
}
|
|
96
111
|
catch (error) {
|
|
97
|
-
|
|
112
|
+
failed(error);
|
|
98
113
|
}
|
|
99
114
|
if (failure !== undefined)
|
|
100
|
-
throw failure;
|
|
101
|
-
if (snapshot !== undefined)
|
|
102
|
-
|
|
115
|
+
throw failure.error;
|
|
116
|
+
if (snapshot !== undefined) {
|
|
117
|
+
try {
|
|
118
|
+
await this.shutdown.publish(snapshot);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
stage = 'publish';
|
|
122
|
+
failed(error);
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
103
126
|
}
|
|
104
127
|
}
|
package/dist/connector.js
CHANGED
|
@@ -197,7 +197,11 @@ export class NodeConnector {
|
|
|
197
197
|
closeResume: () => this.externalSessionResumeService.close(),
|
|
198
198
|
capture: () => (this.config?.nodeId ? this.restartHandoff.capture() : undefined),
|
|
199
199
|
dispose: () => this.disposeRuntime(),
|
|
200
|
-
publish: (snapshot) => this.restartHandoff.publish(snapshot)
|
|
200
|
+
publish: (snapshot) => this.restartHandoff.publish(snapshot),
|
|
201
|
+
diagnose: (stage, error) => nodeLog('node.shutdown.failed', {
|
|
202
|
+
stage,
|
|
203
|
+
errorCode: safeErrorCode(error, 'NODE_SHUTDOWN_FAILED')
|
|
204
|
+
})
|
|
201
205
|
});
|
|
202
206
|
get stopped() {
|
|
203
207
|
return this.lifecycle.stopped;
|
|
@@ -647,10 +651,17 @@ export class NodeConnector {
|
|
|
647
651
|
}),
|
|
648
652
|
resources: async (signal) => {
|
|
649
653
|
signal.throwIfAborted();
|
|
650
|
-
const
|
|
654
|
+
const currentSessionId = this.runtime.getAgentSessionById(sessionId)?.id;
|
|
655
|
+
if (!currentSessionId)
|
|
656
|
+
return [];
|
|
657
|
+
const run = this.runtime.activeSessionRun(currentSessionId);
|
|
651
658
|
if (!run || !run.initiatedByUserId)
|
|
652
659
|
return [];
|
|
653
|
-
const result = await this.agentNetworkService.list({
|
|
660
|
+
const result = await this.agentNetworkService.list({
|
|
661
|
+
sessionId: currentSessionId,
|
|
662
|
+
runId: run.id,
|
|
663
|
+
requestUserId: run.initiatedByUserId
|
|
664
|
+
}, { scope: 'children', limit: 100 });
|
|
654
665
|
signal.throwIfAborted();
|
|
655
666
|
const data = result;
|
|
656
667
|
if (!data.sessions?.length && !data.truncated)
|
|
@@ -943,8 +943,7 @@ function modelSummary(model, index) {
|
|
|
943
943
|
: { responsesTransport: model.responsesTransport }),
|
|
944
944
|
responsesPreviousResponseId: model.responsesPreviousResponseId,
|
|
945
945
|
enabled: model.enabled,
|
|
946
|
-
sortOrder: index
|
|
947
|
-
apiKeyConfigured: true
|
|
946
|
+
sortOrder: index
|
|
948
947
|
};
|
|
949
948
|
}
|
|
950
949
|
function terminalHostedTurnStatus(status) {
|
package/dist/main.js
CHANGED
|
@@ -45,10 +45,17 @@ if (command === 'run') {
|
|
|
45
45
|
clearTimeout(deadline);
|
|
46
46
|
releaseOwner();
|
|
47
47
|
process.exit(exitCode);
|
|
48
|
-
}, () => {
|
|
48
|
+
}, (error) => {
|
|
49
49
|
clearTimeout(deadline);
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
try {
|
|
51
|
+
nodeLog('node.restart.diagnostic', {
|
|
52
|
+
code: 'RESTART_HANDOFF_SHUTDOWN_FAILED',
|
|
53
|
+
errorCode: safeErrorCode(error, 'NODE_SHUTDOWN_FAILED')
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
52
59
|
});
|
|
53
60
|
};
|
|
54
61
|
const supervisorHandoff = new SupervisorUpgradeHandoff();
|
package/dist/marctl-guidance.js
CHANGED
|
@@ -5,7 +5,7 @@ export function hasMarctlContext(environment) {
|
|
|
5
5
|
!!environment['MAR_CTL_NODE_ID'] &&
|
|
6
6
|
!!environment['MAR_CTL_WORKSPACE_ID']);
|
|
7
7
|
}
|
|
8
|
-
export const marctlManagementDescription = 'Use marctl
|
|
8
|
+
export const marctlManagementDescription = 'Use marctl to manage MAR Agent session settings (model, effort, title, persistent prompts, and schedules), discover authorized MAR Nodes, and execute commands or transfer files on those Nodes. Use native agent_* tools for other Agent lifecycle and collaboration operations.';
|
|
9
9
|
const marctlSafety = 'Acceptance is not completion. If a request result is unknown, inspect history before retrying. Session IDs and parent relationships do not grant authorization.';
|
|
10
10
|
export const marctlManagementInstructions = [
|
|
11
11
|
'## MAR Workspace management',
|
|
@@ -21,8 +21,10 @@ export const marctlInstructions = [
|
|
|
21
21
|
'Run marctl from the shell. Commands use the authenticated Node and Workspace; marctl help agents, nodes, ssh or scp shows options.',
|
|
22
22
|
'Use agents start --title <title> -m <text> [--runner <runner>] [--model <id>] [--effort <effort>] [--goal <objective>]. An Agent must supply a nonblank title; a manual terminal may omit it. The default Runner is the current Session Runner; a terminal without a current Session must specify --runner or an explicit --parent. Start returns without waiting.',
|
|
23
23
|
'Use agents send <id> -m <text> [--steer|--queue], agents wait [<id>] [--wait-for message|completion] [--timeout <duration>], agents stop <id> --execution <execution-id>, agents list [--scope children|descendants|workspace|profile], and agents view <id> [--history]. Wait defaults to direct-child completion for 30 seconds; --timeout 0ms takes a snapshot. Stop clears the target Session Goal.',
|
|
24
|
+
'Prefer agents send <id> --steer -m <text> for timely communication or course correction. Use --queue only for deliberately deferred input: it is consumed after current work and earlier queued inputs finish, and with an active Goal it is not consumed until that Goal exits. Acceptance is not a guarantee of immediate processing.',
|
|
24
25
|
'Start and send accept repeated --image <local-path> for PNG, JPEG, GIF or WebP; limits are five images, 5 MiB each and 10 MiB total. Send can update a Goal alone with --goal <objective> or --clear-goal; omitted Goal leaves it unchanged. Decide a direct child approval with send <id> --approval <approval-id> --decision approve|reject.',
|
|
25
26
|
'List accepts --agent <id> for a relation root, --query, --parent, --limit and --cursor. Use --scope profile [--runner <runner>] for Runner models; configured profiles do not guarantee account availability.',
|
|
27
|
+
'Only direct-child updates are collected automatically. Sending to a non-child never subscribes; an explicit wait observes it only for that call.',
|
|
26
28
|
'Use agents config, rename, prompt and schedule for management. marctl nodes, ssh and scp use authorized Nodes.',
|
|
27
29
|
marctlSafety
|
|
28
30
|
].join('\n\n');
|
|
@@ -40,8 +40,8 @@ export class AbstractRunner {
|
|
|
40
40
|
childModels() {
|
|
41
41
|
return this.profileForValidation().models;
|
|
42
42
|
}
|
|
43
|
-
assertChildModel(modelId) {
|
|
44
|
-
void modelId;
|
|
43
|
+
assertChildModel(modelId, executionContext) {
|
|
44
|
+
void [modelId, executionContext];
|
|
45
45
|
}
|
|
46
46
|
presentSession(session, capabilities, context) {
|
|
47
47
|
void [session, capabilities, context];
|
|
@@ -462,7 +462,7 @@ export class ClaudeManagedRunController {
|
|
|
462
462
|
const tool = toolInputs.get(result.toolUseId);
|
|
463
463
|
if (tool === undefined)
|
|
464
464
|
continue;
|
|
465
|
-
const normalized = normalizeClaudeTool(tool.name, tool.input, result.output, result.failed, tool.inputTruncated || result.truncated, knownSubagents, result.claudeResult);
|
|
465
|
+
const normalized = normalizeClaudeTool(tool.name, tool.input, result.output, result.failed, tool.inputTruncated || result.truncated, knownSubagents, result.claudeResult, result.truncated);
|
|
466
466
|
this.host.emitItem(runId, {
|
|
467
467
|
itemId: boundedConversationItemId('claude-tool', result.toolUseId),
|
|
468
468
|
kind,
|
|
@@ -339,7 +339,7 @@ export const claudeNativeTranscriptAdapter = {
|
|
|
339
339
|
return {
|
|
340
340
|
userText: (text) => publicGoalHistoryText(stripClaudePlanTag(text)),
|
|
341
341
|
planText: claudePlanText,
|
|
342
|
-
normalizeTool: (entry) => normalizeClaudeTool(entry.toolName, entry.input, entry.outputSummary, entry.failed, entry.inputTruncated || entry.outputTruncated, titles, claudeNativeToolResultMetadata(entry.subagentResult)),
|
|
342
|
+
normalizeTool: (entry) => normalizeClaudeTool(entry.toolName, entry.input, entry.outputSummary, entry.failed, entry.inputTruncated || entry.outputTruncated, titles, claudeNativeToolResultMetadata(entry.subagentResult), entry.outputTruncated),
|
|
343
343
|
userInputQuestions: (entry) => entry.toolName === 'AskUserQuestion' && isPlainRecord(entry.input)
|
|
344
344
|
? claudeUserInputQuestions(entry.input)
|
|
345
345
|
: []
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { claudeContentBlocks } from './message-parsers.js';
|
|
2
|
-
import { compactRunnerText, compactRunnerValue } from '../normalization.js';
|
|
3
|
-
import {
|
|
2
|
+
import { compactRunnerText, compactRunnerValue, publicOutputSnapshot } from '../normalization.js';
|
|
3
|
+
import { shellExecution } from '../execution-presentation.js';
|
|
4
4
|
import { RunnerUsageTracker, usageToken, usageTokenSum } from '../../service/runner-usage-tracker.js';
|
|
5
5
|
export class ClaudeUsageNormalizer {
|
|
6
6
|
tracker;
|
|
@@ -69,7 +69,16 @@ export function extractClaudeToolResults(message) {
|
|
|
69
69
|
return [];
|
|
70
70
|
const blocks = claudeContentBlocks(message).filter((block) => block.type === 'tool_result' && typeof block.tool_use_id === 'string');
|
|
71
71
|
return blocks.map((block) => {
|
|
72
|
-
const
|
|
72
|
+
const textBlocks = Array.isArray(block.content)
|
|
73
|
+
? block.content.flatMap((part) => {
|
|
74
|
+
const value = record(part);
|
|
75
|
+
return value?.type === 'text' && typeof value.text === 'string' ? [value.text] : [];
|
|
76
|
+
})
|
|
77
|
+
: [];
|
|
78
|
+
const content = Array.isArray(block.content) && textBlocks.length === block.content.length
|
|
79
|
+
? textBlocks.join('\n')
|
|
80
|
+
: block.content;
|
|
81
|
+
const output = publicOutputSnapshot(content);
|
|
73
82
|
// A message-level structured result cannot be assigned to multiple calls.
|
|
74
83
|
const structured = blocks.length === 1 ? structuredRecord(message.tool_use_result) : undefined;
|
|
75
84
|
const fields = structured ?? structuredRecord(block.content);
|
|
@@ -90,27 +99,27 @@ export function extractClaudeToolResults(message) {
|
|
|
90
99
|
};
|
|
91
100
|
});
|
|
92
101
|
}
|
|
93
|
-
export function normalizeClaudeTool(toolName, input, output, failed, truncated, knownSubagents = new Map(), resultMetadata) {
|
|
102
|
+
export function normalizeClaudeTool(toolName, input, output, failed, truncated, knownSubagents = new Map(), resultMetadata, sourceOutputTruncated = output === null ? false : truncated) {
|
|
94
103
|
const values = record(input);
|
|
95
104
|
const normalizedToolName = compactRunnerText(toolName, 128) || 'unknown';
|
|
96
105
|
const normalizedOutput = output === null ? null : compactRunnerText(output, 10_000);
|
|
97
|
-
const outputTruncated =
|
|
106
|
+
const outputTruncated = sourceOutputTruncated || (output?.length ?? 0) > 10_000;
|
|
98
107
|
const subagent = claudeSubagentProjection(toolName, input, resultMetadata ?? output, knownSubagents);
|
|
99
108
|
if (isCommandTool(toolName))
|
|
100
109
|
return {
|
|
101
110
|
kind: 'command_execution',
|
|
102
111
|
payload: {
|
|
112
|
+
toolName: normalizedToolName,
|
|
103
113
|
command: compactRunnerText(typeof values?.command === 'string' ? values.command : normalizedToolName, 10_000),
|
|
104
114
|
cwd: null,
|
|
105
115
|
outputPreview: normalizedOutput ?? '',
|
|
106
|
-
outputRef: null,
|
|
107
116
|
exitCode: null,
|
|
108
117
|
durationMs: null,
|
|
109
|
-
truncated: outputTruncated,
|
|
118
|
+
truncated: truncated || outputTruncated,
|
|
110
119
|
...(output === null || output === undefined
|
|
111
120
|
? {}
|
|
112
|
-
: { output: publicOutputSnapshot(output,
|
|
113
|
-
toolPresentation: shellExecution(output ?? undefined,
|
|
121
|
+
: { output: publicOutputSnapshot(output, outputTruncated) }),
|
|
122
|
+
toolPresentation: shellExecution(output ?? undefined, outputTruncated)
|
|
114
123
|
}
|
|
115
124
|
};
|
|
116
125
|
if (isFileTool(toolName)) {
|
|
@@ -132,8 +141,7 @@ export function normalizeClaudeTool(toolName, input, output, failed, truncated,
|
|
|
132
141
|
path: normalizedPath,
|
|
133
142
|
change: 'MODIFIED',
|
|
134
143
|
additions: null,
|
|
135
|
-
deletions: null
|
|
136
|
-
diffAvailable: false
|
|
144
|
+
deletions: null
|
|
137
145
|
}
|
|
138
146
|
]
|
|
139
147
|
}
|
|
@@ -147,9 +155,10 @@ export function normalizeClaudeTool(toolName, input, output, failed, truncated,
|
|
|
147
155
|
title: compactRunnerText(toolName, 500) || normalizedToolName,
|
|
148
156
|
inputSummary: compactRunnerValue(input, 10_000).text || null,
|
|
149
157
|
outputSummary: normalizedOutput,
|
|
158
|
+
...(output === null ? {} : { output: publicOutputSnapshot(output, outputTruncated) }),
|
|
150
159
|
progressLabel: null,
|
|
151
160
|
errorCode: failed ? 'TOOL_EXECUTION_FAILED' : null,
|
|
152
|
-
truncated: outputTruncated,
|
|
161
|
+
truncated: truncated || outputTruncated,
|
|
153
162
|
...(toolName === 'Read'
|
|
154
163
|
? {
|
|
155
164
|
toolPresentation: {
|
|
@@ -131,7 +131,8 @@ import { runnerErrorProjection } from '../runner-error.js';
|
|
|
131
131
|
import { conversationImageAttachmentSchema } from '@myagentroam/protocol';
|
|
132
132
|
import { parseCodexComposerImageMarkers } from './composer-image-markers.js';
|
|
133
133
|
import { normalizeCodexTool } from './tool-normalizer.js';
|
|
134
|
-
import {
|
|
134
|
+
import { shellExecution } from '../execution-presentation.js';
|
|
135
|
+
import { publicOutputSnapshot } from '../normalization.js';
|
|
135
136
|
import { publicGoalHistoryText } from '../../service/goal-runtime.js';
|
|
136
137
|
const MAX_COMPOSER_ATTACHMENT_BYTES = 5 * 1024 * 1024;
|
|
137
138
|
const MAX_COMPOSER_ATTACHMENTS_BYTES = 10 * 1024 * 1024;
|
|
@@ -553,6 +554,7 @@ export function mergeCodexCustomToolItems(invocation, result) {
|
|
|
553
554
|
outputPreview: resultPayload.outputPreview ??
|
|
554
555
|
resultPayload.outputSummary ??
|
|
555
556
|
invocationPayload.outputPreview,
|
|
557
|
+
...(resultPayload.output === undefined ? {} : { output: resultPayload.output }),
|
|
556
558
|
exitCode: resultPayload.exitCode ?? invocationPayload.exitCode,
|
|
557
559
|
durationMs: resultPayload.durationMs ?? invocationPayload.durationMs,
|
|
558
560
|
truncated: invocationPayload.truncated === true || resultPayload.truncated === true,
|
|
@@ -572,6 +574,7 @@ export function mergeCodexCustomToolItems(invocation, result) {
|
|
|
572
574
|
payload: {
|
|
573
575
|
...invocationPayload,
|
|
574
576
|
outputSummary: resultPayload.outputSummary ?? invocationPayload.outputSummary,
|
|
577
|
+
...(resultPayload.output === undefined ? {} : { output: resultPayload.output }),
|
|
575
578
|
errorCode: resultPayload.errorCode ?? invocationPayload.errorCode,
|
|
576
579
|
truncated: invocationPayload.truncated === true || resultPayload.truncated === true,
|
|
577
580
|
...(resultPayload.attachments === undefined ? {} : { attachments: resultPayload.attachments })
|
|
@@ -718,7 +721,6 @@ export function codexOfficialItem(session, nativeTurnId, value, turnSequence, it
|
|
|
718
721
|
: '(No command provided)',
|
|
719
722
|
cwd: typeof value.cwd === 'string' ? compactRunnerText(value.cwd, 4_096) : null,
|
|
720
723
|
outputPreview: publicOutputSnapshot(output).text,
|
|
721
|
-
outputRef: null,
|
|
722
724
|
exitCode: typeof value.exitCode === 'number' && Number.isInteger(value.exitCode)
|
|
723
725
|
? value.exitCode
|
|
724
726
|
: null,
|
|
@@ -756,6 +758,7 @@ export function codexOfficialItem(session, nativeTurnId, value, turnSequence, it
|
|
|
756
758
|
toolName: typeof value.tool === 'string' ? value.tool : '',
|
|
757
759
|
inputSummary: codexCompactJson(value.arguments),
|
|
758
760
|
outputSummary: codexCompactJson(value.result),
|
|
761
|
+
...(value.result == null ? {} : { output: publicOutputSnapshot(value.result) }),
|
|
759
762
|
...(value.error === undefined ? {} : { errorCode: codexCompactJson(value.error) })
|
|
760
763
|
}
|
|
761
764
|
};
|
|
@@ -800,12 +803,16 @@ export function codexOfficialItem(session, nativeTurnId, value, turnSequence, it
|
|
|
800
803
|
: typeof value.name === 'string'
|
|
801
804
|
? value.name
|
|
802
805
|
: 'tool';
|
|
806
|
+
const outputValue = value.contentItems ?? value.output;
|
|
807
|
+
const output = outputValue == null ? undefined : publicOutputSnapshot(codexToolOutput(outputValue));
|
|
803
808
|
const normalized = normalizeCodexTool({
|
|
804
809
|
name,
|
|
805
810
|
namespace: typeof value.namespace === 'string' ? value.namespace : 'codex',
|
|
806
811
|
rawInput: value.arguments ?? value.input,
|
|
807
812
|
inputSummary: codexCompactJson(value.arguments ?? value.input),
|
|
808
|
-
outputSummary:
|
|
813
|
+
outputSummary: output?.text ?? null,
|
|
814
|
+
outputTruncated: output?.truncated ?? false,
|
|
815
|
+
truncated: output?.truncated ?? false,
|
|
809
816
|
outputOnly: value.type === 'custom_tool_call_output' ||
|
|
810
817
|
value.type === 'function_call_output' ||
|
|
811
818
|
value.type === 'customToolCallOutput' ||
|
|
@@ -900,7 +907,6 @@ export function codexLiveConversationItem(value, completed, imageAttachments = [
|
|
|
900
907
|
: '(No command provided)',
|
|
901
908
|
cwd: typeof value.cwd === 'string' ? compactRunnerText(value.cwd, 4_096) : null,
|
|
902
909
|
outputPreview: publicOutputSnapshot(output).text,
|
|
903
|
-
outputRef: null,
|
|
904
910
|
exitCode: typeof value.exitCode === 'number' && Number.isInteger(value.exitCode)
|
|
905
911
|
? value.exitCode
|
|
906
912
|
: null,
|
|
@@ -937,6 +943,7 @@ export function codexLiveConversationItem(value, completed, imageAttachments = [
|
|
|
937
943
|
title: compactRunnerText(`${server}.${tool}`, 500),
|
|
938
944
|
inputSummary: input.text || null,
|
|
939
945
|
outputSummary: output.text || null,
|
|
946
|
+
...(value.result == null ? {} : { output: publicOutputSnapshot(value.result) }),
|
|
940
947
|
progressLabel: null,
|
|
941
948
|
errorCode: error.text || null,
|
|
942
949
|
truncated: input.truncated || output.truncated || error.truncated
|
|
@@ -1013,7 +1020,8 @@ export function codexLiveConversationItem(value, completed, imageAttachments = [
|
|
|
1013
1020
|
? value.name
|
|
1014
1021
|
: 'tool';
|
|
1015
1022
|
const input = compactRunnerValue(value.arguments ?? value.input, 10_000);
|
|
1016
|
-
const
|
|
1023
|
+
const outputValue = value.contentItems ?? value.output;
|
|
1024
|
+
const output = outputValue == null ? undefined : publicOutputSnapshot(codexToolOutput(outputValue));
|
|
1017
1025
|
const outputOnly = value.type === 'custom_tool_call_output' ||
|
|
1018
1026
|
value.type === 'function_call_output' ||
|
|
1019
1027
|
value.type === 'customToolCallOutput' ||
|
|
@@ -1023,8 +1031,9 @@ export function codexLiveConversationItem(value, completed, imageAttachments = [
|
|
|
1023
1031
|
namespace: typeof value.namespace === 'string' ? value.namespace : 'codex',
|
|
1024
1032
|
rawInput: value.arguments ?? value.input,
|
|
1025
1033
|
inputSummary: input.text || null,
|
|
1026
|
-
outputSummary: output
|
|
1027
|
-
truncated: input.truncated || output
|
|
1034
|
+
outputSummary: output?.text ?? null,
|
|
1035
|
+
truncated: input.truncated || output?.truncated === true,
|
|
1036
|
+
outputTruncated: output?.truncated ?? false,
|
|
1028
1037
|
outputOnly,
|
|
1029
1038
|
attachments: imageAttachments
|
|
1030
1039
|
});
|
|
@@ -1067,8 +1076,7 @@ function normalizeCodexFileChanges(changes) {
|
|
|
1067
1076
|
path,
|
|
1068
1077
|
change,
|
|
1069
1078
|
additions: nonnegativeIntegerOrNull(value.additions),
|
|
1070
|
-
deletions: nonnegativeIntegerOrNull(value.deletions)
|
|
1071
|
-
diffAvailable: value.diffAvailable === true
|
|
1079
|
+
deletions: nonnegativeIntegerOrNull(value.deletions)
|
|
1072
1080
|
}
|
|
1073
1081
|
];
|
|
1074
1082
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { NODE_MCP } from '../../mcp/naming.js';
|
|
2
2
|
import { nodeExecutionEnvironment } from '../../node-execution-environment.js';
|
|
3
3
|
import { extractId } from './conversation-parser.js';
|
|
4
|
-
import { publicOutputSnapshot } from '../
|
|
4
|
+
import { publicOutputSnapshot } from '../normalization.js';
|
|
5
5
|
import { normalizeCodexApproval } from './tool-normalizer.js';
|
|
6
6
|
import { parseSecretEnvironment } from '../../mcp/secret-environment.js';
|
|
7
7
|
import { safeErrorCode } from '../../util/safe-error.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { compactRunnerText } from '../normalization.js';
|
|
2
|
-
import {
|
|
1
|
+
import { compactRunnerText, publicOutputSnapshot } from '../normalization.js';
|
|
2
|
+
import { shellExecution } from '../execution-presentation.js';
|
|
3
3
|
export function normalizeCodexApproval(method) {
|
|
4
4
|
return method === 'item/commandExecution/requestApproval'
|
|
5
5
|
? { toolName: 'command_execution', reason: 'Command execution requires approval.' }
|
|
@@ -9,6 +9,7 @@ export function normalizeCodexTool(input) {
|
|
|
9
9
|
const name = compactRunnerText(input.name, 128) || 'tool';
|
|
10
10
|
const rawInput = input.rawInput;
|
|
11
11
|
const attachments = input.attachments ?? [];
|
|
12
|
+
const outputTruncated = input.outputTruncated ?? (input.outputSummary != null && input.truncated === true);
|
|
12
13
|
const subagent = codexSubagentProjection(input.namespace, name, rawInput, input.outputSummary);
|
|
13
14
|
if (isCommandTool(name)) {
|
|
14
15
|
const outputPreview = compactRunnerText(input.outputSummary ?? '', 10_000);
|
|
@@ -16,12 +17,13 @@ export function normalizeCodexTool(input) {
|
|
|
16
17
|
return {
|
|
17
18
|
kind: 'command_execution',
|
|
18
19
|
payload: {
|
|
20
|
+
toolName: name,
|
|
19
21
|
outputPreview,
|
|
20
22
|
truncated: input.truncated === true || (input.outputSummary?.length ?? 0) > 10_000,
|
|
21
23
|
...(input.outputSummary == null
|
|
22
24
|
? {}
|
|
23
|
-
: { output: publicOutputSnapshot(input.outputSummary,
|
|
24
|
-
toolPresentation: shellExecution(input.outputSummary ?? undefined,
|
|
25
|
+
: { output: publicOutputSnapshot(input.outputSummary, outputTruncated) }),
|
|
26
|
+
toolPresentation: shellExecution(input.outputSummary ?? undefined, outputTruncated),
|
|
25
27
|
...(attachments.length === 0 ? {} : { attachments })
|
|
26
28
|
}
|
|
27
29
|
};
|
|
@@ -36,16 +38,16 @@ export function normalizeCodexTool(input) {
|
|
|
36
38
|
return {
|
|
37
39
|
kind: 'command_execution',
|
|
38
40
|
payload: {
|
|
41
|
+
toolName: name,
|
|
39
42
|
command: compactRunnerText(command, 10_000),
|
|
40
43
|
cwd: typeof values?.cwd === 'string' ? compactRunnerText(values.cwd, 4_096) : null,
|
|
41
44
|
outputPreview,
|
|
42
|
-
outputRef: null,
|
|
43
45
|
exitCode: null,
|
|
44
46
|
durationMs: null,
|
|
45
|
-
toolPresentation: shellExecution(input.outputSummary ?? undefined,
|
|
47
|
+
toolPresentation: shellExecution(input.outputSummary ?? undefined, outputTruncated),
|
|
46
48
|
...(input.outputSummary == null
|
|
47
49
|
? {}
|
|
48
|
-
: { output: publicOutputSnapshot(input.outputSummary,
|
|
50
|
+
: { output: publicOutputSnapshot(input.outputSummary, outputTruncated) }),
|
|
49
51
|
truncated: input.truncated === true ||
|
|
50
52
|
command.length > 10_000 ||
|
|
51
53
|
(input.outputSummary?.length ?? 0) > 10_000,
|
|
@@ -57,7 +59,10 @@ export function normalizeCodexTool(input) {
|
|
|
57
59
|
return {
|
|
58
60
|
kind: 'tool_call',
|
|
59
61
|
payload: {
|
|
60
|
-
outputSummary: input.outputSummary
|
|
62
|
+
outputSummary: input.outputSummary == null ? null : compactRunnerText(input.outputSummary, 10_000),
|
|
63
|
+
...(input.outputSummary == null
|
|
64
|
+
? {}
|
|
65
|
+
: { output: publicOutputSnapshot(input.outputSummary, outputTruncated) }),
|
|
61
66
|
...subagent,
|
|
62
67
|
...(attachments.length === 0 ? {} : { attachments })
|
|
63
68
|
}
|
|
@@ -69,7 +74,10 @@ export function normalizeCodexTool(input) {
|
|
|
69
74
|
namespace: compactRunnerText(input.namespace ?? 'codex', 128),
|
|
70
75
|
toolName: name,
|
|
71
76
|
inputSummary: input.inputSummary ?? null,
|
|
72
|
-
outputSummary: input.outputSummary
|
|
77
|
+
outputSummary: input.outputSummary == null ? null : compactRunnerText(input.outputSummary, 10_000),
|
|
78
|
+
...(input.outputSummary == null
|
|
79
|
+
? {}
|
|
80
|
+
: { output: publicOutputSnapshot(input.outputSummary, outputTruncated) }),
|
|
73
81
|
progressLabel: null,
|
|
74
82
|
errorCode: null,
|
|
75
83
|
truncated: input.truncated === true,
|
|
@@ -6,9 +6,6 @@ function tail(text, limit) {
|
|
|
6
6
|
const first = result.charCodeAt(0);
|
|
7
7
|
return first >= 0xdc00 && first <= 0xdfff ? result.slice(1) : result;
|
|
8
8
|
}
|
|
9
|
-
export function publicOutputSnapshot(text, truncated = false) {
|
|
10
|
-
return { text: tail(text, 10_000), truncated: truncated || text.length > 10_000 };
|
|
11
|
-
}
|
|
12
9
|
/** Keep public execution output bounded without copying an unbounded source. */
|
|
13
10
|
export function boundExecutionPresentation(execution) {
|
|
14
11
|
let truncated = (execution.output?.length ?? 0) > 4;
|
|
@@ -52,7 +52,7 @@ const tools = [
|
|
|
52
52
|
},
|
|
53
53
|
{
|
|
54
54
|
action: 'send',
|
|
55
|
-
description: 'Send input, decide
|
|
55
|
+
description: 'Send input, decide an approval or update a Goal; goal:null leaves it unchanged, goal:{clear:true} clears it. Prefer REPLACE_CURRENT for timely communication or course correction. QUEUE is consumed only after current work and earlier queued inputs finish; an active Goal must exit first. Sending to a non-child does not subscribe to its updates.',
|
|
56
56
|
properties: {
|
|
57
57
|
agentId: text,
|
|
58
58
|
content: { type: 'string' },
|
|
@@ -72,7 +72,7 @@ const tools = [
|
|
|
72
72
|
},
|
|
73
73
|
{
|
|
74
74
|
action: 'wait',
|
|
75
|
-
description: 'Wait for completion or messages; defaults to direct children, completion and 30 seconds. Use waitMs 0 for a snapshot.',
|
|
75
|
+
description: 'Wait for completion or messages; defaults to direct children, completion and 30 seconds. Use waitMs 0 for a snapshot. Non-child targets are observed only during this call.',
|
|
76
76
|
properties: {
|
|
77
77
|
agentId: text,
|
|
78
78
|
agentIds: { type: 'array', items: text, minItems: 1, maxItems: 8 },
|