@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,5 +1,5 @@
1
- import { h as releaseLeasedSharedCodexAppServerClient } from "./shared-client-BpTtuLQ5.mjs";
2
- import { lt as normalizeCodexDynamicToolName } from "./thread-lifecycle-Cik28qWn.mjs";
1
+ import { h as releaseLeasedSharedCodexAppServerClient } from "./shared-client-DA4VR4Eb.mjs";
2
+ import { ut as normalizeCodexDynamicToolName } from "./thread-requests-BLvGkP2R.mjs";
3
3
  import { pinExecToolTarget } from "openclaw/plugin-sdk/codex-mcp-projection";
4
4
  import { loadNodeExecAvailability } from "openclaw/plugin-sdk/node-selection-runtime";
5
5
  //#region extensions/codex/src/app-server/shell-dynamic-tools.ts
@@ -51,6 +51,27 @@ function createGatewayProcessProjection(createProjection, processTool) {
51
51
  description: "Manage background shell sessions in the existing per-session OpenClaw process scope: list, poll, log, write, send-keys, submit, paste, kill, clear, or remove. Use for gateway_exec follow-up; use native Codex shell session handling for ordinary local work."
52
52
  });
53
53
  }
54
+ function createSandboxExecProjection(execTool) {
55
+ return {
56
+ ...execTool,
57
+ name: "sandbox_exec",
58
+ description: "Run a shell command through OpenClaw's configured sandbox backend for this session. Use when OpenClaw sandboxing is active or when a command must execute in the sandbox backend, such as an SSH-backed sandbox or Docker container-path bind layout. Use Codex's native shell only when no OpenClaw sandbox is active and native Code Mode is available.",
59
+ execute: async (toolCallId, args, signal, onUpdate) => {
60
+ const result = await execTool.execute(toolCallId, args, signal, onUpdate);
61
+ return {
62
+ ...result,
63
+ content: result.content.map((item) => item.type === "text" ? Object.assign({}, item, { text: item.text.replace(PROCESS_FOLLOWUP_TEXT, "Use sandbox_process (list/poll/log/write/send-keys/submit/paste/kill/clear/remove) for follow-up.") }) : item)
64
+ };
65
+ }
66
+ };
67
+ }
68
+ function createSandboxProcessProjection(processTool) {
69
+ return {
70
+ ...processTool,
71
+ name: "sandbox_process",
72
+ description: "Manage background shell sessions through OpenClaw's configured sandbox backend for this session: list, poll, log, write, send-keys, submit, paste, kill, clear, or remove. Use only for sandbox follow-up; use Codex's native shell session handling only when no OpenClaw sandbox is active and native Code Mode is available."
73
+ };
74
+ }
54
75
  //#endregion
55
76
  //#region extensions/codex/src/app-server/provider-capabilities.ts
