@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
|
@@ -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;
|
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();
|
|
@@ -462,26 +462,19 @@ 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, result.truncated);
|
|
465
|
+
const normalized = normalizeClaudeTool(tool.name, tool.input, result.output, result.failed, tool.inputTruncated || result.truncated, knownSubagents, result.claudeResult, result.truncated, tool.inputTruncated, result.truncated ? 'HEAD' : undefined);
|
|
466
466
|
this.host.emitItem(runId, {
|
|
467
467
|
itemId: boundedConversationItemId('claude-tool', result.toolUseId),
|
|
468
468
|
kind,
|
|
469
469
|
status: result.failed ? 'FAILED' : 'COMPLETED',
|
|
470
470
|
payload: kind === 'command_execution'
|
|
471
|
-
?
|
|
472
|
-
outputPreview: result.output,
|
|
473
|
-
exitCode: null,
|
|
474
|
-
durationMs: null,
|
|
475
|
-
truncated: result.truncated
|
|
476
|
-
}
|
|
471
|
+
? normalized.payload
|
|
477
472
|
: kind === 'file_change'
|
|
478
473
|
? {}
|
|
479
474
|
: {
|
|
480
475
|
...normalized.payload,
|
|
481
|
-
outputSummary: result.output,
|
|
482
476
|
progressLabel: null,
|
|
483
|
-
errorCode: result.failed ? 'TOOL_EXECUTION_FAILED' : null
|
|
484
|
-
truncated: result.truncated
|
|
477
|
+
errorCode: result.failed ? 'TOOL_EXECUTION_FAILED' : null
|
|
485
478
|
},
|
|
486
479
|
merge: true
|
|
487
480
|
});
|
|
@@ -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), entry.outputTruncated),
|
|
342
|
+
normalizeTool: (entry) => normalizeClaudeTool(entry.toolName, entry.input, entry.outputSummary, entry.failed, entry.inputTruncated || entry.outputTruncated, titles, claudeNativeToolResultMetadata(entry.subagentResult), entry.outputTruncated, entry.inputTruncated, entry.outputTruncated ? 'HEAD' : undefined),
|
|
343
343
|
userInputQuestions: (entry) => entry.toolName === 'AskUserQuestion' && isPlainRecord(entry.input)
|
|
344
344
|
? claudeUserInputQuestions(entry.input)
|
|
345
345
|
: []
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { claudeContentBlocks } from './message-parsers.js';
|
|
2
|
-
import { compactRunnerText, compactRunnerValue, publicOutputSnapshot } from '../normalization.js';
|
|
2
|
+
import { compactRunnerText, compactRunnerValue, publicOutputSnapshot, publicToolOutput } from '../normalization.js';
|
|
3
3
|
import { shellExecution } from '../execution-presentation.js';
|
|
4
4
|
import { RunnerUsageTracker, usageToken, usageTokenSum } from '../../service/runner-usage-tracker.js';
|
|
5
5
|
export class ClaudeUsageNormalizer {
|
|
@@ -99,11 +99,9 @@ export function extractClaudeToolResults(message) {
|
|
|
99
99
|
};
|
|
100
100
|
});
|
|
101
101
|
}
|
|
102
|
-
export function normalizeClaudeTool(toolName, input, output, failed, truncated, knownSubagents = new Map(), resultMetadata, sourceOutputTruncated = output === null ? false : truncated) {
|
|
102
|
+
export function normalizeClaudeTool(toolName, input, output, failed, truncated, knownSubagents = new Map(), resultMetadata, sourceOutputTruncated = output === null ? false : truncated, sourceInputTruncated = output === null ? truncated : false, outputDirection) {
|
|
103
103
|
const values = record(input);
|
|
104
104
|
const normalizedToolName = compactRunnerText(toolName, 128) || 'unknown';
|
|
105
|
-
const normalizedOutput = output === null ? null : compactRunnerText(output, 10_000);
|
|
106
|
-
const outputTruncated = sourceOutputTruncated || (output?.length ?? 0) > 10_000;
|
|
107
105
|
const subagent = claudeSubagentProjection(toolName, input, resultMetadata ?? output, knownSubagents);
|
|
108
106
|
if (isCommandTool(toolName))
|
|
109
107
|
return {
|
|
@@ -112,14 +110,15 @@ export function normalizeClaudeTool(toolName, input, output, failed, truncated,
|
|
|
112
110
|
toolName: normalizedToolName,
|
|
113
111
|
command: compactRunnerText(typeof values?.command === 'string' ? values.command : normalizedToolName, 10_000),
|
|
114
112
|
cwd: null,
|
|
115
|
-
outputPreview: normalizedOutput ?? '',
|
|
116
113
|
exitCode: null,
|
|
117
114
|
durationMs: null,
|
|
118
|
-
truncated: truncated || outputTruncated,
|
|
119
115
|
...(output === null || output === undefined
|
|
120
116
|
? {}
|
|
121
|
-
: {
|
|
122
|
-
|
|
117
|
+
: {
|
|
118
|
+
output: publicToolOutput(output, outputDirection ?? (sourceOutputTruncated ? 'SOURCE' : undefined), 'COMBINED')
|
|
119
|
+
}),
|
|
120
|
+
toolPresentation: shellExecution(sourceInputTruncated ||
|
|
121
|
+
(typeof values?.command === 'string' && values.command.length > 10_000))
|
|
123
122
|
}
|
|
124
123
|
};
|
|
125
124
|
if (isFileTool(toolName)) {
|
|
@@ -154,11 +153,17 @@ export function normalizeClaudeTool(toolName, input, output, failed, truncated,
|
|
|
154
153
|
toolName: normalizedToolName,
|
|
155
154
|
title: compactRunnerText(toolName, 500) || normalizedToolName,
|
|
156
155
|
inputSummary: compactRunnerValue(input, 10_000).text || null,
|
|
157
|
-
outputSummary:
|
|
158
|
-
...(output === null
|
|
156
|
+
outputSummary: null,
|
|
157
|
+
...(output === null
|
|
158
|
+
? {}
|
|
159
|
+
: {
|
|
160
|
+
output: publicToolOutput(output, outputDirection ?? (sourceOutputTruncated ? 'SOURCE' : undefined))
|
|
161
|
+
}),
|
|
159
162
|
progressLabel: null,
|
|
160
163
|
errorCode: failed ? 'TOOL_EXECUTION_FAILED' : null,
|
|
161
|
-
|
|
164
|
+
...(sourceInputTruncated || compactRunnerValue(input, 10_000).truncated
|
|
165
|
+
? { inputTruncated: true }
|
|
166
|
+
: {}),
|
|
162
167
|
...(toolName === 'Read'
|
|
163
168
|
? {
|
|
164
169
|
toolPresentation: {
|
|
@@ -132,7 +132,7 @@ import { conversationImageAttachmentSchema } from '@myagentroam/protocol';
|
|
|
132
132
|
import { parseCodexComposerImageMarkers } from './composer-image-markers.js';
|
|
133
133
|
import { normalizeCodexTool } from './tool-normalizer.js';
|
|
134
134
|
import { shellExecution } from '../execution-presentation.js';
|
|
135
|
-
import {
|
|
135
|
+
import { publicToolOutput } from '../normalization.js';
|
|
136
136
|
import { publicGoalHistoryText } from '../../service/goal-runtime.js';
|
|
137
137
|
const MAX_COMPOSER_ATTACHMENT_BYTES = 5 * 1024 * 1024;
|
|
138
138
|
const MAX_COMPOSER_ATTACHMENTS_BYTES = 10 * 1024 * 1024;
|
|
@@ -551,13 +551,9 @@ export function mergeCodexCustomToolItems(invocation, result) {
|
|
|
551
551
|
completedAt: result.completedAt,
|
|
552
552
|
payload: {
|
|
553
553
|
...invocationPayload,
|
|
554
|
-
outputPreview: resultPayload.outputPreview ??
|
|
555
|
-
resultPayload.outputSummary ??
|
|
556
|
-
invocationPayload.outputPreview,
|
|
557
554
|
...(resultPayload.output === undefined ? {} : { output: resultPayload.output }),
|
|
558
555
|
exitCode: resultPayload.exitCode ?? invocationPayload.exitCode,
|
|
559
556
|
durationMs: resultPayload.durationMs ?? invocationPayload.durationMs,
|
|
560
|
-
truncated: invocationPayload.truncated === true || resultPayload.truncated === true,
|
|
561
557
|
...(resultPayload.attachments === undefined
|
|
562
558
|
? {}
|
|
563
559
|
: { attachments: resultPayload.attachments })
|
|
@@ -576,7 +572,6 @@ export function mergeCodexCustomToolItems(invocation, result) {
|
|
|
576
572
|
outputSummary: resultPayload.outputSummary ?? invocationPayload.outputSummary,
|
|
577
573
|
...(resultPayload.output === undefined ? {} : { output: resultPayload.output }),
|
|
578
574
|
errorCode: resultPayload.errorCode ?? invocationPayload.errorCode,
|
|
579
|
-
truncated: invocationPayload.truncated === true || resultPayload.truncated === true,
|
|
580
575
|
...(resultPayload.attachments === undefined ? {} : { attachments: resultPayload.attachments })
|
|
581
576
|
}
|
|
582
577
|
};
|
|
@@ -720,7 +715,6 @@ export function codexOfficialItem(session, nativeTurnId, value, turnSequence, it
|
|
|
720
715
|
? compactRunnerText(value.command, 10_000)
|
|
721
716
|
: '(No command provided)',
|
|
722
717
|
cwd: typeof value.cwd === 'string' ? compactRunnerText(value.cwd, 4_096) : null,
|
|
723
|
-
outputPreview: publicOutputSnapshot(output).text,
|
|
724
718
|
exitCode: typeof value.exitCode === 'number' && Number.isInteger(value.exitCode)
|
|
725
719
|
? value.exitCode
|
|
726
720
|
: null,
|
|
@@ -729,21 +723,16 @@ export function codexOfficialItem(session, nativeTurnId, value, turnSequence, it
|
|
|
729
723
|
value.durationMs >= 0
|
|
730
724
|
? value.durationMs
|
|
731
725
|
: null,
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
? {
|
|
735
|
-
output: typeof value.aggregatedOutput === 'string'
|
|
736
|
-
? publicOutputSnapshot(output)
|
|
737
|
-
: undefined
|
|
738
|
-
}
|
|
726
|
+
...(typeof value.aggregatedOutput === 'string'
|
|
727
|
+
? { output: publicToolOutput(output, undefined, 'COMBINED') }
|
|
739
728
|
: {}),
|
|
740
|
-
toolPresentation: shellExecution(
|
|
741
|
-
|
|
742
|
-
: output)
|
|
729
|
+
toolPresentation: shellExecution((typeof value.command === 'string' && value.command.length > 10_000) ||
|
|
730
|
+
(typeof value.cwd === 'string' && value.cwd.length > 4_096))
|
|
743
731
|
}
|
|
744
732
|
};
|
|
745
733
|
}
|
|
746
|
-
if (value.type === 'mcpToolCall')
|
|
734
|
+
if (value.type === 'mcpToolCall') {
|
|
735
|
+
const input = compactRunnerValue(value.arguments, 10_000);
|
|
747
736
|
return {
|
|
748
737
|
...base,
|
|
749
738
|
kind: 'tool_call',
|
|
@@ -756,12 +745,14 @@ export function codexOfficialItem(session, nativeTurnId, value, turnSequence, it
|
|
|
756
745
|
.join('.'),
|
|
757
746
|
namespace: typeof value.server === 'string' ? value.server : '',
|
|
758
747
|
toolName: typeof value.tool === 'string' ? value.tool : '',
|
|
759
|
-
inputSummary:
|
|
760
|
-
|
|
761
|
-
|
|
748
|
+
inputSummary: input.text,
|
|
749
|
+
...(input.truncated ? { inputTruncated: true } : {}),
|
|
750
|
+
outputSummary: null,
|
|
751
|
+
...(value.result == null ? {} : { output: publicToolOutput(value.result) }),
|
|
762
752
|
...(value.error === undefined ? {} : { errorCode: codexCompactJson(value.error) })
|
|
763
753
|
}
|
|
764
754
|
};
|
|
755
|
+
}
|
|
765
756
|
if (value.type === 'webSearch')
|
|
766
757
|
return {
|
|
767
758
|
...base,
|
|
@@ -804,15 +795,16 @@ export function codexOfficialItem(session, nativeTurnId, value, turnSequence, it
|
|
|
804
795
|
? value.name
|
|
805
796
|
: 'tool';
|
|
806
797
|
const outputValue = value.contentItems ?? value.output;
|
|
807
|
-
const output = outputValue == null ? undefined :
|
|
798
|
+
const output = outputValue == null ? undefined : codexToolOutput(outputValue);
|
|
799
|
+
const input = compactRunnerValue(value.arguments ?? value.input, 10_000);
|
|
808
800
|
const normalized = normalizeCodexTool({
|
|
809
801
|
name,
|
|
810
802
|
namespace: typeof value.namespace === 'string' ? value.namespace : 'codex',
|
|
811
803
|
rawInput: value.arguments ?? value.input,
|
|
812
|
-
inputSummary:
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
804
|
+
inputSummary: input.text || null,
|
|
805
|
+
inputTruncated: input.truncated,
|
|
806
|
+
outputSummary: output === undefined ? null : typeof output === 'string' ? output : JSON.stringify(output),
|
|
807
|
+
outputTruncated: false,
|
|
816
808
|
outputOnly: value.type === 'custom_tool_call_output' ||
|
|
817
809
|
value.type === 'function_call_output' ||
|
|
818
810
|
value.type === 'customToolCallOutput' ||
|
|
@@ -906,7 +898,6 @@ export function codexLiveConversationItem(value, completed, imageAttachments = [
|
|
|
906
898
|
? compactRunnerText(value.command, 10_000)
|
|
907
899
|
: '(No command provided)',
|
|
908
900
|
cwd: typeof value.cwd === 'string' ? compactRunnerText(value.cwd, 4_096) : null,
|
|
909
|
-
outputPreview: publicOutputSnapshot(output).text,
|
|
910
901
|
exitCode: typeof value.exitCode === 'number' && Number.isInteger(value.exitCode)
|
|
911
902
|
? value.exitCode
|
|
912
903
|
: null,
|
|
@@ -915,21 +906,20 @@ export function codexLiveConversationItem(value, completed, imageAttachments = [
|
|
|
915
906
|
value.durationMs >= 0
|
|
916
907
|
? value.durationMs
|
|
917
908
|
: null,
|
|
918
|
-
truncated: output.length > 10_000,
|
|
919
909
|
...(completed
|
|
920
910
|
? {
|
|
921
911
|
output: typeof value.aggregatedOutput === 'string'
|
|
922
|
-
?
|
|
912
|
+
? publicToolOutput(output, undefined, 'COMBINED')
|
|
923
913
|
: undefined
|
|
924
914
|
}
|
|
925
915
|
: {}),
|
|
926
|
-
toolPresentation: shellExecution(
|
|
916
|
+
toolPresentation: shellExecution((typeof value.command === 'string' && value.command.length > 10_000) ||
|
|
917
|
+
(typeof value.cwd === 'string' && value.cwd.length > 4_096))
|
|
927
918
|
}
|
|
928
919
|
};
|
|
929
920
|
}
|
|
930
921
|
if (value.type === 'mcpToolCall') {
|
|
931
922
|
const input = compactRunnerValue(value.arguments, 10_000);
|
|
932
|
-
const output = compactRunnerValue(value.result, 10_000);
|
|
933
923
|
const error = compactRunnerValue(value.error, 80);
|
|
934
924
|
const server = typeof value.server === 'string' ? value.server : 'mcp';
|
|
935
925
|
const tool = typeof value.tool === 'string' ? value.tool : 'tool';
|
|
@@ -942,11 +932,11 @@ export function codexLiveConversationItem(value, completed, imageAttachments = [
|
|
|
942
932
|
toolName: compactRunnerText(tool, 128),
|
|
943
933
|
title: compactRunnerText(`${server}.${tool}`, 500),
|
|
944
934
|
inputSummary: input.text || null,
|
|
945
|
-
outputSummary:
|
|
946
|
-
...(value.result == null ? {} : { output:
|
|
935
|
+
outputSummary: null,
|
|
936
|
+
...(value.result == null ? {} : { output: publicToolOutput(value.result) }),
|
|
947
937
|
progressLabel: null,
|
|
948
938
|
errorCode: error.text || null,
|
|
949
|
-
|
|
939
|
+
...(input.truncated ? { inputTruncated: true } : {})
|
|
950
940
|
}
|
|
951
941
|
};
|
|
952
942
|
}
|
|
@@ -1021,7 +1011,7 @@ export function codexLiveConversationItem(value, completed, imageAttachments = [
|
|
|
1021
1011
|
: 'tool';
|
|
1022
1012
|
const input = compactRunnerValue(value.arguments ?? value.input, 10_000);
|
|
1023
1013
|
const outputValue = value.contentItems ?? value.output;
|
|
1024
|
-
const output = outputValue == null ? undefined :
|
|
1014
|
+
const output = outputValue == null ? undefined : codexToolOutput(outputValue);
|
|
1025
1015
|
const outputOnly = value.type === 'custom_tool_call_output' ||
|
|
1026
1016
|
value.type === 'function_call_output' ||
|
|
1027
1017
|
value.type === 'customToolCallOutput' ||
|
|
@@ -1031,9 +1021,10 @@ export function codexLiveConversationItem(value, completed, imageAttachments = [
|
|
|
1031
1021
|
namespace: typeof value.namespace === 'string' ? value.namespace : 'codex',
|
|
1032
1022
|
rawInput: value.arguments ?? value.input,
|
|
1033
1023
|
inputSummary: input.text || null,
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1024
|
+
inputTruncated: input.truncated,
|
|
1025
|
+
outputSummary: output === undefined ? null : typeof output === 'string' ? output : JSON.stringify(output),
|
|
1026
|
+
truncated: input.truncated,
|
|
1027
|
+
outputTruncated: false,
|
|
1037
1028
|
outputOnly,
|
|
1038
1029
|
attachments: imageAttachments
|
|
1039
1030
|
});
|
|
@@ -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 {
|
|
4
|
+
import { publicToolOutput } 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';
|
|
@@ -280,14 +280,14 @@ export class CodexManagedRunController {
|
|
|
280
280
|
if (notification.method === 'item/commandExecution/outputDelta' &&
|
|
281
281
|
typeof params.itemId === 'string' &&
|
|
282
282
|
typeof params.delta === 'string') {
|
|
283
|
-
const output =
|
|
283
|
+
const output = publicToolOutput(params.delta, undefined, 'COMBINED');
|
|
284
284
|
this.emitItem(runId, {
|
|
285
285
|
itemId: boundedConversationItemId('codex', params.itemId),
|
|
286
286
|
kind: 'command_execution',
|
|
287
287
|
status: 'IN_PROGRESS',
|
|
288
|
-
payload: {
|
|
288
|
+
payload: { output },
|
|
289
289
|
merge: true,
|
|
290
|
-
append: 'output'
|
|
290
|
+
...(output.truncation === 'HEAD' ? {} : { append: 'output' })
|
|
291
291
|
});
|
|
292
292
|
return;
|
|
293
293
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { homedir } from 'node:os';
|
|
2
2
|
import { basename, join } from 'node:path';
|
|
3
3
|
import { forEachJsonlRecord } from '../../native-jsonl-reader.js';
|
|
4
|
-
import { compactRunnerValue as compactValue } from '../normalization.js';
|
|
4
|
+
import { compactRunnerValue as compactValue, publicOutputSnapshot } from '../normalization.js';
|
|
5
5
|
import { stripGoalStartPrompt, publicGoalHistoryText } from '../../service/goal-runtime.js';
|
|
6
6
|
import { parseCodexComposerImageMarkers } from './composer-image-markers.js';
|
|
7
7
|
import { codexTranscriptSourceItemId } from './conversation-parser.js';
|
|
@@ -167,7 +167,7 @@ function codexToolResultsOf(record, createdAt) {
|
|
|
167
167
|
const toolUseId = firstString(payload, ['call_id', 'id']);
|
|
168
168
|
if (toolUseId === undefined)
|
|
169
169
|
return [];
|
|
170
|
-
const output =
|
|
170
|
+
const output = publicOutputSnapshot(codexToolOutput(payload['output'] ?? payload['contentItems']));
|
|
171
171
|
const imageAttachments = codexImagePlaceholders(payload['output'] ?? payload['contentItems']);
|
|
172
172
|
return [
|
|
173
173
|
{
|
|
@@ -566,7 +566,9 @@ export const codexNativeTranscriptAdapter = {
|
|
|
566
566
|
rawInput: entry.input,
|
|
567
567
|
inputSummary: entry.inputSummary,
|
|
568
568
|
outputSummary: entry.outputSummary,
|
|
569
|
-
|
|
569
|
+
inputTruncated: entry.inputTruncated,
|
|
570
|
+
outputTruncated: entry.outputTruncated,
|
|
571
|
+
...(entry.outputTruncated ? { outputDirection: 'HEAD' } : {}),
|
|
570
572
|
...(entry.imageAttachments === undefined ? {} : { attachments: entry.imageAttachments })
|
|
571
573
|
}),
|
|
572
574
|
userInputQuestions: () => []
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { compactRunnerText,
|
|
1
|
+
import { compactRunnerText, publicToolOutput } from '../normalization.js';
|
|
2
2
|
import { shellExecution } from '../execution-presentation.js';
|
|
3
3
|
export function normalizeCodexApproval(method) {
|
|
4
4
|
return method === 'item/commandExecution/requestApproval'
|
|
@@ -10,20 +10,18 @@ export function normalizeCodexTool(input) {
|
|
|
10
10
|
const rawInput = input.rawInput;
|
|
11
11
|
const attachments = input.attachments ?? [];
|
|
12
12
|
const outputTruncated = input.outputTruncated ?? (input.outputSummary != null && input.truncated === true);
|
|
13
|
+
const outputDirection = input.outputDirection ?? (outputTruncated ? 'SOURCE' : undefined);
|
|
13
14
|
const subagent = codexSubagentProjection(input.namespace, name, rawInput, input.outputSummary);
|
|
14
15
|
if (isCommandTool(name)) {
|
|
15
|
-
const outputPreview = compactRunnerText(input.outputSummary ?? '', 10_000);
|
|
16
16
|
if (input.outputOnly === true)
|
|
17
17
|
return {
|
|
18
18
|
kind: 'command_execution',
|
|
19
19
|
payload: {
|
|
20
20
|
toolName: name,
|
|
21
|
-
outputPreview,
|
|
22
|
-
truncated: input.truncated === true || (input.outputSummary?.length ?? 0) > 10_000,
|
|
23
21
|
...(input.outputSummary == null
|
|
24
22
|
? {}
|
|
25
|
-
: { output:
|
|
26
|
-
toolPresentation: shellExecution(
|
|
23
|
+
: { output: publicToolOutput(input.outputSummary, outputDirection, 'COMBINED') }),
|
|
24
|
+
toolPresentation: shellExecution(),
|
|
27
25
|
...(attachments.length === 0 ? {} : { attachments })
|
|
28
26
|
}
|
|
29
27
|
};
|
|
@@ -41,16 +39,14 @@ export function normalizeCodexTool(input) {
|
|
|
41
39
|
toolName: name,
|
|
42
40
|
command: compactRunnerText(command, 10_000),
|
|
43
41
|
cwd: typeof values?.cwd === 'string' ? compactRunnerText(values.cwd, 4_096) : null,
|
|
44
|
-
outputPreview,
|
|
45
42
|
exitCode: null,
|
|
46
43
|
durationMs: null,
|
|
47
|
-
toolPresentation: shellExecution(input.
|
|
44
|
+
toolPresentation: shellExecution(input.inputTruncated === true ||
|
|
45
|
+
command.length > 10_000 ||
|
|
46
|
+
(typeof values?.cwd === 'string' && values.cwd.length > 4_096)),
|
|
48
47
|
...(input.outputSummary == null
|
|
49
48
|
? {}
|
|
50
|
-
: { output:
|
|
51
|
-
truncated: input.truncated === true ||
|
|
52
|
-
command.length > 10_000 ||
|
|
53
|
-
(input.outputSummary?.length ?? 0) > 10_000,
|
|
49
|
+
: { output: publicToolOutput(input.outputSummary, outputDirection, 'COMBINED') }),
|
|
54
50
|
...(attachments.length === 0 ? {} : { attachments })
|
|
55
51
|
}
|
|
56
52
|
};
|
|
@@ -59,10 +55,10 @@ export function normalizeCodexTool(input) {
|
|
|
59
55
|
return {
|
|
60
56
|
kind: 'tool_call',
|
|
61
57
|
payload: {
|
|
62
|
-
outputSummary:
|
|
58
|
+
outputSummary: null,
|
|
63
59
|
...(input.outputSummary == null
|
|
64
60
|
? {}
|
|
65
|
-
: { output:
|
|
61
|
+
: { output: publicToolOutput(input.outputSummary, outputDirection) }),
|
|
66
62
|
...subagent,
|
|
67
63
|
...(attachments.length === 0 ? {} : { attachments })
|
|
68
64
|
}
|
|
@@ -74,13 +70,13 @@ export function normalizeCodexTool(input) {
|
|
|
74
70
|
namespace: compactRunnerText(input.namespace ?? 'codex', 128),
|
|
75
71
|
toolName: name,
|
|
76
72
|
inputSummary: input.inputSummary ?? null,
|
|
77
|
-
outputSummary:
|
|
73
|
+
outputSummary: null,
|
|
78
74
|
...(input.outputSummary == null
|
|
79
75
|
? {}
|
|
80
|
-
: { output:
|
|
76
|
+
: { output: publicToolOutput(input.outputSummary, outputDirection) }),
|
|
81
77
|
progressLabel: null,
|
|
82
78
|
errorCode: null,
|
|
83
|
-
|
|
79
|
+
...(input.inputTruncated ? { inputTruncated: true } : {}),
|
|
84
80
|
...subagent,
|
|
85
81
|
...(attachments.length === 0 ? {} : { attachments })
|
|
86
82
|
}
|
|
@@ -1,53 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
function
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
/** Keep public execution output bounded without copying an unbounded source. */
|
|
10
|
-
export function boundExecutionPresentation(execution) {
|
|
11
|
-
let truncated = (execution.output?.length ?? 0) > 4;
|
|
12
|
-
const output = execution.output?.slice(0, 4).map((block) => {
|
|
13
|
-
if (block.text.length > 10_000)
|
|
14
|
-
truncated = true;
|
|
15
|
-
return { ...block, text: tail(block.text, 10_000) };
|
|
16
|
-
});
|
|
17
|
-
const detail = {
|
|
18
|
-
...execution,
|
|
19
|
-
...(output === undefined ? {} : { output }),
|
|
20
|
-
...(execution.truncation === undefined ? {} : { truncation: { ...execution.truncation } })
|
|
21
|
-
};
|
|
22
|
-
if (truncated)
|
|
23
|
-
detail.truncation = { ...detail.truncation, output: detail.truncation?.output ?? 'HEAD' };
|
|
24
|
-
const presentation = { kind: 'EXECUTION', execution: detail };
|
|
25
|
-
const size = () => Buffer.byteLength(JSON.stringify(presentation));
|
|
26
|
-
for (const block of [...(detail.output ?? [])].reverse()) {
|
|
27
|
-
if (size() <= MAX_BYTES)
|
|
28
|
-
break;
|
|
29
|
-
const source = block.text;
|
|
30
|
-
detail.truncation = { ...detail.truncation, output: detail.truncation?.output ?? 'HEAD' };
|
|
31
|
-
truncated = true;
|
|
32
|
-
let low = 0;
|
|
33
|
-
let high = source.length;
|
|
34
|
-
while (low < high) {
|
|
35
|
-
const middle = Math.ceil((low + high) / 2);
|
|
36
|
-
block.text = tail(source, middle);
|
|
37
|
-
if (size() <= MAX_BYTES)
|
|
38
|
-
low = middle;
|
|
39
|
-
else
|
|
40
|
-
high = middle - 1;
|
|
1
|
+
/** Execution metadata is independent of the public output body and its budget. */
|
|
2
|
+
export function shellExecution(inputTruncated = false) {
|
|
3
|
+
return {
|
|
4
|
+
kind: 'EXECUTION',
|
|
5
|
+
execution: {
|
|
6
|
+
kind: 'SHELL',
|
|
7
|
+
...(inputTruncated ? { truncation: { input: true } } : {})
|
|
41
8
|
}
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
return { presentation, truncated };
|
|
45
|
-
}
|
|
46
|
-
/** Project only the stream facts actually supplied by the runner. */
|
|
47
|
-
export function shellExecution(output, sourceTruncated = false) {
|
|
48
|
-
return boundExecutionPresentation({
|
|
49
|
-
kind: 'SHELL',
|
|
50
|
-
...(output === undefined ? {} : { output: [{ channel: 'COMBINED', text: output }] }),
|
|
51
|
-
...(sourceTruncated ? { truncation: { output: 'SOURCE' } } : {})
|
|
52
|
-
}).presentation;
|
|
9
|
+
};
|
|
53
10
|
}
|