@openclaw/codex 2026.9.5 → 2026.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/assets/icon.png +0 -0
- package/dist/.setup/{account-usage-runtime-C2MOIvfq.mjs → account-usage-runtime-DFhbh1zz.mjs} +6 -6
- package/dist/.setup/{apply-CJ0ZfmBG.mjs → apply-D3GcSoSa.mjs} +35 -55
- package/dist/.setup/{attempt-client-cleanup-BpYKdTA0.mjs → attempt-client-cleanup-DOP-cW5j.mjs} +179 -73
- package/dist/.setup/attempt-workspace-context-C5HigshI.mjs +164 -0
- package/dist/.setup/{auth-binding-DhLWa_7K.mjs → auth-binding-BLWz7stm.mjs} +14 -1
- package/dist/.setup/{auth-cache-key-QirmgiCo.mjs → auth-cache-key-Dbvq-QgB.mjs} +41 -111
- package/dist/.setup/{auth-profile-WqZtZfXN.mjs → auth-profile-B0okYl2D.mjs} +1 -2
- package/dist/.setup/auth-profile-health-oHizqgye.mjs +53 -0
- package/dist/.setup/auth-profile-recovery-BREezV0L.mjs +14 -0
- package/dist/.setup/auth-start-options-BPIPeEX8.mjs +44 -0
- package/dist/.setup/{binding-connection-Bm38niE8.mjs → binding-connection-DTtN1KrX.mjs} +2 -2
- package/dist/.setup/{binding-connection.runtime-CnRMC0ta.mjs → binding-connection.runtime-6TpgD1M6.mjs} +5 -5
- package/dist/.setup/{bounded-turn-BtlZcivC.mjs → bounded-turn-CbjoN2OW.mjs} +140 -37
- package/dist/.setup/bounded-turn-isolation-B8K_ylqk.mjs +14 -0
- package/dist/.setup/{build-state-Xx9ybZqa.mjs → build-state-Da1_z0kd.mjs} +1 -1
- package/dist/.setup/{capabilities-_vXcZGSx.mjs → capabilities-B3WEZl4e.mjs} +2 -10
- package/dist/.setup/{client-vXs2929Q.mjs → client-N0JpgSzF.mjs} +635 -872
- package/dist/.setup/client-catalog-response-5HHLdcde.mjs +285 -0
- package/dist/.setup/{command-dispatch-naHIZwwF.mjs → command-dispatch-BeAoaovI.mjs} +9 -8
- package/dist/.setup/{command-formatters-CGEkdawF.mjs → command-formatters-R3ckE3Co.mjs} +36 -64
- package/dist/.setup/{command-handlers-BtAJEW1X.mjs → command-handlers-ylTMS00z.mjs} +301 -488
- package/dist/.setup/{command-rpc-DHFpn4le.mjs → command-rpc-CGJGUQ6Y.mjs} +40 -28
- package/dist/.setup/compact-C2WamavS.mjs +776 -0
- package/dist/.setup/{config-CedDWjM-.mjs → config-DKhXquav.mjs} +26 -28
- package/dist/.setup/{config-options-BsanJ8QG.mjs → config-options-CzyWLTJt.mjs} +68 -65
- package/dist/.setup/{config-parsing-CcB9iPoq.mjs → config-parsing-b088LyhT.mjs} +57 -60
- package/dist/.setup/{config-runtime-CeAhl_h4.mjs → config-runtime-C0NbLms1.mjs} +2 -2
- package/dist/.setup/{config-security-BRQ2mgW9.mjs → config-security-CE-FcGw9.mjs} +51 -215
- package/dist/.setup/{config-utils-DujwEnhg.mjs → config-utils-D0CXecki.mjs} +3 -13
- package/dist/.setup/context-engine-projection-PezSESth.mjs +387 -0
- package/dist/.setup/{conversation-binding-DhzrpTM6.mjs → conversation-binding-3Min8qvP.mjs} +71 -105
- package/dist/.setup/{conversation-binding-data-CrcyZk6O.mjs → conversation-binding-data-C746z5Pn.mjs} +8 -12
- package/dist/.setup/{conversation-control-DN53ns41.mjs → conversation-control-CEP8X5JC.mjs} +30 -69
- package/dist/.setup/{cyber-failover-DYwbmf1o.mjs → cyber-failover-XV0nNRZu.mjs} +1 -1
- package/dist/.setup/{cyber-failover-notice-e9G3J9-e.mjs → cyber-failover-notice-RNpGpTyP.mjs} +1 -1
- package/dist/.setup/{dynamic-tools-D16lOp67.mjs → dynamic-tools-DzlsLUuS.mjs} +3136 -3167
- package/dist/.setup/{effective-mcp-catalog-K6kLCN8X.mjs → effective-mcp-catalog-CxUtC-xG.mjs} +8 -17
- package/dist/.setup/{ephemeral-turn-R1gA8Sn6.mjs → ephemeral-turn-CDsPJOa2.mjs} +9 -6
- package/dist/.setup/event-projector-assistant-message-CigreO4K.mjs +69 -0
- package/dist/.setup/{event-projector-usage-C7Ntzs-f.mjs → event-projector-usage-03R0I2dM.mjs} +4 -26
- package/dist/.setup/event-projector-values-DJSz8BTk.mjs +106 -0
- package/dist/.setup/incognito-session-DWYapfwf.mjs +2 -0
- package/dist/.setup/{inference-context-fulhZuz8.mjs → inference-context-D-9gWlTR.mjs} +16 -18
- package/dist/.setup/inference-dispatch-CMZtjQyz.mjs +359 -0
- package/dist/.setup/inference-metadata-CgIf7sOx.mjs +81 -0
- package/dist/.setup/inference-proxy-DhcXOgUE.mjs +561 -0
- package/dist/.setup/{isolated-completion-B6srt48J.mjs → isolated-completion-Dm3PzxJk.mjs} +15 -11
- package/dist/.setup/launch-args-DbFCehO7.mjs +196 -0
- package/dist/.setup/{managed-binary-DP6Rib3P.mjs → managed-binary-kiWRhNRE.mjs} +16 -9
- package/dist/.setup/{model-catalog-DkvUuBey.mjs → model-catalog-PAuZgJC6.mjs} +14 -14
- package/dist/.setup/model-runtime-BdqzOMkU.mjs +11 -0
- package/dist/.setup/{models-BDFgm_G-.mjs → models-DHXZtVVk.mjs} +9 -18
- package/dist/.setup/{native-auth-BLZGqFjw.mjs → native-auth-CuG53tu4.mjs} +5 -5
- package/dist/.setup/{native-execution-policy-YBMHSzC4.mjs → native-execution-policy-BxZJy5mP.mjs} +6 -31
- package/dist/.setup/{native-subagent-monitor-B1hxzIOy.mjs → native-subagent-monitor-Dpsmf2wz.mjs} +4422 -3808
- package/dist/.setup/native-subagent-pending-assignments-DwkCzLvD.mjs +203 -0
- package/dist/.setup/native-task-assignments-DMQ0g3hu.mjs +194 -0
- package/dist/.setup/{node-cli-sessions-Cl8b2ZF3.mjs → node-cli-sessions-HC4W6FLI.mjs} +99 -111
- package/dist/.setup/node-exec-server.runtime-BgBfWQqo.mjs +244 -0
- package/dist/.setup/{plan-xD7WKYTM.mjs → plan-Y-QIvrKB.mjs} +118 -163
- package/dist/.setup/{plugin-activation-r8nq5Jzp.mjs → plugin-activation-cNHRfaxU.mjs} +10 -47
- package/dist/.setup/{plugin-app-cache-key-BOxKP7db.mjs → plugin-app-cache-key-BL9B5H0L.mjs} +9 -42
- package/dist/.setup/{plugin-inventory-DUle8DLz.mjs → plugin-inventory-Cky2XJUw.mjs} +32 -23
- package/dist/.setup/{plugin-marketplace-discovery-P-Vndfqq.mjs → plugin-marketplace-discovery-D_dV9FXa.mjs} +22 -25
- package/dist/.setup/{plugin-metadata-cache-DsS5buNa.mjs → plugin-metadata-cache-DsjsL1dr.mjs} +328 -318
- package/dist/.setup/protocol-CANUwXJ3.mjs +17 -0
- package/dist/.setup/provider-DH8NSzGt.mjs +51 -0
- package/dist/.setup/{provider-capabilities-B8J4Dy-O.mjs → provider-capabilities-CAxoF-X1.mjs} +35 -12
- package/dist/.setup/{rate-limits-DOEGYRNs.mjs → rate-limits-B7-X2TgG.mjs} +123 -166
- package/dist/.setup/{request-BioXJLYa.mjs → request-BHZ1nz8d.mjs} +25 -16
- package/dist/.setup/responses-oauth-twnuTaAa.mjs +93 -0
- package/dist/.setup/rpc-error-BlD2vuzn.mjs +31 -0
- package/dist/.setup/{run-attempt-rlA07pUv.mjs → run-attempt-D8RZUOzY.mjs} +2046 -1454
- package/dist/.setup/{run-attempt-lifecycle-B7JbY4-F.mjs → run-attempt-lifecycle-C-6O3Exn.mjs} +10 -24
- package/dist/.setup/{runtime-artifact-Dy38Z5iU.mjs → runtime-artifact-DDQ-HGXf.mjs} +43 -47
- package/dist/.setup/runtime-artifact-connection-D68qQn1m.mjs +78 -0
- package/dist/.setup/sandbox-guard-DjCz2eOw.mjs +126 -0
- package/dist/.setup/scope-DOC1Xjc8.mjs +6 -0
- package/dist/.setup/session-binding-DGCYAfvD.mjs +443 -0
- package/dist/.setup/{session-binding-record-TH3xA0zj.mjs → session-binding-record-Oe9L-CNY.mjs} +73 -132
- package/dist/.setup/{session-binding-sidecars-CKYEcfNn.mjs → session-binding-sidecars-jo6H8dFr.mjs} +242 -60
- package/dist/.setup/{session-catalog-fUdWDx-U.mjs → session-catalog-4sCdv5qx.mjs} +598 -452
- package/dist/.setup/{session-catalog-adoption-CR_whkEW.mjs → session-catalog-adoption-BU_pHWG7.mjs} +59 -26
- package/dist/.setup/{session-catalog-archive-CwZaPacf.mjs → session-catalog-archive-spHfihri.mjs} +7 -7
- package/dist/.setup/session-catalog-events-DePDzzjc.mjs +139 -0
- package/dist/.setup/session-catalog-home-id-vlih0B_g.mjs +22 -0
- package/dist/.setup/{session-catalog-index-B141u15s.mjs → session-catalog-index-CZvDzC6z.mjs} +286 -182
- package/dist/.setup/{session-catalog-index-order-Cc5BzlQr.mjs → session-catalog-index-order-BcQpHks3.mjs} +2 -2
- package/dist/.setup/{session-catalog-index-state-BAuDztHN.mjs → session-catalog-index-state-TeO7EyO-.mjs} +6 -2
- package/dist/.setup/session-catalog-limits-DDxOsQeC.mjs +14 -0
- package/dist/.setup/session-catalog-list-request-CvtxrYSe.mjs +170 -0
- package/dist/.setup/session-catalog-native-projection-DjhwGL6x.mjs +178 -0
- package/dist/.setup/{session-catalog-node-adoption-BVRsYOSh.mjs → session-catalog-node-adoption-DgXvSGu0.mjs} +30 -35
- package/dist/.setup/{session-catalog-node-continue-Dowv8osw.mjs → session-catalog-node-continue-DjKXHBbi.mjs} +25 -18
- package/dist/.setup/session-catalog-node-lookup-CtAXI5W5.mjs +56 -0
- package/dist/.setup/{session-catalog-native-projection-ChV3cCtm.mjs → session-catalog-parsing-CPGaPYr-.mjs} +14 -180
- package/dist/.setup/{session-catalog-projection-C1Bj9Jl-.mjs → session-catalog-projection-Cr5qP5Dj.mjs} +15 -5
- package/dist/.setup/session-catalog-provenance-DoAvktcj.mjs +95 -0
- package/dist/.setup/{session-cli-DIj-IE-E.mjs → session-cli-Cn_nCqfq.mjs} +11 -24
- package/dist/.setup/{session-history-C--SrLI8.mjs → session-history-D83lJWHG.mjs} +16 -23
- package/dist/.setup/{session-history-import-JHXT5Xfi.mjs → session-history-import-WhX-X33a.mjs} +7 -10
- package/dist/.setup/session-history-read-Ov3StuL4.mjs +133 -0
- package/dist/.setup/{session-history.worker-CpNj7H_P.mjs → session-history.worker-MnPKncqP.mjs} +14 -23
- package/dist/.setup/session-initialization-6aveB9qb.mjs +22 -0
- package/dist/.setup/{session-permission-policy-DhurXY0l.mjs → session-permission-policy-Ci_fVX6y.mjs} +4 -8
- package/dist/.setup/{session-retirement-CU87AOg9.mjs → session-retirement-qMTxkNx2.mjs} +31 -12
- package/dist/.setup/{settled-turn-context-fmwouT5I.mjs → settled-turn-context-D4yj4rxf.mjs} +1 -1
- package/dist/.setup/{settled-turn-finalizer-CiY2bLFK.mjs → settled-turn-finalizer-BsvEabkw.mjs} +17 -13
- package/dist/.setup/{shared-client-BpTtuLQ5.mjs → shared-client-DqyTMYug.mjs} +826 -485
- package/dist/.setup/shared-client-lifecycle-DJIgqgMw.mjs +153 -0
- package/dist/.setup/{side-question-DSCZyoBD.mjs → side-question-C4kCmQy1.mjs} +206 -334
- package/dist/.setup/{source-Bjp4UQij.mjs → source-CS_7GFJZ.mjs} +82 -139
- package/dist/.setup/spawn-error-CL3n6MAa.mjs +57 -0
- package/dist/.setup/{thread-archive-guard-jmecf6OJ.mjs → thread-archive-guard-C9frICzX.mjs} +10 -3
- package/dist/.setup/thread-lifecycle-DPflntEJ.mjs +2362 -0
- package/dist/.setup/{incognito-session-uhrBF6wJ.mjs → thread-ownership-queue-Dp24d7-F.mjs} +1 -2
- package/dist/.setup/{thread-ownership-skomxnIt.mjs → thread-ownership-roNP0l1c.mjs} +47 -10
- package/dist/.setup/thread-policy-DTd-DtkX.mjs +109 -0
- package/dist/.setup/thread-requests-B_bRnMGN.mjs +2102 -0
- package/dist/.setup/{thread-resume-BkNpj9Pz.mjs → thread-resume-CdDaoc7T.mjs} +6 -6
- package/dist/.setup/timeout-CXOfNoaX.mjs +46 -0
- package/dist/.setup/transcript-history-projection-DRSifI-1.mjs +201 -0
- package/dist/.setup/{transcript-mirror-attestation-CzM-94NC.mjs → transcript-mirror-attestation-YSegaktH.mjs} +3 -4
- package/dist/.setup/{transcript-mirror-D4qp_leP.mjs → transcript-mirror-kxmCYsuF.mjs} +224 -206
- package/dist/.setup/{transport-stdio-Cmx94Oiy.mjs → transport-stdio-Bdegpn2V.mjs} +138 -75
- package/dist/.setup/transport-websocket-BTBE-LD9.mjs +211 -0
- package/dist/.setup/{upstream-prompt-provenance-LphB8slG.mjs → upstream-prompt-provenance-fXkKbPVC.mjs} +3 -9
- package/dist/.setup/{upstream-session-fork-D3UKxgVD.mjs → upstream-session-fork-CBeVjBpT.mjs} +48 -40
- package/dist/.setup/{usage-BOgBEKso.mjs → usage-BMzNxeR_.mjs} +5 -4
- package/dist/.setup/{usage-limit-error-C0ow7DOc.mjs → usage-limit-error-QXerDo3i.mjs} +5 -20
- package/dist/.setup/{web-search-provider.runtime-CTGuJt6i.mjs → web-search-provider.runtime-P77OUeoo.mjs} +10 -20
- package/dist/api.js +25 -16
- package/dist/catalog-page-worker-entrypoint.js +12 -0
- package/dist/catalog-page.worker.js +9 -0
- package/dist/cli-metadata.js +1 -1
- package/dist/doctor-contract-api.js +50 -8
- package/dist/harness.js +344 -1
- package/dist/index.js +345 -346
- package/dist/media-understanding-provider.js +9 -22
- package/dist/migration-provider-api.js +1 -1
- package/dist/provider-discovery.js +1 -1
- package/dist/session-history-worker-runtime.js +16 -33
- package/dist/session-history.worker.js +1 -1
- package/openclaw.plugin.json +14 -2
- package/package.json +11 -7
- package/dist/.setup/attempt-context-VXVwTCfS.mjs +0 -636
- package/dist/.setup/compact-C3i3qlzj.mjs +0 -687
- package/dist/.setup/event-projector-assistant-message-DNUR1s0A.mjs +0 -105
- package/dist/.setup/event-projector-items-DyTQ_XqL.mjs +0 -200
- package/dist/.setup/harness-rxaaoN-o.mjs +0 -349
- package/dist/.setup/history-rejection-B4nOXNXF.mjs +0 -13
- package/dist/.setup/image-payload-sanitizer-tupAr-2o.mjs +0 -79
- package/dist/.setup/inference-proxy-CC15HuSi.mjs +0 -311
- package/dist/.setup/launch-args-DnMak49W.mjs +0 -111
- package/dist/.setup/local-runtime-attribution-B_2mnqhb.mjs +0 -19
- package/dist/.setup/native-subagent-history-YXaL6dMd.mjs +0 -135
- package/dist/.setup/native-subagent-task-ids-DsuOonKv.mjs +0 -411
- package/dist/.setup/node-exec-server.runtime-BaViBKNz.mjs +0 -226
- package/dist/.setup/plugin-approval-roundtrip-CjfzafAZ.mjs +0 -122
- package/dist/.setup/provider-fFh_-VR3.mjs +0 -50
- package/dist/.setup/rolldown-runtime-8H4AJuhK.mjs +0 -14
- package/dist/.setup/sandbox-guard-BBP-RbTf.mjs +0 -166
- package/dist/.setup/session-binding-_0W_fHRr.mjs +0 -721
- package/dist/.setup/session-catalog-events-jMcYfQyd.mjs +0 -250
- package/dist/.setup/session-history-read-B3ZfSUbF.mjs +0 -50
- package/dist/.setup/session-initialization-DH1z6fXn.mjs +0 -75
- package/dist/.setup/thread-history-page-BTx-4xsg.mjs +0 -83
- package/dist/.setup/thread-lifecycle-Cik28qWn.mjs +0 -4904
- package/dist/.setup/thread-policy-Cjs4B8xf.mjs +0 -54
- package/dist/.setup/timeout-DZF05XrR.mjs +0 -63
- package/dist/.setup/transcript-history-projection-DHNBDhCU.mjs +0 -243
- package/dist/.setup/version-CoqzXPgK.mjs +0 -12
|
@@ -0,0 +1,776 @@
|
|
|
1
|
+
import { n as readCodexRuntimeModelId } from "./model-runtime-BdqzOMkU.mjs";
|
|
2
|
+
import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
|
|
3
|
+
import { v as sessionBindingIdentity } from "./session-binding-record-Oe9L-CNY.mjs";
|
|
4
|
+
import { l as retainSharedCodexAppServerClientByInstanceId, p as waitForCodexAppServerClientExit } from "./shared-client-lifecycle-DJIgqgMw.mjs";
|
|
5
|
+
import { t as isIncognitoSessionKey } from "./incognito-session-DWYapfwf.mjs";
|
|
6
|
+
import { n as CodexAppServerRpcError } from "./rpc-error-BlD2vuzn.mjs";
|
|
7
|
+
import { i as resolveCodexBindingAppServerConnection } from "./binding-connection-DTtN1KrX.mjs";
|
|
8
|
+
import { F as consumeCodexAppServerLiveThread, K as retainCodexAppServerLiveThread, M as getCodexInferenceThreadQualification, U as protectCodexAppServerLiveThread, _ as retainSharedCodexAppServerClientIfCurrent, q as revertCodexAppServerLiveThreadSkillsCatalog, s as createIsolatedCodexAppServerClient } from "./shared-client-DqyTMYug.mjs";
|
|
9
|
+
import "./responses-oauth-twnuTaAa.mjs";
|
|
10
|
+
import { s as isCodexAppServerIndeterminateRequestCancellationError, u as isCodexAppServerPrewriteRequestCancellationError } from "./client-N0JpgSzF.mjs";
|
|
11
|
+
import { b as readCodexNotificationTurnId, l as isCodexNoActiveTurnInterruptError, o as closeCodexStartupClientBestEffort, p as unsubscribeCodexThreadBestEffort, r as CodexAppServerUnsafeSubscriptionError, y as readCodexNotificationThreadId } from "./attempt-client-cleanup-DOP-cW5j.mjs";
|
|
12
|
+
import { n as readCodexThreadContextSnapshot, s as readCodexNotificationItem } from "./event-projector-usage-03R0I2dM.mjs";
|
|
13
|
+
import { o as resolveCodexSessionBinding, t as CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS } from "./session-binding-DGCYAfvD.mjs";
|
|
14
|
+
import { t as codexNativeSubagentMonitorRuntime } from "./native-subagent-monitor-Dpsmf2wz.mjs";
|
|
15
|
+
import { i as assertCodexSupervisionThreadLineage } from "./thread-policy-DTd-DtkX.mjs";
|
|
16
|
+
import { t as resumeCodexAppServerThread } from "./thread-resume-CdDaoc7T.mjs";
|
|
17
|
+
import { s as withCodexAppServerThreadMutationHold, t as isSameCodexAppServerThreadOwner } from "./thread-ownership-roNP0l1c.mjs";
|
|
18
|
+
import { t as persistCodexContextCompactionActivity } from "./context-compaction-activity-CMla5FPJ.mjs";
|
|
19
|
+
import { t as resolveCodexNativeExecutionBlock } from "./sandbox-guard-DjCz2eOw.mjs";
|
|
20
|
+
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
21
|
+
import { coerceErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
22
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
23
|
+
import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
|
|
24
|
+
import { resolveAgentDir } from "openclaw/plugin-sdk/agent-runtime";
|
|
25
|
+
import { embeddedAgentLog, resolveCompactionTimeoutMs } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
26
|
+
import { runWithAsyncWorkResources } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
|
|
27
|
+
import { createDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
|
|
28
|
+
//#region extensions/codex/src/app-server/compact-helpers.ts
|
|
29
|
+
async function clearContextEngineProjectionBeforeNativeCompaction(params) {
|
|
30
|
+
const contextEngineBinding = params.binding.contextEngine;
|
|
31
|
+
if (!contextEngineBinding?.projection) return;
|
|
32
|
+
await params.bindingStore.mutate(params.identity, {
|
|
33
|
+
kind: "patch",
|
|
34
|
+
threadId: params.binding.threadId,
|
|
35
|
+
patch: { contextEngine: {
|
|
36
|
+
...contextEngineBinding,
|
|
37
|
+
projection: void 0
|
|
38
|
+
} }
|
|
39
|
+
}, params.assertCurrent);
|
|
40
|
+
embeddedAgentLog.info("cleared codex context-engine projection before native compaction", {
|
|
41
|
+
sessionId: params.sessionId,
|
|
42
|
+
threadId: params.binding.threadId,
|
|
43
|
+
previousEpoch: contextEngineBinding.projection.epoch,
|
|
44
|
+
previousFingerprint: contextEngineBinding.projection.fingerprint
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function isSameNativeCompactionBinding(current, expected) {
|
|
48
|
+
return isSameCodexAppServerThreadOwner(current, expected) && current.authProfileId === expected.authProfileId && current.contextEngine?.engineId === expected.contextEngine?.engineId && current.contextEngine?.policyFingerprint === expected.contextEngine?.policyFingerprint && current.contextEngine?.projection?.mode === expected.contextEngine?.projection?.mode && current.contextEngine?.projection?.epoch === expected.contextEngine?.projection?.epoch && current.contextEngine?.projection?.fingerprint === expected.contextEngine?.projection?.fingerprint;
|
|
49
|
+
}
|
|
50
|
+
function isCodexThreadNotFoundError(error) {
|
|
51
|
+
return coerceErrorMessage(error).toLowerCase().includes("thread not found");
|
|
52
|
+
}
|
|
53
|
+
const warnedIgnoredCompactionOverrides = createDedupeCache({
|
|
54
|
+
ttlMs: 0,
|
|
55
|
+
maxSize: 4096
|
|
56
|
+
});
|
|
57
|
+
function warnIfIgnoringOpenClawCompactionOverrides(params) {
|
|
58
|
+
const ignoredConfig = readIgnoredCompactionOverridePaths(params);
|
|
59
|
+
if (ignoredConfig.length === 0) return;
|
|
60
|
+
const warningKey = ignoredConfig.join("\0");
|
|
61
|
+
if (warnedIgnoredCompactionOverrides.check(warningKey)) return;
|
|
62
|
+
embeddedAgentLog.warn("ignoring OpenClaw compaction overrides for Codex app-server compaction; Codex uses native server-side compaction", {
|
|
63
|
+
sessionId: params.sessionId,
|
|
64
|
+
sessionKey: params.sessionKey,
|
|
65
|
+
ignoredConfig
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function readIgnoredCompactionOverridePaths(params) {
|
|
69
|
+
const compaction = asOptionalRecord(params.config?.agents?.defaults?.compaction);
|
|
70
|
+
return [
|
|
71
|
+
"model",
|
|
72
|
+
"thinkingLevel",
|
|
73
|
+
"provider"
|
|
74
|
+
].flatMap((field) => {
|
|
75
|
+
const value = compaction?.[field];
|
|
76
|
+
return typeof value === "string" && value.trim() ? [`agents.defaults.compaction.${field}`] : [];
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region extensions/codex/src/app-server/compact-lifecycle.ts
|
|
81
|
+
function watchCodexNativeCompactionCompletion(params) {
|
|
82
|
+
const runOutsideBindingLease = AsyncLocalStorage.snapshot();
|
|
83
|
+
let settled = false;
|
|
84
|
+
let requestStarted = false;
|
|
85
|
+
let abortRequested = false;
|
|
86
|
+
let interruptRequested = false;
|
|
87
|
+
let retirementStarted = false;
|
|
88
|
+
let compactionTurnId;
|
|
89
|
+
let compactionItemId;
|
|
90
|
+
let compactionItemCompleted = false;
|
|
91
|
+
let tokensAfter;
|
|
92
|
+
let admissionFailure;
|
|
93
|
+
const { promise: completion, resolve: resolveCompletion } = createDeferred();
|
|
94
|
+
let removeNotificationHandler = () => {};
|
|
95
|
+
let removeCloseHandler = () => {};
|
|
96
|
+
let removeAbortHandler = () => {};
|
|
97
|
+
let completionTimeout;
|
|
98
|
+
let interruptGraceTimeout;
|
|
99
|
+
const finish = (result) => {
|
|
100
|
+
if (settled) return;
|
|
101
|
+
settled = true;
|
|
102
|
+
removeNotificationHandler();
|
|
103
|
+
removeCloseHandler();
|
|
104
|
+
removeAbortHandler();
|
|
105
|
+
clearTimeout(completionTimeout);
|
|
106
|
+
clearTimeout(interruptGraceTimeout);
|
|
107
|
+
resolveCompletion(result);
|
|
108
|
+
};
|
|
109
|
+
const complete = () => finish({
|
|
110
|
+
completed: true,
|
|
111
|
+
...compactionTurnId ? { turnId: compactionTurnId } : {},
|
|
112
|
+
...compactionItemId ? { itemId: compactionItemId } : {},
|
|
113
|
+
...tokensAfter !== void 0 ? { tokensAfter } : {}
|
|
114
|
+
});
|
|
115
|
+
const fail = (reason) => finish({
|
|
116
|
+
completed: false,
|
|
117
|
+
reason
|
|
118
|
+
});
|
|
119
|
+
const retireUnconfirmed = (reason) => {
|
|
120
|
+
if (settled || retirementStarted) return;
|
|
121
|
+
retirementStarted = true;
|
|
122
|
+
runOutsideBindingLease(() => params.retireUnconfirmed()).then(() => fail(reason)).catch((error) => {
|
|
123
|
+
embeddedAgentLog.error("failed to retire unconfirmed codex app-server compaction", {
|
|
124
|
+
threadId: params.threadId,
|
|
125
|
+
turnId: compactionTurnId,
|
|
126
|
+
reason: coerceErrorMessage(error)
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
const requestInterrupt = () => {
|
|
131
|
+
if (settled || !requestStarted || !abortRequested || !compactionTurnId || interruptRequested) return;
|
|
132
|
+
interruptRequested = true;
|
|
133
|
+
params.client.request("turn/interrupt", {
|
|
134
|
+
threadId: params.threadId,
|
|
135
|
+
turnId: compactionTurnId
|
|
136
|
+
}, { timeoutMs: Math.max(1, params.interruptGraceMs) }).catch((error) => {
|
|
137
|
+
if (isCodexNoActiveTurnInterruptError(error)) return;
|
|
138
|
+
embeddedAgentLog.warn("codex app-server compaction interrupt request failed", {
|
|
139
|
+
threadId: params.threadId,
|
|
140
|
+
turnId: compactionTurnId,
|
|
141
|
+
reason: coerceErrorMessage(error)
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
const beginInterruptGrace = () => {
|
|
146
|
+
if (settled || !requestStarted || interruptGraceTimeout) return;
|
|
147
|
+
requestInterrupt();
|
|
148
|
+
interruptGraceTimeout = setTimeout(() => {
|
|
149
|
+
embeddedAgentLog.warn("codex app-server compaction did not reach terminal state after interruption", {
|
|
150
|
+
threadId: params.threadId,
|
|
151
|
+
turnId: compactionTurnId,
|
|
152
|
+
interruptGraceMs: params.interruptGraceMs
|
|
153
|
+
});
|
|
154
|
+
retireUnconfirmed("codex app-server compaction did not reach terminal state after interruption");
|
|
155
|
+
}, Math.max(1, params.interruptGraceMs));
|
|
156
|
+
interruptGraceTimeout.unref?.();
|
|
157
|
+
};
|
|
158
|
+
const beginCompletionTimeout = () => {
|
|
159
|
+
completionTimeout = setTimeout(() => {
|
|
160
|
+
abortRequested = true;
|
|
161
|
+
beginInterruptGrace();
|
|
162
|
+
embeddedAgentLog.warn("codex app-server compaction exceeded its completion budget", {
|
|
163
|
+
threadId: params.threadId,
|
|
164
|
+
timeoutMs: params.timeoutMs,
|
|
165
|
+
interruptRequested
|
|
166
|
+
});
|
|
167
|
+
}, Math.max(1, params.timeoutMs));
|
|
168
|
+
completionTimeout.unref?.();
|
|
169
|
+
};
|
|
170
|
+
removeNotificationHandler = params.client.addNotificationHandler((notification) => {
|
|
171
|
+
if (!requestStarted) return;
|
|
172
|
+
if (!isJsonObject(notification.params)) return;
|
|
173
|
+
if (readCodexNotificationThreadId(notification.params) !== params.threadId) return;
|
|
174
|
+
const notificationTurnId = readCodexNotificationTurnId(notification.params);
|
|
175
|
+
if (notification.method === "turn/started") {
|
|
176
|
+
compactionTurnId = notificationTurnId;
|
|
177
|
+
requestInterrupt();
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (compactionTurnId && notificationTurnId !== compactionTurnId) return;
|
|
181
|
+
if (notification.method === "thread/tokenUsage/updated") {
|
|
182
|
+
tokensAfter = readCodexThreadContextSnapshot(notification.params).activeContextTokens ?? tokensAfter;
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const item = readCodexNotificationItem(notification.params);
|
|
186
|
+
if (item?.type === "contextCompaction") {
|
|
187
|
+
if (notification.method === "item/started") {
|
|
188
|
+
compactionTurnId = compactionTurnId ?? notificationTurnId;
|
|
189
|
+
if (!compactionItemId && compactionTurnId) try {
|
|
190
|
+
params.onCompactionTurn?.(compactionTurnId);
|
|
191
|
+
} catch (error) {
|
|
192
|
+
admissionFailure = coerceErrorMessage(error);
|
|
193
|
+
abortRequested = true;
|
|
194
|
+
beginInterruptGrace();
|
|
195
|
+
}
|
|
196
|
+
compactionItemId = item.id;
|
|
197
|
+
requestInterrupt();
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (notification.method === "item/completed" && compactionItemId === item.id) {
|
|
201
|
+
compactionItemCompleted = true;
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (notification.method !== "turn/completed" || !compactionTurnId || notificationTurnId !== compactionTurnId) return;
|
|
206
|
+
const turn = isJsonObject(notification.params.turn) ? notification.params.turn : void 0;
|
|
207
|
+
const status = typeof turn?.status === "string" ? turn.status : void 0;
|
|
208
|
+
if (admissionFailure) {
|
|
209
|
+
fail(admissionFailure);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
if (status !== "completed") {
|
|
213
|
+
fail(`codex app-server compaction turn ended with status ${status ?? "unknown"}`);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const incompleteReason = !compactionItemId ? "codex app-server compaction turn completed without a compaction item" : !compactionItemCompleted ? "codex app-server compaction turn completed before its compaction item" : void 0;
|
|
217
|
+
if (incompleteReason) {
|
|
218
|
+
fail(incompleteReason);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
complete();
|
|
222
|
+
});
|
|
223
|
+
removeCloseHandler = params.client.addCloseHandler(() => {
|
|
224
|
+
retireUnconfirmed("codex app-server closed before native compaction completed");
|
|
225
|
+
});
|
|
226
|
+
if (params.signal) {
|
|
227
|
+
const onAbort = () => {
|
|
228
|
+
abortRequested = true;
|
|
229
|
+
beginInterruptGrace();
|
|
230
|
+
};
|
|
231
|
+
params.signal.addEventListener("abort", onAbort, { once: true });
|
|
232
|
+
removeAbortHandler = () => params.signal?.removeEventListener("abort", onAbort);
|
|
233
|
+
if (params.signal.aborted) onAbort();
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
completion,
|
|
237
|
+
beginRequest: () => {
|
|
238
|
+
requestStarted = true;
|
|
239
|
+
beginCompletionTimeout();
|
|
240
|
+
if (abortRequested) beginInterruptGrace();
|
|
241
|
+
},
|
|
242
|
+
confirmRequestRejected: () => fail("codex app-server rejected the compaction request"),
|
|
243
|
+
retireUnconfirmedRequest: async (reason) => {
|
|
244
|
+
retireUnconfirmed(reason);
|
|
245
|
+
return await completion;
|
|
246
|
+
},
|
|
247
|
+
cancel: () => {
|
|
248
|
+
if (!requestStarted) fail("compaction request did not start");
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
//#endregion
|
|
253
|
+
//#region extensions/codex/src/app-server/compact-result.ts
|
|
254
|
+
function codexNativeCompactionResult(params, outcome) {
|
|
255
|
+
return {
|
|
256
|
+
ok: true,
|
|
257
|
+
compacted: outcome.compacted,
|
|
258
|
+
...outcome.reason ? { reason: outcome.reason } : {},
|
|
259
|
+
result: {
|
|
260
|
+
summary: "",
|
|
261
|
+
firstKeptEntryId: "",
|
|
262
|
+
tokensBefore: params.currentTokenCount ?? 0,
|
|
263
|
+
...outcome.tokensAfter !== void 0 ? { tokensAfter: outcome.tokensAfter } : {},
|
|
264
|
+
details: outcome.details
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
function skippedCodexNativeCompactionResult(params, skipped) {
|
|
269
|
+
return codexNativeCompactionResult(params, {
|
|
270
|
+
compacted: false,
|
|
271
|
+
reason: skipped.reason,
|
|
272
|
+
details: {
|
|
273
|
+
backend: "codex-app-server",
|
|
274
|
+
skipped: true,
|
|
275
|
+
reason: skipped.code,
|
|
276
|
+
request: skipped.request ?? "after_context_engine",
|
|
277
|
+
trigger: params.trigger ?? "unknown",
|
|
278
|
+
...skipped.expectedThreadId ? { expectedThreadId: skipped.expectedThreadId } : {},
|
|
279
|
+
...skipped.currentThreadId ? { currentThreadId: skipped.currentThreadId } : {}
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
function failedCodexThreadBindingCompactionResult(params, recovery) {
|
|
284
|
+
embeddedAgentLog.warn("codex app-server compaction could not use thread binding", {
|
|
285
|
+
sessionId: params.sessionId,
|
|
286
|
+
sessionKey: params.sessionKey,
|
|
287
|
+
threadId: recovery.threadId,
|
|
288
|
+
reason: recovery.reason,
|
|
289
|
+
recovery: recovery.recovery
|
|
290
|
+
});
|
|
291
|
+
return {
|
|
292
|
+
ok: false,
|
|
293
|
+
compacted: false,
|
|
294
|
+
reason: recovery.reason,
|
|
295
|
+
failure: {
|
|
296
|
+
reason: recovery.recovery,
|
|
297
|
+
rawError: recovery.reason
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
//#endregion
|
|
302
|
+
//#region extensions/codex/src/app-server/compact.ts
|
|
303
|
+
const CODEX_NATIVE_COMPACTION_INTERRUPT_GRACE_MS = 3e4;
|
|
304
|
+
/**
|
|
305
|
+
* Starts native Codex compaction for a manually requested bound session, or
|
|
306
|
+
* reports why Codex-owned automatic compaction should handle the trigger.
|
|
307
|
+
*/
|
|
308
|
+
async function maybeCompactCodexAppServerSession(params, options) {
|
|
309
|
+
params.hostCapabilities.assertActive();
|
|
310
|
+
warnIfIgnoringOpenClawCompactionOverrides(params);
|
|
311
|
+
if (params.trigger !== "manual" && !options.allowNonManualNativeRequest) {
|
|
312
|
+
embeddedAgentLog.info("skipping codex app-server compaction for non-manual trigger", {
|
|
313
|
+
sessionId: params.sessionId,
|
|
314
|
+
sessionKey: params.sessionKey,
|
|
315
|
+
trigger: params.trigger
|
|
316
|
+
});
|
|
317
|
+
return codexNativeCompactionResult(params, {
|
|
318
|
+
compacted: false,
|
|
319
|
+
reason: "codex app-server owns automatic compaction",
|
|
320
|
+
details: {
|
|
321
|
+
backend: "codex-app-server",
|
|
322
|
+
skipped: true,
|
|
323
|
+
reason: "non_manual_trigger",
|
|
324
|
+
trigger: params.trigger ?? "unknown"
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
const sandbox = params.sandbox;
|
|
329
|
+
const nativeExecutionBlock = resolveCodexNativeExecutionBlock({
|
|
330
|
+
config: params.config,
|
|
331
|
+
sessionKey: params.sandboxSessionKey ?? params.sessionKey,
|
|
332
|
+
sessionId: params.sessionId,
|
|
333
|
+
agentId: params.sandboxAgentId ?? params.agentId,
|
|
334
|
+
sandbox,
|
|
335
|
+
surface: "native compaction"
|
|
336
|
+
});
|
|
337
|
+
if (nativeExecutionBlock) return {
|
|
338
|
+
ok: false,
|
|
339
|
+
compacted: false,
|
|
340
|
+
reason: nativeExecutionBlock
|
|
341
|
+
};
|
|
342
|
+
const bindingIdentity = sessionBindingIdentity({
|
|
343
|
+
sessionId: params.sessionId,
|
|
344
|
+
sessionKey: params.sessionKey,
|
|
345
|
+
agentId: params.agentId,
|
|
346
|
+
config: params.config
|
|
347
|
+
});
|
|
348
|
+
const abortedResult = (attempt, expectedThreadId, currentThreadId = expectedThreadId) => options.allowNonManualNativeRequest ? skippedCodexNativeCompactionResult(attempt, {
|
|
349
|
+
reason: "codex app-server compaction aborted before native compaction",
|
|
350
|
+
code: "aborted_before_native_compaction",
|
|
351
|
+
request: options.nativeCompactionRequest ?? "after_context_engine",
|
|
352
|
+
...expectedThreadId ? {
|
|
353
|
+
expectedThreadId,
|
|
354
|
+
currentThreadId
|
|
355
|
+
} : {}
|
|
356
|
+
}) : {
|
|
357
|
+
ok: false,
|
|
358
|
+
compacted: false,
|
|
359
|
+
reason: "codex app-server compaction aborted while waiting to start"
|
|
360
|
+
};
|
|
361
|
+
let resolvedBinding;
|
|
362
|
+
try {
|
|
363
|
+
resolvedBinding = await resolveCodexSessionBinding({
|
|
364
|
+
bindingStore: options.bindingStore,
|
|
365
|
+
identity: bindingIdentity,
|
|
366
|
+
config: params.config,
|
|
367
|
+
storePath: params.sessionTarget?.storePath,
|
|
368
|
+
signal: params.abortSignal
|
|
369
|
+
});
|
|
370
|
+
} catch (error) {
|
|
371
|
+
if (!params.abortSignal?.aborted) throw error;
|
|
372
|
+
return abortedResult(params, options.bindingStore.read(bindingIdentity)?.threadId);
|
|
373
|
+
}
|
|
374
|
+
const { binding: initialBinding, assertCurrent } = resolvedBinding;
|
|
375
|
+
if (!initialBinding?.threadId) return failedCodexThreadBindingCompactionResult(params, {
|
|
376
|
+
reason: "no codex app-server thread binding",
|
|
377
|
+
recovery: "missing_thread_binding"
|
|
378
|
+
});
|
|
379
|
+
if (initialBinding.modelProvider === "openclaw_token_sharing") return {
|
|
380
|
+
ok: false,
|
|
381
|
+
compacted: false,
|
|
382
|
+
reason: "Manual compaction is unavailable with ChatGPT subscription sharing. Automatic compaction runs during normal turns; continue the conversation or start a new session."
|
|
383
|
+
};
|
|
384
|
+
if (params.nativeToolSurface === "host-isolated" || initialBinding.nativeToolPolicyRestricted === true || initialBinding.ringZeroConfigFingerprint !== void 0) return codexNativeCompactionResult(params, {
|
|
385
|
+
compacted: false,
|
|
386
|
+
reason: "native compaction is unavailable for a host-isolated Codex session",
|
|
387
|
+
details: {
|
|
388
|
+
backend: "codex-app-server",
|
|
389
|
+
skipped: true,
|
|
390
|
+
reason: "native_tool_policy_restricted",
|
|
391
|
+
expectedThreadId: initialBinding.threadId
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
let binding = initialBinding;
|
|
395
|
+
const requestedAuthProfileId = params.authProfileId?.trim() || void 0;
|
|
396
|
+
let connection;
|
|
397
|
+
try {
|
|
398
|
+
const config = params.config ?? {};
|
|
399
|
+
connection = await resolveCodexBindingAppServerConnection({
|
|
400
|
+
binding,
|
|
401
|
+
authProfileId: requestedAuthProfileId ?? binding.authProfileId,
|
|
402
|
+
pluginConfig: options.pluginConfig,
|
|
403
|
+
config,
|
|
404
|
+
assertCurrent,
|
|
405
|
+
agentDir: resolveAgentDir(config, bindingIdentity.agentId)
|
|
406
|
+
});
|
|
407
|
+
} catch (error) {
|
|
408
|
+
return {
|
|
409
|
+
ok: false,
|
|
410
|
+
compacted: false,
|
|
411
|
+
reason: coerceErrorMessage(error)
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
const { appServer, usesSupervisionConnection } = connection;
|
|
415
|
+
if (!usesSupervisionConnection && requestedAuthProfileId && binding.authProfileId && binding.authProfileId !== requestedAuthProfileId) return {
|
|
416
|
+
ok: false,
|
|
417
|
+
compacted: false,
|
|
418
|
+
reason: "auth profile mismatch for session binding"
|
|
419
|
+
};
|
|
420
|
+
const shouldReleaseDefaultLease = !options.clientFactory;
|
|
421
|
+
const clientFactory = options.clientFactory ?? createIsolatedCodexAppServerClient;
|
|
422
|
+
const runtimeAuthPlan = usesSupervisionConnection ? void 0 : params.runtimeAuthPlan ?? params.runtimePlan?.auth;
|
|
423
|
+
const usesPreparedApiKey = appServer.start.homeScope !== "user" && runtimeAuthPlan?.modelRoute?.authRequirement === "api-key";
|
|
424
|
+
const preparedApiKey = usesPreparedApiKey ? params.resolvedApiKey?.trim() : void 0;
|
|
425
|
+
if (usesPreparedApiKey && !preparedApiKey) return {
|
|
426
|
+
ok: false,
|
|
427
|
+
compacted: false,
|
|
428
|
+
reason: "Prepared Codex Platform compaction route is missing its resolved API key."
|
|
429
|
+
};
|
|
430
|
+
return await runWithAsyncWorkResources(async (onAcquired) => {
|
|
431
|
+
const modelSource = params.hostCapabilities.retainSourceAuthority();
|
|
432
|
+
let modelSourceTransferred = false;
|
|
433
|
+
onAcquired({
|
|
434
|
+
release: () => {
|
|
435
|
+
if (!modelSourceTransferred) modelSource?.release();
|
|
436
|
+
},
|
|
437
|
+
releaseBeforeResultWhenIdle: true
|
|
438
|
+
});
|
|
439
|
+
const modelCancellation = new AbortController();
|
|
440
|
+
const signals = [
|
|
441
|
+
params.abortSignal,
|
|
442
|
+
modelSource?.signal,
|
|
443
|
+
modelCancellation.signal
|
|
444
|
+
].filter((signal) => signal !== void 0);
|
|
445
|
+
const attempt = {
|
|
446
|
+
...params,
|
|
447
|
+
abortSignal: AbortSignal.any(signals)
|
|
448
|
+
};
|
|
449
|
+
const assertAdmissionCurrent = () => {
|
|
450
|
+
attempt.hostCapabilities.assertActive();
|
|
451
|
+
assertCurrent();
|
|
452
|
+
};
|
|
453
|
+
try {
|
|
454
|
+
return await withCodexAppServerThreadMutationHold(binding.threadId, async (hold, start) => {
|
|
455
|
+
assertAdmissionCurrent();
|
|
456
|
+
const boundClientLease = await retainSharedCodexAppServerClientByInstanceId(binding.clientId);
|
|
457
|
+
if (attempt.abortSignal.aborted) {
|
|
458
|
+
await boundClientLease?.release();
|
|
459
|
+
attempt.abortSignal.throwIfAborted();
|
|
460
|
+
}
|
|
461
|
+
const client = boundClientLease?.client ?? await clientFactory({
|
|
462
|
+
startOptions: appServer.start,
|
|
463
|
+
...preparedApiKey ? { preparedAuth: {
|
|
464
|
+
kind: "api-key",
|
|
465
|
+
apiKey: preparedApiKey
|
|
466
|
+
} } : { authProfileId: connection.clientAuthProfileId },
|
|
467
|
+
authRequirement: runtimeAuthPlan?.modelRoute?.authRequirement,
|
|
468
|
+
agentDir: attempt.agentDir,
|
|
469
|
+
config: attempt.config,
|
|
470
|
+
assertCurrent: assertAdmissionCurrent
|
|
471
|
+
});
|
|
472
|
+
start();
|
|
473
|
+
embeddedAgentLog.info("selected codex app-server compaction client", {
|
|
474
|
+
clientId: client.getInstanceId(),
|
|
475
|
+
recordedOwnerReused: Boolean(boundClientLease),
|
|
476
|
+
threadId: binding.threadId
|
|
477
|
+
});
|
|
478
|
+
let releaseThreadSubscription;
|
|
479
|
+
let retainedThreadOwnership;
|
|
480
|
+
let canRetainThreadOwnership = false;
|
|
481
|
+
let compactionSucceeded = false;
|
|
482
|
+
let temporaryClientExited = true;
|
|
483
|
+
let compactionRequestDefinitelyRejected = false;
|
|
484
|
+
let tokensAfter;
|
|
485
|
+
let modelOwner;
|
|
486
|
+
const releaseCompactionThread = async (threadId) => {
|
|
487
|
+
if (await unsubscribeCodexThreadBestEffort(client, {
|
|
488
|
+
threadId,
|
|
489
|
+
timeoutMs: 5e3
|
|
490
|
+
})) return;
|
|
491
|
+
await closeCodexStartupClientBestEffort(client);
|
|
492
|
+
throw new CodexAppServerUnsafeSubscriptionError(`Codex compaction thread subscription could not be released: ${threadId}`);
|
|
493
|
+
};
|
|
494
|
+
const completionWatch = watchCodexNativeCompactionCompletion({
|
|
495
|
+
client,
|
|
496
|
+
threadId: binding.threadId,
|
|
497
|
+
signal: attempt.abortSignal,
|
|
498
|
+
timeoutMs: options.nativeCompletionTimeoutMs ?? resolveCompactionTimeoutMs(attempt.config),
|
|
499
|
+
interruptGraceMs: options.nativeInterruptGraceMs ?? CODEX_NATIVE_COMPACTION_INTERRUPT_GRACE_MS,
|
|
500
|
+
onCompactionTurn: (turnId) => {
|
|
501
|
+
assertAdmissionCurrent();
|
|
502
|
+
const runtimeModel = attempt.runtimeModel;
|
|
503
|
+
const mapping = !usesSupervisionConnection && attempt.provider && attempt.model && runtimeModel?.provider === attempt.provider && runtimeModel.id === attempt.model ? {
|
|
504
|
+
nativeModel: {
|
|
505
|
+
provider: attempt.provider,
|
|
506
|
+
model: readCodexRuntimeModelId(runtimeModel, attempt.model)
|
|
507
|
+
},
|
|
508
|
+
authorizedModel: {
|
|
509
|
+
provider: attempt.provider,
|
|
510
|
+
model: attempt.model
|
|
511
|
+
}
|
|
512
|
+
} : void 0;
|
|
513
|
+
modelOwner?.bindTurn(turnId, mapping);
|
|
514
|
+
},
|
|
515
|
+
retireUnconfirmed: async () => {
|
|
516
|
+
releaseThreadSubscription = void 0;
|
|
517
|
+
const transportStopped = await client.closeAndWait({
|
|
518
|
+
exitTimeoutMs: 5e3,
|
|
519
|
+
forceKillDelayMs: 250
|
|
520
|
+
});
|
|
521
|
+
temporaryClientExited = transportStopped.exited;
|
|
522
|
+
if (appServer.start.transport === "stdio") {
|
|
523
|
+
if (transportStopped.exited) return;
|
|
524
|
+
throw new Error("failed to stop unconfirmed codex app-server process");
|
|
525
|
+
}
|
|
526
|
+
if (usesSupervisionConnection) throw new Error("cannot detach an unconfirmed supervised codex thread");
|
|
527
|
+
if (await options.bindingStore.mutate(bindingIdentity, {
|
|
528
|
+
kind: "clear",
|
|
529
|
+
threadId: binding.threadId
|
|
530
|
+
}, assertCurrent)) return;
|
|
531
|
+
if (options.bindingStore.read(bindingIdentity)?.threadId !== binding.threadId) return;
|
|
532
|
+
throw new Error("failed to detach unconfirmed codex app-server thread binding");
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
const acquireThreadSubscription = async (timeoutMs) => {
|
|
536
|
+
if (!isIncognitoSessionKey(attempt.sessionKey)) {
|
|
537
|
+
retainedThreadOwnership = await consumeCodexAppServerLiveThread(client, binding.threadId);
|
|
538
|
+
if (!retainedThreadOwnership) {
|
|
539
|
+
const resumed = await resumeCodexAppServerThread({
|
|
540
|
+
client,
|
|
541
|
+
abandonClient: async () => closeCodexStartupClientBestEffort(client),
|
|
542
|
+
request: {
|
|
543
|
+
threadId: binding.threadId,
|
|
544
|
+
excludeTurns: true
|
|
545
|
+
},
|
|
546
|
+
timeoutMs: timeoutMs ?? appServer.requestTimeoutMs,
|
|
547
|
+
assertCurrent,
|
|
548
|
+
signal: attempt.abortSignal
|
|
549
|
+
});
|
|
550
|
+
releaseThreadSubscription = async () => releaseCompactionThread(binding.threadId);
|
|
551
|
+
assertCodexSupervisionThreadLineage(binding, resumed.thread);
|
|
552
|
+
} else if (binding.connectionScope === "supervision") {
|
|
553
|
+
releaseThreadSubscription = async () => retainedThreadOwnership?.release(binding.threadId);
|
|
554
|
+
const { thread } = await client.request("thread/read", {
|
|
555
|
+
threadId: binding.threadId,
|
|
556
|
+
includeTurns: false
|
|
557
|
+
}, { assertCurrent });
|
|
558
|
+
assertCurrent();
|
|
559
|
+
retainedThreadOwnership.assertCurrent();
|
|
560
|
+
assertCodexSupervisionThreadLineage(binding, thread);
|
|
561
|
+
}
|
|
562
|
+
releaseThreadSubscription ??= async () => releaseCompactionThread(binding.threadId);
|
|
563
|
+
}
|
|
564
|
+
};
|
|
565
|
+
try {
|
|
566
|
+
const guardedResult = await options.bindingStore.withLease(bindingIdentity, async () => {
|
|
567
|
+
const currentBinding = options.bindingStore.read(bindingIdentity);
|
|
568
|
+
if (attempt.abortSignal.aborted) {
|
|
569
|
+
if (!options.allowNonManualNativeRequest) attempt.abortSignal.throwIfAborted();
|
|
570
|
+
return {
|
|
571
|
+
started: false,
|
|
572
|
+
result: skippedCodexNativeCompactionResult(attempt, {
|
|
573
|
+
reason: "codex app-server compaction aborted before native compaction",
|
|
574
|
+
code: "aborted_before_native_compaction",
|
|
575
|
+
request: options.nativeCompactionRequest ?? "after_context_engine",
|
|
576
|
+
expectedThreadId: binding.threadId,
|
|
577
|
+
currentThreadId: currentBinding?.threadId
|
|
578
|
+
})
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
assertCurrent();
|
|
582
|
+
if (!currentBinding || !isSameNativeCompactionBinding(currentBinding, binding)) {
|
|
583
|
+
embeddedAgentLog.warn("codex app-server compaction could not use the thread binding because it changed", {
|
|
584
|
+
sessionId: attempt.sessionId,
|
|
585
|
+
sessionKey: attempt.sessionKey,
|
|
586
|
+
expectedThreadId: binding.threadId,
|
|
587
|
+
currentThreadId: currentBinding?.threadId
|
|
588
|
+
});
|
|
589
|
+
const isRequiredPreflight = options.nativeCompactionRequest === "required_preflight";
|
|
590
|
+
return {
|
|
591
|
+
started: false,
|
|
592
|
+
result: options.allowNonManualNativeRequest && !isRequiredPreflight ? skippedCodexNativeCompactionResult(attempt, {
|
|
593
|
+
reason: "codex app-server binding changed before native compaction",
|
|
594
|
+
code: "binding_changed_before_native_compaction",
|
|
595
|
+
request: options.nativeCompactionRequest ?? "after_context_engine",
|
|
596
|
+
expectedThreadId: binding.threadId,
|
|
597
|
+
currentThreadId: currentBinding?.threadId
|
|
598
|
+
}) : failedCodexThreadBindingCompactionResult(attempt, {
|
|
599
|
+
threadId: currentBinding?.threadId ?? binding.threadId,
|
|
600
|
+
reason: "codex app-server binding changed before native compaction",
|
|
601
|
+
recovery: "stale_thread_binding"
|
|
602
|
+
})
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
binding = currentBinding;
|
|
606
|
+
const guardedRequestTimeoutMs = options.allowNonManualNativeRequest ? Math.min(appServer.requestTimeoutMs, CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS) : void 0;
|
|
607
|
+
assertAdmissionCurrent();
|
|
608
|
+
await acquireThreadSubscription(guardedRequestTimeoutMs);
|
|
609
|
+
canRetainThreadOwnership = true;
|
|
610
|
+
attempt.abortSignal.throwIfAborted();
|
|
611
|
+
const configurationQualification = getCodexInferenceThreadQualification(client, binding.threadId);
|
|
612
|
+
modelOwner = await codexNativeSubagentMonitorRuntime.register({
|
|
613
|
+
client,
|
|
614
|
+
parentThreadId: binding.threadId,
|
|
615
|
+
modelSource,
|
|
616
|
+
configurationQualification,
|
|
617
|
+
unqualifiedModelExecution: modelSource && !configurationQualification ? true : void 0,
|
|
618
|
+
onUnqualifiedModelCancelled: (reason) => modelCancellation.abort(reason),
|
|
619
|
+
requesterSessionKey: attempt.sessionKey,
|
|
620
|
+
agentId: bindingIdentity.agentId,
|
|
621
|
+
assertCurrent: assertAdmissionCurrent,
|
|
622
|
+
retainClient: () => retainSharedCodexAppServerClientIfCurrent(client),
|
|
623
|
+
retainParentThread: (threadId) => protectCodexAppServerLiveThread(client, threadId)
|
|
624
|
+
});
|
|
625
|
+
modelSourceTransferred = true;
|
|
626
|
+
assertAdmissionCurrent();
|
|
627
|
+
attempt.abortSignal.throwIfAborted();
|
|
628
|
+
await clearContextEngineProjectionBeforeNativeCompaction({
|
|
629
|
+
sessionId: attempt.sessionId,
|
|
630
|
+
bindingStore: options.bindingStore,
|
|
631
|
+
identity: bindingIdentity,
|
|
632
|
+
binding,
|
|
633
|
+
assertCurrent: assertAdmissionCurrent
|
|
634
|
+
});
|
|
635
|
+
assertAdmissionCurrent();
|
|
636
|
+
try {
|
|
637
|
+
canRetainThreadOwnership = false;
|
|
638
|
+
completionWatch.beginRequest();
|
|
639
|
+
await client.request("thread/compact/start", { threadId: binding.threadId }, {
|
|
640
|
+
...guardedRequestTimeoutMs === void 0 ? {} : { timeoutMs: guardedRequestTimeoutMs },
|
|
641
|
+
signal: attempt.abortSignal,
|
|
642
|
+
assertCurrent: () => {
|
|
643
|
+
try {
|
|
644
|
+
assertAdmissionCurrent();
|
|
645
|
+
} catch (error) {
|
|
646
|
+
compactionRequestDefinitelyRejected = true;
|
|
647
|
+
throw error;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
});
|
|
651
|
+
return {
|
|
652
|
+
started: true,
|
|
653
|
+
accepted: true
|
|
654
|
+
};
|
|
655
|
+
} catch (error) {
|
|
656
|
+
compactionRequestDefinitelyRejected ||= isCodexAppServerPrewriteRequestCancellationError(error) || error instanceof CodexAppServerRpcError;
|
|
657
|
+
if (compactionRequestDefinitelyRejected) {
|
|
658
|
+
canRetainThreadOwnership = !isCodexThreadNotFoundError(error);
|
|
659
|
+
completionWatch.confirmRequestRejected();
|
|
660
|
+
if (error instanceof CodexAppServerRpcError || binding.contextEngine?.projection) await options.bindingStore.mutate(bindingIdentity, {
|
|
661
|
+
kind: "set",
|
|
662
|
+
binding
|
|
663
|
+
}, assertCurrent);
|
|
664
|
+
}
|
|
665
|
+
return {
|
|
666
|
+
started: true,
|
|
667
|
+
accepted: false,
|
|
668
|
+
error
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
});
|
|
672
|
+
if (!guardedResult.started) return guardedResult.result;
|
|
673
|
+
if (!guardedResult.accepted) {
|
|
674
|
+
if (compactionRequestDefinitelyRejected) throw guardedResult.error;
|
|
675
|
+
if (!attempt.abortSignal.aborted || !isCodexAppServerIndeterminateRequestCancellationError(guardedResult.error)) {
|
|
676
|
+
await completionWatch.retireUnconfirmedRequest(`codex app-server compaction start was unconfirmed: ${coerceErrorMessage(guardedResult.error)}`);
|
|
677
|
+
throw guardedResult.error;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
embeddedAgentLog.info("waiting for codex app-server compaction completion", {
|
|
681
|
+
sessionId: attempt.sessionId,
|
|
682
|
+
threadId: binding.threadId
|
|
683
|
+
});
|
|
684
|
+
const completion = await completionWatch.completion;
|
|
685
|
+
assertCurrent();
|
|
686
|
+
if (!completion.completed) throw new Error(completion.reason);
|
|
687
|
+
compactionSucceeded = true;
|
|
688
|
+
tokensAfter = completion.tokensAfter;
|
|
689
|
+
if (completion.turnId && completion.itemId) await persistCodexContextCompactionActivity({
|
|
690
|
+
sessionTarget: attempt.sessionTarget,
|
|
691
|
+
config: attempt.config,
|
|
692
|
+
cwd: attempt.workspaceDir,
|
|
693
|
+
runId: attempt.runId,
|
|
694
|
+
threadId: binding.threadId,
|
|
695
|
+
turnId: completion.turnId,
|
|
696
|
+
itemId: completion.itemId,
|
|
697
|
+
timestamp: Date.now()
|
|
698
|
+
});
|
|
699
|
+
assertCurrent();
|
|
700
|
+
embeddedAgentLog.info("completed codex app-server compaction", {
|
|
701
|
+
sessionId: attempt.sessionId,
|
|
702
|
+
threadId: binding.threadId
|
|
703
|
+
});
|
|
704
|
+
canRetainThreadOwnership = true;
|
|
705
|
+
} catch (error) {
|
|
706
|
+
if (isCodexThreadNotFoundError(error)) return failedCodexThreadBindingCompactionResult(attempt, {
|
|
707
|
+
threadId: binding.threadId,
|
|
708
|
+
reason: coerceErrorMessage(error),
|
|
709
|
+
recovery: "stale_thread_binding"
|
|
710
|
+
});
|
|
711
|
+
embeddedAgentLog.warn("codex app-server compaction failed", {
|
|
712
|
+
sessionId: attempt.sessionId,
|
|
713
|
+
sessionKey: attempt.sessionKey,
|
|
714
|
+
threadId: binding.threadId,
|
|
715
|
+
reason: coerceErrorMessage(error)
|
|
716
|
+
});
|
|
717
|
+
return {
|
|
718
|
+
ok: false,
|
|
719
|
+
compacted: false,
|
|
720
|
+
reason: coerceErrorMessage(error)
|
|
721
|
+
};
|
|
722
|
+
} finally {
|
|
723
|
+
completionWatch.cancel();
|
|
724
|
+
try {
|
|
725
|
+
if (compactionSucceeded) revertCodexAppServerLiveThreadSkillsCatalog(client, binding.threadId);
|
|
726
|
+
if (canRetainThreadOwnership && retainedThreadOwnership) {
|
|
727
|
+
const ownership = retainedThreadOwnership;
|
|
728
|
+
const currentBinding = options.bindingStore.read(bindingIdentity);
|
|
729
|
+
if (!(isSameCodexAppServerThreadOwner(currentBinding, binding) && await options.bindingStore.withLease(bindingIdentity, async () => {
|
|
730
|
+
const leasedBinding = options.bindingStore.read(bindingIdentity);
|
|
731
|
+
if (!isSameCodexAppServerThreadOwner(leasedBinding, binding)) return false;
|
|
732
|
+
return await retainCodexAppServerLiveThread(client, binding.threadId, ownership.release, ownership.configFingerprint, ownership.serviceTier, ownership.ephemeralPolicy && compactionSucceeded ? {
|
|
733
|
+
...ownership.ephemeralPolicy,
|
|
734
|
+
skillsInstructions: ownership.ephemeralPolicy.nativeSkillsInstructions
|
|
735
|
+
} : ownership.ephemeralPolicy);
|
|
736
|
+
}))) await releaseThreadSubscription?.();
|
|
737
|
+
} else await releaseThreadSubscription?.();
|
|
738
|
+
} finally {
|
|
739
|
+
try {
|
|
740
|
+
await modelOwner?.unregister();
|
|
741
|
+
} finally {
|
|
742
|
+
const ownerExit = boundClientLease?.release();
|
|
743
|
+
if (ownerExit && appServer.start.transport === "stdio") hold(ownerExit);
|
|
744
|
+
else if (!boundClientLease && shouldReleaseDefaultLease) {
|
|
745
|
+
if (appServer.start.transport === "stdio") hold(waitForCodexAppServerClientExit(client));
|
|
746
|
+
temporaryClientExited = temporaryClientExited && (await client.closeAndWait()).exited;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
if (!temporaryClientExited) throw new CodexAppServerUnsafeSubscriptionError(`Codex compaction client did not exit: ${binding.threadId}`);
|
|
752
|
+
const details = {
|
|
753
|
+
backend: "codex-app-server",
|
|
754
|
+
threadId: binding.threadId,
|
|
755
|
+
signal: "thread/compact/start",
|
|
756
|
+
pending: false,
|
|
757
|
+
completed: true,
|
|
758
|
+
...options.allowNonManualNativeRequest ? {
|
|
759
|
+
request: options.nativeCompactionRequest ?? "after_context_engine",
|
|
760
|
+
trigger: attempt.trigger ?? "unknown"
|
|
761
|
+
} : {}
|
|
762
|
+
};
|
|
763
|
+
return codexNativeCompactionResult(attempt, {
|
|
764
|
+
compacted: true,
|
|
765
|
+
tokensAfter,
|
|
766
|
+
details
|
|
767
|
+
});
|
|
768
|
+
}, attempt.abortSignal);
|
|
769
|
+
} catch (error) {
|
|
770
|
+
if (attempt.abortSignal.aborted) return abortedResult(attempt, initialBinding.threadId, binding.threadId);
|
|
771
|
+
throw error;
|
|
772
|
+
}
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
//#endregion
|
|
776
|
+
export { maybeCompactCodexAppServerSession };
|