56
77
  function resolveOverriddenProviderWebSearchSupport(modelProviderOverride) {
@@ -59,6 +80,12 @@ function resolveOverriddenProviderWebSearchSupport(modelProviderOverride) {
59
80
  return provider === "openai" ? "supported" : "unsupported";
60
81
  }
61
82
  async function readConfiguredProviderWebSearchSupport(params) {
83
+ if (params.expectedNativeModelProvider) {
84
+ if (((await params.client.request("config/read", { includeLayers: false }, {
85
+ timeoutMs: params.timeoutMs,
86
+ signal: params.signal
87
+ })).config.model_provider ?? "openai") !== params.expectedNativeModelProvider) return "unknown";
88
+ }
62
89
  return (await params.client.request("modelProvider/capabilities/read", {}, {
63
90
  timeoutMs: params.timeoutMs,
64
91
  signal: params.signal
@@ -89,6 +116,7 @@ async function resolveCodexProviderWebSearchSupport(params) {
89
116
  client,
90
117
  timeoutMs: params.appServer.requestTimeoutMs,
91
118
  modelProviderOverride: params.modelProviderOverride,
119
+ expectedNativeModelProvider: params.expectedNativeModelProvider,
92
120
  signal: params.signal
93
121
  });
94
122
  } catch {
@@ -98,4 +126,4 @@ async function resolveCodexProviderWebSearchSupport(params) {
98
126
  }
99
127
  }
100
128
  //#endregion
101
- export { CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME as a, createNodeExecAliasDynamicTool as c, CODEX_GATEWAY_PROCESS_DYNAMIC_TOOL_NAME as i, isCodexDynamicToolExcluded as l, resolveCodexProviderWebSearchSupportForClient as n, createGatewayExecProjection as o, CODEX_GATEWAY_EXEC_DYNAMIC_TOOL_NAME as r, createGatewayProcessProjection as s, resolveCodexProviderWebSearchSupport as t };
129
+ export { CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME as a, createNodeExecAliasDynamicTool as c, isCodexDynamicToolExcluded as d, CODEX_GATEWAY_PROCESS_DYNAMIC_TOOL_NAME as i, createSandboxExecProjection as l, resolveCodexProviderWebSearchSupportForClient as n, createGatewayExecProjection as o, CODEX_GATEWAY_EXEC_DYNAMIC_TOOL_NAME as r, createGatewayProcessProjection as s, resolveCodexProviderWebSearchSupport as t, createSandboxProcessProjection as u };
@@ -1,20 +1,76 @@
1
- import { m as isJsonObject } from "./config-security-BRQ2mgW9.mjs";
1
+ import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
2
2
  import { normalizeOptionalString, parseStrictFiniteNumber } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  import { z } from "zod";
4
4
  import { MAX_DATE_TIMESTAMP_MS, resolveExpiresAtMsFromEpochSeconds } from "openclaw/plugin-sdk/number-runtime";
5
- import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
6
5
  import { PROVIDER_LABELS, clampPercent } from "openclaw/plugin-sdk/provider-usage";
6
+ //#region extensions/codex/src/app-server/rate-limit-time.ts
7
+ /** Human-readable Codex quota reset times; no account or routing decisions. */
8
+ const ONE_SECOND_MS = 1e3;
9
+ const ONE_MINUTE_MS = 6e4;
10
+ const ONE_HOUR_MS = 60 * ONE_MINUTE_MS;
11
+ const ONE_DAY_MS$1 = 24 * ONE_HOUR_MS;
12
+ function formatCalendarResetTime(resetsAtMs, nowMs) {
13
+ const resetDate = new Date(resetsAtMs);
14
+ const resetParts = new Intl.DateTimeFormat("en-US", {
15
+ month: "short",
16
+ day: "numeric",
17
+ ...resetDate.getFullYear() === new Date(nowMs).getFullYear() ? {} : { year: "numeric" },
18
+ hour: "numeric",
19
+ minute: "2-digit",
20
+ timeZoneName: "short"
21
+ }).formatToParts(resetDate);
22
+ const part = (type) => resetParts.find((entry) => entry.type === type)?.value;
23
+ const dateParts = [
24
+ part("month"),
25
+ part("day"),
26
+ part("year")
27
+ ].filter(Boolean);
28
+ return [
29
+ dateParts.length > 1 ? `${dateParts[0]} ${dateParts.slice(1).join(", ")}` : dateParts[0],
30
+ "at",
31
+ [
32
+ [part("hour"), part("minute")].filter(Boolean).join(":"),
33
+ part("dayPeriod"),
34
+ part("timeZoneName")
35
+ ].filter(Boolean).join(" ")
36
+ ].filter(Boolean).join(" ");
37
+ }
38
+ function formatRelativeDuration(durationMs) {
39
+ const safeMs = Math.max(1e3, durationMs);
40
+ if (safeMs < ONE_MINUTE_MS) return `${Math.ceil(safeMs / 1e3)} seconds`;
41
+ if (safeMs < ONE_HOUR_MS) {
42
+ const minutes = Math.ceil(safeMs / ONE_MINUTE_MS);
43
+ return `${minutes} ${minutes === 1 ? "minute" : "minutes"}`;
44
+ }
45
+ if (safeMs < ONE_DAY_MS$1) {
46
+ const hours = Math.ceil(safeMs / ONE_HOUR_MS);
47
+ return `${hours} ${hours === 1 ? "hour" : "hours"}`;
48
+ }
49
+ const days = Math.ceil(safeMs / ONE_DAY_MS$1);
50
+ return `${days} ${days === 1 ? "day" : "days"}`;
51
+ }
52
+ function formatResetDuration(resetsAtMs, nowMs) {
53
+ const durationMs = Math.round(Math.max(ONE_SECOND_MS, resetsAtMs - nowMs) / ONE_SECOND_MS) * ONE_SECOND_MS;
54
+ const days = Math.floor(durationMs / ONE_DAY_MS$1);
55
+ const hours = Math.floor(durationMs % ONE_DAY_MS$1 / ONE_HOUR_MS);
56
+ const minutes = Math.floor(durationMs % ONE_HOUR_MS / ONE_MINUTE_MS);
57
+ const seconds = Math.floor(durationMs % ONE_MINUTE_MS / ONE_SECOND_MS);
58
+ if (days > 0) return hours > 0 ? `${days}d ${hours}h` : `${days}d`;
59
+ if (hours > 0) return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`;
60
+ if (minutes > 0) return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
61
+ return `${seconds}s`;
62
+ }
63
+ //#endregion
7
64
  //#region extensions/codex/src/app-server/rate-limits.ts
8
65
  /**
9
66
  * Parses Codex account rate-limit payloads into user-facing usage summaries,
10
67
  * reset hints, and enriched usage-limit error messages.
11
68
  */
12
69
  const CODEX_LIMIT_ID = "codex";
70
+ const CODEX_RESERVE_ROUTE = "gpt-reserve";
71
+ const CODEX_RESERVE_USAGE_NOTICE = "Luna Reserve is a separate, backend-authorized route. Ordinary Luna does not use this reserve, even with Fast off. An unused reserve does not establish eligibility or per-request billing. Ordinary usage may consume credits after included limits are reached.";
13
72
  const LIMIT_WINDOW_KEYS = ["primary", "secondary"];
14
- const ONE_SECOND_MS = 1e3;
15
- const ONE_MINUTE_MS = 6e4;
16
- const ONE_HOUR_MS = 60 * ONE_MINUTE_MS;
17
- const ONE_DAY_MS = 24 * ONE_HOUR_MS;
73
+ const ONE_DAY_MS = 864e5;
18
74
  const DAY_WINDOW_MINUTES = 1440;
19
75
  const WEEKLY_WINDOW_MINUTES = 7 * DAY_WINDOW_MINUTES;
20
76
  const WEEKLY_RESET_GAP_MS = 3 * ONE_DAY_MS;
@@ -24,32 +80,18 @@ const optionalNumber = z.number().optional().catch(void 0);
24
80
  const optionalBoolean = z.boolean().optional().catch(void 0);
25
81
  const rateLimitWindowSchema = z.object({
26
82
  usedPercent: optionalNumber,
27
- used_percent: optionalNumber,
28
83
  resetsAt: optionalNumber,
29
- resets_at: optionalNumber,
30
- windowDurationMins: optionalNumber,
31
- window_duration_mins: optionalNumber,
32
- windowMinutes: optionalNumber,
33
- window_minutes: optionalNumber
34
- }).transform((window) => {
35
- const resetsAt = window.resetsAt ?? window.resets_at;
36
- return {
37
- usedPercent: window.usedPercent ?? window.used_percent,
38
- resetsAt,
39
- resetsAtMs: resolveExpiresAtMsFromEpochSeconds(resetsAt, { maxMs: MAX_DATE_TIMESTAMP_MS }) ?? 0,
40
- windowDurationMins: window.windowDurationMins ?? window.window_duration_mins ?? window.windowMinutes ?? window.window_minutes
41
- };
42
- }).optional().catch(void 0);
84
+ windowDurationMins: optionalNumber
85
+ }).transform((window) => ({
86
+ usedPercent: window.usedPercent,
87
+ resetsAtMs: resolveExpiresAtMsFromEpochSeconds(window.resetsAt, { maxMs: MAX_DATE_TIMESTAMP_MS }) ?? 0,
88
+ windowDurationMins: window.windowDurationMins
89
+ })).optional().catch(void 0);
43
90
  const creditsSchema = z.object({
44
91
  hasCredits: optionalBoolean,
45
- has_credits: optionalBoolean,
46
92
  unlimited: optionalBoolean,
47
93
  balance: z.preprocess(parseStrictFiniteNumber, optionalNumber)
48
- }).transform((credits) => ({
49
- hasCredits: credits.hasCredits ?? credits.has_credits,
50
- unlimited: credits.unlimited,
51
- balance: credits.balance
52
- })).optional().catch(void 0);
94
+ }).optional().catch(void 0);
53
95
  const rateLimitSnapshotSchema = z.looseObject({
54
96
  primary: rateLimitWindowSchema,
55
97
  secondary: rateLimitWindowSchema,
@@ -58,19 +100,23 @@ const rateLimitSnapshotSchema = z.looseObject({
58
100
  primary: snapshot.primary,
59
101
  secondary: snapshot.secondary,
60
102
  credits: snapshot.credits,
61
- limitId: normalizeOptionalString(snapshot.limitId) ?? normalizeOptionalString(snapshot.limit_id),
62
- limitName: normalizeOptionalString(snapshot.limitName) ?? normalizeOptionalString(snapshot.limit_name),
63
- planType: normalizeOptionalString(snapshot.planType) ?? normalizeOptionalString(snapshot.plan_type),
64
- rateLimitReachedType: normalizeOptionalString(snapshot.rateLimitReachedType) ?? normalizeOptionalString(snapshot.rate_limit_reached_type)
103
+ limitId: normalizeOptionalString(snapshot.limitId),
104
+ limitName: normalizeOptionalString(snapshot.limitName),
105
+ planType: normalizeOptionalString(snapshot.planType),
106
+ rateLimitReachedType: normalizeOptionalString(snapshot.rateLimitReachedType)
65
107
  }));
66
108
  /** Enriches Codex usage-limit failures with reset timing and recovery guidance. */
67
109
  function formatCodexUsageLimitErrorMessage(params) {
68
110
  const message = normalizeOptionalString(params.message);
69
- if (!isCodexUsageLimitError(params.codexErrorInfo)) return;
111
+ if (params.codexErrorInfo !== "usageLimitExceeded") return;
70
112
  const nowMs = params.nowMs ?? Date.now();
71
- const usageSummary = summarizeCodexAccountUsage(params.rateLimits, nowMs);
72
- if (params.rateLimitsAuthoritative && hasCodexRateLimitSnapshots(params.rateLimits) && !usageSummary?.blocked) return [CODEX_USAGE_LIMIT_STATE_MISMATCH_MESSAGE, "Retry the request, use another Codex account if available, or switch to another configured model/provider."].join(" ");
73
- const nextReset = selectBlockingRateLimitReset(params.rateLimits, nowMs) ?? (usageSummary?.blocked ? void 0 : selectNextRateLimitReset(params.rateLimits, nowMs));
113
+ const ordinaryUsageAllowed = readOrdinaryUsageAllowed(params.rateLimits);
114
+ const snapshots = collectCodexRateLimitSnapshots(params.rateLimits).filter(snapshotHasDisplayableData);
115
+ const usageSnapshot = snapshots.find(isCodexLimitSnapshot) ?? snapshots[0];
116
+ const blockingSnapshot = selectBlockingRateLimitSnapshot(snapshots, ordinaryUsageAllowed);
117
+ const usageSummary = usageSnapshot ? summarizeRateLimitUsage(usageSnapshot, blockingSnapshot, nowMs) : void 0;
118
+ if (params.rateLimitsAuthoritative && (ordinaryUsageAllowed === true && !blockingSnapshot || ordinaryUsageAllowed === void 0 && usageSummary?.blocked === false)) return [CODEX_USAGE_LIMIT_STATE_MISMATCH_MESSAGE, "Retry the request, use another Codex account if available, or switch to another configured model/provider."].join(" ");
119
+ const nextReset = (blockingSnapshot ? selectSnapshotBlockingReset(blockingSnapshot, nowMs) : void 0) ?? (ordinaryUsageAllowed === void 0 && !usageSummary?.blocked ? selectNextRateLimitReset(params.rateLimits, nowMs) : void 0);
74
120
  const parts = [CODEX_USAGE_LIMIT_MESSAGE_PREFIX];
75
121
  let recoveryAction = "Wait until Codex becomes available";
76
122
  if (nextReset) {
@@ -99,7 +145,8 @@ function summarizeCodexRateLimits(value, nowMs = Date.now()) {
99
145
  const snapshots = collectCodexRateLimitSnapshots(value).filter(snapshotHasDisplayableData);
100
146
  if (snapshots.length === 0) return;
101
147
  const summaries = snapshots.slice(0, 4).map((snapshot) => summarizeRateLimitSnapshot(snapshot, nowMs)).filter((summary) => summary !== void 0);
102
- return summaries.length > 0 ? summaries.join("; ") : void 0;
148
+ if (summaries.length === 0) return;
149
+ return [summaries.join("; "), reserveUsageNotice(snapshots)].filter(Boolean).join(". ");
103
150
  }
104
151
  /** Returns true when a value contains any recognizable Codex rate-limit snapshots. */
105
152
  function hasCodexRateLimitSnapshots(value) {
@@ -118,11 +165,17 @@ function resolveCodexUsageLimitResetAtMs(value, nowMs = Date.now()) {
118
165
  }
119
166
  /** Summarizes account availability, blocking reason, and reset time from rate-limit data. */
120
167
  function summarizeCodexAccountUsage(value, nowMs = Date.now()) {
121
- const snapshots = collectCodexRateLimitSnapshots(value).filter(snapshotHasDisplayableData);
122
- if (snapshots.length === 0) return;
123
- const usageSnapshot = snapshots.find(isCodexLimitSnapshot) ?? expectDefined(snapshots[0], "displayable Codex rate-limit snapshot");
124
- const blockedSnapshots = snapshots.filter(snapshotHasLimitBlock);
125
- const blockingSnapshot = blockedSnapshots.find(isCodexLimitSnapshot) ?? blockedSnapshots[0] ?? void 0;
168
+ const ordinaryUsageAllowed = readOrdinaryUsageAllowed(value);
169
+ if (ordinaryUsageAllowed === null) return;
170
+ const snapshot = collectCodexRateLimitSnapshots(value).find(isCodexLimitSnapshot);
171
+ if (ordinaryUsageAllowed !== void 0) return {
172
+ usageLine: snapshot ? formatUsageLine(snapshot) : void 0,
173
+ blocked: !ordinaryUsageAllowed,
174
+ ...!ordinaryUsageAllowed ? { blockingReason: "Codex usage limit is reached" } : {}
175
+ };
176
+ return snapshot && snapshotHasDisplayableData(snapshot) ? summarizeRateLimitUsage(snapshot, snapshotHasLimitBlock(snapshot) ? snapshot : void 0, nowMs) : void 0;
177
+ }
178
+ function summarizeRateLimitUsage(usageSnapshot, blockingSnapshot, nowMs) {
126
179
  const blockingEntries = blockingSnapshot ? readWindowEntries(blockingSnapshot) : [];
127
180
  const blockingWindowEntry = selectBlockingWindowEntry(blockingEntries, nowMs);
128
181
  const blockingWindow = blockingWindowEntry?.window;
@@ -147,7 +200,9 @@ function buildCodexAppServerUsageSnapshot(value, options = {}) {
147
200
  const snapshot = snapshots.find(isCodexLimitSnapshot) ?? snapshots[0];
148
201
  const entries = snapshot ? readWindowEntries(snapshot) : [];
149
202
  const windows = entries.map((entry) => readProviderUsageWindow(entry, entries)).filter((window) => Boolean(window));
203
+ const summary = reserveUsageNotice(snapshots);
150
204
  const result = {
205
+ ...summary ? { summary } : {},
151
206
  provider: "openai",
152
207
  displayName: PROVIDER_LABELS.openai,
153
208
  windows,
@@ -176,13 +231,6 @@ function buildCodexAppServerUsageSnapshot(value, options = {}) {
176
231
  }
177
232
  return result;
178
233
  }
179
- function isCodexUsageLimitError(codexErrorInfo) {
180
- if (codexErrorInfo === "usageLimitExceeded") return true;
181
- if (typeof codexErrorInfo === "string") {
182
- if (codexErrorInfo.replace(/[_\s-]/gu, "").toLowerCase() === "usagelimitexceeded") return true;
183
- }
184
- return false;
185
- }
186
234
  function selectNextRateLimitReset(value, nowMs) {
187
235
  const futureWindows = collectCodexRateLimitSnapshots(value).flatMap((snapshot) => LIMIT_WINDOW_KEYS.flatMap((key) => snapshot[key] ?? [])).filter((window) => window.resetsAtMs > nowMs);
188
236
  if (futureWindows.length === 0) return;
@@ -190,10 +238,13 @@ function selectNextRateLimitReset(value, nowMs) {
190
238
  return (exhaustedWindows.length > 0 ? exhaustedWindows : futureWindows).toSorted((left, right) => left.resetsAtMs - right.resetsAtMs)[0];
191
239
  }
192
240
  function selectBlockingRateLimitReset(value, nowMs) {
193
- const blockedSnapshots = collectCodexRateLimitSnapshots(value).filter(snapshotHasLimitBlock);
194
- const blockingSnapshot = blockedSnapshots.find(isCodexLimitSnapshot) ?? blockedSnapshots[0] ?? void 0;
241
+ const blockingSnapshot = selectBlockingRateLimitSnapshot(collectCodexRateLimitSnapshots(value), readOrdinaryUsageAllowed(value));
195
242
  return blockingSnapshot ? selectSnapshotBlockingReset(blockingSnapshot, nowMs) : void 0;
196
243
  }
244
+ function selectBlockingRateLimitSnapshot(snapshots, ordinaryUsageAllowed) {
245
+ const blockedSnapshots = snapshots.filter((snapshot) => snapshotHasLimitBlock(snapshot) && (ordinaryUsageAllowed !== true && ordinaryUsageAllowed !== null || !isCodexLimitSnapshot(snapshot)));
246
+ return blockedSnapshots.find(isCodexLimitSnapshot) ?? blockedSnapshots[0];
247
+ }
197
248
  function summarizeRateLimitSnapshot(snapshot, nowMs) {
198
249
  const label = formatLimitLabel(snapshot);
199
250
  const windows = LIMIT_WINDOW_KEYS.flatMap((key) => {
@@ -206,28 +257,14 @@ function summarizeRateLimitSnapshot(snapshot, nowMs) {
206
257
  if (reachedType) return `${label}: ${formatReachedType(reachedType)}`;
207
258
  }
208
259
  function collectCodexRateLimitSnapshots(value) {
209
- const snapshots = [];
210
- collectRateLimitSnapshots(value, snapshots, /* @__PURE__ */ new Set());
211
- return snapshots;
212
- }
213
- function collectRateLimitSnapshots(value, snapshots, seen) {
214
- if (Array.isArray(value)) {
215
- for (const entry of value) collectRateLimitSnapshots(entry, snapshots, seen);
216
- return;
217
- }
218
- if (!isJsonObject(value)) return;
219
- if (isRateLimitSnapshot(value)) {
220
- addRateLimitSnapshot(rateLimitSnapshotSchema.parse(value), snapshots, seen);
221
- return;
222
- }
260
+ if (!isJsonObject(value)) return [];
261
+ if (isRateLimitSnapshot(value)) return [rateLimitSnapshotSchema.parse(value)];
223
262
  const byLimitId = value.rateLimitsByLimitId;
224
- if (isJsonObject(byLimitId)) for (const key of sortedRateLimitKeys(Object.keys(byLimitId))) collectRateLimitSnapshots(byLimitId[key], snapshots, seen);
225
- const snakeByLimitId = value.rate_limits_by_limit_id;
226
- if (isJsonObject(snakeByLimitId)) for (const key of sortedRateLimitKeys(Object.keys(snakeByLimitId))) collectRateLimitSnapshots(snakeByLimitId[key], snapshots, seen);
227
- collectRateLimitSnapshots(value.rateLimits, snapshots, seen);
228
- collectRateLimitSnapshots(value.rate_limits, snapshots, seen);
229
- collectRateLimitSnapshots(value.data, snapshots, seen);
230
- collectRateLimitSnapshots(value.items, snapshots, seen);
263
+ return (isJsonObject(byLimitId) ? sortedRateLimitKeys(Object.keys(byLimitId)).map((key) => byLimitId[key]) : [value.rateLimits]).filter(isJsonObject).filter(isRateLimitSnapshot).map((snapshot) => rateLimitSnapshotSchema.parse(snapshot));
264
+ }
265
+ function readOrdinaryUsageAllowed(value) {
266
+ const allowed = isJsonObject(value) ? value.ordinaryUsageAllowed : void 0;
267
+ return allowed === null || typeof allowed === "boolean" ? allowed : void 0;
231
268
  }
232
269
  function sortedRateLimitKeys(keys) {
233
270
  return keys.toSorted((left, right) => {
@@ -236,19 +273,8 @@ function sortedRateLimitKeys(keys) {
236
273
  return left.localeCompare(right);
237
274
  });
238
275
  }
239
- function addRateLimitSnapshot(snapshot, snapshots, seen) {
240
- const signature = [
241
- snapshot.limitId ?? "",
242
- snapshot.limitName ?? "",
243
- formatWindowSignature(snapshot.primary),
244
- formatWindowSignature(snapshot.secondary)
245
- ].join("|");
246
- if (seen.has(signature)) return;
247
- seen.add(signature);
248
- snapshots.push(snapshot);
249
- }
250
276
  function isRateLimitSnapshot(value) {
251
- return isJsonObject(value.primary) || isJsonObject(value.secondary) || value.rateLimitReachedType !== void 0 || value.rate_limit_reached_type !== void 0 || value.limitId !== void 0 || value.limit_id !== void 0 || value.limitName !== void 0 || value.limit_name !== void 0;
277
+ return isJsonObject(value.primary) || isJsonObject(value.secondary) || value.rateLimitReachedType !== void 0 || value.limitId !== void 0 || value.limitName !== void 0;
252
278
  }
253
279
  function snapshotHasDisplayableData(snapshot) {
254
280
  return Boolean(snapshot.rateLimitReachedType) || readWindowEntries(snapshot).some((entry) => entry.window.usedPercent !== void 0 || entry.window.resetsAtMs > 0);
@@ -259,7 +285,14 @@ function formatRateLimitWindow(key, window, nowMs) {
259
285
  function formatRateLimitWindowDetails(window, nowMs) {
260
286
  return `${window.usedPercent === void 0 ? "usage unknown" : `${Math.max(0, 100 - Math.round(window.usedPercent))}% left`}${window.resetsAtMs > nowMs ? ` ⏱${formatResetDuration(window.resetsAtMs, nowMs)}` : ""}`;
261
287
  }
288
+ function reserveUsageNotice(snapshots) {
289
+ return snapshots.some(isReserveSnapshot) ? CODEX_RESERVE_USAGE_NOTICE : void 0;
290
+ }
291
+ function isReserveSnapshot(snapshot) {
292
+ return snapshot.limitName === CODEX_RESERVE_ROUTE || snapshot.limitId === CODEX_RESERVE_ROUTE;
293
+ }
262
294
  function formatLimitLabel(snapshot) {
295
+ if (isReserveSnapshot(snapshot)) return "Luna Reserve (separate route)";
263
296
  const label = snapshot.limitName ?? snapshot.limitId;
264
297
  if (!label || label === CODEX_LIMIT_ID) return "Codex";
265
298
  return label.replace(/[_-]+/gu, " ").replace(/\s+/gu, " ").trim();
@@ -364,60 +397,6 @@ function hasWeeklySecondaryResetCadence(entry, entries) {
364
397
  const primaryResetMs = entries.find((candidate) => candidate.key === "primary")?.window.resetsAtMs;
365
398
  return typeof primaryResetMs === "number" && primaryResetMs > 0 && entry.window.resetsAtMs > 0 && entry.window.resetsAtMs - primaryResetMs >= WEEKLY_RESET_GAP_MS;
366
399
  }
367
- function formatCalendarResetTime(resetsAtMs, nowMs) {
368
- const resetDate = new Date(resetsAtMs);
369
- const resetParts = new Intl.DateTimeFormat("en-US", {
370
- month: "short",
371
- day: "numeric",
372
- ...resetDate.getFullYear() === new Date(nowMs).getFullYear() ? {} : { year: "numeric" },
373
- hour: "numeric",
374
- minute: "2-digit",
375
- timeZoneName: "short"
376
- }).formatToParts(resetDate);
377
- const part = (type) => resetParts.find((entry) => entry.type === type)?.value;
378
- const dateParts = [
379
- part("month"),
380
- part("day"),
381
- part("year")
382
- ].filter(Boolean);
383
- return [
384
- dateParts.length > 1 ? `${dateParts[0]} ${dateParts.slice(1).join(", ")}` : dateParts[0],
385
- "at",
386
- [
387
- [part("hour"), part("minute")].filter(Boolean).join(":"),
388
- part("dayPeriod"),
389
- part("timeZoneName")
390
- ].filter(Boolean).join(" ")
391
- ].filter(Boolean).join(" ");
392
- }
393
- function formatRelativeDuration(durationMs) {
394
- const safeMs = Math.max(1e3, durationMs);
395
- if (safeMs < ONE_MINUTE_MS) return `${Math.ceil(safeMs / 1e3)} seconds`;
396
- if (safeMs < ONE_HOUR_MS) {
397
- const minutes = Math.ceil(safeMs / ONE_MINUTE_MS);
398
- return `${minutes} ${minutes === 1 ? "minute" : "minutes"}`;
399
- }
400
- if (safeMs < ONE_DAY_MS) {
401
- const hours = Math.ceil(safeMs / ONE_HOUR_MS);
402
- return `${hours} ${hours === 1 ? "hour" : "hours"}`;
403
- }
404
- const days = Math.ceil(safeMs / ONE_DAY_MS);
405
- return `${days} ${days === 1 ? "day" : "days"}`;
406
- }
407
- function formatResetDuration(resetsAtMs, nowMs) {
408
- const durationMs = Math.round(Math.max(ONE_SECOND_MS, resetsAtMs - nowMs) / ONE_SECOND_MS) * ONE_SECOND_MS;
409
- const days = Math.floor(durationMs / ONE_DAY_MS);
410
- const hours = Math.floor(durationMs % ONE_DAY_MS / ONE_HOUR_MS);
411
- const minutes = Math.floor(durationMs % ONE_HOUR_MS / ONE_MINUTE_MS);
412
- const seconds = Math.floor(durationMs % ONE_MINUTE_MS / ONE_SECOND_MS);
413
- if (days > 0) return hours > 0 ? `${days}d ${hours}h` : `${days}d`;
414
- if (hours > 0) return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`;
415
- if (minutes > 0) return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
416
- return `${seconds}s`;
417
- }
418
- function formatWindowSignature(window) {
419
- return window ? `${window.usedPercent ?? ""}:${window.resetsAt ?? ""}` : "";
420
- }
421
400
  function extractCodexRetryHint(message) {
422
401
  if (!message) return;
423
402
  const tryAgainAt = /\btry again\s+(at\s+[^.!?\n]+)(?:[.!?]|$)/iu.exec(message);
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
2
- import { i as CodexAppServerRpcError, n as withTimeout, t as withAbortableTimeout } from "./timeout-DZF05XrR.mjs";
2
+ import { i as withTimeout, o as CodexAppServerRpcError, r as withAbortableTimeout } from "./timeout-C910MdAB.mjs";
3
3
  //#region extensions/codex/src/app-server/request.ts
4
4
  var request_exports = /* @__PURE__ */ __exportAll({
5
5
  CodexAppServerScopedRequestRejectedError: () => CodexAppServerScopedRequestRejectedError,
@@ -28,7 +28,7 @@ async function requestCodexAppServerClientJson(params) {
28
28
  let phase = "prepare";
29
29
  observeControlPhase(params.controlObservation, phase);
30
30
  try {
31
- const { resolveCodexAppServerDirectSandboxBypassBlock } = await import("./sandbox-guard-BBP-RbTf.mjs").then((n) => n.r);
31
+ const { resolveCodexAppServerDirectSandboxBypassBlock } = await import("./sandbox-guard-C2sRMOEY.mjs").then((n) => n.r);
32
32
  const sandboxBlock = resolveCodexAppServerDirectSandboxBypassBlock({
33
33
  method: params.method,
34
34
  requestParams: params.requestParams,
@@ -57,7 +57,7 @@ async function requestCodexAppServerClientJson(params) {
57
57
  }
58
58
  async function requestCodexAppServerJson(params) {
59
59
  observeControlPhase(params.controlObservation, "prepare");
60
- const { resolveCodexAppServerDirectSandboxBypassBlock } = await import("./sandbox-guard-BBP-RbTf.mjs").then((n) => n.r);
60
+ const { resolveCodexAppServerDirectSandboxBypassBlock } = await import("./sandbox-guard-C2sRMOEY.mjs").then((n) => n.r);
61
61
  const sandboxBlock = resolveCodexAppServerDirectSandboxBypassBlock({
62
62
  method: params.method,
63
63
  requestParams: params.requestParams,
@@ -81,6 +81,15 @@ var CodexAppServerScopedRequestRejectedError = class extends Error {
81
81
  this.name = "CodexAppServerScopedRequestRejectedError";
82
82
  }
83
83
  };
84
+ function createScopeCleanupError(message) {
85
+ const stackTraceLimit = Error.stackTraceLimit;
86
+ try {
87
+ Error.stackTraceLimit = 0;
88
+ return new CodexAppServerScopedRequestRejectedError(message);
89
+ } finally {
90
+ Error.stackTraceLimit = stackTraceLimit;
91
+ }
92
+ }
84
93
  function assertRequestOwnerCurrent(assertCurrent) {
85
94
  try {
86
95
  assertCurrent?.();
@@ -99,6 +108,7 @@ async function readCodexAppServerUsage(options) {
99
108
  const deadline = performance.now() + options.timeoutMs;
100
109
  return await withCodexAppServerJsonClient({
101
110
  timeoutMs: options.timeoutMs,
111
+ signal: options.signal,
102
112
  timeoutMessage: "codex app-server usage read timed out",
103
113
  agentDir: options.agentDir,
104
114
  ...options.authProfileId ? { authProfileId: options.authProfileId } : {},
@@ -118,20 +128,13 @@ async function readCodexAppServerUsage(options) {
118
128
  };
119
129
  });
120
130
  }
121
- function extractCodexAccountEmail(value) {
122
- if (!value || typeof value !== "object") return;
123
- const record = value;
124
- const account = record.account && typeof record.account === "object" ? record.account : record;
125
- const email = account.email ?? account.accountEmail;
126
- return typeof email === "string" && email.trim() ? email.trim() : void 0;
127
- }
128
131
  async function readCodexAccountEmailBestEffort(request, deadline) {
129
132
  const boundMs = Math.min(CODEX_ACCOUNT_READ_MAX_TIMEOUT_MS, deadline - performance.now() - CODEX_USAGE_DEADLINE_RESERVE_MS);
130
133
  if (boundMs <= 0) return;
131
134
  const read = request({
132
135
  method: "account/read",
133
136
  requestParams: {}
134
- }).then((account) => extractCodexAccountEmail(account), () => void 0);
137
+ }).then(({ account }) => account?.type === "chatgpt" ? account.email?.trim() || void 0 : void 0, () => void 0);
135
138
  let timer;
136
139
  const timeout = new Promise((resolve) => {
137
140
  timer = setTimeout(() => resolve(void 0), boundMs);
@@ -155,6 +158,9 @@ async function withCodexAppServerJsonClient(params, run) {
155
158
  let errorPhase;
156
159
  observeControlPhase(params.controlObservation, activePhase);
157
160
  const timeoutController = new AbortController();
161
+ const abort = () => timeoutController.abort(params.signal?.reason);
162
+ params.signal?.addEventListener("abort", abort, { once: true });
163
+ if (params.signal?.aborted) abort();
158
164
  const deadline = Number.isFinite(timeoutMs) && timeoutMs > 0 ? performance.now() + timeoutMs : void 0;
159
165
  const isPastDeadline = () => deadline !== void 0 && performance.now() >= deadline;
160
166
  const throwIfAbandoned = () => {
@@ -166,13 +172,14 @@ async function withCodexAppServerJsonClient(params, run) {
166
172
  return deadline === void 0 ? timeoutMs : Math.max(1, deadline - performance.now());
167
173
  };
168
174
  try {
175
+ throwIfAbandoned();
169
176
  return await withAbortableTimeout({
170
177
  signal: timeoutController.signal,
171
178
  timeoutMs,
172
179
  timeoutMessage,
173
180
  promise: (async () => {
174
- const { resolveCodexAppServerDirectSandboxBypassBlock } = await import("./sandbox-guard-BBP-RbTf.mjs").then((n) => n.r);
175
- const { createIsolatedCodexAppServerClient, getLeasedSharedCodexAppServerClient, isCodexAppServerStartSelectionChangedError, releaseLeasedSharedCodexAppServerClient, retireSharedCodexAppServerClientIfCurrent } = await import("./shared-client-BpTtuLQ5.mjs").then((n) => n.y);
181
+ const { resolveCodexAppServerDirectSandboxBypassBlock } = await import("./sandbox-guard-C2sRMOEY.mjs").then((n) => n.r);
182
+ const { createIsolatedCodexAppServerClient, getLeasedSharedCodexAppServerClient, isCodexAppServerStartSelectionChangedError, releaseLeasedSharedCodexAppServerClient, retireSharedCodexAppServerClientIfCurrent } = await import("./shared-client-DA4VR4Eb.mjs").then((n) => n.y);
176
183
  for (let attempt = 0; attempt < 2; attempt += 1) {
177
184
  errorPhase = void 0;
178
185
  activePhase = "prepare";
@@ -225,7 +232,7 @@ async function withCodexAppServerJsonClient(params, run) {
225
232
  timeoutMs: remainingTimeoutMs(),
226
233
  signal: timeoutController.signal,
227
234
  ...attemptWaiterFinished ? { attemptWaiterFinished } : {},
228
- ...params.catalogPreview && method === "thread/list" ? {
235
+ ...params.catalogPreview ? {
229
236
  catalogPreview: true,
230
237
  catalogPreviewCache: params.catalogPreviewCache,
231
238
  catalogRows: params.catalogRows
@@ -285,7 +292,8 @@ async function withCodexAppServerJsonClient(params, run) {
285
292
  if (deadlineObserved) throw new Error(timeoutMessage, { cause: error });
286
293
  throw error;
287
294
  } finally {
288
- timeoutController.abort(new CodexAppServerScopedRequestRejectedError(timeoutMessage));
295
+ params.signal?.removeEventListener("abort", abort);
296
+ timeoutController.abort(createScopeCleanupError(timeoutMessage));
289
297
  }
290
298
  }
291
299
  //#endregion