@openclaw/codex 2026.9.5 → 2026.9.6

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.
Files changed (120) hide show
  1. package/dist/.setup/{account-usage-runtime-C2MOIvfq.mjs → account-usage-runtime-Eem_WGqY.mjs} +5 -5
  2. package/dist/.setup/{apply-CJ0ZfmBG.mjs → apply-DDOi8uNx.mjs} +22 -28
  3. package/dist/.setup/{attempt-client-cleanup-BpYKdTA0.mjs → attempt-client-cleanup-CEv1cKwF.mjs} +58 -43
  4. package/dist/.setup/attempt-workspace-context-DUVEn_CS.mjs +331 -0
  5. package/dist/.setup/{auth-cache-key-QirmgiCo.mjs → auth-cache-key-B2mpaI9D.mjs} +9 -81
  6. package/dist/.setup/auth-profile-health-oHizqgye.mjs +53 -0
  7. package/dist/.setup/auth-profile-recovery-BREezV0L.mjs +14 -0
  8. package/dist/.setup/{binding-connection-Bm38niE8.mjs → binding-connection-ThoatDcb.mjs} +1 -1
  9. package/dist/.setup/{binding-connection.runtime-CnRMC0ta.mjs → binding-connection.runtime-yoHrABt-.mjs} +4 -4
  10. package/dist/.setup/{bounded-turn-BtlZcivC.mjs → bounded-turn-B2HScEgT.mjs} +138 -32
  11. package/dist/.setup/{build-state-Xx9ybZqa.mjs → build-state-C7EnDVgr.mjs} +1 -1
  12. package/dist/.setup/{capabilities-_vXcZGSx.mjs → capabilities-CDXOOFdZ.mjs} +1 -1
  13. package/dist/.setup/{client-vXs2929Q.mjs → client-Cs08OXVQ.mjs} +583 -559
  14. package/dist/.setup/client-catalog-response-BMgt_4q4.mjs +285 -0
  15. package/dist/.setup/{command-dispatch-naHIZwwF.mjs → command-dispatch-B4JuOsOk.mjs} +8 -4
  16. package/dist/.setup/{command-formatters-CGEkdawF.mjs → command-formatters-Bmqvr9tO.mjs} +8 -4
  17. package/dist/.setup/{command-handlers-BtAJEW1X.mjs → command-handlers-DW7Lx9oH.mjs} +106 -172
  18. package/dist/.setup/{command-rpc-DHFpn4le.mjs → command-rpc-DixIj3HW.mjs} +36 -21
  19. package/dist/.setup/{compact-C3i3qlzj.mjs → compact-Du5UvtxA.mjs} +14 -21
  20. package/dist/.setup/{config-CedDWjM-.mjs → config-BoTP_mrL.mjs} +3 -3
  21. package/dist/.setup/{config-options-BsanJ8QG.mjs → config-options-BvaRs51b.mjs} +46 -30
  22. package/dist/.setup/{config-runtime-CeAhl_h4.mjs → config-runtime-C8Rw1m1m.mjs} +1 -1
  23. package/dist/.setup/{config-security-BRQ2mgW9.mjs → config-security-BEReZ6go.mjs} +35 -120
  24. package/dist/.setup/{conversation-binding-DhzrpTM6.mjs → conversation-binding-DP-gMrBP.mjs} +21 -32
  25. package/dist/.setup/{conversation-control-DN53ns41.mjs → conversation-control-uK9Jomlc.mjs} +28 -67
  26. package/dist/.setup/{dynamic-tools-D16lOp67.mjs → dynamic-tools-BDXl-8Cw.mjs} +848 -578
  27. package/dist/.setup/{effective-mcp-catalog-K6kLCN8X.mjs → effective-mcp-catalog-CvnvnGIe.mjs} +3 -3
  28. package/dist/.setup/{ephemeral-turn-R1gA8Sn6.mjs → ephemeral-turn-poidXgek.mjs} +9 -6
  29. package/dist/.setup/{event-projector-assistant-message-DNUR1s0A.mjs → event-projector-assistant-message-BsruvNrH.mjs} +2 -4
  30. package/dist/.setup/{event-projector-items-DyTQ_XqL.mjs → event-projector-items-C6L_5ZiT.mjs} +42 -8
  31. package/dist/.setup/{event-projector-usage-C7Ntzs-f.mjs → event-projector-usage-CnBS8Wa3.mjs} +1 -1
  32. package/dist/.setup/{harness-rxaaoN-o.mjs → harness-a_MsE4-_.mjs} +23 -17
  33. package/dist/.setup/{inference-context-fulhZuz8.mjs → inference-context-D96l9-ew.mjs} +1 -1
  34. package/dist/.setup/inference-proxy-b-aJMSxm.mjs +601 -0
  35. package/dist/.setup/{isolated-completion-B6srt48J.mjs → isolated-completion-BIZFhTNG.mjs} +17 -10
  36. package/dist/.setup/launch-args-DbFCehO7.mjs +196 -0
  37. package/dist/.setup/{managed-binary-DP6Rib3P.mjs → managed-binary-BnshlFag.mjs} +13 -2
  38. package/dist/.setup/{model-catalog-DkvUuBey.mjs → model-catalog-CfXJf9Ay.mjs} +9 -10
  39. package/dist/.setup/{models-BDFgm_G-.mjs → models-KnqBv0hE.mjs} +3 -3
  40. package/dist/.setup/{native-auth-BLZGqFjw.mjs → native-auth-rWbGbMn3.mjs} +4 -4
  41. package/dist/.setup/{native-subagent-history-YXaL6dMd.mjs → native-subagent-history-0nYYgo0k.mjs} +26 -13
  42. package/dist/.setup/{native-subagent-monitor-B1hxzIOy.mjs → native-subagent-monitor-D3filLY2.mjs} +145 -317
  43. package/dist/.setup/{native-subagent-task-ids-DsuOonKv.mjs → native-subagent-task-ids-wb8CKZGN.mjs} +69 -39
  44. package/dist/.setup/{node-cli-sessions-Cl8b2ZF3.mjs → node-cli-sessions-r3avj02l.mjs} +86 -68
  45. package/dist/.setup/node-exec-server.runtime-BDwWXVpK.mjs +247 -0
  46. package/dist/.setup/{plan-xD7WKYTM.mjs → plan-CN3VwfNU.mjs} +74 -76
  47. package/dist/.setup/{plugin-activation-r8nq5Jzp.mjs → plugin-activation-DT3MNtqj.mjs} +7 -16
  48. package/dist/.setup/{plugin-app-cache-key-BOxKP7db.mjs → plugin-app-cache-key-B2CsSdnV.mjs} +4 -20
  49. package/dist/.setup/{plugin-approval-roundtrip-CjfzafAZ.mjs → plugin-approval-roundtrip-C0MZzCuP.mjs} +1 -1
  50. package/dist/.setup/{plugin-inventory-DUle8DLz.mjs → plugin-inventory-BoRei8Z4.mjs} +16 -7
  51. package/dist/.setup/{plugin-marketplace-discovery-P-Vndfqq.mjs → plugin-marketplace-discovery-CDOi8IFs.mjs} +4 -1
  52. package/dist/.setup/{plugin-metadata-cache-DsS5buNa.mjs → plugin-metadata-cache-Ctmo83k_.mjs} +224 -154
  53. package/dist/.setup/protocol-CANUwXJ3.mjs +17 -0
  54. package/dist/.setup/{provider-fFh_-VR3.mjs → provider-BOsxQHOM.mjs} +9 -5
  55. package/dist/.setup/{provider-capabilities-B8J4Dy-O.mjs → provider-capabilities-BfE88FZ5.mjs} +31 -3
  56. package/dist/.setup/{rate-limits-DOEGYRNs.mjs → rate-limits-CMU3DUD0.mjs} +116 -137
  57. package/dist/.setup/{request-BioXJLYa.mjs → request-D2L0zMrq.mjs} +23 -15
  58. package/dist/.setup/{run-attempt-rlA07pUv.mjs → run-attempt-BHu11r7h.mjs} +1197 -617
  59. package/dist/.setup/{runtime-artifact-Dy38Z5iU.mjs → runtime-artifact-CLZ8udh-.mjs} +29 -45
  60. package/dist/.setup/{sandbox-guard-BBP-RbTf.mjs → sandbox-guard-C2sRMOEY.mjs} +1 -1
  61. package/dist/.setup/{session-binding-_0W_fHRr.mjs → session-binding-Cm0apEbd.mjs} +3 -32
  62. package/dist/.setup/{session-binding-record-TH3xA0zj.mjs → session-binding-record-BGoz8wOK.mjs} +22 -3
  63. package/dist/.setup/{session-binding-sidecars-CKYEcfNn.mjs → session-binding-sidecars-BlB5EvIS.mjs} +48 -45
  64. package/dist/.setup/{session-catalog-fUdWDx-U.mjs → session-catalog-Pno1xGcl.mjs} +482 -182
  65. package/dist/.setup/{session-catalog-adoption-CR_whkEW.mjs → session-catalog-adoption-BI6UTDZT.mjs} +57 -25
  66. package/dist/.setup/{session-catalog-archive-CwZaPacf.mjs → session-catalog-archive-lHBqzhaO.mjs} +6 -6
  67. package/dist/.setup/{session-catalog-events-jMcYfQyd.mjs → session-catalog-events-Bj6j94E_.mjs} +122 -25
  68. package/dist/.setup/{session-catalog-index-B141u15s.mjs → session-catalog-index-B9_VQIUz.mjs} +178 -78
  69. package/dist/.setup/{session-catalog-index-order-Cc5BzlQr.mjs → session-catalog-index-order-hcdz07yN.mjs} +2 -2
  70. package/dist/.setup/{session-catalog-index-state-BAuDztHN.mjs → session-catalog-index-state-Dgh8ORJm.mjs} +5 -2
  71. package/dist/.setup/{session-catalog-native-projection-ChV3cCtm.mjs → session-catalog-native-projection-DowriLid.mjs} +30 -13
  72. package/dist/.setup/{session-catalog-node-adoption-BVRsYOSh.mjs → session-catalog-node-adoption-ITddWx_X.mjs} +24 -12
  73. package/dist/.setup/{session-catalog-node-continue-Dowv8osw.mjs → session-catalog-node-continue-6g6qi4A9.mjs} +22 -13
  74. package/dist/.setup/{session-catalog-projection-C1Bj9Jl-.mjs → session-catalog-projection-zK_PUsiE.mjs} +13 -5
  75. package/dist/.setup/{session-cli-DIj-IE-E.mjs → session-cli-irrD-uo7.mjs} +4 -4
  76. package/dist/.setup/{session-history-C--SrLI8.mjs → session-history-BrqhSCf9.mjs} +17 -22
  77. package/dist/.setup/{session-history-import-JHXT5Xfi.mjs → session-history-import-D-3wAgOP.mjs} +4 -4
  78. package/dist/.setup/{session-history.worker-CpNj7H_P.mjs → session-history.worker-CaCh0xF_.mjs} +5 -18
  79. package/dist/.setup/{session-initialization-DH1z6fXn.mjs → session-initialization-rcgbZiid.mjs} +2 -2
  80. package/dist/.setup/{session-permission-policy-DhurXY0l.mjs → session-permission-policy-BI1QK_98.mjs} +2 -2
  81. package/dist/.setup/{session-retirement-CU87AOg9.mjs → session-retirement-BH-S6qkJ.mjs} +25 -6
  82. package/dist/.setup/{settled-turn-finalizer-CiY2bLFK.mjs → settled-turn-finalizer-DiAi6Kx6.mjs} +8 -8
  83. package/dist/.setup/{shared-client-BpTtuLQ5.mjs → shared-client-DA4VR4Eb.mjs} +59 -89
  84. package/dist/.setup/{side-question-DSCZyoBD.mjs → side-question-BJ1wSDcB.mjs} +147 -211
  85. package/dist/.setup/{source-Bjp4UQij.mjs → source-CUzJq5WN.mjs} +9 -9
  86. package/dist/.setup/spawn-error-CL3n6MAa.mjs +57 -0
  87. package/dist/.setup/{thread-archive-guard-jmecf6OJ.mjs → thread-archive-guard-C9frICzX.mjs} +10 -3
  88. package/dist/.setup/{thread-history-page-BTx-4xsg.mjs → thread-history-page-DoVpnHim.mjs} +1 -1
  89. package/dist/.setup/{thread-lifecycle-Cik28qWn.mjs → thread-lifecycle-B3mfz1TG.mjs} +172 -2271
  90. package/dist/.setup/{thread-ownership-skomxnIt.mjs → thread-ownership-DcTtAcXj.mjs} +4 -2
  91. package/dist/.setup/{thread-policy-Cjs4B8xf.mjs → thread-policy-DGuQsuFC.mjs} +19 -3
  92. package/dist/.setup/thread-requests-BLvGkP2R.mjs +2205 -0
  93. package/dist/.setup/{thread-resume-BkNpj9Pz.mjs → thread-resume-DIBXwOpE.mjs} +6 -6
  94. package/dist/.setup/{timeout-DZF05XrR.mjs → timeout-C910MdAB.mjs} +19 -2
  95. package/dist/.setup/{transcript-history-projection-DHNBDhCU.mjs → transcript-history-projection-ZZpkFkJ_.mjs} +94 -64
  96. package/dist/.setup/{transcript-mirror-D4qp_leP.mjs → transcript-mirror-BtHDBp1G.mjs} +218 -198
  97. package/dist/.setup/{transport-stdio-Cmx94Oiy.mjs → transport-stdio-h2VHOskC.mjs} +135 -55
  98. package/dist/.setup/{upstream-session-fork-D3UKxgVD.mjs → upstream-session-fork-BUr4OUbC.mjs} +44 -36
  99. package/dist/.setup/{usage-BOgBEKso.mjs → usage-BML0r-ua.mjs} +5 -4
  100. package/dist/.setup/{usage-limit-error-C0ow7DOc.mjs → usage-limit-error-DUMbefVY.mjs} +4 -4
  101. package/dist/.setup/{web-search-provider.runtime-CTGuJt6i.mjs → web-search-provider.runtime-CDKlN-Rv.mjs} +4 -3
  102. package/dist/api.js +23 -12
  103. package/dist/catalog-page-worker-entrypoint.js +12 -0
  104. package/dist/catalog-page.worker.js +9 -0
  105. package/dist/cli-metadata.js +1 -1
  106. package/dist/doctor-contract-api.js +2 -2
  107. package/dist/harness.js +1 -1
  108. package/dist/index.js +221 -170
  109. package/dist/media-understanding-provider.js +2 -2
  110. package/dist/migration-provider-api.js +1 -1
  111. package/dist/provider-discovery.js +1 -1
  112. package/dist/session-history-worker-runtime.js +15 -32
  113. package/dist/session-history.worker.js +1 -1
  114. package/package.json +9 -6
  115. package/dist/.setup/attempt-context-VXVwTCfS.mjs +0 -636
  116. package/dist/.setup/inference-proxy-CC15HuSi.mjs +0 -311
  117. package/dist/.setup/launch-args-DnMak49W.mjs +0 -111
  118. package/dist/.setup/node-exec-server.runtime-BaViBKNz.mjs +0 -226
  119. package/dist/.setup/version-CoqzXPgK.mjs +0 -12
  120. package/dist/.setup/{native-execution-policy-YBMHSzC4.mjs → native-execution-policy-umd0tgh4.mjs} +1 -1
