@myagentroam/node 0.11.44 → 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/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 +42 -12
- package/dist/runner/mar-agent/agent-operation-presentation.js +167 -0
- package/dist/runner/mar-agent/conversation-normalizer.js +118 -107
- package/dist/runner/normalization.js +5 -0
- package/dist/runner/opencode/tool-normalizer.js +10 -10
- package/dist/service/agent-network-bindings.js +4 -0
- 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
|
@@ -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
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { agentNetworkWaitModelOutput } from './agent-network-wait-output.js';
|
|
2
|
+
import { agentOperationEvent } from './agent-operation-presentation.js';
|
|
2
3
|
const text = { type: 'string', minLength: 1 };
|
|
3
4
|
const attachmentIds = {
|
|
4
5
|
type: 'array',
|
|
@@ -112,11 +113,50 @@ const tools = [
|
|
|
112
113
|
required: ['agentId']
|
|
113
114
|
}
|
|
114
115
|
];
|
|
116
|
+
const delegationPrompt = [
|
|
117
|
+
'# Delegation and coordination',
|
|
118
|
+
'Delegate bounded, self-contained tasks when independent progress or context savings materially helps. Keep simple or tightly coupled work local.',
|
|
119
|
+
'Give each child an objective, necessary context, expected output, and a read-only boundary or non-overlapping write scope.',
|
|
120
|
+
'While children run, continue meaningful non-overlapping work. Do not redo delegated work. Wait only when the next step needs the result.',
|
|
121
|
+
'Verify consequential findings and changes. Join or stop task-required child work before final delivery, and retain responsibility for the final result.'
|
|
122
|
+
].join('\n\n');
|
|
123
|
+
const collaborationPrompt = [
|
|
124
|
+
'# Workspace collaboration',
|
|
125
|
+
"Use native agent_* tools to collaborate within the Agent Network when another Session's context or ongoing work materially helps. Keep requests focused and avoid unnecessary cross-Session coordination. Peer Sessions retain their own work and lifecycle; do not treat them as task-owned children or stop them merely for task cleanup. Sending to a non-child does not subscribe to its updates; explicitly wait when you need its progress or completion."
|
|
126
|
+
].join('\n\n');
|
|
127
|
+
const managementPrompt = [
|
|
128
|
+
'# Workspace management',
|
|
129
|
+
"Load marctl when needed to manage existing Session settings, titles, persistent prompts or schedules, or to discover authorized Nodes, execute remote commands or transfer files. Ordinary Agent collaboration and selecting a child's model or effort at creation use native agent_* tools. Do not switch to marctl when a native operation fails."
|
|
130
|
+
].join('\n\n');
|
|
115
131
|
export function agentNetworkExtension(invoke, currentExecution) {
|
|
116
132
|
return {
|
|
117
133
|
id: 'mar.node.agent-network',
|
|
118
134
|
apiVersion: '1.0',
|
|
119
135
|
attachSession(context) {
|
|
136
|
+
context.hooks.intercept('prompt.sections', (input, _call, next) => {
|
|
137
|
+
const available = new Set(input.facts?.tools);
|
|
138
|
+
const enabled = input.facts?.mode !== 'compact';
|
|
139
|
+
return next({
|
|
140
|
+
...input,
|
|
141
|
+
sections: [
|
|
142
|
+
...input.sections,
|
|
143
|
+
{
|
|
144
|
+
id: 'mar.node.agent-network:delegation',
|
|
145
|
+
text: enabled && available.has('agent_start') ? delegationPrompt : null
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
id: 'mar.node.agent-network:collaboration',
|
|
149
|
+
text: enabled && available.has('agent_send') ? collaborationPrompt : null
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
id: 'mar.node.agent-network:management',
|
|
153
|
+
text: enabled && tools.some((tool) => available.has(`agent_${tool.action}`))
|
|
154
|
+
? managementPrompt
|
|
155
|
+
: null
|
|
156
|
+
}
|
|
157
|
+
]
|
|
158
|
+
});
|
|
159
|
+
});
|
|
120
160
|
for (const tool of tools)
|
|
121
161
|
context.tools.register({
|
|
122
162
|
name: `agent_${tool.action}`,
|
|
@@ -124,6 +164,7 @@ export function agentNetworkExtension(invoke, currentExecution) {
|
|
|
124
164
|
allowedCallers: ['direct', 'programmatic'],
|
|
125
165
|
eventInputFields: [
|
|
126
166
|
'agentId',
|
|
167
|
+
'agentIds',
|
|
127
168
|
'title',
|
|
128
169
|
'executionId',
|
|
129
170
|
'runner',
|
|
@@ -144,22 +185,11 @@ export function agentNetworkExtension(invoke, currentExecution) {
|
|
|
144
185
|
if (!executionId)
|
|
145
186
|
throw new Error('AGENT_ACTOR_NOT_ACTIVE');
|
|
146
187
|
const result = await invoke(executionId, tool.action, input, call);
|
|
147
|
-
const value = result !== null && typeof result === 'object' && !Array.isArray(result)
|
|
148
|
-
? result
|
|
149
|
-
: undefined;
|
|
150
|
-
const id = value?.agentId;
|
|
151
|
-
const eventData = ['start', 'send', 'stop', 'wait'].includes(tool.action) &&
|
|
152
|
-
typeof id === 'string' &&
|
|
153
|
-
id.length > 0 &&
|
|
154
|
-
id.length <= 128
|
|
155
|
-
? { agentId: id, productSessionId: id }
|
|
156
|
-
: undefined;
|
|
157
188
|
const modelResult = tool.action === 'wait' ? agentNetworkWaitModelOutput(result) : result;
|
|
158
189
|
return {
|
|
159
190
|
data: result,
|
|
160
191
|
content: JSON.stringify(modelResult),
|
|
161
|
-
|
|
162
|
-
eventData: eventData ?? {}
|
|
192
|
+
...agentOperationEvent(tool.action, input, result)
|
|
163
193
|
};
|
|
164
194
|
}
|
|
165
195
|
});
|