@openclaw/codex 2026.9.5 → 2026.9.7
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/README.md +2 -0
- package/assets/icon.png +0 -0
- package/dist/.setup/{account-usage-runtime-C2MOIvfq.mjs → account-usage-runtime-DFhbh1zz.mjs} +6 -6
- package/dist/.setup/{apply-CJ0ZfmBG.mjs → apply-D3GcSoSa.mjs} +35 -55
- package/dist/.setup/{attempt-client-cleanup-BpYKdTA0.mjs → attempt-client-cleanup-DOP-cW5j.mjs} +179 -73
- package/dist/.setup/attempt-workspace-context-C5HigshI.mjs +164 -0
- package/dist/.setup/{auth-binding-DhLWa_7K.mjs → auth-binding-BLWz7stm.mjs} +14 -1
- package/dist/.setup/{auth-cache-key-QirmgiCo.mjs → auth-cache-key-Dbvq-QgB.mjs} +41 -111
- package/dist/.setup/{auth-profile-WqZtZfXN.mjs → auth-profile-B0okYl2D.mjs} +1 -2
- package/dist/.setup/auth-profile-health-oHizqgye.mjs +53 -0
- package/dist/.setup/auth-profile-recovery-BREezV0L.mjs +14 -0
- package/dist/.setup/auth-start-options-BPIPeEX8.mjs +44 -0
- package/dist/.setup/{binding-connection-Bm38niE8.mjs → binding-connection-DTtN1KrX.mjs} +2 -2
- package/dist/.setup/{binding-connection.runtime-CnRMC0ta.mjs → binding-connection.runtime-6TpgD1M6.mjs} +5 -5
- package/dist/.setup/{bounded-turn-BtlZcivC.mjs → bounded-turn-CbjoN2OW.mjs} +140 -37
- package/dist/.setup/bounded-turn-isolation-B8K_ylqk.mjs +14 -0
- package/dist/.setup/{build-state-Xx9ybZqa.mjs → build-state-Da1_z0kd.mjs} +1 -1
- package/dist/.setup/{capabilities-_vXcZGSx.mjs → capabilities-B3WEZl4e.mjs} +2 -10
- package/dist/.setup/{client-vXs2929Q.mjs → client-N0JpgSzF.mjs} +635 -872
- package/dist/.setup/client-catalog-response-5HHLdcde.mjs +285 -0
- package/dist/.setup/{command-dispatch-naHIZwwF.mjs → command-dispatch-BeAoaovI.mjs} +9 -8
- package/dist/.setup/{command-formatters-CGEkdawF.mjs → command-formatters-R3ckE3Co.mjs} +36 -64
- package/dist/.setup/{command-handlers-BtAJEW1X.mjs → command-handlers-ylTMS00z.mjs} +301 -488
- package/dist/.setup/{command-rpc-DHFpn4le.mjs → command-rpc-CGJGUQ6Y.mjs} +40 -28
- package/dist/.setup/compact-C2WamavS.mjs +776 -0
- package/dist/.setup/{config-CedDWjM-.mjs → config-DKhXquav.mjs} +26 -28
- package/dist/.setup/{config-options-BsanJ8QG.mjs → config-options-CzyWLTJt.mjs} +68 -65
- package/dist/.setup/{config-parsing-CcB9iPoq.mjs → config-parsing-b088LyhT.mjs} +57 -60
- package/dist/.setup/{config-runtime-CeAhl_h4.mjs → config-runtime-C0NbLms1.mjs} +2 -2
- package/dist/.setup/{config-security-BRQ2mgW9.mjs → config-security-CE-FcGw9.mjs} +51 -215
- package/dist/.setup/{config-utils-DujwEnhg.mjs → config-utils-D0CXecki.mjs} +3 -13
- package/dist/.setup/context-engine-projection-PezSESth.mjs +387 -0
- package/dist/.setup/{conversation-binding-DhzrpTM6.mjs → conversation-binding-3Min8qvP.mjs} +71 -105
- package/dist/.setup/{conversation-binding-data-CrcyZk6O.mjs → conversation-binding-data-C746z5Pn.mjs} +8 -12
- package/dist/.setup/{conversation-control-DN53ns41.mjs → conversation-control-CEP8X5JC.mjs} +30 -69
- package/dist/.setup/{cyber-failover-DYwbmf1o.mjs → cyber-failover-XV0nNRZu.mjs} +1 -1
- package/dist/.setup/{cyber-failover-notice-e9G3J9-e.mjs → cyber-failover-notice-RNpGpTyP.mjs} +1 -1
- package/dist/.setup/{dynamic-tools-D16lOp67.mjs → dynamic-tools-DzlsLUuS.mjs} +3136 -3167
- package/dist/.setup/{effective-mcp-catalog-K6kLCN8X.mjs → effective-mcp-catalog-CxUtC-xG.mjs} +8 -17
- package/dist/.setup/{ephemeral-turn-R1gA8Sn6.mjs → ephemeral-turn-CDsPJOa2.mjs} +9 -6
- package/dist/.setup/event-projector-assistant-message-CigreO4K.mjs +69 -0
- package/dist/.setup/{event-projector-usage-C7Ntzs-f.mjs → event-projector-usage-03R0I2dM.mjs} +4 -26
- package/dist/.setup/event-projector-values-DJSz8BTk.mjs +106 -0
- package/dist/.setup/incognito-session-DWYapfwf.mjs +2 -0
- package/dist/.setup/{inference-context-fulhZuz8.mjs → inference-context-D-9gWlTR.mjs} +16 -18
- package/dist/.setup/inference-dispatch-CMZtjQyz.mjs +359 -0
- package/dist/.setup/inference-metadata-CgIf7sOx.mjs +81 -0
- package/dist/.setup/inference-proxy-DhcXOgUE.mjs +561 -0
- package/dist/.setup/{isolated-completion-B6srt48J.mjs → isolated-completion-Dm3PzxJk.mjs} +15 -11
- package/dist/.setup/launch-args-DbFCehO7.mjs +196 -0
- package/dist/.setup/{managed-binary-DP6Rib3P.mjs → managed-binary-kiWRhNRE.mjs} +16 -9
- package/dist/.setup/{model-catalog-DkvUuBey.mjs → model-catalog-PAuZgJC6.mjs} +14 -14
- package/dist/.setup/model-runtime-BdqzOMkU.mjs +11 -0
- package/dist/.setup/{models-BDFgm_G-.mjs → models-DHXZtVVk.mjs} +9 -18
- package/dist/.setup/{native-auth-BLZGqFjw.mjs → native-auth-CuG53tu4.mjs} +5 -5
- package/dist/.setup/{native-execution-policy-YBMHSzC4.mjs → native-execution-policy-BxZJy5mP.mjs} +6 -31
- package/dist/.setup/{native-subagent-monitor-B1hxzIOy.mjs → native-subagent-monitor-Dpsmf2wz.mjs} +4422 -3808
- package/dist/.setup/native-subagent-pending-assignments-DwkCzLvD.mjs +203 -0
- package/dist/.setup/native-task-assignments-DMQ0g3hu.mjs +194 -0
- package/dist/.setup/{node-cli-sessions-Cl8b2ZF3.mjs → node-cli-sessions-HC4W6FLI.mjs} +99 -111
- package/dist/.setup/node-exec-server.runtime-BgBfWQqo.mjs +244 -0
- package/dist/.setup/{plan-xD7WKYTM.mjs → plan-Y-QIvrKB.mjs} +118 -163
- package/dist/.setup/{plugin-activation-r8nq5Jzp.mjs → plugin-activation-cNHRfaxU.mjs} +10 -47
- package/dist/.setup/{plugin-app-cache-key-BOxKP7db.mjs → plugin-app-cache-key-BL9B5H0L.mjs} +9 -42
- package/dist/.setup/{plugin-inventory-DUle8DLz.mjs → plugin-inventory-Cky2XJUw.mjs} +32 -23
- package/dist/.setup/{plugin-marketplace-discovery-P-Vndfqq.mjs → plugin-marketplace-discovery-D_dV9FXa.mjs} +22 -25
- package/dist/.setup/{plugin-metadata-cache-DsS5buNa.mjs → plugin-metadata-cache-DsjsL1dr.mjs} +328 -318
- package/dist/.setup/protocol-CANUwXJ3.mjs +17 -0
- package/dist/.setup/provider-DH8NSzGt.mjs +51 -0
- package/dist/.setup/{provider-capabilities-B8J4Dy-O.mjs → provider-capabilities-CAxoF-X1.mjs} +35 -12
- package/dist/.setup/{rate-limits-DOEGYRNs.mjs → rate-limits-B7-X2TgG.mjs} +123 -166
- package/dist/.setup/{request-BioXJLYa.mjs → request-BHZ1nz8d.mjs} +25 -16
- package/dist/.setup/responses-oauth-twnuTaAa.mjs +93 -0
- package/dist/.setup/rpc-error-BlD2vuzn.mjs +31 -0
- package/dist/.setup/{run-attempt-rlA07pUv.mjs → run-attempt-D8RZUOzY.mjs} +2046 -1454
- package/dist/.setup/{run-attempt-lifecycle-B7JbY4-F.mjs → run-attempt-lifecycle-C-6O3Exn.mjs} +10 -24
- package/dist/.setup/{runtime-artifact-Dy38Z5iU.mjs → runtime-artifact-DDQ-HGXf.mjs} +43 -47
- package/dist/.setup/runtime-artifact-connection-D68qQn1m.mjs +78 -0
- package/dist/.setup/sandbox-guard-DjCz2eOw.mjs +126 -0
- package/dist/.setup/scope-DOC1Xjc8.mjs +6 -0
- package/dist/.setup/session-binding-DGCYAfvD.mjs +443 -0
- package/dist/.setup/{session-binding-record-TH3xA0zj.mjs → session-binding-record-Oe9L-CNY.mjs} +73 -132
- package/dist/.setup/{session-binding-sidecars-CKYEcfNn.mjs → session-binding-sidecars-jo6H8dFr.mjs} +242 -60
- package/dist/.setup/{session-catalog-fUdWDx-U.mjs → session-catalog-4sCdv5qx.mjs} +598 -452
- package/dist/.setup/{session-catalog-adoption-CR_whkEW.mjs → session-catalog-adoption-BU_pHWG7.mjs} +59 -26
- package/dist/.setup/{session-catalog-archive-CwZaPacf.mjs → session-catalog-archive-spHfihri.mjs} +7 -7
- package/dist/.setup/session-catalog-events-DePDzzjc.mjs +139 -0
- package/dist/.setup/session-catalog-home-id-vlih0B_g.mjs +22 -0
- package/dist/.setup/{session-catalog-index-B141u15s.mjs → session-catalog-index-CZvDzC6z.mjs} +286 -182
- package/dist/.setup/{session-catalog-index-order-Cc5BzlQr.mjs → session-catalog-index-order-BcQpHks3.mjs} +2 -2
- package/dist/.setup/{session-catalog-index-state-BAuDztHN.mjs → session-catalog-index-state-TeO7EyO-.mjs} +6 -2
- package/dist/.setup/session-catalog-limits-DDxOsQeC.mjs +14 -0
- package/dist/.setup/session-catalog-list-request-CvtxrYSe.mjs +170 -0
- package/dist/.setup/session-catalog-native-projection-DjhwGL6x.mjs +178 -0
- package/dist/.setup/{session-catalog-node-adoption-BVRsYOSh.mjs → session-catalog-node-adoption-DgXvSGu0.mjs} +30 -35
- package/dist/.setup/{session-catalog-node-continue-Dowv8osw.mjs → session-catalog-node-continue-DjKXHBbi.mjs} +25 -18
- package/dist/.setup/session-catalog-node-lookup-CtAXI5W5.mjs +56 -0
- package/dist/.setup/{session-catalog-native-projection-ChV3cCtm.mjs → session-catalog-parsing-CPGaPYr-.mjs} +14 -180
- package/dist/.setup/{session-catalog-projection-C1Bj9Jl-.mjs → session-catalog-projection-Cr5qP5Dj.mjs} +15 -5
- package/dist/.setup/session-catalog-provenance-DoAvktcj.mjs +95 -0
- package/dist/.setup/{session-cli-DIj-IE-E.mjs → session-cli-Cn_nCqfq.mjs} +11 -24
- package/dist/.setup/{session-history-C--SrLI8.mjs → session-history-D83lJWHG.mjs} +16 -23
- package/dist/.setup/{session-history-import-JHXT5Xfi.mjs → session-history-import-WhX-X33a.mjs} +7 -10
- package/dist/.setup/session-history-read-Ov3StuL4.mjs +133 -0
- package/dist/.setup/{session-history.worker-CpNj7H_P.mjs → session-history.worker-MnPKncqP.mjs} +14 -23
- package/dist/.setup/session-initialization-6aveB9qb.mjs +22 -0
- package/dist/.setup/{session-permission-policy-DhurXY0l.mjs → session-permission-policy-Ci_fVX6y.mjs} +4 -8
- package/dist/.setup/{session-retirement-CU87AOg9.mjs → session-retirement-qMTxkNx2.mjs} +31 -12
- package/dist/.setup/{settled-turn-context-fmwouT5I.mjs → settled-turn-context-D4yj4rxf.mjs} +1 -1
- package/dist/.setup/{settled-turn-finalizer-CiY2bLFK.mjs → settled-turn-finalizer-BsvEabkw.mjs} +17 -13
- package/dist/.setup/{shared-client-BpTtuLQ5.mjs → shared-client-DqyTMYug.mjs} +826 -485
- package/dist/.setup/shared-client-lifecycle-DJIgqgMw.mjs +153 -0
- package/dist/.setup/{side-question-DSCZyoBD.mjs → side-question-C4kCmQy1.mjs} +206 -334
- package/dist/.setup/{source-Bjp4UQij.mjs → source-CS_7GFJZ.mjs} +82 -139
- package/dist/.setup/spawn-error-CL3n6MAa.mjs +57 -0
- package/dist/.setup/{thread-archive-guard-jmecf6OJ.mjs → thread-archive-guard-C9frICzX.mjs} +10 -3
- package/dist/.setup/thread-lifecycle-DPflntEJ.mjs +2362 -0
- package/dist/.setup/{incognito-session-uhrBF6wJ.mjs → thread-ownership-queue-Dp24d7-F.mjs} +1 -2
- package/dist/.setup/{thread-ownership-skomxnIt.mjs → thread-ownership-roNP0l1c.mjs} +47 -10
- package/dist/.setup/thread-policy-DTd-DtkX.mjs +109 -0
- package/dist/.setup/thread-requests-B_bRnMGN.mjs +2102 -0
- package/dist/.setup/{thread-resume-BkNpj9Pz.mjs → thread-resume-CdDaoc7T.mjs} +6 -6
- package/dist/.setup/timeout-CXOfNoaX.mjs +46 -0
- package/dist/.setup/transcript-history-projection-DRSifI-1.mjs +201 -0
- package/dist/.setup/{transcript-mirror-attestation-CzM-94NC.mjs → transcript-mirror-attestation-YSegaktH.mjs} +3 -4
- package/dist/.setup/{transcript-mirror-D4qp_leP.mjs → transcript-mirror-kxmCYsuF.mjs} +224 -206
- package/dist/.setup/{transport-stdio-Cmx94Oiy.mjs → transport-stdio-Bdegpn2V.mjs} +138 -75
- package/dist/.setup/transport-websocket-BTBE-LD9.mjs +211 -0
- package/dist/.setup/{upstream-prompt-provenance-LphB8slG.mjs → upstream-prompt-provenance-fXkKbPVC.mjs} +3 -9
- package/dist/.setup/{upstream-session-fork-D3UKxgVD.mjs → upstream-session-fork-CBeVjBpT.mjs} +48 -40
- package/dist/.setup/{usage-BOgBEKso.mjs → usage-BMzNxeR_.mjs} +5 -4
- package/dist/.setup/{usage-limit-error-C0ow7DOc.mjs → usage-limit-error-QXerDo3i.mjs} +5 -20
- package/dist/.setup/{web-search-provider.runtime-CTGuJt6i.mjs → web-search-provider.runtime-P77OUeoo.mjs} +10 -20
- package/dist/api.js +25 -16
- package/dist/catalog-page-worker-entrypoint.js +12 -0
- package/dist/catalog-page.worker.js +9 -0
- package/dist/cli-metadata.js +1 -1
- package/dist/doctor-contract-api.js +50 -8
- package/dist/harness.js +344 -1
- package/dist/index.js +345 -346
- package/dist/media-understanding-provider.js +9 -22
- package/dist/migration-provider-api.js +1 -1
- package/dist/provider-discovery.js +1 -1
- package/dist/session-history-worker-runtime.js +16 -33
- package/dist/session-history.worker.js +1 -1
- package/openclaw.plugin.json +14 -2
- package/package.json +11 -7
- package/dist/.setup/attempt-context-VXVwTCfS.mjs +0 -636
- package/dist/.setup/compact-C3i3qlzj.mjs +0 -687
- package/dist/.setup/event-projector-assistant-message-DNUR1s0A.mjs +0 -105
- package/dist/.setup/event-projector-items-DyTQ_XqL.mjs +0 -200
- package/dist/.setup/harness-rxaaoN-o.mjs +0 -349
- package/dist/.setup/history-rejection-B4nOXNXF.mjs +0 -13
- package/dist/.setup/image-payload-sanitizer-tupAr-2o.mjs +0 -79
- package/dist/.setup/inference-proxy-CC15HuSi.mjs +0 -311
- package/dist/.setup/launch-args-DnMak49W.mjs +0 -111
- package/dist/.setup/local-runtime-attribution-B_2mnqhb.mjs +0 -19
- package/dist/.setup/native-subagent-history-YXaL6dMd.mjs +0 -135
- package/dist/.setup/native-subagent-task-ids-DsuOonKv.mjs +0 -411
- package/dist/.setup/node-exec-server.runtime-BaViBKNz.mjs +0 -226
- package/dist/.setup/plugin-approval-roundtrip-CjfzafAZ.mjs +0 -122
- package/dist/.setup/provider-fFh_-VR3.mjs +0 -50
- package/dist/.setup/rolldown-runtime-8H4AJuhK.mjs +0 -14
- package/dist/.setup/sandbox-guard-BBP-RbTf.mjs +0 -166
- package/dist/.setup/session-binding-_0W_fHRr.mjs +0 -721
- package/dist/.setup/session-catalog-events-jMcYfQyd.mjs +0 -250
- package/dist/.setup/session-history-read-B3ZfSUbF.mjs +0 -50
- package/dist/.setup/session-initialization-DH1z6fXn.mjs +0 -75
- package/dist/.setup/thread-history-page-BTx-4xsg.mjs +0 -83
- package/dist/.setup/thread-lifecycle-Cik28qWn.mjs +0 -4904
- package/dist/.setup/thread-policy-Cjs4B8xf.mjs +0 -54
- package/dist/.setup/timeout-DZF05XrR.mjs +0 -63
- package/dist/.setup/transcript-history-projection-DHNBDhCU.mjs +0 -243
- package/dist/.setup/version-CoqzXPgK.mjs +0 -12
|
@@ -1,411 +0,0 @@
|
|
|
1
|
-
import { m as isJsonObject } from "./config-security-BRQ2mgW9.mjs";
|
|
2
|
-
import { C as readNonEmptyString, _ as normalizeOptionalString$1, c as itemName, l as itemStatus, m as shouldSynthesizeToolProgressForItem, w as readNonEmptyStringArray } from "./event-projector-items-DyTQ_XqL.mjs";
|
|
3
|
-
import { asNonArrayRecord, normalizeOptionalString, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
|
-
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
5
|
-
import { formatToolAggregate, formatToolProgressOutput, inferToolMetaFromArgs } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
6
|
-
import { redactSensitiveFieldValue, redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
|
|
7
|
-
//#region extensions/codex/src/app-server/event-projector-tool-output.ts
|
|
8
|
-
const TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS = 1e4;
|
|
9
|
-
const TOOL_PROGRESS_ECHO_PREFIX_MIN_CHARS = 1024;
|
|
10
|
-
const TOOL_OUTPUT_TRUNCATION_NOTICE_PREFIX = "...(OpenClaw truncated Codex native tool output";
|
|
11
|
-
var ToolOutputAccumulator = class {
|
|
12
|
-
constructor() {
|
|
13
|
-
this.prefixByItem = /* @__PURE__ */ new Map();
|
|
14
|
-
this.originalLengthByItem = /* @__PURE__ */ new Map();
|
|
15
|
-
this.trimStateByItem = /* @__PURE__ */ new Map();
|
|
16
|
-
this.truncatedItemIds = /* @__PURE__ */ new Set();
|
|
17
|
-
this.textByItem = /* @__PURE__ */ new Map();
|
|
18
|
-
}
|
|
19
|
-
append(itemId, delta) {
|
|
20
|
-
const originalLength = (this.originalLengthByItem.get(itemId) ?? this.textByItem.get(itemId)?.length ?? 0) + delta.length;
|
|
21
|
-
this.originalLengthByItem.set(itemId, originalLength);
|
|
22
|
-
const normalizedLength = updateToolOutputTrimState(this.trimStateByItem, itemId, delta);
|
|
23
|
-
const next = appendBoundedToolTranscriptText(this.prefixByItem.get(itemId) ?? this.textByItem.get(itemId) ?? "", this.truncatedItemIds.has(itemId) ? "" : delta, originalLength);
|
|
24
|
-
this.prefixByItem.set(itemId, next.rawPrefix);
|
|
25
|
-
this.textByItem.set(itemId, next.text);
|
|
26
|
-
if (originalLength > 1e4) this.truncatedItemIds.add(itemId);
|
|
27
|
-
return {
|
|
28
|
-
text: next.text,
|
|
29
|
-
originalLength,
|
|
30
|
-
normalizedLength,
|
|
31
|
-
rawPrefix: next.rawPrefix
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
function updateToolOutputTrimState(trimStateByItem, itemId, delta) {
|
|
36
|
-
const state = trimStateByItem.get(itemId) ?? {
|
|
37
|
-
totalLength: 0,
|
|
38
|
-
leadingWhitespaceLength: 0,
|
|
39
|
-
trailingWhitespaceLength: 0,
|
|
40
|
-
sawNonWhitespace: false
|
|
41
|
-
};
|
|
42
|
-
state.totalLength += delta.length;
|
|
43
|
-
const firstNonWhitespace = delta.search(/\S/u);
|
|
44
|
-
if (firstNonWhitespace === -1) {
|
|
45
|
-
if (!state.sawNonWhitespace) state.leadingWhitespaceLength += delta.length;
|
|
46
|
-
state.trailingWhitespaceLength += delta.length;
|
|
47
|
-
trimStateByItem.set(itemId, state);
|
|
48
|
-
return state.sawNonWhitespace ? state.totalLength - state.leadingWhitespaceLength - state.trailingWhitespaceLength : 0;
|
|
49
|
-
}
|
|
50
|
-
if (!state.sawNonWhitespace) {
|
|
51
|
-
state.leadingWhitespaceLength += firstNonWhitespace;
|
|
52
|
-
state.sawNonWhitespace = true;
|
|
53
|
-
}
|
|
54
|
-
state.trailingWhitespaceLength = delta.match(/\s*$/u)?.[0].length ?? 0;
|
|
55
|
-
trimStateByItem.set(itemId, state);
|
|
56
|
-
return state.totalLength - state.leadingWhitespaceLength - state.trailingWhitespaceLength;
|
|
57
|
-
}
|
|
58
|
-
function toolOutputRawEchoSignature(text) {
|
|
59
|
-
const trimmed = text.trim();
|
|
60
|
-
if (!trimmed) return;
|
|
61
|
-
return {
|
|
62
|
-
rawLength: trimmed.length,
|
|
63
|
-
rawPrefix: trimmed.slice(0, TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS)
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
function normalizeToolTranscriptArguments(value) {
|
|
67
|
-
return asNonArrayRecord(value);
|
|
68
|
-
}
|
|
69
|
-
function collectDynamicToolContentText(contentItems) {
|
|
70
|
-
if (!Array.isArray(contentItems)) return "";
|
|
71
|
-
return contentItems.flatMap((entry) => {
|
|
72
|
-
if (!isJsonObject(entry)) return [];
|
|
73
|
-
const text = readStringField(entry, "text");
|
|
74
|
-
return text ? [text] : [];
|
|
75
|
-
}).join("\n");
|
|
76
|
-
}
|
|
77
|
-
function appendBoundedToolTranscriptText(currentPrefix, delta, originalLength) {
|
|
78
|
-
if (originalLength <= 1e4) {
|
|
79
|
-
const rawPrefix = currentPrefix + delta;
|
|
80
|
-
return {
|
|
81
|
-
text: rawPrefix,
|
|
82
|
-
rawPrefix
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
const notice = toolTranscriptTruncationNotice(originalLength);
|
|
86
|
-
if (notice.length >= 1e4) return {
|
|
87
|
-
text: notice.slice(0, TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS),
|
|
88
|
-
rawPrefix: ""
|
|
89
|
-
};
|
|
90
|
-
const textBudget = TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS - notice.length;
|
|
91
|
-
const remaining = Math.max(0, textBudget - currentPrefix.length);
|
|
92
|
-
const prefix = remaining > 0 ? `${currentPrefix}${truncateUtf16Safe(delta, remaining)}` : currentPrefix;
|
|
93
|
-
const rawPrefix = truncateUtf16Safe(prefix, textBudget);
|
|
94
|
-
return {
|
|
95
|
-
text: `${rawPrefix}${notice}`,
|
|
96
|
-
rawPrefix
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
function toolTranscriptTruncationNotice(originalLength) {
|
|
100
|
-
return `\n${`${TOOL_OUTPUT_TRUNCATION_NOTICE_PREFIX}: original ${originalLength} chars, showing ${TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS}; rerun with narrower args.)`}`;
|
|
101
|
-
}
|
|
102
|
-
function truncateToolTranscriptText(text, originalLength = text.length) {
|
|
103
|
-
if (originalLength <= 1e4 && text.length <= 1e4) return text;
|
|
104
|
-
const notice = toolTranscriptTruncationNotice(originalLength);
|
|
105
|
-
if (notice.length >= 1e4) return notice.slice(1, 10001);
|
|
106
|
-
const textBudget = TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS - notice.length;
|
|
107
|
-
return `${truncateUtf16Safe(text, textBudget)}${notice}`;
|
|
108
|
-
}
|
|
109
|
-
function formatToolSummary(toolName, meta) {
|
|
110
|
-
const trimmedMeta = meta?.trim();
|
|
111
|
-
return formatToolAggregate(toolName, trimmedMeta ? [trimmedMeta] : void 0, { markdown: true });
|
|
112
|
-
}
|
|
113
|
-
function formatToolOutput(toolName, meta, output) {
|
|
114
|
-
const formattedOutput = formatToolProgressOutput(output);
|
|
115
|
-
if (!formattedOutput) return formatToolSummary(toolName, meta);
|
|
116
|
-
const fence = markdownFenceForText(formattedOutput);
|
|
117
|
-
return `${formatToolSummary(toolName, meta)}\n${fence}txt\n${formattedOutput}\n${fence}`;
|
|
118
|
-
}
|
|
119
|
-
function markdownFenceForText(text) {
|
|
120
|
-
return "`".repeat(Math.max(3, longestBacktickRun(text) + 1));
|
|
121
|
-
}
|
|
122
|
-
function longestBacktickRun(value) {
|
|
123
|
-
let longest = 0;
|
|
124
|
-
let current = 0;
|
|
125
|
-
for (const char of value) {
|
|
126
|
-
if (char === "`") {
|
|
127
|
-
current += 1;
|
|
128
|
-
longest = Math.max(longest, current);
|
|
129
|
-
continue;
|
|
130
|
-
}
|
|
131
|
-
current = 0;
|
|
132
|
-
}
|
|
133
|
-
return longest;
|
|
134
|
-
}
|
|
135
|
-
//#endregion
|
|
136
|
-
//#region extensions/codex/src/app-server/tool-progress-normalization.ts
|
|
137
|
-
/**
|
|
138
|
-
* Normalizes and sanitizes Codex dynamic-tool progress payloads before they are
|
|
139
|
-
* emitted into OpenClaw events or logs.
|
|
140
|
-
*/
|
|
141
|
-
/** Maps OpenClaw tool-progress config to the mode used by Codex progress metadata. */
|
|
142
|
-
function resolveCodexToolProgressDetailMode(value) {
|
|
143
|
-
return value === "raw" ? "raw" : "explain";
|
|
144
|
-
}
|
|
145
|
-
function isCodexCommandBearingToolCall(name, args) {
|
|
146
|
-
const normalizedName = name?.trim().toLowerCase();
|
|
147
|
-
return normalizedName === "exec" || normalizedName === "bash" || normalizedName === "shell" || typeof args?.command === "string" && args.command.trim().length > 0;
|
|
148
|
-
}
|
|
149
|
-
/** Recursively redacts sensitive strings and handles circular values in event payloads. */
|
|
150
|
-
function sanitizeCodexAgentEventValue(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
151
|
-
if (typeof value === "string") return redactToolPayloadText(value);
|
|
152
|
-
if (Array.isArray(value)) {
|
|
153
|
-
if (seen.has(value)) return "[Circular]";
|
|
154
|
-
seen.add(value);
|
|
155
|
-
return value.map((entry) => sanitizeCodexAgentEventValue(entry, seen));
|
|
156
|
-
}
|
|
157
|
-
if (value && typeof value === "object") {
|
|
158
|
-
if (seen.has(value)) return "[Circular]";
|
|
159
|
-
seen.add(value);
|
|
160
|
-
const out = {};
|
|
161
|
-
for (const [key, child] of Object.entries(value)) out[key] = typeof child === "string" ? redactSensitiveFieldValue(key, child) : sanitizeCodexAgentEventValue(child, seen);
|
|
162
|
-
return out;
|
|
163
|
-
}
|
|
164
|
-
return value;
|
|
165
|
-
}
|
|
166
|
-
/** Sanitizes a record-shaped Codex agent event payload. */
|
|
167
|
-
function sanitizeCodexAgentEventRecord(value) {
|
|
168
|
-
return sanitizeCodexAgentEventValue(value);
|
|
169
|
-
}
|
|
170
|
-
/** Sanitizes dynamic-tool arguments before diagnostic/event emission. */
|
|
171
|
-
function sanitizeCodexToolArguments(value) {
|
|
172
|
-
if (!isJsonObject(value)) return;
|
|
173
|
-
return sanitizeCodexAgentEventRecord(value);
|
|
174
|
-
}
|
|
175
|
-
/** Sanitizes a Codex dynamic-tool response before diagnostic/event emission. */
|
|
176
|
-
function sanitizeCodexToolResponse(response) {
|
|
177
|
-
return sanitizeCodexAgentEventRecord({ ...response });
|
|
178
|
-
}
|
|
179
|
-
/** Infers compact human-readable tool metadata from Codex dynamic-tool arguments. */
|
|
180
|
-
function inferCodexDynamicToolMeta(call, detailMode) {
|
|
181
|
-
return inferToolMetaFromArgs(call.tool, call.arguments, { detailMode });
|
|
182
|
-
}
|
|
183
|
-
//#endregion
|
|
184
|
-
//#region extensions/codex/src/app-server/event-projector-tool-items.ts
|
|
185
|
-
function isNativePostToolUseRelayItem(item) {
|
|
186
|
-
switch (item.type) {
|
|
187
|
-
case "commandExecution":
|
|
188
|
-
case "fileChange":
|
|
189
|
-
case "mcpToolCall": return true;
|
|
190
|
-
default: return false;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
function shouldSuppressChannelProgressForItem(item) {
|
|
194
|
-
if (shouldSynthesizeToolProgressForItem(item)) return true;
|
|
195
|
-
return item.type === "dynamicToolCall";
|
|
196
|
-
}
|
|
197
|
-
function itemToolArgs(item) {
|
|
198
|
-
if (item.type === "commandExecution") return sanitizeCodexAgentEventRecord({
|
|
199
|
-
command: item.command,
|
|
200
|
-
...typeof item.cwd === "string" ? { cwd: item.cwd } : {}
|
|
201
|
-
});
|
|
202
|
-
if (item.type === "fileChange") return sanitizeCodexAgentEventRecord({ changes: itemFileChangesForTranscript(item) });
|
|
203
|
-
if (item.type === "webSearch") return webSearchToolArgs(item);
|
|
204
|
-
if (item.type === "dynamicToolCall" || item.type === "mcpToolCall") return sanitizeCodexToolArguments(item.arguments);
|
|
205
|
-
}
|
|
206
|
-
function isCommandBearingToolItem(item, args) {
|
|
207
|
-
if (item.type === "commandExecution") return true;
|
|
208
|
-
return typeof args?.command === "string" && args.command.trim().length > 0;
|
|
209
|
-
}
|
|
210
|
-
function webSearchToolArgs(item) {
|
|
211
|
-
const action = isJsonObject(item.action) ? item.action : void 0;
|
|
212
|
-
const actionType = action ? readNonEmptyString(action, "type") : void 0;
|
|
213
|
-
const queries = action && actionType === "search" ? readNonEmptyStringArray(action, "queries") : [];
|
|
214
|
-
const query = normalizeOptionalString$1(item.query) ?? (action && actionType === "search" ? readNonEmptyString(action, "query") : void 0) ?? queries[0];
|
|
215
|
-
const url = action ? readNonEmptyString(action, "url") : void 0;
|
|
216
|
-
const pattern = action ? readNonEmptyString(action, "pattern") : void 0;
|
|
217
|
-
const args = {};
|
|
218
|
-
if (query) args.query = query;
|
|
219
|
-
if (queries.length > 0) args.queries = queries;
|
|
220
|
-
if (actionType && actionType !== "search") args.action = actionType;
|
|
221
|
-
if (url) args.url = url;
|
|
222
|
-
if (pattern) args.pattern = pattern;
|
|
223
|
-
if (!query && !url && !pattern) args.queryUnavailable = true;
|
|
224
|
-
return sanitizeCodexAgentEventRecord(args);
|
|
225
|
-
}
|
|
226
|
-
function itemToolResult(item) {
|
|
227
|
-
if (item.type === "commandExecution") return { result: sanitizeCodexAgentEventRecord({
|
|
228
|
-
status: item.status,
|
|
229
|
-
exitCode: item.exitCode,
|
|
230
|
-
durationMs: item.durationMs
|
|
231
|
-
}) };
|
|
232
|
-
if (item.type === "fileChange") return { result: sanitizeCodexAgentEventRecord({
|
|
233
|
-
status: item.status,
|
|
234
|
-
changes: itemFileChanges(item)
|
|
235
|
-
}) };
|
|
236
|
-
if (item.type === "mcpToolCall") return { result: sanitizeCodexAgentEventRecord({
|
|
237
|
-
status: item.status,
|
|
238
|
-
durationMs: item.durationMs,
|
|
239
|
-
...item.error ? { error: item.error } : {},
|
|
240
|
-
...item.result ? { result: item.result } : {}
|
|
241
|
-
}) };
|
|
242
|
-
if (item.type === "webSearch") return { result: webSearchToolResult(item) };
|
|
243
|
-
return {};
|
|
244
|
-
}
|
|
245
|
-
function webSearchToolResult(item) {
|
|
246
|
-
return sanitizeCodexAgentEventRecord({
|
|
247
|
-
status: itemStatus(item),
|
|
248
|
-
...typeof item.durationMs === "number" ? { durationMs: item.durationMs } : {},
|
|
249
|
-
...webSearchToolArgs(item)
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
function itemFileChangeRecords(item) {
|
|
253
|
-
const changes = item.changes;
|
|
254
|
-
return Array.isArray(changes) ? changes.filter(isJsonObject) : [];
|
|
255
|
-
}
|
|
256
|
-
function itemFileChanges(item) {
|
|
257
|
-
return itemFileChangeRecords(item).flatMap((change) => {
|
|
258
|
-
const path = normalizeOptionalString$1(change.path);
|
|
259
|
-
if (!path || change.kind === void 0) return [];
|
|
260
|
-
return [{
|
|
261
|
-
path,
|
|
262
|
-
kind: change.kind
|
|
263
|
-
}];
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
function fileChangeKindType(kind) {
|
|
267
|
-
if (typeof kind === "string") return kind;
|
|
268
|
-
return isJsonObject(kind) ? normalizeOptionalString$1(kind.type) : void 0;
|
|
269
|
-
}
|
|
270
|
-
function countFileContentLines(content) {
|
|
271
|
-
if (!content) return 0;
|
|
272
|
-
const lines = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n");
|
|
273
|
-
if (lines.length > 1 && lines.at(-1) === "") lines.pop();
|
|
274
|
-
return lines.length;
|
|
275
|
-
}
|
|
276
|
-
function fileChangeDiffStat(diff, kind) {
|
|
277
|
-
const kindType = fileChangeKindType(kind);
|
|
278
|
-
if (kindType === "add") return {
|
|
279
|
-
added: countFileContentLines(diff),
|
|
280
|
-
removed: 0
|
|
281
|
-
};
|
|
282
|
-
if (kindType === "delete") return {
|
|
283
|
-
added: 0,
|
|
284
|
-
removed: countFileContentLines(diff)
|
|
285
|
-
};
|
|
286
|
-
let added = 0;
|
|
287
|
-
let removed = 0;
|
|
288
|
-
let inHunk = false;
|
|
289
|
-
for (const line of diff.replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n")) {
|
|
290
|
-
if (line.startsWith("@@")) {
|
|
291
|
-
inHunk = true;
|
|
292
|
-
continue;
|
|
293
|
-
}
|
|
294
|
-
if (!inHunk) continue;
|
|
295
|
-
if (line.startsWith("+")) added += 1;
|
|
296
|
-
else if (line.startsWith("-")) removed += 1;
|
|
297
|
-
}
|
|
298
|
-
return {
|
|
299
|
-
added,
|
|
300
|
-
removed
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
function truncateFileChangeDiffAtLineBoundary(diff, maxChars) {
|
|
304
|
-
if (diff.length <= maxChars) return { diff };
|
|
305
|
-
if (maxChars <= 0) return { diffTruncated: true };
|
|
306
|
-
const boundary = diff.lastIndexOf("\n", maxChars - 1);
|
|
307
|
-
return boundary >= 0 ? {
|
|
308
|
-
diff: diff.slice(0, boundary + 1),
|
|
309
|
-
diffTruncated: true
|
|
310
|
-
} : { diffTruncated: true };
|
|
311
|
-
}
|
|
312
|
-
function itemFileChangesForTranscript(item) {
|
|
313
|
-
let remainingDiffChars = 1e4;
|
|
314
|
-
return itemFileChangeRecords(item).flatMap((change) => {
|
|
315
|
-
const path = normalizeOptionalString$1(change.path);
|
|
316
|
-
if (!path || change.kind === void 0) return [];
|
|
317
|
-
const result = {
|
|
318
|
-
path,
|
|
319
|
-
kind: change.kind
|
|
320
|
-
};
|
|
321
|
-
if (typeof change.diff !== "string") return [result];
|
|
322
|
-
result.stat = fileChangeDiffStat(change.diff, change.kind);
|
|
323
|
-
const bounded = truncateFileChangeDiffAtLineBoundary(change.diff, remainingDiffChars);
|
|
324
|
-
if (bounded.diff !== void 0) {
|
|
325
|
-
result.diff = bounded.diff;
|
|
326
|
-
remainingDiffChars -= bounded.diff.length;
|
|
327
|
-
}
|
|
328
|
-
if (bounded.diffTruncated) result.diffTruncated = true;
|
|
329
|
-
return [result];
|
|
330
|
-
});
|
|
331
|
-
}
|
|
332
|
-
function itemToolError(item, status, outputTextByItem) {
|
|
333
|
-
if (status === "blocked") return "codex native tool blocked";
|
|
334
|
-
if (status !== "failed") return;
|
|
335
|
-
return itemOutputText(item, outputTextByItem) ?? "codex native tool failed";
|
|
336
|
-
}
|
|
337
|
-
function itemMeta(item, detailMode = "explain") {
|
|
338
|
-
if (item.type === "commandExecution" && typeof item.command === "string") return inferToolMetaFromArgs("exec", {
|
|
339
|
-
command: item.command,
|
|
340
|
-
cwd: typeof item.cwd === "string" ? item.cwd : void 0
|
|
341
|
-
}, { detailMode });
|
|
342
|
-
if (item.type === "webSearch") return inferToolMetaFromArgs("web_search", webSearchToolArgs(item), { detailMode });
|
|
343
|
-
const toolName = itemName(item);
|
|
344
|
-
if ((item.type === "dynamicToolCall" || item.type === "mcpToolCall") && toolName) return inferToolMetaFromArgs(toolName, item.arguments, { detailMode });
|
|
345
|
-
}
|
|
346
|
-
function itemOutputText(item, outputTextByItem) {
|
|
347
|
-
if (item.type === "commandExecution") {
|
|
348
|
-
const output = item.aggregatedOutput?.trim() || outputTextByItem?.get(item.id)?.trim();
|
|
349
|
-
return output ? truncateToolTranscriptText(output) : void 0;
|
|
350
|
-
}
|
|
351
|
-
if (item.type === "dynamicToolCall") {
|
|
352
|
-
const output = collectDynamicToolContentText(item.contentItems).trim();
|
|
353
|
-
return output ? truncateToolTranscriptText(output) : void 0;
|
|
354
|
-
}
|
|
355
|
-
if (item.type === "mcpToolCall") {
|
|
356
|
-
const output = item.error ? stringifyJsonValue(item.error) : item.result ? stringifyJsonValue(item.result) : void 0;
|
|
357
|
-
return output ? truncateToolTranscriptText(output) : void 0;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
function itemTranscriptResultText(item, outputTextByItem) {
|
|
361
|
-
const output = itemOutputText(item, outputTextByItem);
|
|
362
|
-
if (output) return output;
|
|
363
|
-
const result = itemToolResult(item).result;
|
|
364
|
-
const resultText = result ? stringifyJsonValue(result) : void 0;
|
|
365
|
-
return resultText ? truncateToolTranscriptText(resultText) : itemStatus(item);
|
|
366
|
-
}
|
|
367
|
-
function stringifyJsonValue(value) {
|
|
368
|
-
try {
|
|
369
|
-
return JSON.stringify(value, null, 2);
|
|
370
|
-
} catch {
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
//#endregion
|
|
375
|
-
//#region extensions/codex/src/app-server/native-subagent-task-ids.ts
|
|
376
|
-
/** Task runtime namespace for Codex native subagent task rows. */
|
|
377
|
-
const CODEX_NATIVE_SUBAGENT_RUNTIME = "subagent";
|
|
378
|
-
/** Task kind used to distinguish native Codex subagents from other subagent runtimes. */
|
|
379
|
-
const CODEX_NATIVE_SUBAGENT_TASK_KIND = "codex-native";
|
|
380
|
-
/** Run id prefix for task rows keyed by Codex child thread ids. */
|
|
381
|
-
const CODEX_NATIVE_SUBAGENT_RUN_ID_PREFIX = "codex-thread:";
|
|
382
|
-
/** Initial tasks keep their shipped locator; later assignments belong to a native turn. */
|
|
383
|
-
function codexNativeSubagentRunId(threadId, turnId) {
|
|
384
|
-
return `${CODEX_NATIVE_SUBAGENT_RUN_ID_PREFIX}${threadId.trim()}${turnId ? `:turn:${turnId}` : ""}`;
|
|
385
|
-
}
|
|
386
|
-
function readCodexNativeSubagentRunId(runId) {
|
|
387
|
-
if (!runId?.startsWith("codex-thread:")) return;
|
|
388
|
-
const [threadId, turnId] = runId.slice(13).split(":turn:");
|
|
389
|
-
return threadId?.trim() ? {
|
|
390
|
-
threadId,
|
|
391
|
-
...turnId ? { turnId } : {}
|
|
392
|
-
} : void 0;
|
|
393
|
-
}
|
|
394
|
-
function readNativeTaskAssignment(task) {
|
|
395
|
-
const runId = task.runId;
|
|
396
|
-
const identity = readCodexNativeSubagentRunId(runId);
|
|
397
|
-
if (!runId || !identity) return;
|
|
398
|
-
const storedTurnId = isJsonObject(task.detail) ? normalizeOptionalString(readStringField(task.detail, "nativeTurnId")) : void 0;
|
|
399
|
-
return {
|
|
400
|
-
runId,
|
|
401
|
-
childThreadId: identity.threadId,
|
|
402
|
-
nativeTurnId: storedTurnId ?? identity.turnId,
|
|
403
|
-
initialTurnId: identity.turnId
|
|
404
|
-
};
|
|
405
|
-
}
|
|
406
|
-
function readNativeSubagentThreadIds(value) {
|
|
407
|
-
if (!Array.isArray(value)) return [];
|
|
408
|
-
return value.filter((entry) => typeof entry === "string" && entry.trim() !== "");
|
|
409
|
-
}
|
|
410
|
-
//#endregion
|
|
411
|
-
export { truncateToolTranscriptText as A, TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS as C, formatToolSummary as D, formatToolOutput as E, normalizeToolTranscriptArguments as O, TOOL_PROGRESS_ECHO_PREFIX_MIN_CHARS as S, collectDynamicToolContentText as T, inferCodexDynamicToolMeta as _, readCodexNativeSubagentRunId as a, sanitizeCodexToolArguments as b, isCommandBearingToolItem as c, itemOutputText as d, itemToolArgs as f, shouldSuppressChannelProgressForItem as g, itemTranscriptResultText as h, codexNativeSubagentRunId as i, toolOutputRawEchoSignature as k, isNativePostToolUseRelayItem as l, itemToolResult as m, CODEX_NATIVE_SUBAGENT_RUN_ID_PREFIX as n, readNativeSubagentThreadIds as o, itemToolError as p, CODEX_NATIVE_SUBAGENT_TASK_KIND as r, readNativeTaskAssignment as s, CODEX_NATIVE_SUBAGENT_RUNTIME as t, itemMeta as u, isCodexCommandBearingToolCall as v, ToolOutputAccumulator as w, sanitizeCodexToolResponse as x, resolveCodexToolProgressDetailMode as y };
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
import { i as resolveManagedCodexNativeCommand, r as resolveManagedCodexAppServerStartOptions, t as isManagedCodexDesktopCommand } from "./managed-binary-DP6Rib3P.mjs";
|
|
2
|
-
import { i as closeCodexAppServerTransportAndWait, t as createStdioTransport } from "./transport-stdio-Cmx94Oiy.mjs";
|
|
3
|
-
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
|
-
import { stripVTControlCharacters } from "node:util";
|
|
5
|
-
import { killProcessTree } from "openclaw/plugin-sdk/process-runtime";
|
|
6
|
-
import path from "node:path";
|
|
7
|
-
import { mkdir } from "node:fs/promises";
|
|
8
|
-
import { once } from "node:events";
|
|
9
|
-
import { resolvePreferredOpenClawTmpDir, withTempWorkspace } from "openclaw/plugin-sdk/temp-path";
|
|
10
|
-
import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
|
|
11
|
-
import { StringDecoder } from "node:string_decoder";
|
|
12
|
-
import { sanitizeEnvVars } from "openclaw/plugin-sdk/sandbox";
|
|
13
|
-
//#region extensions/codex/src/node-exec-server.runtime.ts
|
|
14
|
-
const MAX_CODEX_EXEC_SERVER_MESSAGE_BYTES = 67108864;
|
|
15
|
-
const MAX_CODEX_EXEC_SERVER_STDERR_BYTES = 4096;
|
|
16
|
-
const CODEX_EXEC_SERVER_READY_LINE = "codex_exec_server::server::transport: codex-exec-server listening on stdio";
|
|
17
|
-
const CODEX_EXEC_SERVER_TERMINATION_GRACE_MS = 1e3;
|
|
18
|
-
const CODEX_EXEC_SERVER_REAP_TIMEOUT_MS = 5e3;
|
|
19
|
-
const NODE_EXEC_SERVER_PLATFORM_ENVIRONMENT = /^(?:SYSTEMROOT|WINDIR|COMSPEC|PATHEXT|TEMP|TMP|TMPDIR)$/iu;
|
|
20
|
-
function validateNodeExecServerMessage(message) {
|
|
21
|
-
if (message.byteLength === 0 || message.byteLength > MAX_CODEX_EXEC_SERVER_MESSAGE_BYTES) throw new Error("Codex exec-server JSON-RPC message exceeds its 64 MiB limit.");
|
|
22
|
-
const encoded = Buffer.from(message.buffer, message.byteOffset, message.byteLength);
|
|
23
|
-
if (encoded.includes(10) || encoded.includes(13)) throw new Error("Codex exec-server JSON-RPC frames must contain exactly one message.");
|
|
24
|
-
let decoded;
|
|
25
|
-
try {
|
|
26
|
-
const text = new TextDecoder("utf-8", { fatal: true }).decode(encoded);
|
|
27
|
-
decoded = JSON.parse(text);
|
|
28
|
-
} catch {
|
|
29
|
-
throw new Error("Codex exec-server received malformed UTF-8 or JSON-RPC.");
|
|
30
|
-
}
|
|
31
|
-
if (!isRecord(decoded) || decoded.jsonrpc !== void 0 && decoded.jsonrpc !== "2.0" || typeof decoded.method !== "string" && !("id" in decoded && ("result" in decoded || "error" in decoded))) throw new Error("Codex exec-server received an invalid JSON-RPC message.");
|
|
32
|
-
return encoded;
|
|
33
|
-
}
|
|
34
|
-
function nodeExecServerAbortError(signal) {
|
|
35
|
-
return signal.reason instanceof Error ? signal.reason : /* @__PURE__ */ new Error("Codex node exec-server connection closed.");
|
|
36
|
-
}
|
|
37
|
-
function writeNodeExecServerMessage(child, message, signal) {
|
|
38
|
-
if (signal.aborted) throw nodeExecServerAbortError(signal);
|
|
39
|
-
const payload = Buffer.concat([message, Buffer.from("\n")]);
|
|
40
|
-
if (!child.stdin.write(payload)) return once(child.stdin, "drain", { signal }).then(() => void 0);
|
|
41
|
-
}
|
|
42
|
-
async function relayNodeExecServerOutput(child, send) {
|
|
43
|
-
let fragments = [];
|
|
44
|
-
let pendingBytes = 0;
|
|
45
|
-
for await (const rawChunk of child.stdout) {
|
|
46
|
-
const chunk = Buffer.isBuffer(rawChunk) ? rawChunk : Buffer.from(rawChunk);
|
|
47
|
-
let offset = 0;
|
|
48
|
-
while (offset < chunk.byteLength) {
|
|
49
|
-
const newline = chunk.indexOf(10, offset);
|
|
50
|
-
const fragment = chunk.subarray(offset, newline === -1 ? chunk.byteLength : newline);
|
|
51
|
-
const nextLength = pendingBytes + fragment.byteLength;
|
|
52
|
-
if (nextLength > 67108865) throw new Error("Codex exec-server stdout message exceeds its 64 MiB limit.");
|
|
53
|
-
if (fragment.byteLength > 0) fragments.push(fragment);
|
|
54
|
-
pendingBytes = nextLength;
|
|
55
|
-
if (newline === -1) {
|
|
56
|
-
if (pendingBytes > MAX_CODEX_EXEC_SERVER_MESSAGE_BYTES && fragment[fragment.byteLength - 1] !== 13) throw new Error("Codex exec-server stdout message exceeds its 64 MiB limit.");
|
|
57
|
-
break;
|
|
58
|
-
}
|
|
59
|
-
const trailing = fragments.at(-1);
|
|
60
|
-
if (trailing?.[trailing.byteLength - 1] === 13) {
|
|
61
|
-
pendingBytes -= 1;
|
|
62
|
-
if (trailing.byteLength === 1) fragments.pop();
|
|
63
|
-
else fragments[fragments.length - 1] = trailing.subarray(0, trailing.byteLength - 1);
|
|
64
|
-
}
|
|
65
|
-
const message = validateNodeExecServerMessage(fragments.length === 1 ? fragments[0] : Buffer.concat(fragments, pendingBytes));
|
|
66
|
-
fragments = [];
|
|
67
|
-
pendingBytes = 0;
|
|
68
|
-
await send(message);
|
|
69
|
-
offset = newline + 1;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (pendingBytes > 0) throw new Error("Codex exec-server stdout ended with an unterminated JSON-RPC message.");
|
|
73
|
-
}
|
|
74
|
-
function createNodeExecServerProcessOwner(child, closed) {
|
|
75
|
-
let termination;
|
|
76
|
-
return { terminate: () => termination ??= (async () => {
|
|
77
|
-
if (process.platform === "win32" && child.pid) killProcessTree(child.pid, { graceMs: CODEX_EXEC_SERVER_TERMINATION_GRACE_MS });
|
|
78
|
-
const { exited } = await closeCodexAppServerTransportAndWait(child, {
|
|
79
|
-
forceKillDelayMs: CODEX_EXEC_SERVER_TERMINATION_GRACE_MS,
|
|
80
|
-
exitTimeoutMs: CODEX_EXEC_SERVER_REAP_TIMEOUT_MS
|
|
81
|
-
});
|
|
82
|
-
if (!exited) throw new Error("Codex node exec-server process tree did not terminate.");
|
|
83
|
-
await closed;
|
|
84
|
-
})() };
|
|
85
|
-
}
|
|
86
|
-
/** Runs the one-connection paired-node exec-server after lightweight command admission. */
|
|
87
|
-
async function runCodexNodeExecServer(params) {
|
|
88
|
-
const { io } = params;
|
|
89
|
-
const frames = io.frames;
|
|
90
|
-
if (!frames) throw new Error("Codex node exec-server requires duplex frames.");
|
|
91
|
-
const cwd = params.workspaceDir;
|
|
92
|
-
let writes;
|
|
93
|
-
let rejectDisconnected;
|
|
94
|
-
const disconnected = new Promise((_resolve, reject) => {
|
|
95
|
-
rejectDisconnected = reject;
|
|
96
|
-
});
|
|
97
|
-
disconnected.catch(() => {});
|
|
98
|
-
const onAbort = () => {
|
|
99
|
-
const error = nodeExecServerAbortError(io.signal);
|
|
100
|
-
rejectDisconnected(error);
|
|
101
|
-
};
|
|
102
|
-
io.signal.addEventListener("abort", onAbort, { once: true });
|
|
103
|
-
try {
|
|
104
|
-
if (io.signal.aborted) throw nodeExecServerAbortError(io.signal);
|
|
105
|
-
return await withTempWorkspace({
|
|
106
|
-
rootDir: resolvePreferredOpenClawTmpDir(),
|
|
107
|
-
prefix: "codex-node-exec-server-"
|
|
108
|
-
}, async ({ dir }) => {
|
|
109
|
-
const codexHome = path.join(dir, ".codex");
|
|
110
|
-
await mkdir(codexHome, {
|
|
111
|
-
recursive: true,
|
|
112
|
-
mode: 448
|
|
113
|
-
});
|
|
114
|
-
const resolved = await resolveManagedCodexAppServerStartOptions({
|
|
115
|
-
transport: "stdio",
|
|
116
|
-
command: "codex",
|
|
117
|
-
commandSource: "managed",
|
|
118
|
-
managedCommandOrder: "package-first",
|
|
119
|
-
args: [
|
|
120
|
-
"exec-server",
|
|
121
|
-
"--listen",
|
|
122
|
-
"stdio"
|
|
123
|
-
],
|
|
124
|
-
headers: {}
|
|
125
|
-
});
|
|
126
|
-
const native = resolveManagedCodexNativeCommand(resolved.command);
|
|
127
|
-
if (!native || isManagedCodexDesktopCommand(resolved.command)) throw new Error("Codex node exec-server requires the pinned managed package binary.");
|
|
128
|
-
const baseEnv = sanitizeEnvVars(process.env, {
|
|
129
|
-
strictMode: true,
|
|
130
|
-
customAllowedPatterns: [NODE_EXEC_SERVER_PLATFORM_ENVIRONMENT]
|
|
131
|
-
}).allowed;
|
|
132
|
-
if (io.signal.aborted) throw nodeExecServerAbortError(io.signal);
|
|
133
|
-
params.assertExecAuthorized();
|
|
134
|
-
const nativeReady = createDeferred();
|
|
135
|
-
const exit = createDeferred();
|
|
136
|
-
let stderr = Buffer.alloc(0);
|
|
137
|
-
let startupSettled = false;
|
|
138
|
-
let pendingLine = "";
|
|
139
|
-
const decoder = new StringDecoder("utf8");
|
|
140
|
-
const child = await createStdioTransport({
|
|
141
|
-
transport: "stdio",
|
|
142
|
-
command: native,
|
|
143
|
-
commandSource: "resolved-managed",
|
|
144
|
-
args: resolved.args,
|
|
145
|
-
headers: {},
|
|
146
|
-
cwd,
|
|
147
|
-
env: {
|
|
148
|
-
HOME: params.homeDir ?? dir,
|
|
149
|
-
CODEX_HOME: codexHome,
|
|
150
|
-
RUST_LOG: "error,opentelemetry_sdk=off,opentelemetry_otlp=off,codex_exec_server::server::transport=info",
|
|
151
|
-
...process.platform === "win32" ? { USERPROFILE: params.homeDir ?? dir } : {}
|
|
152
|
-
},
|
|
153
|
-
clearEnv: ["NODE_OPTIONS"]
|
|
154
|
-
}, baseEnv, () => {
|
|
155
|
-
if (io.signal.aborted) throw nodeExecServerAbortError(io.signal);
|
|
156
|
-
params.assertExecAuthorized();
|
|
157
|
-
}, (spawned) => {
|
|
158
|
-
spawned.once("close", (code, signal) => exit.resolve({
|
|
159
|
-
code,
|
|
160
|
-
signal
|
|
161
|
-
}));
|
|
162
|
-
spawned.once("error", rejectDisconnected);
|
|
163
|
-
spawned.stdin.on("error", rejectDisconnected);
|
|
164
|
-
spawned.stderr.on("data", (chunk) => {
|
|
165
|
-
const next = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
166
|
-
stderr = Buffer.concat([stderr, next.subarray(-4096)]).subarray(-4096);
|
|
167
|
-
if (startupSettled) return;
|
|
168
|
-
const lines = (pendingLine + decoder.write(next)).split("\n");
|
|
169
|
-
pendingLine = lines.pop();
|
|
170
|
-
for (const line of [...lines, pendingLine]) if (Buffer.byteLength(line, "utf8") > MAX_CODEX_EXEC_SERVER_STDERR_BYTES) {
|
|
171
|
-
startupSettled = true;
|
|
172
|
-
pendingLine = "";
|
|
173
|
-
rejectDisconnected(/* @__PURE__ */ new Error("Codex node startup diagnostic line exceeded 4 KiB."));
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
if (lines.some((line) => stripVTControlCharacters(line).trimEnd().endsWith(CODEX_EXEC_SERVER_READY_LINE))) {
|
|
177
|
-
startupSettled = true;
|
|
178
|
-
pendingLine = "";
|
|
179
|
-
nativeReady.resolve();
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
const closed = exit.promise;
|
|
184
|
-
const stopped = closed.then((outcome) => {
|
|
185
|
-
const diagnostic = stderr.toString("utf8").trim();
|
|
186
|
-
throw new Error(`Codex node exec-server exited (code ${outcome.code ?? "none"}, signal ${outcome.signal ?? "none"})${diagnostic ? `: ${diagnostic}` : "."}`);
|
|
187
|
-
});
|
|
188
|
-
const owner = createNodeExecServerProcessOwner(child, closed);
|
|
189
|
-
params.activeProcesses.add(owner.terminate);
|
|
190
|
-
const output = relayNodeExecServerOutput(child, frames.send.bind(frames));
|
|
191
|
-
output.catch((error) => {
|
|
192
|
-
rejectDisconnected(error instanceof Error ? error : new Error(String(error)));
|
|
193
|
-
});
|
|
194
|
-
try {
|
|
195
|
-
await Promise.race([
|
|
196
|
-
nativeReady.promise,
|
|
197
|
-
stopped,
|
|
198
|
-
disconnected
|
|
199
|
-
]);
|
|
200
|
-
if (io.signal.aborted) throw nodeExecServerAbortError(io.signal);
|
|
201
|
-
if (child.exitCode !== null || child.signalCode !== null) await stopped;
|
|
202
|
-
params.assertExecAuthorized();
|
|
203
|
-
params.onFrameReceiver((message) => {
|
|
204
|
-
const encoded = validateNodeExecServerMessage(message);
|
|
205
|
-
const operation = writes ? writes.then(() => writeNodeExecServerMessage(child, encoded, io.signal)) : writeNodeExecServerMessage(child, encoded, io.signal);
|
|
206
|
-
if (!operation) return;
|
|
207
|
-
const observed = operation.catch(() => {});
|
|
208
|
-
writes = observed;
|
|
209
|
-
observed.then(() => {
|
|
210
|
-
if (writes === observed) writes = void 0;
|
|
211
|
-
});
|
|
212
|
-
return operation;
|
|
213
|
-
});
|
|
214
|
-
return await Promise.race([stopped, disconnected]);
|
|
215
|
-
} finally {
|
|
216
|
-
await owner.terminate();
|
|
217
|
-
params.activeProcesses.delete(owner.terminate);
|
|
218
|
-
await Promise.allSettled([output, ...writes ? [writes] : []]);
|
|
219
|
-
}
|
|
220
|
-
});
|
|
221
|
-
} finally {
|
|
222
|
-
io.signal.removeEventListener("abort", onAbort);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
//#endregion
|
|
226
|
-
export { runCodexNodeExecServer };
|