@@ -1,11 +1,14 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
2
- import { _ as resolveCodexAppServerUserHomeDir, m as isJsonObject } from "./config-security-BRQ2mgW9.mjs";
3
- import { a as closeCodexCatalogClientSource, l as recordCodexCatalogResponseSource, n as projectCodexCatalogNativeResponse, o as codexCatalogSourceForClient } from "./session-catalog-native-projection-ChV3cCtm.mjs";
4
- import { r as MIN_SUPPORTED_CODEX_APP_SERVER_VERSION, t as CODEX_APP_SERVER_VERSION } from "./version-CoqzXPgK.mjs";
5
- import { a as hasCodexAppServerNaturalExit, i as closeCodexAppServerTransportAndWait, r as closeCodexAppServerTransport, t as createStdioTransport } from "./transport-stdio-Cmx94Oiy.mjs";
6
- import { i as CodexAppServerRpcError, r as CODEX_APP_SERVER_OVERLOADED_ERROR_CODE } from "./timeout-DZF05XrR.mjs";
7
- import "./config-CedDWjM-.mjs";
8
- import { n as resolveCodexAppServerRuntimeOptions } from "./config-runtime-CeAhl_h4.mjs";
2
+ import { p as resolveCodexAppServerUserHomeDir } from "./config-security-BEReZ6go.mjs";
3
+ import { d as recordCodexCatalogResponseSource, i as reuseCodexCatalogPreview, o as closeCodexCatalogClientSource, s as codexCatalogSourceForClient } from "./session-catalog-native-projection-DowriLid.mjs";
4
+ import { a as stringifyCodexAppServerMessage, c as isRpcResponse, i as readCodexCatalogDecodeRoute, n as projectCodexCatalogMessage, o as CodexAppServerMessageDecoder, r as listenCodexAppServerLines, s as redactCodexAppServerLinePreview } from "./client-catalog-response-BMgt_4q4.mjs";
5
+ import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
6
+ import { c as MIN_SUPPORTED_CODEX_APP_SERVER_VERSION, s as CODEX_APP_SERVER_VERSION } from "./managed-binary-BnshlFag.mjs";
7
+ import { a as closeCodexAppServerTransportAndWait, i as closeCodexAppServerTransport, o as hasCodexAppServerNaturalExit, t as createStdioTransport } from "./transport-stdio-h2VHOskC.mjs";
8
+ import { a as CODEX_APP_SERVER_OVERLOADED_ERROR_CODE, o as CodexAppServerRpcError } from "./timeout-C910MdAB.mjs";
9
+ import "./config-BoTP_mrL.mjs";
10
+ import { n as resolveCodexAppServerRuntimeOptions } from "./config-runtime-C8Rw1m1m.mjs";
11
+ import { codexCatalogPageWorkerEntrypoint } from "../catalog-page-worker-entrypoint.js";
9
12
  import { isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
10
13
  import { randomUUID } from "node:crypto";
11
14
  import { addSafeTimeoutDelayGraceMs, addTimerTimeoutGraceMs, parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
@@ -17,23 +20,188 @@ import { sliceUtf16Safe, truncateUtf16Safe } from "openclaw/plugin-sdk/text-util
17
20
  import { hasPendingInternalDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime";
18
21
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
19
22
  import { OPENCLAW_VERSION, embeddedAgentLog, formatToolExecutionErrorMessage, normalizeQuestionTimeoutSeconds, resolveToolExecutionErrorKind } from "openclaw/plugin-sdk/agent-harness-runtime";
20
- import { createInterface } from "node:readline";
21
23
  import { parse } from "semver";
22
- import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
23
- import { copyInternalToolResultState } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
24
+ import { copyInternalToolResultState, runWithAsyncWorkResources } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
24
25
  import { Compile } from "typebox/compile";
25
26
  import net from "node:net";
26
27
  import { PassThrough, Writable } from "node:stream";
27
28
  import { StringDecoder } from "node:string_decoder";
28
29
  import { WebSocket } from "openclaw/plugin-sdk/websocket-runtime";
29
- //#region extensions/codex/src/app-server/protocol-json.ts
30
- function isRpcResponse(message) {
31
- return "id" in message && !("method" in message);
30
+ //#region extensions/codex/src/app-server/client-catalog-worker.ts
31
+ const INLINE_CATALOG_MAX_BYTES = 65536;
32
+ /** Late responses retain their decode route after cancellation removes the waiter. */
33
+ function codexCatalogRequestId(method, params, sequence, catalogPreview) {
34
+ const kind = catalogPreview ? method === "thread/list" ? "list" : method === "thread/read" && isJsonObject(params) && params.includeTurns !== true ? "thread" : void 0 : void 0;
35
+ return kind ? Number.MAX_SAFE_INTEGER - 2 * sequence - (kind === "thread" ? 1 : 0) : sequence;
36
+ }
37
+ /** Each physical client owns one decoder, including incomplete-line recovery state. */
38
+ var CodexCatalogWorker = class {
39
+ constructor() {
40
+ this.closed = false;
41
+ }
42
+ get continuation() {
43
+ return this.continuationRoute;
44
+ }
45
+ async decode(line, route, attempts, projections) {
46
+ if (this.closed) return;
47
+ if (!this.continuationRoute && route !== "unresolved" && line.byteLength <= INLINE_CATALOG_MAX_BYTES) {
48
+ let parsed;
49
+ try {
50
+ parsed = JSON.parse(line.toString("utf8"));
51
+ } catch {}
52
+ if (parsed !== void 0) {
53
+ await Promise.resolve();
54
+ if (this.closed) return;
55
+ const attempt = attempts.get(route.id);
56
+ const projection = attempt ? projections.get(attempt) : void 0;
57
+ return projectCodexCatalogMessage(parsed, {
58
+ route,
59
+ remainingRows: attempt ? projection?.remainingRows : 0
60
+ }, projection?.preview);
61
+ }
62
+ }
63
+ if (!this.pool) {
64
+ const { resolveRuntimeWorkerUrl, WorkerTaskPool } = await import("openclaw/plugin-sdk/process-runtime");
65
+ if (this.closed) return;
66
+ this.pool = new WorkerTaskPool({
67
+ workerUrl: resolveRuntimeWorkerUrl(codexCatalogPageWorkerEntrypoint),
68
+ maxWorkers: 1,
69
+ maxPendingTasks: 1,
70
+ maxPendingBytes: Number.MAX_SAFE_INTEGER,
71
+ idleTimeoutMs: 0,
72
+ restartOnError: false
73
+ });
74
+ }
75
+ const attempt = route === "unresolved" ? void 0 : attempts.get(route.id);
76
+ const remainingRows = attempt ? projections.get(attempt)?.remainingRows : 0;
77
+ let catalogRows;
78
+ if (route === "unresolved") {
79
+ catalogRows = /* @__PURE__ */ new Map();
80
+ for (const [id, pending] of attempts) {
81
+ const projection = projections.get(pending);
82
+ if (typeof id === "number" && projection) catalogRows.set(id, projection.remainingRows);
83
+ }
84
+ }
85
+ const bytes = line.byteOffset === 0 && line.byteLength === line.buffer.byteLength && line.buffer instanceof ArrayBuffer ? new Uint8Array(line.buffer) : Uint8Array.from(line);
86
+ const decoded = await this.pool.run({
87
+ bytes,
88
+ route,
89
+ remainingRows,
90
+ catalogRows
91
+ }, {
92
+ inputBytes: bytes.byteLength,
93
+ transferList: (input) => [input.bytes.buffer]
94
+ });
95
+ if (this.closed) return;
96
+ this.continuationRoute = decoded.pending ? route : void 0;
97
+ return decoded;
98
+ }
99
+ close(error) {
100
+ this.closed = true;
101
+ this.continuationRoute = void 0;
102
+ return this.pool?.close(error) ?? Promise.resolve();
103
+ }
104
+ };
105
+ //#endregion
106
+ //#region extensions/codex/src/app-server/client-diagnostics.ts
107
+ function observeCodexAppServerStderr(stderr, consume) {
108
+ stderr.setEncoding("utf8");
109
+ stderr.on("data", (chunk) => {
110
+ const text = consume(chunk).trim();
111
+ if (text) embeddedAgentLog.debug(`codex app-server stderr: ${text}`);
112
+ });
113
+ stderr.on("error", (error) => embeddedAgentLog.warn("codex app-server stderr stream failed", { error }));
114
+ }
115
+ function appendBoundedTail(current, next, maxLength) {
116
+ const combined = `${current}${next}`;
117
+ return combined.length > maxLength ? sliceUtf16Safe(combined, -maxLength) : combined;
118
+ }
119
+ function buildCodexAppServerExitError(code, signal, stderrTail) {
120
+ const stderrPreview = redactCodexAppServerLinePreview(stderrTail);
121
+ const suffix = stderrPreview ? ` stderr=${JSON.stringify(stderrPreview)}` : "";
122
+ return /* @__PURE__ */ new Error(`codex app-server exited: code=${formatExitValue(code)} signal=${formatExitValue(signal)}${suffix}`);
123
+ }
124
+ function logCodexAppServerParseFailure(value, error, fragmentCount) {
125
+ const linePreview = redactCodexAppServerLinePreview(value);
126
+ const suffix = fragmentCount > 1 ? ` fragments=${fragmentCount}` : "";
127
+ embeddedAgentLog.warn("failed to parse codex app-server message", {
128
+ error,
129
+ errorMessage: coerceErrorMessage(error),
130
+ fragmentCount,
131
+ linePreview,
132
+ consoleMessage: `failed to parse codex app-server message${suffix}: preview=${JSON.stringify(linePreview)}`
133
+ });
134
+ }
135
+ function formatExitValue(value) {
136
+ if (value === null || value === void 0) return "null";
137
+ if (typeof value === "string" || typeof value === "number") return String(value);
138
+ return "unknown";
139
+ }
140
+ //#endregion
141
+ //#region extensions/codex/src/app-server/notification-policy.ts
142
+ const CODEX_APP_SERVER_OPT_OUT_NOTIFICATION_METHODS = [
143
+ "account/login/completed",
144
+ "app/list/updated",
145
+ "command/exec/outputDelta",
146
+ "deprecationNotice",
147
+ "externalAgentConfig/import/completed",
148
+ "externalAgentConfig/import/progress",
149
+ "fs/changed",
150
+ "fuzzyFileSearch/sessionCompleted",
151
+ "fuzzyFileSearch/sessionUpdated",
152
+ "mcpServer/event/stream/notification",
153
+ "mcpServer/oauthLogin/completed",
154
+ "mcpServer/startupStatus/updated",
155
+ "process/exited",
156
+ "process/outputDelta",
157
+ "project/changed",
158
+ "remoteControl/status/changed",
159
+ "thread/environment/connected",
160
+ "thread/environment/disconnected",
161
+ "thread/goal/cleared",
162
+ "thread/project/updated",
163
+ "thread/queue/changed",
164
+ "thread/realtime/closed",
165
+ "thread/realtime/error",
166
+ "thread/realtime/item/completed",
167
+ "thread/realtime/item/started",
168
+ "thread/realtime/item/transcript/delta",
169
+ "thread/realtime/itemAdded",
170
+ "thread/realtime/outputAudio/delta",
171
+ "thread/realtime/sdp",
172
+ "thread/realtime/started",
173
+ "thread/realtime/transcript/delta",
174
+ "thread/realtime/transcript/done",
175
+ "windows/worldWritableWarning",
176
+ "windowsSandbox/setupCompleted",
177
+ "turn/diff/updated",
178
+ "item/fileChange/outputDelta",
179
+ "thread/compacted"
180
+ ];
181
+ //#endregion
182
+ //#region extensions/codex/src/app-server/client-initialize.ts
183
+ function buildCodexAppServerInitializeParams() {
184
+ return {
185
+ clientInfo: {
186
+ name: "openclaw",
187
+ title: "OpenClaw",
188
+ version: OPENCLAW_VERSION
189
+ },
190
+ capabilities: {
191
+ experimentalApi: true,
192
+ optOutNotificationMethods: [...CODEX_APP_SERVER_OPT_OUT_NOTIFICATION_METHODS],
193
+ extensions: {
194
+ "openai/standard-form-input": {},
195
+ "openai/form": {},
196
+ "io.modelcontextprotocol/ui": { mimeTypes: ["text/html;profile=mcp-app"] }
197
+ }
198
+ }
199
+ };
32
200
  }
33
201
  //#endregion
34
202
  //#region extensions/codex/src/app-server/client-response.ts
35
203
  /** Settles one wire attempt and reports newly observed native execution. */
36
- function dispatchCodexAppServerResponse(response, attempts, catalogResponses, source) {
204
+ function dispatchCodexAppServerResponse(response, attempts, catalogResponses, source, previewStates) {
37
205
  const pending = attempts.get(response.id);
38
206
  if (!pending) return false;
39
207
  attempts.delete(response.id);
@@ -43,112 +211,218 @@ function dispatchCodexAppServerResponse(response, attempts, catalogResponses, so
43
211
  return false;
44
212
  }
45
213
  const nativeExecution = pending.method === "thread/backgroundTerminals/list" && isJsonObject(response.result) && Array.isArray(response.result.data) && response.result.data.length > 0;
46
- if (catalogResponses.has(pending) && isJsonObject(response.result) && Array.isArray(response.result.data)) {
47
- const projection = catalogResponses.get(pending);
48
- try {
49
- response.result = projectCodexCatalogNativeResponse(response.result, sanitizeTerminalText, projection?.preview, projection?.remainingRows);
50
- } catch (error) {
51
- pending.reject(error instanceof Error ? error : new Error("Codex catalog projection failed", { cause: error }), false);
52
- return false;
214
+ const cache = catalogResponses.get(pending)?.preview;
215
+ if (cache && previewStates && isJsonObject(response.result) && Array.isArray(response.result.data)) try {
216
+ for (const [index, row] of response.result.data.entries()) if (isJsonObject(row) && typeof row.id === "string" && row.ephemeral !== true) {
217
+ const preview = reuseCodexCatalogPreview({
218
+ id: row.id,
219
+ path: typeof row.path === "string" ? row.path : null,
220
+ updatedAt: typeof row.updatedAt === "number" ? row.updatedAt : null,
221
+ recencyAt: typeof row.recencyAt === "number" ? row.recencyAt : null
222
+ }, previewStates[index], cache);
223
+ if (preview !== void 0) row.preview = preview;
53
224
  }
225
+ } catch (error) {
226
+ pending.reject(error instanceof Error ? error : new Error("Codex catalog projection failed", { cause: error }), false);
227
+ return false;
54
228
  }
55
229
  recordCodexCatalogResponseSource(pending.method, response.result, source);
56
230
  pending.resolve(response.result);
57
231
  return nativeExecution;
58
232
  }
59
233
  //#endregion
60
- //#region extensions/codex/src/app-server/dynamic-tool-response-state.ts
61
- /** Retains the host-owned app preview without adding it to Codex's response payload. */
62
- function withDynamicToolTranscriptDetails(response, details) {
63
- if (details === void 0) return response;
64
- Object.defineProperty(response, "transcriptDetails", {
65
- configurable: true,
66
- enumerable: false,
67
- value: details
68
- });
69
- return response;
70
- }
71
- function withDynamicToolTerminalResolution(response, terminalResolution) {
72
- if (terminalResolution) {
73
- Object.defineProperties(response, {
74
- terminalResolution: {
75
- configurable: true,
76
- enumerable: false,
77
- value: terminalResolution
78
- },
79
- executionStarted: {
80
- configurable: true,
81
- enumerable: false,
82
- value: terminalResolution.executionStarted
83
- },
84
- ...terminalResolution.executedArguments ? { executedArguments: {
85
- configurable: true,
86
- enumerable: false,
87
- value: terminalResolution.executedArguments
88
- } } : {}
89
- });
90
- withDynamicToolSideEffectEvidence(response, terminalResolution.sideEffectEvidence);
91
- }
92
- return response;
93
- }
94
- function withDynamicToolExecutionState(response, state) {
95
- Object.defineProperties(response, {
96
- executedArguments: {
97
- configurable: true,
98
- enumerable: false,
99
- value: state.executedArguments
234
+ //#region extensions/codex/src/app-server/request-attempt.ts
235
+ /** One wire attempt; local waiter expiry need not imply a native response. */
236
+ function createCodexRequestAttempt(params) {
237
+ let pending = true;
238
+ let mayHaveWritten = false;
239
+ const waiters = /* @__PURE__ */ new Set();
240
+ const diagnostics = params.diagnosticIdentity ? {
241
+ ...params.diagnosticIdentity,
242
+ waiterOrdinal: 0,
243
+ attemptCreatedAtMs: performance.now(),
244
+ firstPossibleWriteAtMs: null,
245
+ wireOutcomeAtWaiterSettlement: "retained-pending",
246
+ wireObservedAtMs: null
247
+ } : void 0;
248
+ const finish = (outcome) => {
249
+ if (!pending) return false;
250
+ pending = false;
251
+ if (diagnostics) {
252
+ diagnostics.wireOutcomeAtWaiterSettlement = outcome;
253
+ diagnostics.wireObservedAtMs = performance.now();
254
+ }
255
+ params.onSettled();
256
+ return true;
257
+ };
258
+ const rejectWaiters = (error, outcome) => {
259
+ for (const waiter of waiters) waiter.reject(error, outcome);
260
+ };
261
+ const currentWaiterError = (waiter) => {
262
+ if (!params.retainWritten) return;
263
+ if (waiter.signal?.aborted) return {
264
+ error: params.cancellationError("aborted", mayHaveWritten, waiter.signal.reason),
265
+ outcome: "aborted"
266
+ };
267
+ if (waiter.deadline !== void 0 && performance.now() >= waiter.deadline) return {
268
+ error: params.cancellationError("timed out", mayHaveWritten),
269
+ outcome: "timed-out"
270
+ };
271
+ try {
272
+ waiter.assertCurrent?.();
273
+ } catch (error) {
274
+ return {
275
+ error: toStringifiedError(error),
276
+ outcome: "authority-rejected"
277
+ };
278
+ }
279
+ if (waiter.signal?.aborted) return {
280
+ error: params.cancellationError("aborted", mayHaveWritten, waiter.signal.reason),
281
+ outcome: "aborted"
282
+ };
283
+ if (waiter.deadline !== void 0 && performance.now() >= waiter.deadline) return {
284
+ error: params.cancellationError("timed out", mayHaveWritten),
285
+ outcome: "timed-out"
286
+ };
287
+ };
288
+ return {
289
+ method: params.method,
290
+ get pending() {
291
+ return pending;
292
+ },
293
+ wait(options, deadline) {
294
+ const { timeoutMs, signal, assertCurrent, disposition, overloadAttemptOrdinal } = options;
295
+ let observe = options.attemptWaiterFinished;
296
+ return new Promise((resolve, reject) => {
297
+ if (!pending) {
298
+ reject(/* @__PURE__ */ new Error("Codex request attempt is already settled"));
299
+ return;
300
+ }
301
+ let timer;
302
+ let removeAbort;
303
+ const waiterOrdinal = diagnostics ? ++diagnostics.waiterOrdinal : 0;
304
+ const waiterAttachedAtMs = diagnostics && observe ? performance.now() : 0;
305
+ const cleanup = () => {
306
+ clearTimeout(timer);
307
+ timer = void 0;
308
+ removeAbort?.();
309
+ removeAbort = void 0;
310
+ };
311
+ const detach = (waiterOutcome) => {
312
+ if (!waiters.delete(waiter)) return false;
313
+ cleanup();
314
+ if (waiters.size === 0 && (!params.retainWritten || !mayHaveWritten)) finish(mayHaveWritten ? "correlation-closed" : "not-written");
315
+ const callback = observe;
316
+ observe = void 0;
317
+ if (diagnostics && callback) try {
318
+ callback({
319
+ ...diagnostics,
320
+ waiterOrdinal,
321
+ disposition,
322
+ overloadAttemptOrdinal,
323
+ waiterAttachedAtMs,
324
+ waiterSettledAtMs: performance.now(),
325
+ waiterOutcome
326
+ });
327
+ } catch {}
328
+ return true;
329
+ };
330
+ const waiter = {
331
+ resolve: (value) => {
332
+ if (!detach("resolved")) return;
333
+ resolve(value);
334
+ },
335
+ reject: (error, outcome) => {
336
+ if (detach(outcome)) reject(error);
337
+ },
338
+ cleanup,
339
+ signal,
340
+ ...params.retainWritten ? {
341
+ deadline,
342
+ assertCurrent
343
+ } : {}
344
+ };
345
+ waiters.add(waiter);
346
+ if (params.retainWritten && deadline !== void 0 && performance.now() >= deadline) {
347
+ waiter.reject(params.cancellationError("timed out", mayHaveWritten), "timed-out");
348
+ return;
349
+ }
350
+ if (timeoutMs && Number.isFinite(timeoutMs) && timeoutMs > 0) {
351
+ const remaining = params.retainWritten && deadline !== void 0 ? deadline - performance.now() : timeoutMs;
352
+ timer = setTimeout(() => waiter.reject(params.cancellationError("timed out", mayHaveWritten), "timed-out"), Math.max(params.retainWritten ? 1 : 100, remaining));
353
+ timer.unref?.();
354
+ }
355
+ if (signal) {
356
+ const abort = () => waiter.reject(params.cancellationError("aborted", mayHaveWritten, signal.reason), "aborted");
357
+ signal.addEventListener("abort", abort, { once: true });
358
+ removeAbort = () => signal.removeEventListener("abort", abort);
359
+ if (signal.aborted) abort();
360
+ }
361
+ });
362
+ },
363
+ resolve(value) {
364
+ if (!finish("native-ok")) return;
365
+ params.onResponse?.(mayHaveWritten);
366
+ for (const waiter of waiters) {
367
+ const error = currentWaiterError(waiter);
368
+ if (error) waiter.reject(error.error, error.outcome);
369
+ else waiter.resolve(value);
370
+ }
371
+ },
372
+ reject(error, definitelyNotEnqueued = false) {
373
+ if (finish(definitelyNotEnqueued ? "ingress-rejected" : "native-error")) {
374
+ if (definitelyNotEnqueued) mayHaveWritten = false;
375
+ params.onResponse?.(mayHaveWritten);
376
+ for (const waiter of waiters) {
377
+ const current = currentWaiterError(waiter);
378
+ waiter.reject(current?.error ?? params.localError(error, mayHaveWritten), current?.outcome ?? "native-error");
379
+ }
380
+ }
381
+ },
382
+ close(error) {
383
+ if (finish("correlation-closed")) rejectWaiters(params.localError(error, mayHaveWritten), "client-closed");
384
+ },
385
+ failLocal(error) {
386
+ if (!pending) return;
387
+ if (!params.retainWritten || !mayHaveWritten) finish(mayHaveWritten ? "correlation-closed" : "not-written");
388
+ rejectWaiters(params.localError(error, mayHaveWritten), "local-failed");
389
+ },
390
+ markWritten() {
391
+ mayHaveWritten = true;
392
+ if (diagnostics && diagnostics.firstPossibleWriteAtMs === null) diagnostics.firstPossibleWriteAtMs = performance.now();
100
393
  },
101
- executionStarted: {
102
- configurable: true,
103
- enumerable: false,
104
- value: state.executionStarted
394
+ cleanup() {
395
+ for (const waiter of waiters) waiter.cleanup();
105
396
  }
106
- });
107
- return withDynamicToolSideEffectEvidence(response, state.sideEffectEvidence === true);
108
- }
109
- function withDynamicToolSideEffectEvidence(response, sideEffectEvidence) {
110
- if (!sideEffectEvidence) {
111
- delete response.sideEffectEvidence;
112
- return response;
113
- }
114
- Object.defineProperty(response, "sideEffectEvidence", {
115
- configurable: true,
116
- enumerable: false,
117
- value: true
118
- });
119
- return response;
397
+ };
120
398
  }
399
+ //#endregion
400
+ //#region extensions/codex/src/app-server/dynamic-tool-response-state.ts
121
401
  function createFailedDynamicToolResponse(message, options) {
122
- const response = {
402
+ return {
123
403
  contentItems: [{
124
404
  type: "inputText",
125
405
  text: message
126
406
  }],
127
- success: false
407
+ success: false,
408
+ diagnosticTerminalReason: options?.terminalReason ?? "failed",
409
+ diagnosticTerminalType: "error",
410
+ executionStarted: options?.executionStarted,
411
+ executedArguments: options?.executedArguments,
412
+ sideEffectEvidence: options?.sideEffectEvidence === true || void 0
128
413
  };
129
- Object.defineProperties(response, {
130
- diagnosticTerminalReason: {
131
- configurable: true,
132
- enumerable: false,
133
- value: options?.terminalReason ?? "failed"
134
- },
135
- diagnosticTerminalType: {
136
- configurable: true,
137
- enumerable: false,
138
- value: "error"
414
+ }
415
+ function failedToolResult(message, status = "failed") {
416
+ return {
417
+ content: [{
418
+ type: "text",
419
+ text: message
420
+ }],
421
+ details: {
422
+ status,
423
+ error: message
139
424
  }
140
- });
141
- if (options?.executionStarted !== void 0) Object.defineProperty(response, "executionStarted", {
142
- configurable: true,
143
- enumerable: false,
144
- value: options.executionStarted
145
- });
146
- if (options?.executedArguments !== void 0) Object.defineProperty(response, "executedArguments", {
147
- configurable: true,
148
- enumerable: false,
149
- value: options.executedArguments
150
- });
151
- return withDynamicToolSideEffectEvidence(response, options?.sideEffectEvidence === true);
425
+ };
152
426
  }
153
427
  //#endregion
154
428
  //#region extensions/codex/src/app-server/tool-abort-terminal-reason.ts
@@ -244,11 +518,13 @@ function formatDynamicToolTimeoutDetails(params) {
244
518
  }
245
519
  };
246
520
  }
247
- /**
248
- * Runs a dynamic tool call with run-abort and the budget prepared by
249
- * resolveDynamicToolCallTimeoutMs, preserving tool-specific completion grace.
250
- */
251
521
  async function handleDynamicToolCallWithTimeout(params) {
522
+ return await runWithAsyncWorkResources((onAcquired) => executeDynamicToolCallWithTimeout(params, (release) => onAcquired({
523
+ release,
524
+ releaseBeforeResultWhenIdle: true
525
+ })));
526
+ }
527
+ async function executeDynamicToolCallWithTimeout(params, retainCleanup) {
252
528
  let didNotifyAgentToolResult = false;
253
529
  const conservativeRaceResponses = /* @__PURE__ */ new WeakSet();
254
530
  const finalizeTerminal = (response) => {
@@ -265,11 +541,18 @@ async function handleDynamicToolCallWithTimeout(params) {
265
541
  arguments: response.executedArguments ?? executionSnapshot?.executedArguments ?? params.call.arguments,
266
542
  ...params.toolMeta ? { meta: params.toolMeta } : {},
267
543
  ...ownerKey ? { ownerMutation: { ownerKey } } : {},
544
+ replaySafe: ownerKey ? false : response.replaySafe,
268
545
  ...observedExecutionStarted !== void 0 ? { executionStarted: observedExecutionStarted } : {},
269
546
  outcome: response.success ? "success" : "failure",
270
547
  ...!response.success ? { failure: { error: readDynamicToolResponseText(response) } } : {}
271
548
  });
272
- return withDynamicToolTerminalResolution(response, terminalResolution);
549
+ if (terminalResolution) {
550
+ response.terminalResolution = terminalResolution;
551
+ response.executionStarted = terminalResolution.executionStarted;
552
+ response.executedArguments = terminalResolution.executedArguments ?? response.executedArguments;
553
+ response.sideEffectEvidence = terminalResolution.sideEffectEvidence || void 0;
554
+ }
555
+ return response;
273
556
  };
274
557
  const createFailedAfterPossibleDispatch = (message, terminalReason) => {
275
558
  const response = createFailedDynamicToolResponse(message, {
@@ -319,15 +602,26 @@ async function handleDynamicToolCallWithTimeout(params) {
319
602
  const controller = new AbortController();
320
603
  let timeout;
321
604
  let timedOut = false;
605
+ let toolCallSettled = false;
606
+ let completedSuccessfully = false;
607
+ let operationReleased = false;
322
608
  let resolveAbort;
323
609
  const abortFromRun = () => {
324
610
  const message = "OpenClaw dynamic tool call aborted.";
325
611
  const terminalReason = resolveCodexToolAbortTerminalReason(params.signal);
326
- params.onFallbackSelected?.();
327
612
  controller.abort(params.signal.reason ?? /* @__PURE__ */ new Error(message));
613
+ if (toolCallSettled) return;
614
+ params.onFallbackSelected?.();
328
615
  notifyFailedToolResult(message, terminalReason);
329
616
  resolveAbort?.(createFailedAfterPossibleDispatch(message, terminalReason));
330
617
  };
618
+ const releaseOperation = () => {
619
+ if (operationReleased) return;
620
+ operationReleased = true;
621
+ params.signal.removeEventListener("abort", abortFromRun);
622
+ if (!controller.signal.aborted) controller.abort(/* @__PURE__ */ new Error("OpenClaw dynamic tool call finished."));
623
+ };
624
+ retainCleanup(releaseOperation);
331
625
  const abortPromise = new Promise((resolve) => {
332
626
  resolveAbort = resolve;
333
627
  });
@@ -365,7 +659,9 @@ async function handleDynamicToolCallWithTimeout(params) {
365
659
  timeoutPromise
366
660
  ]);
367
661
  if (!response.success && !didNotifyAgentToolResult) notifyFailedToolResult(readDynamicToolResponseText(response), response.diagnosticTerminalReason ?? "failed");
368
- return finalizeTerminal(response);
662
+ const terminal = finalizeTerminal(response);
663
+ completedSuccessfully = terminal.success;
664
+ return terminal;
369
665
  } catch (error) {
370
666
  const terminalReason = params.signal.aborted ? resolveCodexToolAbortTerminalReason(params.signal) : resolveToolExecutionErrorKind(error);
371
667
  const message = formatToolExecutionErrorMessage(error, "OpenClaw dynamic tool call failed.");
@@ -373,9 +669,9 @@ async function handleDynamicToolCallWithTimeout(params) {
373
669
  return finalizeTerminal(createFailedAfterPossibleDispatch(message, terminalReason));
374
670
  } finally {
375
671
  if (timeout) clearTimeout(timeout);
376
- params.signal.removeEventListener("abort", abortFromRun);
672
+ toolCallSettled = true;
377
673
  resolveAbort = void 0;
378
- if (!timedOut && !controller.signal.aborted) controller.abort(/* @__PURE__ */ new Error("OpenClaw dynamic tool call finished."));
674
+ if (!completedSuccessfully || timedOut || controller.signal.aborted) releaseOperation();
379
675
  }
380
676
  }
381
677
  function readDynamicToolResponseText(response) {
@@ -2943,14 +3239,15 @@ function assertCodexThreadAcceptsDirectInput(thread) {
2943
3239
  }
2944
3240
  /** Asserts and normalizes a Codex turn/start response. */
2945
3241
  function assertCodexTurnStartResponse(value) {
2946
- const normalized = normalizeWithDefaults(turnStartResponseSchema, normalizeTurnEnvelope(value));
3242
+ const normalized = normalizeWithDefaults(turnStartResponseSchema, value);
2947
3243
  return assertCodexShape(validateTurnStartResponse, normalized, "turn/start response");
2948
3244
  }
2949
- /** Only the current text prompt may be echoed; capabilities and historical items are not passive. */
2950
- function assertCodexPassiveTurnItems(items, prompt, taskLabel) {
3245
+ /** Prompt echoes and attested managed-hook continuations cannot admit native capabilities. */
3246
+ function assertCodexPassiveTurnItems(items, prompt, taskLabel, options = {}) {
2951
3247
  let promptEchoSeen = false;
2952
3248
  for (const item of items) {
2953
3249
  if (item.type === "agentMessage" || item.type === "reasoning") continue;
3250
+ if (item.type === "hookPrompt" && options.allowManagedHookPrompts === true && Array.isArray(item.fragments) && item.fragments.length > 0 && item.fragments.every((fragment) => isJsonObject(fragment) && typeof fragment.text === "string" && typeof fragment.hookRunId === "string" && fragment.hookRunId.trim().length > 0)) continue;
2954
3251
  if (item.type === "userMessage" && !promptEchoSeen) {
2955
3252
  const content = Array.isArray(item.content) ? item.content : [];
2956
3253
  const input = content[0];
@@ -2974,13 +3271,10 @@ function readCodexErrorNotification(value) {
2974
3271
  function assertCodexModelListResponse(value) {
2975
3272
  return assertCodexShape(validateModelListResponse, normalizeWithDefaults(modelListResponseSchema, value), "model/list response");
2976
3273
  }
2977
- /** Reads and normalizes a Codex turn object. */
2978
- function readCodexTurn(value) {
2979
- return readCodexShape(validateTurnStartResponse, normalizeWithDefaults(turnStartResponseSchema, { turn: normalizeTurn(value) }))?.turn;
2980
- }
2981
3274
  /** Reads a Codex turn/completed notification payload if it matches the protocol schema. */
2982
3275
  function readCodexTurnCompletedNotification(value) {
2983
- return readCodexShape(validateTurnCompletedNotification, normalizeWithDefaults(turnCompletedNotificationSchema, normalizeTurnEnvelope(value)));
3276
+ const notification = readCodexShape(validateTurnCompletedNotification, normalizeWithDefaults(turnCompletedNotificationSchema, value));
3277
+ return notification?.turn.status === "inProgress" ? void 0 : notification;
2984
3278
  }
2985
3279
  function assertCodexShape(validate, value, label) {
2986
3280
  if (validate.check(value)) return value;
@@ -2989,54 +3283,6 @@ function assertCodexShape(validate, value, label) {
2989
3283
  function readCodexShape(validate, value) {
2990
3284
  return validate.check(value) ? value : void 0;
2991
3285
  }
2992
- function normalizeTurn(value) {
2993
- if (!value || typeof value !== "object" || Array.isArray(value)) return value;
2994
- return {
2995
- error: null,
2996
- startedAt: null,
2997
- completedAt: null,
2998
- durationMs: null,
2999
- ...value,
3000
- items: Array.isArray(value.items) ? value.items.map(normalizeThreadItem) : []
3001
- };
3002
- }
3003
- function normalizeThreadItem(value) {
3004
- if (!value || typeof value !== "object" || Array.isArray(value)) return value;
3005
- switch (value.type) {
3006
- case "agentMessage": return {
3007
- phase: null,
3008
- delivery: null,
3009
- memoryCitation: null,
3010
- ...value
3011
- };
3012
- case "plan": return {
3013
- text: "",
3014
- ...value
3015
- };
3016
- case "reasoning": return {
3017
- summary: [],
3018
- content: [],
3019
- ...value
3020
- };
3021
- case "dynamicToolCall": return {
3022
- namespace: null,
3023
- arguments: null,
3024
- status: "completed",
3025
- contentItems: null,
3026
- success: null,
3027
- durationMs: null,
3028
- ...value
3029
- };
3030
- default: return value;
3031
- }
3032
- }
3033
- function normalizeTurnEnvelope(value) {
3034
- if (!value || typeof value !== "object" || Array.isArray(value) || !("turn" in value)) return value;
3035
- return {
3036
- ...value,
3037
- turn: normalizeTurn(value.turn)
3038
- };
3039
- }
3040
3286
  function formatValidationErrors(validate, value) {
3041
3287
  const errors = validate.errors(value);
3042
3288
  if (!errors || errors.length === 0) return "schema validation failed";
@@ -3046,169 +3292,130 @@ function formatValidationErrors(validate, value) {
3046
3292
  }).join("; ");
3047
3293
  }
3048
3294
  //#endregion
3049
- //#region extensions/codex/src/app-server/request-attempt.ts
3050
- /** One wire attempt; local waiter expiry need not imply a native response. */
3051
- function createCodexRequestAttempt(params) {
3052
- let pending = true;
3053
- let mayHaveWritten = false;
3054
- const waiters = /* @__PURE__ */ new Set();
3055
- const diagnostics = params.diagnosticIdentity ? {
3056
- ...params.diagnosticIdentity,
3057
- waiterOrdinal: 0,
3058
- attemptCreatedAtMs: performance.now(),
3059
- firstPossibleWriteAtMs: null,
3060
- wireOutcomeAtWaiterSettlement: "retained-pending",
3061
- wireObservedAtMs: null
3062
- } : void 0;
3063
- const finish = (outcome) => {
3064
- if (!pending) return false;
3065
- pending = false;
3066
- if (diagnostics) {
3067
- diagnostics.wireOutcomeAtWaiterSettlement = outcome;
3068
- diagnostics.wireObservedAtMs = performance.now();
3295
+ //#region extensions/codex/src/app-server/server-requests.ts
3296
+ var CodexServerRequestResolvedError = class extends Error {
3297
+ constructor() {
3298
+ super("Codex server request resolved by another client");
3299
+ this.name = "CodexServerRequestResolvedError";
3300
+ }
3301
+ };
3302
+ /** Physical-client owner for inbound requests, cancellation, and response deadlines. */
3303
+ var CodexServerRequests = class {
3304
+ constructor(respond) {
3305
+ this.respond = respond;
3306
+ this.handlers = /* @__PURE__ */ new Set();
3307
+ this.active = /* @__PURE__ */ new Map();
3308
+ }
3309
+ resolve(params) {
3310
+ if (!isJsonObject(params) || typeof params.threadId !== "string") return;
3311
+ const id = params.requestId;
3312
+ if (typeof id !== "string" && typeof id !== "number") return;
3313
+ const request = this.active.get(id);
3314
+ if (request?.threadId === params.threadId) {
3315
+ this.active.delete(id);
3316
+ request.controller.abort(new CodexServerRequestResolvedError());
3069
3317
  }
3070
- params.onSettled();
3071
- return true;
3072
- };
3073
- const rejectWaiters = (error, outcome) => {
3074
- for (const waiter of waiters) waiter.reject(error, outcome);
3075
- };
3076
- const currentWaiterError = (waiter) => {
3077
- if (!params.retainWritten) return;
3078
- if (waiter.signal?.aborted) return {
3079
- error: params.cancellationError("aborted", mayHaveWritten, waiter.signal.reason),
3080
- outcome: "aborted"
3318
+ }
3319
+ close(error) {
3320
+ const requests = [...this.active.values()];
3321
+ this.active.clear();
3322
+ for (const request of requests) request.controller.abort(error);
3323
+ }
3324
+ async handle(request) {
3325
+ const controller = new AbortController();
3326
+ const entry = {
3327
+ threadId: isJsonObject(request.params) ? request.params.threadId : void 0,
3328
+ controller
3081
3329
  };
3082
- if (waiter.deadline !== void 0 && performance.now() >= waiter.deadline) return {
3083
- error: params.cancellationError("timed out", mayHaveWritten),
3084
- outcome: "timed-out"
3330
+ this.active.set(request.id, entry);
3331
+ const deadline = createDeferred();
3332
+ const onAbort = () => deadline.resolve(void 0);
3333
+ controller.signal.addEventListener("abort", onAbort, { once: true });
3334
+ let timeout;
3335
+ let timeoutMs = resolveDynamicToolServerRequestTimeoutMs(readCodexDynamicToolCallParams(request.params));
3336
+ let settled = false;
3337
+ let executionTimeoutResolved = false;
3338
+ const armTimeout = () => {
3339
+ clearTimeout(timeout);
3340
+ timeout = setTimeout(() => {
3341
+ embeddedAgentLog.warn("codex app-server server request timed out", {
3342
+ id: request.id,
3343
+ method: request.method,
3344
+ timeoutMs
3345
+ });
3346
+ deadline.resolve(timeoutServerRequestResponse(timeoutMs));
3347
+ controller.abort(/* @__PURE__ */ new Error("codex app-server server request timed out"));
3348
+ }, timeoutMs);
3349
+ timeout.unref?.();
3085
3350
  };
3086
- try {
3087
- waiter.assertCurrent?.();
3088
- } catch (error) {
3089
- return {
3090
- error: toStringifiedError(error),
3091
- outcome: "authority-rejected"
3092
- };
3093
- }
3094
- if (waiter.signal?.aborted) return {
3095
- error: params.cancellationError("aborted", mayHaveWritten, waiter.signal.reason),
3096
- outcome: "aborted"
3351
+ const setExecutionTimeoutMs = (executionTimeoutMs) => {
3352
+ if (settled || controller.signal.aborted || executionTimeoutResolved || !Number.isFinite(executionTimeoutMs) || executionTimeoutMs <= 0) return;
3353
+ executionTimeoutResolved = true;
3354
+ timeoutMs = addSafeTimeoutDelayGraceMs(executionTimeoutMs, 3e4);
3355
+ armTimeout();
3097
3356
  };
3098
- if (waiter.deadline !== void 0 && performance.now() >= waiter.deadline) return {
3099
- error: params.cancellationError("timed out", mayHaveWritten),
3100
- outcome: "timed-out"
3357
+ const dynamicTool = request.method === "item/tool/call";
3358
+ if (dynamicTool) armTimeout();
3359
+ const run = async () => {
3360
+ for (const handler of this.handlers) {
3361
+ if (controller.signal.aborted) return;
3362
+ const result = await handler(request, controller.signal, dynamicTool ? setExecutionTimeoutMs : void 0);
3363
+ if (result !== void 0) return result;
3364
+ }
3101
3365
  };
3102
- };
3103
- return {
3104
- method: params.method,
3105
- get pending() {
3106
- return pending;
3107
- },
3108
- wait(options, deadline) {
3109
- const { timeoutMs, signal, assertCurrent, disposition, overloadAttemptOrdinal } = options;
3110
- let observe = options.attemptWaiterFinished;
3111
- return new Promise((resolve, reject) => {
3112
- if (!pending) {
3113
- reject(/* @__PURE__ */ new Error("Codex request attempt is already settled"));
3114
- return;
3115
- }
3116
- let timer;
3117
- let removeAbort;
3118
- const waiterOrdinal = diagnostics ? ++diagnostics.waiterOrdinal : 0;
3119
- const waiterAttachedAtMs = diagnostics && observe ? performance.now() : 0;
3120
- const cleanup = () => {
3121
- clearTimeout(timer);
3122
- timer = void 0;
3123
- removeAbort?.();
3124
- removeAbort = void 0;
3125
- };
3126
- const detach = (waiterOutcome) => {
3127
- if (!waiters.delete(waiter)) return false;
3128
- cleanup();
3129
- if (waiters.size === 0 && (!params.retainWritten || !mayHaveWritten)) finish(mayHaveWritten ? "correlation-closed" : "not-written");
3130
- const callback = observe;
3131
- observe = void 0;
3132
- if (diagnostics && callback) try {
3133
- callback({
3134
- ...diagnostics,
3135
- waiterOrdinal,
3136
- disposition,
3137
- overloadAttemptOrdinal,
3138
- waiterAttachedAtMs,
3139
- waiterSettledAtMs: performance.now(),
3140
- waiterOutcome
3141
- });
3142
- } catch {}
3143
- return true;
3144
- };
3145
- const waiter = {
3146
- resolve: (value) => {
3147
- if (!detach("resolved")) return;
3148
- resolve(value);
3149
- },
3150
- reject: (error, outcome) => {
3151
- if (detach(outcome)) reject(error);
3152
- },
3153
- cleanup,
3154
- signal,
3155
- ...params.retainWritten ? {
3156
- deadline,
3157
- assertCurrent
3158
- } : {}
3159
- };
3160
- waiters.add(waiter);
3161
- if (params.retainWritten && deadline !== void 0 && performance.now() >= deadline) {
3162
- waiter.reject(params.cancellationError("timed out", mayHaveWritten), "timed-out");
3163
- return;
3164
- }
3165
- if (timeoutMs && Number.isFinite(timeoutMs) && timeoutMs > 0) {
3166
- const remaining = params.retainWritten && deadline !== void 0 ? deadline - performance.now() : timeoutMs;
3167
- timer = setTimeout(() => waiter.reject(params.cancellationError("timed out", mayHaveWritten), "timed-out"), Math.max(params.retainWritten ? 1 : 100, remaining));
3168
- timer.unref?.();
3169
- }
3170
- if (signal) {
3171
- const abort = () => waiter.reject(params.cancellationError("aborted", mayHaveWritten, signal.reason), "aborted");
3172
- signal.addEventListener("abort", abort, { once: true });
3173
- removeAbort = () => signal.removeEventListener("abort", abort);
3174
- if (signal.aborted) abort();
3175
- }
3366
+ try {
3367
+ const result = await Promise.race([run(), deadline.promise]);
3368
+ if (this.active.get(request.id) === entry) this.respond({
3369
+ id: request.id,
3370
+ result: result === void 0 ? defaultServerRequestResponse(request) : result
3176
3371
  });
3177
- },
3178
- resolve(value) {
3179
- if (!finish("native-ok")) return;
3180
- params.onResponse?.(mayHaveWritten);
3181
- for (const waiter of waiters) {
3182
- const error = currentWaiterError(waiter);
3183
- if (error) waiter.reject(error.error, error.outcome);
3184
- else waiter.resolve(value);
3185
- }
3186
- },
3187
- reject(error, definitelyNotEnqueued = false) {
3188
- if (finish(definitelyNotEnqueued ? "ingress-rejected" : "native-error")) {
3189
- if (definitelyNotEnqueued) mayHaveWritten = false;
3190
- params.onResponse?.(mayHaveWritten);
3191
- for (const waiter of waiters) {
3192
- const current = currentWaiterError(waiter);
3193
- waiter.reject(current?.error ?? params.localError(error, mayHaveWritten), current?.outcome ?? "native-error");
3194
- }
3372
+ } catch (error) {
3373
+ if (this.active.get(request.id) === entry) {
3374
+ embeddedAgentLog.warn("codex app-server server request handler failed", {
3375
+ id: request.id,
3376
+ method: request.method,
3377
+ error
3378
+ });
3379
+ this.respond({
3380
+ id: request.id,
3381
+ error: {
3382
+ code: -32603,
3383
+ message: coerceErrorMessage(error)
3384
+ }
3385
+ });
3195
3386
  }
3196
- },
3197
- close(error) {
3198
- if (finish("correlation-closed")) rejectWaiters(params.localError(error, mayHaveWritten), "client-closed");
3199
- },
3200
- failLocal(error) {
3201
- if (!pending) return;
3202
- if (!params.retainWritten || !mayHaveWritten) finish(mayHaveWritten ? "correlation-closed" : "not-written");
3203
- rejectWaiters(params.localError(error, mayHaveWritten), "local-failed");
3204
- },
3205
- markWritten() {
3206
- mayHaveWritten = true;
3207
- if (diagnostics && diagnostics.firstPossibleWriteAtMs === null) diagnostics.firstPossibleWriteAtMs = performance.now();
3208
- },
3209
- cleanup() {
3210
- for (const waiter of waiters) waiter.cleanup();
3387
+ } finally {
3388
+ settled = true;
3389
+ clearTimeout(timeout);
3390
+ controller.signal.removeEventListener("abort", onAbort);
3391
+ if (this.active.get(request.id) === entry) this.active.delete(request.id);
3211
3392
  }
3393
+ }
3394
+ };
3395
+ function defaultServerRequestResponse(request) {
3396
+ if (request.method === "item/tool/call") return {
3397
+ contentItems: [{
3398
+ type: "inputText",
3399
+ text: "OpenClaw did not register a handler for this app-server tool call."
3400
+ }],
3401
+ success: false
3402
+ };
3403
+ if (request.method === "item/commandExecution/requestApproval" || request.method === "item/fileChange/requestApproval") return { decision: "decline" };
3404
+ if (request.method === "item/permissions/requestApproval") return {
3405
+ permissions: {},
3406
+ scope: "turn"
3407
+ };
3408
+ if (request.method === "item/tool/requestUserInput") return { answers: {} };
3409
+ if (request.method === "mcpServer/elicitation/request") return createCodexElicitationResponse("decline", null, { message: "OpenClaw has no interactive handler for this elicitation." });
3410
+ return {};
3411
+ }
3412
+ function timeoutServerRequestResponse(timeoutMs) {
3413
+ return {
3414
+ contentItems: [{
3415
+ type: "inputText",
3416
+ text: `OpenClaw dynamic tool call timed out after ${timeoutMs}ms before sending a response to Codex.`
3417
+ }],
3418
+ success: false
3212
3419
  };
3213
3420
  }
3214
3421
  //#endregion
@@ -3325,8 +3532,13 @@ function createWebSocketTransport(options) {
3325
3532
  });
3326
3533
  socket.on("message", (data) => {
3327
3534
  if (options.transport === "websocket") recordConnectionActivity();
3328
- const text = websocketFrameToText(data);
3329
- stdout.write(text.endsWith("\n") ? text : `${text}\n`);
3535
+ const frame = websocketFrameToBuffer(data);
3536
+ const writable = stdout.write(frame);
3537
+ const delimited = frame.at(-1) === 10 || stdout.write(Buffer.from("\n"));
3538
+ if (!writable || !delimited) socket.pause();
3539
+ });
3540
+ stdout.on("drain", () => {
3541
+ if (socket.readyState === WebSocket.OPEN) socket.resume();
3330
3542
  });
3331
3543
  const stdin = new Writable({
3332
3544
  write(chunk, _encoding, callback) {
@@ -3384,11 +3596,11 @@ function resolveCodexAppServerUnixSocketPath(options) {
3384
3596
  if (!url.startsWith("unix://")) throw new Error("codex app-server unix transport requires a unix:// URL");
3385
3597
  return url.slice(7) || path.join(resolveCodexAppServerUserHomeDir(options.env ?? process.env), "app-server-control", "app-server-control.sock");
3386
3598
  }
3387
- function websocketFrameToText(data) {
3388
- if (typeof data === "string") return data;
3389
- if (Buffer.isBuffer(data)) return data.toString("utf8");
3390
- if (Array.isArray(data)) return Buffer.concat(data).toString("utf8");
3391
- return Buffer.from(data).toString("utf8");
3599
+ function websocketFrameToBuffer(data) {
3600
+ if (typeof data === "string") return Buffer.from(data);
3601
+ if (Buffer.isBuffer(data)) return data;
3602
+ if (Array.isArray(data)) return Buffer.concat(data);
3603
+ return Buffer.from(data);
3392
3604
  }
3393
3605
  //#endregion
3394
3606
  //#region extensions/codex/src/app-server/client.ts
@@ -3410,15 +3622,11 @@ var client_exports = /* @__PURE__ */ __exportAll({
3410
3622
  isUnsupportedCodexAppServerVersionError: () => isUnsupportedCodexAppServerVersionError,
3411
3623
  resolveCodexAppServerClientInstanceId: () => resolveCodexAppServerClientInstanceId
3412
3624
  });
3413
- const CODEX_APP_SERVER_PARSE_LOG_MAX = 500;
3414
- const CODEX_APP_SERVER_PARSE_BUFFER_MAX = 8388608;
3415
- const CODEX_APP_SERVER_PARSE_BUFFER_MAX_LINES = 1e3;
3416
3625
  const CODEX_APP_SERVER_STDERR_TAIL_MAX = 2e3;
3417
3626
  const CODEX_APP_SERVER_OVERLOAD_MAX_RETRIES = 3;
3418
3627
  const CODEX_APP_SERVER_OVERLOAD_RETRY_BASE_MS = 50;
3419
3628
  const CODEX_APP_SERVER_PENDING_STARTUP_WARNINGS_MAX = 32;
3420
3629
  const CODEX_APP_SERVER_CLIENT_INSTANCE_IDS = /* @__PURE__ */ new WeakMap();
3421
- const UNPAIRED_SURROGATE_RE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g;
3422
3630
  /** Process-local generation fence for bindings tied to one app-server client instance. */
3423
3631
  function getCodexAppServerClientInstanceId(client) {
3424
3632
  const current = CODEX_APP_SERVER_CLIENT_INSTANCE_IDS.get(client);
@@ -3487,9 +3695,11 @@ function isCodexAppServerConnectionClosedError(error) {
3487
3695
  var CodexAppServerClient = class CodexAppServerClient {
3488
3696
  constructor(child) {
3489
3697
  this.instanceId = randomUUID();
3698
+ this.decoder = new CodexAppServerMessageDecoder(logCodexAppServerParseFailure);
3699
+ this.catalogWorker = new CodexCatalogWorker();
3490
3700
  this.pending = /* @__PURE__ */ new Map();
3491
3701
  this.catalogResponses = /* @__PURE__ */ new WeakMap();
3492
- this.requestHandlers = /* @__PURE__ */ new Set();
3702
+ this.serverRequests = new CodexServerRequests((response) => this.writeMessage(response));
3493
3703
  this.notificationHandlers = /* @__PURE__ */ new Set();
3494
3704
  this.pendingStartupWarnings = [];
3495
3705
  this.closeHandlers = /* @__PURE__ */ new Set();
@@ -3503,24 +3713,21 @@ var CodexAppServerClient = class CodexAppServerClient {
3503
3713
  this.privateTransportSecrets = /* @__PURE__ */ new Set();
3504
3714
  this.privateStderrPending = "";
3505
3715
  this.child = child;
3506
- this.lines = createInterface({ input: child.stdout });
3507
- this.lines.on("line", (line) => this.handleLine(line));
3508
- this.lines.on("error", (error) => this.closeWithError(toStringifiedError(error)));
3716
+ this.closeMessageReader = listenCodexAppServerLines(child.stdout, (line) => {
3717
+ const route = this.catalogWorker.continuation ?? (this.decoder.hasPending ? void 0 : readCodexCatalogDecodeRoute(line));
3718
+ if (route) return this.decodeCatalogLine(line, route);
3719
+ return this.handleParsedMessage(this.decoder.parse(line.toString("utf8")));
3720
+ }, (error) => this.closeWithError(toStringifiedError(error)));
3509
3721
  child.stdout.on("error", (error) => this.closeWithError(toStringifiedError(error)));
3510
- child.stderr.setEncoding("utf8");
3511
- child.stderr.on("data", (chunk) => {
3722
+ observeCodexAppServerStderr(child.stderr, (chunk) => {
3512
3723
  const text = this.redactPrivateStderr(chunk);
3513
3724
  this.stderrTail = appendBoundedTail(this.stderrTail, text, CODEX_APP_SERVER_STDERR_TAIL_MAX);
3514
- const trimmed = text.trim();
3515
- if (trimmed) embeddedAgentLog.debug(`codex app-server stderr: ${trimmed}`);
3516
- });
3517
- child.stderr.on("error", (error) => {
3518
- embeddedAgentLog.warn("codex app-server stderr stream failed", { error });
3725
+ return text;
3519
3726
  });
3520
3727
  child.once("error", (error) => this.closeWithError(toStringifiedError(error)));
3521
3728
  child.once("exit", (code, signal) => {
3522
3729
  this.transportExited = true;
3523
- this.closeWithError(buildCodexAppServerExitError(code, signal, this.stderrTail));
3730
+ this.closeWithError(child.startupFailure?.error ?? buildCodexAppServerExitError(code, signal, this.stderrTail));
3524
3731
  });
3525
3732
  child.stdin.on?.("error", (error) => this.closeWithError(toStringifiedError(error)));
3526
3733
  }
@@ -3542,7 +3749,7 @@ var CodexAppServerClient = class CodexAppServerClient {
3542
3749
  return client;
3543
3750
  } catch (error) {
3544
3751
  assertCurrent?.();
3545
- if (client?.transportExited && hasCodexAppServerNaturalExit(client.child)) throw buildCodexAppServerExitError(client.child.exitCode, client.child.signalCode, client.stderrTail);
3752
+ if (client?.transportExited && hasCodexAppServerNaturalExit(client.child)) throw client.child.startupFailure?.error ?? buildCodexAppServerExitError(client.child.exitCode, client.child.signalCode, client.stderrTail);
3546
3753
  const stderr = client?.getStderrDiagnostic();
3547
3754
  throw stderr ? new Error(`${coerceErrorMessage(error)}; stderr=${JSON.stringify(stderr)}`, { cause: error }) : error;
3548
3755
  }
@@ -3554,21 +3761,8 @@ var CodexAppServerClient = class CodexAppServerClient {
3554
3761
  /** Performs the app-server initialize handshake and validates protocol version. */
3555
3762
  async initialize() {
3556
3763
  if (this.initialized) return;
3557
- const response = await this.request("initialize", {
3558
- clientInfo: {
3559
- name: "openclaw",
3560
- title: "OpenClaw",
3561
- version: OPENCLAW_VERSION
3562
- },
3563
- capabilities: {
3564
- experimentalApi: true,
3565
- extensions: {
3566
- "openai/standard-form-input": {},
3567
- "openai/form": {},
3568
- "io.modelcontextprotocol/ui": { mimeTypes: ["text/html;profile=mcp-app"] }
3569
- }
3570
- }
3571
- });
3764
+ const response = await this.request("initialize", buildCodexAppServerInitializeParams());
3765
+ this.child.startupFailure?.complete();
3572
3766
  this.serverVersion = assertSupportedCodexAppServerVersion(response);
3573
3767
  this.runtimeIdentity = buildCodexAppServerRuntimeIdentity(response, this.serverVersion);
3574
3768
  this.notify("initialized");
@@ -3717,7 +3911,7 @@ var CodexAppServerClient = class CodexAppServerClient {
3717
3911
  requestOnce(method, params, options, overloadAttemptOrdinal, onWriteStateChange, deadline, onResponse) {
3718
3912
  if (this.closed) return Promise.reject(this.closeError ?? /* @__PURE__ */ new Error("codex app-server client is closed"));
3719
3913
  if (options.signal?.aborted) return Promise.reject(new CodexAppServerLocalRequestCancellationError(method, "aborted", false, options.signal?.reason));
3720
- const id = this.nextId++;
3914
+ const id = codexCatalogRequestId(method, params, this.nextId++, options.catalogPreview);
3721
3915
  if (method === "account/login/start" || method === "account/logout" || method === "config/value/write" || method === "config/batchWrite") this.modelCatalogRevision += 1;
3722
3916
  const message = {
3723
3917
  id,
@@ -3742,7 +3936,7 @@ var CodexAppServerClient = class CodexAppServerClient {
3742
3936
  localError: (error, written) => written && !(error instanceof CodexAppServerRpcError) && !isCodexAppServerIndeterminateRequestCancellationError(error) && !isCodexAppServerIndeterminateTransportError(error) ? new CodexAppServerIndeterminateTransportError(method, error) : error
3743
3937
  });
3744
3938
  this.pending.set(id, attempt);
3745
- if (options.catalogPreview && method === "thread/list") this.catalogResponses.set(attempt, {
3939
+ if (options.catalogPreview) this.catalogResponses.set(attempt, {
3746
3940
  preview: options.catalogPreviewCache,
3747
3941
  remainingRows: options.catalogRows
3748
3942
  });
@@ -3773,8 +3967,8 @@ var CodexAppServerClient = class CodexAppServerClient {
3773
3967
  }
3774
3968
  /** Registers a handler for app-server requests sent back to OpenClaw. */
3775
3969
  addRequestHandler(handler) {
3776
- this.requestHandlers.add(handler);
3777
- return () => this.requestHandlers.delete(handler);
3970
+ this.serverRequests.handlers.add(handler);
3971
+ return () => this.serverRequests.handlers.delete(handler);
3778
3972
  }
3779
3973
  /** Registers a notification handler and returns its disposer. */
3780
3974
  addNotificationHandler(handler) {
@@ -3805,7 +3999,7 @@ var CodexAppServerClient = class CodexAppServerClient {
3805
3999
  /** Closes the transport and waits for shutdown according to transport policy. */
3806
4000
  async closeAndWait(options) {
3807
4001
  this.markClosed(/* @__PURE__ */ new Error("codex app-server client is closed"));
3808
- const result = await closeCodexAppServerTransportAndWait(this.child, options);
4002
+ const [result] = await Promise.all([closeCodexAppServerTransportAndWait(this.child, options), this.catalogWorkerClosed]);
3809
4003
  return this.nativeExecutionObserved ? {
3810
4004
  ...result,
3811
4005
  cleanup: "uncertain"
@@ -3871,65 +4065,16 @@ var CodexAppServerClient = class CodexAppServerClient {
3871
4065
  this.privateStderrPending = held ? text.slice(-held) : "";
3872
4066
  return held ? text.slice(0, -held) : text;
3873
4067
  }
3874
- handleLine(line) {
3875
- const rawLine = line.endsWith("\r") ? line.slice(0, -1) : line;
3876
- if (this.pendingParse) {
3877
- this.handlePendingParseLine(rawLine);
3878
- return;
3879
- }
3880
- const trimmed = rawLine.trim();
3881
- if (!trimmed) return;
3882
- let parsed;
3883
- try {
3884
- parsed = JSON.parse(trimmed);
3885
- } catch (error) {
3886
- if (shouldBufferCodexAppServerParseFailure(trimmed, error)) {
3887
- this.pendingParse = {
3888
- text: trimmed,
3889
- lineCount: 1,
3890
- firstError: error
3891
- };
3892
- return;
3893
- }
3894
- logCodexAppServerParseFailure(trimmed, error, 1);
3895
- return;
3896
- }
3897
- this.handleParsedMessage(parsed);
3898
- }
3899
- handlePendingParseLine(line) {
3900
- const pending = this.pendingParse;
3901
- if (!pending) return;
3902
- const candidate = `${pending.text}\\n${line}`;
3903
- let parsed;
3904
- try {
3905
- parsed = JSON.parse(candidate);
3906
- } catch (error) {
3907
- const lineCount = pending.lineCount + 1;
3908
- if (shouldBufferCodexAppServerParseFailure(candidate.trim(), error) && candidate.length <= CODEX_APP_SERVER_PARSE_BUFFER_MAX && lineCount <= CODEX_APP_SERVER_PARSE_BUFFER_MAX_LINES) {
3909
- this.pendingParse = {
3910
- text: candidate,
3911
- lineCount,
3912
- firstError: pending.firstError
3913
- };
3914
- return;
3915
- }
3916
- this.pendingParse = void 0;
3917
- logCodexAppServerParseFailure(candidate, error, lineCount);
3918
- return;
3919
- }
3920
- this.pendingParse = void 0;
3921
- this.handleParsedMessage(parsed);
3922
- }
3923
- handleParsedMessage(parsed) {
3924
- if (!parsed || typeof parsed !== "object") return;
4068
+ handleParsedMessage(parsed, previewStates) {
4069
+ if (this.closed || !parsed || typeof parsed !== "object") return;
3925
4070
  const message = parsed;
3926
4071
  if (isRpcResponse(message)) {
3927
- this.handleResponse(message);
4072
+ this.handleResponse(message, previewStates);
3928
4073
  return;
3929
4074
  }
3930
4075
  if (!("method" in message)) return;
3931
4076
  if ("id" in message && message.id !== void 0) {
3932
- this.handleServerRequest({
4077
+ this.serverRequests.handle({
3933
4078
  id: message.id,
3934
4079
  method: message.method,
3935
4080
  params: message.params
@@ -3941,83 +4086,19 @@ var CodexAppServerClient = class CodexAppServerClient {
3941
4086
  params: message.params
3942
4087
  });
3943
4088
  }
3944
- handleResponse(response) {
3945
- this.nativeExecutionObserved = dispatchCodexAppServerResponse(response, this.pending, this.catalogResponses, codexCatalogSourceForClient(this)) || this.nativeExecutionObserved;
4089
+ async decodeCatalogLine(line, route) {
4090
+ const decoded = await this.catalogWorker.decode(line, route, this.pending, this.catalogResponses);
4091
+ if (!decoded || this.closed) return;
4092
+ for (const failure of decoded.failures) logCodexAppServerParseFailure(failure.value, failure.error, failure.fragmentCount);
4093
+ if (decoded.projectionError) this.pending.get(decoded.projectionError.id)?.reject(decoded.projectionError.error, false);
4094
+ else if (decoded.message) this.handleParsedMessage(decoded.message, decoded.previewStates);
3946
4095
  }
3947
- async handleServerRequest(request) {
3948
- try {
3949
- const result = await this.runServerRequestHandlers(request);
3950
- if (result !== void 0) {
3951
- this.writeMessage({
3952
- id: request.id,
3953
- result
3954
- });
3955
- return;
3956
- }
3957
- this.writeMessage({
3958
- id: request.id,
3959
- result: defaultServerRequestResponse(request)
3960
- });
3961
- } catch (error) {
3962
- const message = coerceErrorMessage(error);
3963
- embeddedAgentLog.warn("codex app-server server request handler failed", {
3964
- id: request.id,
3965
- method: request.method,
3966
- error
3967
- });
3968
- this.writeMessage({
3969
- id: request.id,
3970
- error: {
3971
- code: -32603,
3972
- message
3973
- }
3974
- });
3975
- }
3976
- }
3977
- async runServerRequestHandlers(request) {
3978
- const controller = new AbortController();
3979
- if (request.method !== "item/tool/call") return await this.runServerRequestHandlersWithoutTimeout(request, controller.signal);
3980
- let timeoutMs = resolveDynamicToolServerRequestTimeoutMs(readCodexDynamicToolCallParams(request.params));
3981
- const deadline = createDeferred();
3982
- let timeout;
3983
- let settled = false;
3984
- let executionTimeoutResolved = false;
3985
- const armTimeout = () => {
3986
- clearTimeout(timeout);
3987
- timeout = setTimeout(() => {
3988
- embeddedAgentLog.warn("codex app-server server request timed out", {
3989
- id: request.id,
3990
- method: request.method,
3991
- timeoutMs
3992
- });
3993
- controller.abort(/* @__PURE__ */ new Error("codex app-server server request timed out"));
3994
- deadline.resolve(timeoutServerRequestResponse(timeoutMs));
3995
- }, timeoutMs);
3996
- timeout.unref?.();
3997
- };
3998
- const setExecutionTimeoutMs = (executionTimeoutMs) => {
3999
- if (settled || controller.signal.aborted || executionTimeoutResolved || !Number.isFinite(executionTimeoutMs) || executionTimeoutMs <= 0) return;
4000
- executionTimeoutResolved = true;
4001
- timeoutMs = addSafeTimeoutDelayGraceMs(executionTimeoutMs, 3e4);
4002
- armTimeout();
4003
- };
4004
- armTimeout();
4005
- try {
4006
- return await Promise.race([this.runServerRequestHandlersWithoutTimeout(request, controller.signal, setExecutionTimeoutMs), deadline.promise]);
4007
- } finally {
4008
- settled = true;
4009
- clearTimeout(timeout);
4010
- }
4011
- }
4012
- async runServerRequestHandlersWithoutTimeout(request, signal, setExecutionTimeoutMs) {
4013
- for (const handler of this.requestHandlers) {
4014
- if (signal.aborted) return;
4015
- const result = await handler(request, signal, setExecutionTimeoutMs);
4016
- if (result !== void 0) return result;
4017
- }
4096
+ handleResponse(response, previewStates) {
4097
+ this.nativeExecutionObserved = dispatchCodexAppServerResponse(response, this.pending, this.catalogResponses, codexCatalogSourceForClient(this), previewStates) || this.nativeExecutionObserved;
4018
4098
  }
4019
4099
  handleNotification(notification) {
4020
4100
  const params = notification.params;
4101
+ if (notification.method === "serverRequest/resolved") this.serverRequests.resolve(params);
4021
4102
  if (notification.method === "item/commandExecution/outputDelta" || notification.method === "item/commandExecution/terminalInteraction" || isJsonObject(params) && (isJsonObject(params.item) && params.item.type === "commandExecution" || isJsonObject(params.turn) && Array.isArray(params.turn.items) && params.turn.items.some((item) => isJsonObject(item) && item.type === "commandExecution"))) this.nativeExecutionObserved = true;
4022
4103
  if (notification.method === "account/updated") this.modelCatalogRevision += 1;
4023
4104
  if (this.notificationHandlers.size === 0 && notification.method === "configWarning") {
@@ -4041,7 +4122,13 @@ var CodexAppServerClient = class CodexAppServerClient {
4041
4122
  this.closed = true;
4042
4123
  closeCodexCatalogClientSource(this);
4043
4124
  this.closeError = error;
4044
- this.lines.close();
4125
+ this.closeMessageReader();
4126
+ this.decoder.clear();
4127
+ this.catalogWorkerClosed = this.catalogWorker.close(error);
4128
+ this.catalogWorkerClosed?.catch((closeError) => {
4129
+ embeddedAgentLog.warn("codex catalog worker shutdown failed", { error: closeError });
4130
+ });
4131
+ this.serverRequests.close(error);
4045
4132
  this.rejectPendingRequests(error);
4046
4133
  return true;
4047
4134
  }
@@ -4058,35 +4145,6 @@ var CodexAppServerClient = class CodexAppServerClient {
4058
4145
  }
4059
4146
  }
4060
4147
  };
4061
- function defaultServerRequestResponse(request) {
4062
- if (request.method === "item/tool/call") return {
4063
- contentItems: [{
4064
- type: "inputText",
4065
- text: "OpenClaw did not register a handler for this app-server tool call."
4066
- }],
4067
- success: false
4068
- };
4069
- if (request.method === "item/commandExecution/requestApproval" || request.method === "item/fileChange/requestApproval") return { decision: "decline" };
4070
- if (request.method === "item/permissions/requestApproval") return {
4071
- permissions: {},
4072
- scope: "turn"
4073
- };
4074
- if (request.method === "item/tool/requestUserInput") return { answers: {} };
4075
- if (request.method === "mcpServer/elicitation/request") return createCodexElicitationResponse("decline", null, { message: "OpenClaw has no interactive handler for this elicitation." });
4076
- return {};
4077
- }
4078
- function stringifyCodexAppServerMessage(message) {
4079
- return JSON.stringify(message, (_key, value) => typeof value === "string" ? value.replace(UNPAIRED_SURROGATE_RE, "") : value) ?? "null";
4080
- }
4081
- function timeoutServerRequestResponse(timeoutMs) {
4082
- return {
4083
- contentItems: [{
4084
- type: "inputText",
4085
- text: `OpenClaw dynamic tool call timed out after ${timeoutMs}ms before sending a response to Codex.`
4086
- }],
4087
- success: false
4088
- };
4089
- }
4090
4148
  /** Raised when the initialize handshake detects an unsupported app-server version. */
4091
4149
  var CodexAppServerVersionError = class extends Error {
4092
4150
  constructor(detectedVersion) {
@@ -4101,7 +4159,7 @@ function assertSupportedCodexAppServerVersion(response) {
4101
4159
  if (!detectedVersion) throw new CodexAppServerVersionError(detectedVersion);
4102
4160
  const detected = parse(detectedVersion);
4103
4161
  if (!detected || detected.compare("0.149.0") < 0) throw new CodexAppServerVersionError(detectedVersion);
4104
- if (detected.compare("0.154.0") > 0) embeddedAgentLog.warn("codex app-server is newer than OpenClaw's managed runtime; continuing with normal startup validation", {
4162
+ if (detected.compare("0.155.1") > 0) embeddedAgentLog.warn("codex app-server is newer than OpenClaw's managed runtime; continuing with normal startup validation", {
4105
4163
  detectedVersion,
4106
4164
  validatedVersion: CODEX_APP_SERVER_VERSION
4107
4165
  });
@@ -4127,35 +4185,6 @@ function buildCodexAppServerRuntimeIdentity(response, serverVersion) {
4127
4185
  function readCodexVersionFromUserAgent(userAgent) {
4128
4186
  return (userAgent?.match(/^[^/]+\/(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?)(?:[\s(]|$)/))?.[1];
4129
4187
  }
4130
- function redactCodexAppServerLinePreview(value) {
4131
- const redacted = value.replace(/\s+/g, " ").trim().replace(/(Bearer\s+)[A-Za-z0-9._~+/-]+/gi, "$1<redacted>").replace(/("(?:api_?key|authorization|token|access_token|refresh_token)"\s*:\s*")([^"]+)(")/gi, "$1<redacted>$3").replace(/\b([a-z0-9_]*(?:api_?key|authorization|access_token|refresh_token|token))(\s*=\s*)(["']?)[^\s"']+(\3)/gi, "$1$2$3<redacted>$4");
4132
- return redacted.length > CODEX_APP_SERVER_PARSE_LOG_MAX ? `${truncateUtf16Safe(redacted, CODEX_APP_SERVER_PARSE_LOG_MAX)}...` : redacted;
4133
- }
4134
- function appendBoundedTail(current, next, maxLength) {
4135
- const combined = `${current}${next}`;
4136
- return combined.length > maxLength ? sliceUtf16Safe(combined, -maxLength) : combined;
4137
- }
4138
- function buildCodexAppServerExitError(code, signal, stderrTail) {
4139
- const stderrPreview = redactCodexAppServerLinePreview(stderrTail);
4140
- const suffix = stderrPreview ? ` stderr=${JSON.stringify(stderrPreview)}` : "";
4141
- return /* @__PURE__ */ new Error(`codex app-server exited: code=${formatExitValue(code)} signal=${formatExitValue(signal)}${suffix}`);
4142
- }
4143
- function shouldBufferCodexAppServerParseFailure(value, error) {
4144
- if (!value.startsWith("{") && !value.startsWith("[")) return false;
4145
- const message = coerceErrorMessage(error);
4146
- return message.includes("Unterminated string") || message.includes("Unexpected end of JSON input");
4147
- }
4148
- function logCodexAppServerParseFailure(value, error, fragmentCount) {
4149
- const linePreview = redactCodexAppServerLinePreview(value);
4150
- const suffix = fragmentCount > 1 ? ` fragments=${fragmentCount}` : "";
4151
- embeddedAgentLog.warn("failed to parse codex app-server message", {
4152
- error,
4153
- errorMessage: coerceErrorMessage(error),
4154
- fragmentCount,
4155
- linePreview,
4156
- consoleMessage: `failed to parse codex app-server message${suffix}: preview=${JSON.stringify(linePreview)}`
4157
- });
4158
- }
4159
4188
  const CODEX_APP_SERVER_APPROVAL_REQUEST_METHODS = /* @__PURE__ */ new Set([
4160
4189
  "item/commandExecution/requestApproval",
4161
4190
  "item/fileChange/requestApproval",
@@ -4165,10 +4194,5 @@ const CODEX_APP_SERVER_APPROVAL_REQUEST_METHODS = /* @__PURE__ */ new Set([
4165
4194
  function isCodexAppServerApprovalRequest(method) {
4166
4195
  return CODEX_APP_SERVER_APPROVAL_REQUEST_METHODS.has(method);
4167
4196
  }
4168
- function formatExitValue(value) {
4169
- if (value === null || value === void 0) return "null";
4170
- if (typeof value === "string" || typeof value === "number") return String(value);
4171
- return "unknown";
4172
- }
4173
4197
  //#endregion
4174
- export { isMatchingDynamicToolTerminalDiagnostic as A, withDynamicToolTranscriptDetails as B, readCodexErrorNotification as C, handleDynamicToolCallWithTimeout as D, createCodexElicitationResponse as E, toCodexDynamicToolProgressResponse as F, toCodexDynamicToolProtocolResponse as I, resolveCodexToolAbortTerminalReason as L, resolveTerminalDynamicToolBatchAction as M, shouldBlockTerminalReleaseForNonTerminalDynamicToolResult as N, hasPendingDynamicToolTerminalDiagnostic as O, shouldReleaseTurnAfterTerminalDynamicTool as P, createFailedDynamicToolResponse as R, readCodexDynamicToolCallParams as S, readCodexTurnCompletedNotification as T, assertCodexThreadAcceptsDirectInput as _, isCodexAppServerBrokenPipeError as a, assertCodexThreadStartResponse as b, isCodexAppServerIndeterminateTransportError as c, isCodexAppServerRequestTimeoutError as d, isUnsupportedCodexAppServerVersionError as f, assertCodexPassiveTurnItems as g, assertCodexModelListResponse as h, isCodexAppServerApprovalRequest as i, resolveDynamicToolCallTimeoutMs as j, isDynamicToolTerminalDiagnosticEvent as k, isCodexAppServerOverloadError as l, CodexThreadDirectInputError as m, client_exports as n, isCodexAppServerConnectionClosedError as o, resolveCodexAppServerClientInstanceId as p, getCodexAppServerClientInstanceId as r, isCodexAppServerIndeterminateRequestCancellationError as s, CodexAppServerClient as t, isCodexAppServerPrewriteRequestCancellationError as u, assertCodexThreadForkResponse as v, readCodexTurn as w, assertCodexTurnStartResponse as x, assertCodexThreadResumeResponse as y, withDynamicToolExecutionState as z };
4198
+ export { isMatchingDynamicToolTerminalDiagnostic as A, CODEX_APP_SERVER_OPT_OUT_NOTIFICATION_METHODS as B, readCodexDynamicToolCallParams as C, handleDynamicToolCallWithTimeout as D, createCodexElicitationResponse as E, toCodexDynamicToolProgressResponse as F, toCodexDynamicToolProtocolResponse as I, resolveCodexToolAbortTerminalReason as L, resolveTerminalDynamicToolBatchAction as M, shouldBlockTerminalReleaseForNonTerminalDynamicToolResult as N, hasPendingDynamicToolTerminalDiagnostic as O, shouldReleaseTurnAfterTerminalDynamicTool as P, createFailedDynamicToolResponse as R, assertCodexTurnStartResponse as S, readCodexTurnCompletedNotification as T, assertCodexPassiveTurnItems as _, isCodexAppServerBrokenPipeError as a, assertCodexThreadResumeResponse as b, isCodexAppServerIndeterminateTransportError as c, isCodexAppServerRequestTimeoutError as d, isUnsupportedCodexAppServerVersionError as f, assertCodexModelListResponse as g, CodexThreadDirectInputError as h, isCodexAppServerApprovalRequest as i, resolveDynamicToolCallTimeoutMs as j, isDynamicToolTerminalDiagnosticEvent as k, isCodexAppServerOverloadError as l, CodexServerRequestResolvedError as m, client_exports as n, isCodexAppServerConnectionClosedError as o, resolveCodexAppServerClientInstanceId as p, getCodexAppServerClientInstanceId as r, isCodexAppServerIndeterminateRequestCancellationError as s, CodexAppServerClient as t, isCodexAppServerPrewriteRequestCancellationError as u, assertCodexThreadAcceptsDirectInput as v, readCodexErrorNotification as w, assertCodexThreadStartResponse as x, assertCodexThreadForkResponse as y, failedToolResult as z };