@openclaw/codex 2026.10.1-beta.2 → 2026.10.5-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.setup/{account-usage-runtime-DGqFpAud.mjs → account-usage-runtime-QBZsvZS8.mjs} +8 -7
- package/dist/.setup/{app-server-policy-Bg4FZw1f.mjs → app-server-policy-D_zv8J7V.mjs} +3 -4
- package/dist/.setup/{apply-CXTudl9p.mjs → apply-CBMV8LN0.mjs} +40 -51
- package/dist/.setup/{attempt-client-cleanup-BH0hW2xU.mjs → attempt-client-cleanup-t-kd_1ys.mjs} +6 -6
- package/dist/.setup/attempt-terminal-jO5IMj9K.mjs +2 -0
- package/dist/.setup/{attempt-workspace-context-BY0jprWJ.mjs → attempt-workspace-context-CcwP3DA3.mjs} +21 -18
- package/dist/.setup/{auth-binding-BoMwpuPN.mjs → auth-binding-BaxlhaNx.mjs} +2 -2
- package/dist/.setup/{auth-cache-key-CGm0UJOr.mjs → auth-cache-key-DyfUvsSa.mjs} +30 -41
- package/dist/.setup/{binding-connection-C-08ez1w.mjs → binding-connection-B7HAAZSI.mjs} +2 -2
- package/dist/.setup/{binding-connection.runtime-Dn2p-fdy.mjs → binding-connection.runtime-DAXn7iFl.mjs} +6 -5
- package/dist/.setup/{bounded-turn-pGsfXcmH.mjs → bounded-turn-CyQVQwGe.mjs} +21 -17
- package/dist/.setup/{bounded-turn-isolation-DklXNk3k.mjs → bounded-turn-isolation-BfDAo-qZ.mjs} +4 -4
- package/dist/.setup/{build-state-CqQnsg7T.mjs → build-state-CzLMy1S9.mjs} +1 -1
- package/dist/.setup/{capabilities-kQntafj_.mjs → capabilities-DbOzOglY.mjs} +1 -1
- package/dist/.setup/{client-catalog-response-Bqp7WG51.mjs → client-catalog-response-DsbEAtpd.mjs} +25 -32
- package/dist/.setup/{client-C8lgBOoO.mjs → client-y7nO6X9c.mjs} +198 -247
- package/dist/.setup/{command-dispatch-DhBbFIQ5.mjs → command-dispatch-uA9lz2Kf.mjs} +3 -4
- package/dist/.setup/{command-formatters-DV3DHhdr.mjs → command-formatters-xW9KpoSZ.mjs} +16 -26
- package/dist/.setup/{command-handlers-ztOOzm6O.mjs → command-handlers-VBaJnpZo.mjs} +270 -360
- package/dist/.setup/{command-rpc-CuC5fPom.mjs → command-rpc-C9VxOLuG.mjs} +19 -18
- package/dist/.setup/{compact-tUb9AYfH.mjs → compact-CD8xJxXS.mjs} +41 -61
- package/dist/.setup/{computer-use-BBN9y326.mjs → computer-use-CiToXF5C.mjs} +109 -147
- package/dist/.setup/{config-0Gxk3_eq.mjs → config-C1YVVLEA.mjs} +32 -59
- package/dist/.setup/config-contracts.shared-D85SGEuq.mjs +4 -0
- package/dist/.setup/{config-options-HG_Rr3W_.mjs → config-options-DDzeNQ8m.mjs} +52 -90
- package/dist/.setup/{config-parsing-BQq-CHTF.mjs → config-parsing-DsWSCPHO.mjs} +19 -55
- package/dist/.setup/{config-runtime-cUYrqu_a.mjs → config-runtime-DWzK-k0n.mjs} +2 -2
- package/dist/.setup/{config-security-KAPScztc.mjs → config-security-clxAZYWX.mjs} +35 -39
- package/dist/.setup/config-utils-DN_YT7dE.mjs +47 -0
- package/dist/.setup/{context-engine-projection-CsgYSQhW.mjs → context-engine-projection-ps-yn_ci.mjs} +10 -22
- package/dist/.setup/{conversation-binding-B3MNMVzb.mjs → conversation-binding-CTSLDM9S.mjs} +85 -119
- package/dist/.setup/{conversation-binding-data-DJ4ix-W5.mjs → conversation-binding-data-UgLuTSQT.mjs} +9 -8
- package/dist/.setup/{conversation-control-CYsMlCuE.mjs → conversation-control-GXM3unE4.mjs} +7 -10
- package/dist/.setup/{cyber-failover-Bb1J6hS1.mjs → cyber-failover-D4dgNfFf.mjs} +2 -5
- package/dist/.setup/{cyber-failover-notice-XR03ef31.mjs → cyber-failover-notice-ljgGGL0s.mjs} +1 -1
- package/dist/.setup/{doctor-start-options-DPW9JxIE.mjs → doctor-start-options-JjTAl-q_.mjs} +5 -5
- package/dist/.setup/{dynamic-tool-build-C8xGEXmR.mjs → dynamic-tool-build-D731PCdv.mjs} +57 -69
- package/dist/.setup/{dynamic-tools-DyERJnR6.mjs → dynamic-tools-D0pYbxHH.mjs} +689 -710
- package/dist/.setup/{effective-mcp-catalog-C26Mio5l.mjs → effective-mcp-catalog-1hWFKghy.mjs} +11 -20
- package/dist/.setup/{elicitation-input-r9axtppm.mjs → elicitation-input-DXG_qaXr.mjs} +14 -20
- package/dist/.setup/{ephemeral-turn-D8VcDTNo.mjs → ephemeral-turn-Cphy5Qr_.mjs} +3 -3
- package/dist/.setup/{event-projector-assistant-message-BN7CNUB5.mjs → event-projector-assistant-message-CLMKN4x-.mjs} +2 -2
- package/dist/.setup/{event-projector-usage-03R0I2dM.mjs → event-projector-usage-BpKfdoTm.mjs} +20 -33
- package/dist/.setup/{event-projector-values-DTqZHizf.mjs → event-projector-values-CLvG1Hil.mjs} +4 -5
- package/dist/.setup/history-rejection-B4nOXNXF.mjs +13 -0
- package/dist/.setup/{inference-context-D-9gWlTR.mjs → inference-context-DNlGwzwy.mjs} +10 -11
- package/dist/.setup/{inference-dispatch-B5UKEUyC.mjs → inference-dispatch-CO6tTs4q.mjs} +5 -4
- package/dist/.setup/{inference-metadata-CgIf7sOx.mjs → inference-metadata-DCvcG_N_.mjs} +36 -41
- package/dist/.setup/{inference-proxy-DUO5E2QQ.mjs → inference-proxy-BDWV0djM.mjs} +10 -14
- package/dist/.setup/{isolated-completion-C0jrcplS.mjs → isolated-completion-Bhqd2yBq.mjs} +8 -8
- package/dist/.setup/local-runtime-attribution-CZz2DJ4q.mjs +15 -0
- package/dist/.setup/{managed-binary-C1VFoVPf.mjs → managed-binary-BtIjV7yN.mjs} +16 -36
- package/dist/.setup/{mcp-app-session-preparation-BxN0_CYe.mjs → mcp-app-session-preparation-DqSvxFqc.mjs} +24 -25
- package/dist/.setup/{mcp-tool-metadata-j10HhfTC.mjs → mcp-tool-metadata-DW41snf3.mjs} +1 -1
- package/dist/.setup/{model-catalog-DZyNeDKG.mjs → model-catalog-B227ST3D.mjs} +6 -6
- package/dist/.setup/{models-DSseKSMg.mjs → models-DdRyi93L.mjs} +6 -10
- package/dist/.setup/{native-auth-Cjb9y7IZ.mjs → native-auth-esN5MdIv.mjs} +5 -5
- package/dist/.setup/{native-execution-policy-ClzpdG3D.mjs → native-execution-policy-MXEe7PB3.mjs} +11 -28
- package/dist/.setup/native-hook-relay-BUWIOrSr.mjs +561 -0
- package/dist/.setup/{native-mcp-app-CqcPVmhH.mjs → native-mcp-app-CjxJQ4F7.mjs} +6 -6
- package/dist/.setup/native-skill-isolation-UMVoNjZz.mjs +391 -0
- package/dist/.setup/{native-subagent-monitor-BUYOUp9X.mjs → native-subagent-monitor-iHc8oLg5.mjs} +505 -639
- package/dist/.setup/{native-subagent-pending-assignments-BDqhOdJp.mjs → native-subagent-pending-assignments-DmVhedNs.mjs} +11 -23
- package/dist/.setup/{native-task-assignments-C6KVqiN1.mjs → native-task-assignments-DimsQ9Qa.mjs} +73 -27
- package/dist/.setup/{node-cli-sessions-B5oNDkUS.mjs → node-cli-sessions-CzKg2nGq.mjs} +18 -26
- package/dist/.setup/{node-exec-server.runtime-0xSEjKYt.mjs → node-exec-server.runtime-BWkULhBM.mjs} +5 -8
- package/dist/.setup/{plan-BJ37d2Og.mjs → plan-C_F3aio0.mjs} +40 -50
- package/dist/.setup/{plugin-activation-BcyBv8PG.mjs → plugin-activation-D7WkJMvU.mjs} +4 -5
- package/dist/.setup/{plugin-app-cache-key-BW8rd98k.mjs → plugin-app-cache-key-Bg9DbDI6.mjs} +18 -23
- package/dist/.setup/{plugin-approval-roundtrip-CuahdPLC.mjs → plugin-approval-roundtrip-BSV-51ig.mjs} +4 -6
- package/dist/.setup/{plugin-inventory-Bf0_piTw.mjs → plugin-inventory-CYgdo14P.mjs} +28 -43
- package/dist/.setup/{plugin-marketplace-discovery-SQPhSuic.mjs → plugin-marketplace-discovery-BblHM3DU.mjs} +7 -10
- package/dist/.setup/{plugin-metadata-cache-DWnB7VMj.mjs → plugin-metadata-cache-Bi8TAPwX.mjs} +5 -10
- package/dist/.setup/project-doc-thread-config-BVcvnps8.mjs +490 -0
- package/dist/.setup/{provider-BnwHVD_z.mjs → provider-BJ4xhaGX.mjs} +4 -4
- package/dist/.setup/{provider-capabilities-D68Whix6.mjs → provider-capabilities-CjRaV3bx.mjs} +1 -1
- package/dist/.setup/{rate-limits-CMPy24F5.mjs → rate-limits-CI8pTPqL.mjs} +15 -32
- package/dist/.setup/reasoning-effort-CS9kKWB9.mjs +37 -0
- package/dist/.setup/{request-jSbhc1sg.mjs → request-Y8dmbqZ3.mjs} +28 -48
- package/dist/.setup/{rpc-error-hmWM21RB.mjs → rpc-error-C98SHchT.mjs} +3 -6
- package/dist/.setup/{run-attempt-BLDZeYLD.mjs → run-attempt-Dx7a4Mfm.mjs} +927 -849
- package/dist/.setup/{run-attempt-lifecycle-BuZgVbDA.mjs → run-attempt-lifecycle-KN4oh-7O.mjs} +13 -4
- package/dist/.setup/{runtime-artifact-CUTOOnKw.mjs → runtime-artifact-C13pR7tD.mjs} +18 -22
- package/dist/.setup/{runtime-artifact-connection-CADz3_BY.mjs → runtime-artifact-connection-jS5DeCok.mjs} +3 -3
- package/dist/.setup/{sandbox-guard-WqE8yPge.mjs → sandbox-guard-DIImwCy1.mjs} +4 -6
- package/dist/.setup/service-tier-normalization-BPgw2Wdt.mjs +9 -0
- package/dist/.setup/{session-binding-Ce7BqiPN.mjs → session-binding-JEHNMPsr.mjs} +13 -40
- package/dist/.setup/{session-binding-record-BZB8RgcF.mjs → session-binding-record-DU_0biMD.mjs} +4 -4
- package/dist/.setup/{session-binding-record-codec-z4ZpDn6E.mjs → session-binding-record-codec-BpH8u_G9.mjs} +16 -39
- package/dist/.setup/{session-binding-sidecars-BrdV95Fg.mjs → session-binding-sidecars-DD-enC8w.mjs} +49 -54
- package/dist/.setup/{session-catalog-adoption-CPIP4S_y.mjs → session-catalog-adoption-Ca3OYGYM.mjs} +23 -27
- package/dist/.setup/{session-catalog-archive-DcgwvSbF.mjs → session-catalog-archive-Bv6gV7x9.mjs} +6 -6
- package/dist/.setup/{session-catalog-events-Bdjw9HEn.mjs → session-catalog-events-DzFlXNUe.mjs} +6 -5
- package/dist/.setup/{session-catalog-index-DufISKJ6.mjs → session-catalog-index-DozvkUPd.mjs} +111 -105
- package/dist/.setup/{session-catalog-index-order-nhyO0wdW.mjs → session-catalog-index-order-CTfoefow.mjs} +28 -5
- package/dist/.setup/{session-catalog-limits-DEU36Qlo.mjs → session-catalog-limits-BynIoOYm.mjs} +1 -1
- package/dist/.setup/{session-catalog-list-request-tXephOB4.mjs → session-catalog-list-request-D4MYNgDB.mjs} +11 -8
- package/dist/.setup/{session-catalog-native-projection-D6IiLtMb.mjs → session-catalog-native-projection-rCKnZud1.mjs} +5 -61
- package/dist/.setup/{session-catalog-node-adoption-7-WEQTB1.mjs → session-catalog-node-adoption-BdP9Zjqo.mjs} +2 -2
- package/dist/.setup/{session-catalog-node-continue-DLWBwAAO.mjs → session-catalog-node-continue-CNJibO4_.mjs} +27 -49
- package/dist/.setup/{session-catalog-node-lookup-Uufckwcm.mjs → session-catalog-node-lookup-BH_DBGa9.mjs} +3 -3
- package/dist/.setup/{session-catalog-parsing-B-qWJh2x.mjs → session-catalog-parsing-DkeoVn60.mjs} +9 -19
- package/dist/.setup/{session-catalog-projection-8aHNwzWD.mjs → session-catalog-projection-DDVmALHj.mjs} +8 -22
- package/dist/.setup/session-catalog-source-CygTGmrb.mjs +58 -0
- package/dist/.setup/{session-cli-kH4vuGod.mjs → session-cli-GwU0izn-.mjs} +20 -41
- package/dist/.setup/{session-history-BogBHKLk.mjs → session-history-BO6i_pfk.mjs} +1 -1
- package/dist/.setup/{session-history-import-NWKPa4ZO.mjs → session-history-import-CaO8s6ta.mjs} +4 -4
- package/dist/.setup/{session-history-read-CNN8zwbD.mjs → session-history-read-BI_2jRED.mjs} +4 -15
- package/dist/.setup/{session-history.worker-Cq_4DYgN.mjs → session-history.worker-DJQfek5p.mjs} +147 -159
- package/dist/.setup/{session-initialization-D6dtFQkE.mjs → session-initialization-Bi_2DKhc.mjs} +3 -5
- package/dist/.setup/{session-permission-policy-BxIUJ0Zd.mjs → session-permission-policy-CD2MAWU8.mjs} +12 -20
- package/dist/.setup/{session-retirement-Czbchv_O.mjs → session-retirement-IoS3zr17.mjs} +7 -7
- package/dist/.setup/{settled-turn-context-BZsMjkIO.mjs → settled-turn-context-BPL6D3RO.mjs} +1 -1
- package/dist/.setup/{settled-turn-finalizer-DjZsIwbZ.mjs → settled-turn-finalizer-X-Fylp-u.mjs} +12 -11
- package/dist/.setup/{shared-client-qhyYWbew.mjs → shared-client-ByIwuAC-.mjs} +172 -229
- package/dist/.setup/{side-question-D3NJlgbl.mjs → side-question-BDUdozFy.mjs} +116 -137
- package/dist/.setup/{source-BYu0T780.mjs → source-Bxbqf3S1.mjs} +37 -56
- package/dist/.setup/thread-archive-guard-LKdwQKyr.mjs +56 -0
- package/dist/.setup/{thread-lifecycle-Cbz_7ySv.mjs → thread-lifecycle-run-CfP4PnEf.mjs} +348 -484
- package/dist/.setup/thread-model-selection-DcVebr8N.mjs +61 -0
- package/dist/.setup/{thread-ownership-DwuSrt3s.mjs → thread-ownership-Be53aiaG.mjs} +5 -5
- package/dist/.setup/{thread-ownership-queue-Dp24d7-F.mjs → thread-ownership-queue-CeyYScUC.mjs} +5 -6
- package/dist/.setup/{thread-policy-DoNxbhqt.mjs → thread-policy-CHgY-KNl.mjs} +4 -4
- package/dist/.setup/thread-requests-BgzJwJtS.mjs +745 -0
- package/dist/.setup/{thread-resume-BT6NHMkM.mjs → thread-resume-B2EmMcgE.mjs} +5 -5
- package/dist/.setup/{timeout-CXOfNoaX.mjs → timeout-D0mEWSGG.mjs} +6 -12
- package/dist/.setup/{transcript-history-projection-B9a7HwUV.mjs → transcript-history-projection-DfKcoZCB.mjs} +3 -4
- package/dist/.setup/{transcript-mirror-BfLRARNL.mjs → transcript-mirror-Bee2o6jj.mjs} +68 -68
- package/dist/.setup/{transcript-mirror-attestation-YSegaktH.mjs → transcript-mirror-attestation-BzUXnrvv.mjs} +5 -2
- package/dist/.setup/{transport-stdio-a0HDa2Mj.mjs → transport-stdio-CRWTkKOn.mjs} +67 -77
- package/dist/.setup/{transport-websocket-zqJ0Cmtn.mjs → transport-websocket-DIyPfkHo.mjs} +8 -16
- package/dist/.setup/{turn-router-sS69wYnI.mjs → turn-router-DKDAziUW.mjs} +30 -31
- package/dist/.setup/upstream-prompt-provenance-Ccd9MFRJ.mjs +44 -0
- package/dist/.setup/{upstream-session-fork-ChSld66u.mjs → upstream-session-fork-Djp_yssT.mjs} +50 -43
- package/dist/.setup/{usage-D8e8Xiqf.mjs → usage-DQA-peQC.mjs} +4 -4
- package/dist/.setup/{usage-limit-error-GbT-5NcW.mjs → usage-limit-error-2t3KBqiX.mjs} +12 -21
- package/dist/.setup/web-search-item-CvokaZOo.mjs +20 -0
- package/dist/.setup/{web-search-provider.runtime-dL2GD1Kl.mjs → web-search-provider.runtime-BsuCMNix.mjs} +3 -3
- package/dist/.setup/{workspace-write-sandbox-probe-DmUHLrrl.mjs → workspace-write-sandbox-probe-BDWO2Qkh.mjs} +4 -4
- package/dist/api.js +15 -15
- package/dist/catalog-page.worker.js +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/doctor-contract-api.js +5 -6
- package/dist/harness.js +32 -61
- package/dist/index.js +302 -416
- package/dist/media-understanding-provider.js +32 -43
- package/dist/migration-provider-api.js +1 -1
- package/dist/native-session-binding-api.js +1 -1
- package/dist/native-tool-policy.js +23 -1
- package/dist/provider-discovery.js +1 -1
- package/dist/session-history-worker-runtime.js +52 -31
- package/dist/session-history.worker.js +1 -1
- package/openclaw.plugin.json +20 -3
- package/package.json +7 -7
- package/dist/.setup/attempt-terminal-gZrxQ35N.mjs +0 -5
- package/dist/.setup/plugin-thread-config-deadline-B8LGaZNW.mjs +0 -124
- package/dist/.setup/service-tier-normalization-Cei89SW6.mjs +0 -15
- package/dist/.setup/shell-dynamic-tools-D3Brj3g9.mjs +0 -85
- package/dist/.setup/thread-archive-guard-C9frICzX.mjs +0 -60
- package/dist/.setup/thread-requests-CL1e8Wmx.mjs +0 -2111
- package/dist/.setup/upstream-prompt-provenance-fXkKbPVC.mjs +0 -37
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
|
|
2
|
+
import { l as fingerprintCodexPolicy } from "./config-security-clxAZYWX.mjs";
|
|
3
|
+
import { f as resolveCodexPluginsPolicy } from "./config-parsing-DsWSCPHO.mjs";
|
|
4
|
+
import { u as CODEX_SESSION_OVERRIDABLE_LAYER_TYPES } from "./config-options-DDzeNQ8m.mjs";
|
|
5
|
+
import { a as defaultCodexAppInventoryCache, i as CodexAppInventoryCache, o as serializeCodexAppInventoryError, s as codexAppIdentityKey } from "./plugin-app-cache-key-Bg9DbDI6.mjs";
|
|
6
|
+
import { l as toCodexPluginOwnedAccountApp, s as readCodexPluginInventory, t as createCodexAppInventoryRequest } from "./plugin-inventory-CYgdo14P.mjs";
|
|
7
|
+
import "./config-C1YVVLEA.mjs";
|
|
8
|
+
import { t as ensureCodexPluginActivation } from "./plugin-activation-D7WkJMvU.mjs";
|
|
9
|
+
import { embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
10
|
+
//#region extensions/codex/src/app-server/plugin-app-approval-overrides.ts
|
|
11
|
+
/** Projects ask approvals into the native session layer without changing saved settings. */
|
|
12
|
+
function buildCodexAppApprovalOverrides(config, app) {
|
|
13
|
+
const appsRoot = config.apps;
|
|
14
|
+
const appConfig = isJsonObject(appsRoot) ? appsRoot[app.id] : void 0;
|
|
15
|
+
if (!isJsonObject(appConfig)) return {};
|
|
16
|
+
const overrides = {};
|
|
17
|
+
const keys = app.approvalOverrideToolConfigKeys;
|
|
18
|
+
for (const [section, fields] of [["tools", { approval_mode: "auto" }], ["links", {
|
|
19
|
+
approvals_reviewer: "user",
|
|
20
|
+
default_tools_approval_mode: "auto"
|
|
21
|
+
}]]) {
|
|
22
|
+
const entries = appConfig[section];
|
|
23
|
+
if (!isJsonObject(entries)) continue;
|
|
24
|
+
const projected = Object.entries(entries).toSorted(([left], [right]) => left.localeCompare(right)).filter(([name, value]) => isJsonObject(value) && (section !== "tools" || !keys || keys.includes(name)) && Object.keys(fields).some((field) => value[field] !== void 0 && value[field] !== null)).map(([name]) => [name, fields]);
|
|
25
|
+
if (projected.length > 0) overrides[section] = Object.fromEntries(projected);
|
|
26
|
+
}
|
|
27
|
+
return overrides;
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region extensions/codex/src/app-server/plugin-thread-app-admission.ts
|
|
31
|
+
function resolveCodexPluginThreadAppCacheKey(params) {
|
|
32
|
+
return params.threadId ? `${params.appCacheKey}:thread:${encodeURIComponent(params.threadId)}` : params.appCacheKey;
|
|
33
|
+
}
|
|
34
|
+
async function refreshCodexPluginAppInventory(params, appCache, options = {}) {
|
|
35
|
+
if (!params.appCacheKey) return;
|
|
36
|
+
const request = createCodexAppInventoryRequest(params);
|
|
37
|
+
try {
|
|
38
|
+
return await appCache.refreshNow({
|
|
39
|
+
key: resolveCodexPluginThreadAppCacheKey(params),
|
|
40
|
+
request,
|
|
41
|
+
nowMs: params.nowMs,
|
|
42
|
+
forceRefetch: options.forceRefetch,
|
|
43
|
+
targetAppIds: options.targetAppIds
|
|
44
|
+
});
|
|
45
|
+
} catch (error) {
|
|
46
|
+
embeddedAgentLog.warn("codex plugin thread config app inventory refresh failed", {
|
|
47
|
+
reason: options.reason,
|
|
48
|
+
forceRefetch: options.forceRefetch === true,
|
|
49
|
+
error: serializeCodexAppInventoryError(error)
|
|
50
|
+
});
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function collectCodexPluginOwnedAppIds(inventory) {
|
|
55
|
+
return Array.from(new Set(inventory.records.flatMap((record) => record.ownedAppIds).filter(Boolean))).toSorted();
|
|
56
|
+
}
|
|
57
|
+
function collectCodexReservedPluginAppIds(params) {
|
|
58
|
+
const reserved = new Set(params.inventory.records.flatMap((record) => record.appOwnership === "proven" ? record.ownedAppIds : []).map(codexAppIdentityKey));
|
|
59
|
+
const recordsByConfigKey = new Map(params.inventory.records.map((record) => [record.policy.configKey, record]));
|
|
60
|
+
const configuredOwnerNames = new Set(params.policy.pluginPolicies.flatMap((policy) => {
|
|
61
|
+
const record = recordsByConfigKey.get(policy.configKey);
|
|
62
|
+
return [
|
|
63
|
+
policy.configKey,
|
|
64
|
+
policy.pluginName,
|
|
65
|
+
record?.summary.name,
|
|
66
|
+
record?.summary.id
|
|
67
|
+
].filter((name) => Boolean(name)).map(normalizeCodexPluginOwnerName);
|
|
68
|
+
}));
|
|
69
|
+
for (const app of params.accountApps) if (app.pluginDisplayNames.some((name) => configuredOwnerNames.has(normalizeCodexPluginOwnerName(name)))) reserved.add(codexAppIdentityKey(app.id));
|
|
70
|
+
return reserved;
|
|
71
|
+
}
|
|
72
|
+
function normalizeCodexPluginOwnerName(name) {
|
|
73
|
+
return name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "");
|
|
74
|
+
}
|
|
75
|
+
async function readCodexThreadAdmissibleAccountApps(params, appCache) {
|
|
76
|
+
const request = createCodexAppInventoryRequest(params);
|
|
77
|
+
const cachedInventory = appCache.read({
|
|
78
|
+
key: resolveCodexPluginThreadAppCacheKey(params),
|
|
79
|
+
request,
|
|
80
|
+
nowMs: params.nowMs,
|
|
81
|
+
suppressRefresh: true
|
|
82
|
+
});
|
|
83
|
+
const snapshot = cachedInventory.state === "fresh" && !cachedInventory.snapshot?.targetAppIds?.length ? cachedInventory.snapshot : await refreshCodexPluginAppInventory(params, appCache, {
|
|
84
|
+
forceRefetch: false,
|
|
85
|
+
reason: "account_apps_all",
|
|
86
|
+
targetAppIds: []
|
|
87
|
+
});
|
|
88
|
+
if (!snapshot) return {
|
|
89
|
+
apps: [],
|
|
90
|
+
diagnostic: {
|
|
91
|
+
code: "account_app_inventory_unavailable",
|
|
92
|
+
message: "Codex account app inventory was unavailable; account apps were not exposed."
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
const installedAppsById = new Map(snapshot.installedApps.map((app) => [app.id, app]));
|
|
96
|
+
return { apps: snapshot.apps.filter((app) => isCodexInstalledAppThreadAdmissible(installedAppsById.get(app.id))).toSorted((left, right) => left.id.localeCompare(right.id)) };
|
|
97
|
+
}
|
|
98
|
+
function isCodexPluginAppThreadAdmissible(app, inventory) {
|
|
99
|
+
const snapshot = inventory.appInventory?.snapshot;
|
|
100
|
+
if (!app.accessible || !snapshot) return false;
|
|
101
|
+
return isCodexInstalledAppThreadAdmissible(snapshot.installedApps.find((candidate) => candidate.id === app.id));
|
|
102
|
+
}
|
|
103
|
+
function isCodexInstalledAppThreadAdmissible(installed) {
|
|
104
|
+
return Boolean(installed && (installed.enabled && installed.callable || !installed.enabled && !installed.callable));
|
|
105
|
+
}
|
|
106
|
+
async function readCodexConfigForAppAdmission(params) {
|
|
107
|
+
try {
|
|
108
|
+
const response = await params.request("config/read", {
|
|
109
|
+
includeLayers: true,
|
|
110
|
+
...params.configCwd ? { cwd: params.configCwd } : {}
|
|
111
|
+
});
|
|
112
|
+
if (!isJsonObject(response) || !isJsonObject(response.config) || !Array.isArray(response.layers)) throw new Error("Codex config/read omitted effective config or config layers");
|
|
113
|
+
return {
|
|
114
|
+
config: response.config,
|
|
115
|
+
layers: response.layers.flatMap((layer) => {
|
|
116
|
+
if (!isJsonObject(layer)) throw new Error("Codex config/read returned an invalid config layer");
|
|
117
|
+
if (layer.disabledReason !== void 0 && layer.disabledReason !== null) {
|
|
118
|
+
if (typeof layer.disabledReason !== "string") throw new Error("Codex config/read returned an invalid disabled layer");
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
if (!isJsonObject(layer.config)) throw new Error("Codex config/read returned an invalid layer config");
|
|
122
|
+
if (!isJsonObject(layer.name) || typeof layer.name.type !== "string") throw new Error("Codex config/read returned an invalid config layer source");
|
|
123
|
+
if (layer.config.apps !== void 0 && !CODEX_SESSION_OVERRIDABLE_LAYER_TYPES.has(layer.name.type)) throw new Error(`Codex app policy cannot override ${layer.name.type}; move app settings to a supported user or project config layer before exposing native apps`);
|
|
124
|
+
return [layer.config];
|
|
125
|
+
})
|
|
126
|
+
};
|
|
127
|
+
} catch (error) {
|
|
128
|
+
const details = serializeCodexAppInventoryError(error);
|
|
129
|
+
embeddedAgentLog.warn("codex plugin app admission config read failed", { error: details });
|
|
130
|
+
throw new Error(`Could not verify the Codex app allowlist: ${String(details.message)}. No native thread was started; resolve the native configuration error and retry.`, { cause: error });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function resolveCodexExplicitAppEnablement(layersHighestPrecedenceFirst, appId) {
|
|
134
|
+
for (const layer of layersHighestPrecedenceFirst) {
|
|
135
|
+
const apps = layer.apps;
|
|
136
|
+
const values = isJsonObject(apps) ? Object.entries(apps).filter(([id, app]) => codexAppIdentityKey(id) === codexAppIdentityKey(appId) && isJsonObject(app) && Object.hasOwn(app, "enabled")).map(([, app]) => isJsonObject(app) && app.enabled === true) : [];
|
|
137
|
+
if (values.length > 0) return values.every(Boolean);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function shouldForceRefreshCodexNotReadyPluginApps(params, policy, inventory) {
|
|
141
|
+
if (!params.appCacheKey || !policy.pluginPolicies.some((plugin) => plugin.enabled) || inventory.appInventory?.state === "missing") return false;
|
|
142
|
+
return inventory.records.some((record) => record.appOwnership === "proven" && record.ownedAppIds.length > 0 && (record.apps.length === 0 || record.apps.some((app) => !app.accessible)));
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
145
|
+
//#region extensions/codex/src/app-server/plugin-thread-config.ts
|
|
146
|
+
const CODEX_PLUGIN_THREAD_CONFIG_INPUT_FINGERPRINT_VERSION = 15;
|
|
147
|
+
const CODEX_PLUGIN_THREAD_CONFIG_FINGERPRINT_VERSION = 2;
|
|
148
|
+
function shouldBuildCodexPluginThreadConfig(pluginConfig) {
|
|
149
|
+
return resolveCodexPluginsPolicy(pluginConfig).configured;
|
|
150
|
+
}
|
|
151
|
+
/** Fingerprints policy and app-cache identity before runtime inventory is read. */
|
|
152
|
+
function buildCodexPluginThreadConfigInputFingerprint(params) {
|
|
153
|
+
const policy = resolveCodexPluginsPolicy(params.pluginConfig);
|
|
154
|
+
return fingerprintCodexPolicy({
|
|
155
|
+
version: CODEX_PLUGIN_THREAD_CONFIG_INPUT_FINGERPRINT_VERSION,
|
|
156
|
+
policy: {
|
|
157
|
+
enabled: policy.enabled,
|
|
158
|
+
allowAllPlugins: policy.allowAllPlugins,
|
|
159
|
+
allowDestructiveActions: policy.allowDestructiveActions,
|
|
160
|
+
destructiveApprovalMode: policy.destructiveApprovalMode,
|
|
161
|
+
plugins: policy.pluginPolicies
|
|
162
|
+
},
|
|
163
|
+
appCacheKey: params.appCacheKey ?? null
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/** Builds the deny-all app patch used when plugin discovery exceeds its turn budget. */
|
|
167
|
+
function buildCodexPluginThreadConfigTimeoutFallback(params) {
|
|
168
|
+
return finishPluginThreadConfig({
|
|
169
|
+
enabled: true,
|
|
170
|
+
inputFingerprint: buildCodexPluginThreadConfigInputFingerprint(params),
|
|
171
|
+
configPatch: buildDisabledAppsConfigPatch(),
|
|
172
|
+
diagnostics: [{
|
|
173
|
+
code: "plugin_config_timeout",
|
|
174
|
+
message: params.message
|
|
175
|
+
}]
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
async function buildCodexPluginThreadConfig(params) {
|
|
179
|
+
const appCache = params.appCache ?? defaultCodexAppInventoryCache;
|
|
180
|
+
const threadAppCacheKey = resolveCodexPluginThreadAppCacheKey(params);
|
|
181
|
+
let inputFingerprint = buildCodexPluginThreadConfigInputFingerprint(params);
|
|
182
|
+
const policy = resolveCodexPluginsPolicy(params.pluginConfig);
|
|
183
|
+
if (!policy.enabled) return finishPluginThreadConfig({
|
|
184
|
+
enabled: false,
|
|
185
|
+
inputFingerprint,
|
|
186
|
+
configPatch: buildDisabledAppsConfigPatch()
|
|
187
|
+
});
|
|
188
|
+
const inventoryParams = {
|
|
189
|
+
request: params.request,
|
|
190
|
+
threadId: params.threadId,
|
|
191
|
+
appCache,
|
|
192
|
+
appCacheKey: params.appCacheKey,
|
|
193
|
+
appInventoryCacheKey: threadAppCacheKey,
|
|
194
|
+
configCwd: params.configCwd,
|
|
195
|
+
metadataCache: params.metadataCache
|
|
196
|
+
};
|
|
197
|
+
const readInventory = (suppressAppInventoryRefresh) => readCodexPluginInventory({
|
|
198
|
+
...inventoryParams,
|
|
199
|
+
policy,
|
|
200
|
+
nowMs: params.nowMs,
|
|
201
|
+
suppressAppInventoryRefresh
|
|
202
|
+
});
|
|
203
|
+
let inventory = policy.pluginPolicies.length > 0 ? await readInventory(true) : {
|
|
204
|
+
policy,
|
|
205
|
+
records: [],
|
|
206
|
+
diagnostics: []
|
|
207
|
+
};
|
|
208
|
+
const refreshInventory = async (options) => {
|
|
209
|
+
await refreshCodexPluginAppInventory(params, appCache, {
|
|
210
|
+
...options,
|
|
211
|
+
targetAppIds: collectCodexPluginOwnedAppIds(inventory)
|
|
212
|
+
});
|
|
213
|
+
inventory = await readInventory();
|
|
214
|
+
inputFingerprint = buildCodexPluginThreadConfigInputFingerprint(params);
|
|
215
|
+
};
|
|
216
|
+
const activationRequired = inventory.records.some((record) => record.activationRequired);
|
|
217
|
+
const appInventoryMissing = shouldRefreshMissingAppInventory(params, policy, inventory);
|
|
218
|
+
const appInventoryRefreshDeferredForActivation = activationRequired && appInventoryMissing;
|
|
219
|
+
if (!activationRequired && appInventoryMissing) await refreshInventory({
|
|
220
|
+
forceRefetch: false,
|
|
221
|
+
reason: "initial_missing"
|
|
222
|
+
});
|
|
223
|
+
const activationDiagnostics = [];
|
|
224
|
+
const activationResults = [];
|
|
225
|
+
for (const record of inventory.records) {
|
|
226
|
+
if (!record.activationRequired) continue;
|
|
227
|
+
const activation = await ensureCodexPluginActivation({
|
|
228
|
+
...inventoryParams,
|
|
229
|
+
identity: record.policy,
|
|
230
|
+
deferAppInventoryRefresh: true,
|
|
231
|
+
targetAppIds: record.ownedAppIds
|
|
232
|
+
});
|
|
233
|
+
activationResults.push(activation);
|
|
234
|
+
if (!activation.ok) activationDiagnostics.push({
|
|
235
|
+
code: "plugin_activation_failed",
|
|
236
|
+
plugin: record.policy,
|
|
237
|
+
message: activation.diagnostics.map((item) => item.message).join(" ") || activation.reason
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
const postInstallRefreshRequired = activationResults.some((activation) => activation.ok && activation.installAttempted);
|
|
241
|
+
const deferredMissingRefreshRequired = appInventoryRefreshDeferredForActivation && !postInstallRefreshRequired && shouldRefreshMissingAppInventory(params, policy, inventory);
|
|
242
|
+
if (postInstallRefreshRequired || deferredMissingRefreshRequired) await refreshInventory({
|
|
243
|
+
forceRefetch: true,
|
|
244
|
+
reason: postInstallRefreshRequired ? "post_install" : "deferred_missing"
|
|
245
|
+
});
|
|
246
|
+
if (shouldForceRefreshCodexNotReadyPluginApps(params, policy, inventory)) await refreshInventory({
|
|
247
|
+
forceRefetch: true,
|
|
248
|
+
reason: "not_ready_plugin_apps"
|
|
249
|
+
});
|
|
250
|
+
const accountAppsResult = policy.allowAllPlugins ? await readCodexThreadAdmissibleAccountApps(params, appCache) : { apps: [] };
|
|
251
|
+
let appAdmissionConfig;
|
|
252
|
+
const getAdmissionConfig = () => appAdmissionConfig ??= readCodexConfigForAppAdmission(params);
|
|
253
|
+
const diagnostics = [
|
|
254
|
+
...inventory.diagnostics,
|
|
255
|
+
...activationDiagnostics,
|
|
256
|
+
...accountAppsResult.diagnostic ? [accountAppsResult.diagnostic] : []
|
|
257
|
+
];
|
|
258
|
+
const provisionalAppIds = /* @__PURE__ */ new Set();
|
|
259
|
+
const { apps } = buildDisabledAppsConfigPatch();
|
|
260
|
+
const policyApps = {};
|
|
261
|
+
const pluginAppIds = {};
|
|
262
|
+
const pluginOwnedAppIds = collectCodexReservedPluginAppIds({
|
|
263
|
+
policy: inventory.policy,
|
|
264
|
+
inventory,
|
|
265
|
+
accountApps: accountAppsResult.apps
|
|
266
|
+
});
|
|
267
|
+
const unresolvedDisabledPluginOwnership = policy.allowAllPlugins ? inventory.policy.pluginPolicies.find((pluginPolicy) => {
|
|
268
|
+
const record = inventory.records.find((candidate) => candidate.policy.configKey === pluginPolicy.configKey);
|
|
269
|
+
const disabledByMarketplacePolicy = record?.summary.availability === "DISABLED_BY_ADMIN" || record?.summary.installPolicy === "NOT_AVAILABLE";
|
|
270
|
+
const unresolvedPluginIdentity = !record && inventory.diagnostics.some((diagnostic) => diagnostic.plugin?.configKey === pluginPolicy.configKey && (diagnostic.code === "plugin_disabled" || diagnostic.code === "plugin_missing" || diagnostic.code === "marketplace_missing"));
|
|
271
|
+
return (!pluginPolicy.enabled || disabledByMarketplacePolicy || unresolvedPluginIdentity) && !record?.detail;
|
|
272
|
+
}) : void 0;
|
|
273
|
+
if (unresolvedDisabledPluginOwnership) diagnostics.push({
|
|
274
|
+
code: "account_app_ownership_unavailable",
|
|
275
|
+
plugin: unresolvedDisabledPluginOwnership,
|
|
276
|
+
message: `Could not verify disabled Codex plugin app ownership for ${unresolvedDisabledPluginOwnership.pluginName}; account apps were not exposed.`
|
|
277
|
+
});
|
|
278
|
+
for (const record of inventory.records) {
|
|
279
|
+
if (!record.policy.enabled) continue;
|
|
280
|
+
const activation = activationResults.find((item) => item.identity.configKey === record.policy.configKey);
|
|
281
|
+
if (activation?.ok === false || record.activationRequired && !activation?.ok) continue;
|
|
282
|
+
if (record.appOwnership !== "proven") continue;
|
|
283
|
+
pluginAppIds[record.policy.configKey] = [...record.ownedAppIds].toSorted();
|
|
284
|
+
for (const app of inventory.appInventory?.state === "missing" ? [] : record.apps) {
|
|
285
|
+
const admissionConfig = isCodexPluginAppThreadAdmissible(app, inventory) ? await getAdmissionConfig() : void 0;
|
|
286
|
+
if (!admissionConfig || resolveCodexExplicitAppEnablement(admissionConfig.layers, app.id) === false) {
|
|
287
|
+
diagnostics.push({
|
|
288
|
+
code: "app_not_ready",
|
|
289
|
+
plugin: record.policy,
|
|
290
|
+
message: `${app.id} is not accessible for ${record.policy.pluginName}.`
|
|
291
|
+
});
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
provisionalAppIds.add(app.id);
|
|
295
|
+
apps[app.id] = buildEnabledAppConfig(record.policy, record.policy.destructiveApprovalMode === "ask" ? buildCodexAppApprovalOverrides(admissionConfig.config, app) : void 0);
|
|
296
|
+
policyApps[app.id] = {
|
|
297
|
+
configKey: record.policy.configKey,
|
|
298
|
+
marketplaceName: record.policy.marketplaceName,
|
|
299
|
+
pluginName: record.policy.pluginName,
|
|
300
|
+
allowDestructiveActions: record.policy.allowDestructiveActions,
|
|
301
|
+
allowOpenWorld: true,
|
|
302
|
+
destructiveApprovalMode: record.policy.destructiveApprovalMode,
|
|
303
|
+
mcpServerNames: [...record.detail?.mcpServers ?? []].toSorted()
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
for (const app of unresolvedDisabledPluginOwnership ? [] : accountAppsResult.apps) {
|
|
308
|
+
if (pluginOwnedAppIds.has(codexAppIdentityKey(app.id))) continue;
|
|
309
|
+
const admissionConfig = await getAdmissionConfig();
|
|
310
|
+
if (resolveCodexExplicitAppEnablement(admissionConfig.layers, app.id) === false) continue;
|
|
311
|
+
const accountApp = toCodexPluginOwnedAccountApp(app);
|
|
312
|
+
provisionalAppIds.add(app.id);
|
|
313
|
+
apps[app.id] = buildEnabledAppConfig(policy, policy.destructiveApprovalMode === "ask" ? buildCodexAppApprovalOverrides(admissionConfig.config, accountApp) : void 0);
|
|
314
|
+
policyApps[app.id] = {
|
|
315
|
+
source: "account",
|
|
316
|
+
appName: app.name,
|
|
317
|
+
allowDestructiveActions: policy.allowDestructiveActions,
|
|
318
|
+
allowOpenWorld: true,
|
|
319
|
+
destructiveApprovalMode: policy.destructiveApprovalMode,
|
|
320
|
+
mcpServerNames: []
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
const configPatch = Object.keys(policyApps).length === 0 ? buildDisabledAppsConfigPatch() : disableUnlistedCodexApps({ apps }, (await getAdmissionConfig()).config);
|
|
324
|
+
const policyContext = buildPluginAppPolicyContext(policyApps, pluginAppIds);
|
|
325
|
+
return finishPluginThreadConfig({
|
|
326
|
+
enabled: true,
|
|
327
|
+
configPatch,
|
|
328
|
+
...provisionalAppIds.size > 0 ? { provisionalAppIds: Array.from(provisionalAppIds).toSorted() } : {},
|
|
329
|
+
inputFingerprint,
|
|
330
|
+
policyContext,
|
|
331
|
+
diagnostics
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
/** Deep-merges optional Codex thread config patches, returning undefined when empty. */
|
|
335
|
+
function mergeCodexThreadConfigs(...configs) {
|
|
336
|
+
let merged;
|
|
337
|
+
for (const config of configs) {
|
|
338
|
+
if (!config) continue;
|
|
339
|
+
merged = mergeJsonObjects(merged ?? {}, normalizeShellEnvironmentOverrides(config));
|
|
340
|
+
}
|
|
341
|
+
return merged && Object.keys(merged).length > 0 ? merged : void 0;
|
|
342
|
+
}
|
|
343
|
+
function isCodexPluginThreadBindingStale(params) {
|
|
344
|
+
if (!params.codexPluginsEnabled) return Boolean(params.bindingFingerprint || params.bindingInputFingerprint || params.hasBindingPolicyContext);
|
|
345
|
+
if (!params.bindingFingerprint || !params.bindingInputFingerprint || !params.hasBindingPolicyContext) return true;
|
|
346
|
+
return params.bindingInputFingerprint !== params.currentInputFingerprint;
|
|
347
|
+
}
|
|
348
|
+
function finishPluginThreadConfig(config) {
|
|
349
|
+
const policyContext = config.policyContext ?? buildPluginAppPolicyContext({}, {});
|
|
350
|
+
return {
|
|
351
|
+
...config,
|
|
352
|
+
policyContext,
|
|
353
|
+
diagnostics: config.diagnostics ?? [],
|
|
354
|
+
fingerprint: fingerprintCodexPolicy({
|
|
355
|
+
version: CODEX_PLUGIN_THREAD_CONFIG_FINGERPRINT_VERSION,
|
|
356
|
+
inputFingerprint: config.inputFingerprint,
|
|
357
|
+
configPatch: config.configPatch ?? null,
|
|
358
|
+
policyContext
|
|
359
|
+
})
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
function buildDisabledAppsConfigPatch() {
|
|
363
|
+
return {
|
|
364
|
+
"features.apps": false,
|
|
365
|
+
apps: { _default: {
|
|
366
|
+
enabled: false,
|
|
367
|
+
destructive_enabled: false,
|
|
368
|
+
open_world_enabled: false
|
|
369
|
+
} }
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
function disableUnlistedCodexApps(configPatch, nativeConfig) {
|
|
373
|
+
const apps = { ...configPatch.apps };
|
|
374
|
+
for (const id of Object.keys(isJsonObject(nativeConfig.apps) ? nativeConfig.apps : {})) if (id !== "_default" && !Object.hasOwn(apps, id)) apps[id] = { enabled: false };
|
|
375
|
+
return {
|
|
376
|
+
...configPatch,
|
|
377
|
+
apps
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
function buildEnabledAppConfig(policy, approvalOverrides = {}) {
|
|
381
|
+
return {
|
|
382
|
+
...approvalOverrides,
|
|
383
|
+
enabled: true,
|
|
384
|
+
destructive_enabled: policy.allowDestructiveActions,
|
|
385
|
+
open_world_enabled: policy.allowOpenWorld !== false,
|
|
386
|
+
...policy.destructiveApprovalMode === "ask" ? {
|
|
387
|
+
default_tools_approval_mode: "auto",
|
|
388
|
+
approvals_reviewer: "user"
|
|
389
|
+
} : {}
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
/** Rebuilds the safe per-thread apps patch persisted with a Codex thread binding. */
|
|
393
|
+
function buildCodexPluginAppsConfigPatchFromPolicyContext(policyContext) {
|
|
394
|
+
const disabledConfigPatch = buildDisabledAppsConfigPatch();
|
|
395
|
+
const { apps } = disabledConfigPatch;
|
|
396
|
+
for (const [appId, policy] of Object.entries(policyContext.apps).toSorted(([left], [right]) => left.localeCompare(right))) apps[appId] = buildEnabledAppConfig(policy);
|
|
397
|
+
return Object.keys(policyContext.apps).length > 0 ? { apps } : disabledConfigPatch;
|
|
398
|
+
}
|
|
399
|
+
/** Projects current ask overrides before a side thread replays its bound app policy. */
|
|
400
|
+
async function refreshCodexPluginAppApprovalPolicy(params) {
|
|
401
|
+
if (Object.keys(params.policyContext.apps).length === 0) return {
|
|
402
|
+
policyContext: params.policyContext,
|
|
403
|
+
configPatch: buildDisabledAppsConfigPatch(),
|
|
404
|
+
diagnostics: []
|
|
405
|
+
};
|
|
406
|
+
const targetApps = Object.entries(params.policyContext.apps).filter(([, app]) => app.destructiveApprovalMode === "ask").toSorted(([left], [right]) => left.localeCompare(right));
|
|
407
|
+
const targetAppIds = targetApps.map(([id]) => id);
|
|
408
|
+
const diagnostics = [];
|
|
409
|
+
const readParams = {
|
|
410
|
+
...params,
|
|
411
|
+
appCacheKey: "approval-policy-replay"
|
|
412
|
+
};
|
|
413
|
+
const [inventory, admissionConfig] = await Promise.all([targetAppIds.length > 0 ? refreshCodexPluginAppInventory(readParams, new CodexAppInventoryCache(), { targetAppIds }) : void 0, readCodexConfigForAppAdmission(readParams)]);
|
|
414
|
+
const configPatch = disableUnlistedCodexApps(buildCodexPluginAppsConfigPatchFromPolicyContext(params.policyContext), admissionConfig.config);
|
|
415
|
+
const currentApps = new Map(inventory?.apps.map((app) => [app.id, toCodexPluginOwnedAccountApp(app)]));
|
|
416
|
+
const apps = { ...params.policyContext.apps };
|
|
417
|
+
for (const [id, policy] of targetApps) {
|
|
418
|
+
const app = currentApps.get(id);
|
|
419
|
+
if (!app) diagnostics.push({
|
|
420
|
+
code: "app_not_ready",
|
|
421
|
+
message: `Could not verify current Codex app approval policy for ${id}; the app was not exposed.`
|
|
422
|
+
});
|
|
423
|
+
else {
|
|
424
|
+
configPatch.apps[id] = buildEnabledAppConfig(policy, buildCodexAppApprovalOverrides(admissionConfig.config, app));
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
delete apps[id];
|
|
428
|
+
configPatch.apps[id] = { enabled: false };
|
|
429
|
+
}
|
|
430
|
+
return {
|
|
431
|
+
policyContext: buildPluginAppPolicyContext(apps, Object.fromEntries(Object.entries(params.policyContext.pluginAppIds).map(([key, ids]) => [key, ids.filter((id) => Object.hasOwn(apps, id))]))),
|
|
432
|
+
configPatch,
|
|
433
|
+
diagnostics
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
function buildPluginAppPolicyContext(apps, pluginAppIds) {
|
|
437
|
+
return {
|
|
438
|
+
fingerprint: fingerprintCodexPolicy({
|
|
439
|
+
version: 2,
|
|
440
|
+
apps,
|
|
441
|
+
pluginAppIds
|
|
442
|
+
}),
|
|
443
|
+
apps,
|
|
444
|
+
pluginAppIds
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
function shouldRefreshMissingAppInventory(params, policy, inventory) {
|
|
448
|
+
return Boolean(params.appCacheKey && policy.pluginPolicies.some((plugin) => plugin.enabled) && inventory.appInventory?.state === "missing");
|
|
449
|
+
}
|
|
450
|
+
function normalizeShellEnvironmentOverrides(config) {
|
|
451
|
+
let normalized = { ...config };
|
|
452
|
+
for (const [key, value] of Object.entries(config)) {
|
|
453
|
+
if (!key.startsWith("shell_environment_policy.")) continue;
|
|
454
|
+
delete normalized[key];
|
|
455
|
+
let patch = value;
|
|
456
|
+
for (const segment of key.split(".").toReversed()) patch = { [segment]: patch };
|
|
457
|
+
normalized = mergeJsonObjects(normalized, patch);
|
|
458
|
+
}
|
|
459
|
+
return normalized;
|
|
460
|
+
}
|
|
461
|
+
function mergeJsonObjects(left, right) {
|
|
462
|
+
const merged = {
|
|
463
|
+
...left,
|
|
464
|
+
...right
|
|
465
|
+
};
|
|
466
|
+
for (const [key, value] of Object.entries(right)) {
|
|
467
|
+
const existing = left[key];
|
|
468
|
+
if (Object.hasOwn(left, key) && isJsonObject(existing) && isJsonObject(value)) merged[key] = mergeJsonObjects(existing, value);
|
|
469
|
+
}
|
|
470
|
+
return merged;
|
|
471
|
+
}
|
|
472
|
+
//#endregion
|
|
473
|
+
//#region extensions/codex/src/app-server/project-doc-thread-config.ts
|
|
474
|
+
const CODEX_NATIVE_PROJECT_DOC_MAX_BYTES = 131072;
|
|
475
|
+
function buildCodexProjectDocThreadConfig(config, effectiveNativeConfig) {
|
|
476
|
+
const defaults = { project_doc_max_bytes: resolveCodexNativeProjectDocMaxBytes(effectiveNativeConfig) ?? CODEX_NATIVE_PROJECT_DOC_MAX_BYTES };
|
|
477
|
+
return mergeCodexThreadConfigs(defaults, config) ?? defaults;
|
|
478
|
+
}
|
|
479
|
+
function resolveCodexNativeProjectDocMaxBytes(effectiveNativeConfig) {
|
|
480
|
+
if (effectiveNativeConfig?.origins?.project_doc_max_bytes === void 0) return;
|
|
481
|
+
const authoredMaxBytes = effectiveNativeConfig.config.project_doc_max_bytes;
|
|
482
|
+
if (typeof authoredMaxBytes !== "number" || !Number.isSafeInteger(authoredMaxBytes) || authoredMaxBytes < 0) throw new Error("Codex config/read returned an invalid project_doc_max_bytes value");
|
|
483
|
+
return authoredMaxBytes;
|
|
484
|
+
}
|
|
485
|
+
function mergeCodexNativeProjectDocThreadConfig(config, effectiveNativeConfig) {
|
|
486
|
+
const authoredMaxBytes = resolveCodexNativeProjectDocMaxBytes(effectiveNativeConfig);
|
|
487
|
+
return authoredMaxBytes === void 0 ? config : mergeCodexThreadConfigs({ project_doc_max_bytes: authoredMaxBytes }, config);
|
|
488
|
+
}
|
|
489
|
+
//#endregion
|
|
490
|
+
export { buildCodexPluginThreadConfigInputFingerprint as a, buildPluginAppPolicyContext as c, mergeCodexThreadConfigs as d, refreshCodexPluginAppApprovalPolicy as f, buildCodexPluginThreadConfig as i, disableUnlistedCodexApps as l, buildCodexAppApprovalOverrides as m, mergeCodexNativeProjectDocThreadConfig as n, buildCodexPluginThreadConfigTimeoutFallback as o, shouldBuildCodexPluginThreadConfig as p, buildCodexPluginAppsConfigPatchFromPolicyContext as r, buildDisabledAppsConfigPatch as s, buildCodexProjectDocThreadConfig as t, isCodexPluginThreadBindingStale as u };
|
|
@@ -11,7 +11,7 @@ function buildCodexMigrationProvider(params = {}) {
|
|
|
11
11
|
].join(" "),
|
|
12
12
|
supportedItemKinds: ["memory", "auth"],
|
|
13
13
|
async detect(ctx) {
|
|
14
|
-
const { discoverCodexSource, hasCodexSource } = await import("./source-
|
|
14
|
+
const { discoverCodexSource, hasCodexSource } = await import("./source-Bxbqf3S1.mjs").then((n) => n.a);
|
|
15
15
|
const memoryOnly = isOnlyMigrationKind(ctx, "memory");
|
|
16
16
|
const authOnly = isOnlyMigrationKind(ctx, "auth");
|
|
17
17
|
const source = await discoverCodexSource({
|
|
@@ -29,16 +29,16 @@ function buildCodexMigrationProvider(params = {}) {
|
|
|
29
29
|
};
|
|
30
30
|
},
|
|
31
31
|
async plan(ctx) {
|
|
32
|
-
const { buildCodexMigrationPlan } = await import("./plan-
|
|
32
|
+
const { buildCodexMigrationPlan } = await import("./plan-C_F3aio0.mjs");
|
|
33
33
|
return buildCodexMigrationPlan(ctx);
|
|
34
34
|
},
|
|
35
35
|
deferredApply: { retrySafe: true },
|
|
36
36
|
prepareApply(ctx) {
|
|
37
37
|
if (isOnlyMigrationKind(ctx, "memory") || isOnlyMigrationKind(ctx, "auth")) return;
|
|
38
|
-
return import("./apply-
|
|
38
|
+
return import("./apply-CBMV8LN0.mjs").then(({ prepareTargetCodexAppServer }) => prepareTargetCodexAppServer(ctx));
|
|
39
39
|
},
|
|
40
40
|
async apply(ctx, plan) {
|
|
41
|
-
const { applyCodexMigrationPlan } = await import("./apply-
|
|
41
|
+
const { applyCodexMigrationPlan } = await import("./apply-CBMV8LN0.mjs");
|
|
42
42
|
return await applyCodexMigrationPlan({
|
|
43
43
|
ctx,
|
|
44
44
|
plan,
|
package/dist/.setup/{provider-capabilities-D68Whix6.mjs → provider-capabilities-CjRaV3bx.mjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { h as releaseLeasedSharedCodexAppServerClient } from "./shared-client-
|
|
1
|
+
import { h as releaseLeasedSharedCodexAppServerClient } from "./shared-client-ByIwuAC-.mjs";
|
|
2
2
|
//#region extensions/codex/src/app-server/provider-capabilities.ts
|
|
3
3
|
function resolveOverriddenProviderWebSearchSupport(modelProviderOverride) {
|
|
4
4
|
const provider = modelProviderOverride?.trim().toLowerCase();
|
|
@@ -38,16 +38,9 @@ function formatCalendarResetTime(resetsAtMs, nowMs) {
|
|
|
38
38
|
function formatRelativeDuration(durationMs) {
|
|
39
39
|
const safeMs = Math.max(1e3, durationMs);
|
|
40
40
|
if (safeMs < ONE_MINUTE_MS) return `${Math.ceil(safeMs / 1e3)} seconds`;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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"}`;
|
|
41
|
+
const [unitMs, unit] = safeMs < ONE_HOUR_MS ? [ONE_MINUTE_MS, "minute"] : safeMs < ONE_DAY_MS$1 ? [ONE_HOUR_MS, "hour"] : [ONE_DAY_MS$1, "day"];
|
|
42
|
+
const count = Math.ceil(safeMs / unitMs);
|
|
43
|
+
return `${count} ${unit}${count === 1 ? "" : "s"}`;
|
|
51
44
|
}
|
|
52
45
|
function formatResetDuration(resetsAtMs, nowMs) {
|
|
53
46
|
const durationMs = Math.round(Math.max(ONE_SECOND_MS, resetsAtMs - nowMs) / ONE_SECOND_MS) * ONE_SECOND_MS;
|
|
@@ -111,11 +104,11 @@ function formatCodexUsageLimitErrorMessage(params) {
|
|
|
111
104
|
const blockingSnapshot = selectBlockingRateLimitSnapshot(snapshots, ordinaryUsageAllowed);
|
|
112
105
|
const usageSummary = usageSnapshot ? summarizeRateLimitUsage(usageSnapshot, blockingSnapshot, nowMs) : void 0;
|
|
113
106
|
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(" ");
|
|
114
|
-
const nextReset = (blockingSnapshot ? selectSnapshotBlockingReset(blockingSnapshot, nowMs) : void 0) ?? (ordinaryUsageAllowed === void 0 && !usageSummary?.blocked ?
|
|
107
|
+
const nextReset = (blockingSnapshot ? selectSnapshotBlockingReset(blockingSnapshot, nowMs) : void 0) ?? (ordinaryUsageAllowed === void 0 && !usageSummary?.blocked ? selectRateLimitWindowEntry(collectCodexRateLimitSnapshots(params.rateLimits).flatMap(readWindowEntries), nowMs, "next")?.window : void 0);
|
|
115
108
|
const parts = [CODEX_USAGE_LIMIT_MESSAGE_PREFIX];
|
|
116
109
|
let recoveryAction = "Wait until Codex becomes available";
|
|
117
110
|
if (nextReset) {
|
|
118
|
-
parts.push(`Next reset ${
|
|
111
|
+
parts.push(`Next reset in ${formatRelativeDuration(nextReset.resetsAtMs - nowMs)}, ${formatCalendarResetTime(nextReset.resetsAtMs, nowMs)}.`);
|
|
119
112
|
recoveryAction = "Wait until the reset time";
|
|
120
113
|
} else {
|
|
121
114
|
const codexRetryHint = extractCodexRetryHint(message);
|
|
@@ -167,19 +160,19 @@ function summarizeCodexAccountUsage(value, nowMs = Date.now()) {
|
|
|
167
160
|
}
|
|
168
161
|
function summarizeRateLimitUsage(usageSnapshot, blockingSnapshot, nowMs) {
|
|
169
162
|
const blockingEntries = blockingSnapshot ? readWindowEntries(blockingSnapshot) : [];
|
|
170
|
-
const blockingWindowEntry =
|
|
163
|
+
const blockingWindowEntry = selectRateLimitWindowEntry(blockingEntries, nowMs);
|
|
171
164
|
const blockingWindow = blockingWindowEntry?.window;
|
|
172
165
|
const blockingReset = blockingWindow && blockingWindow.resetsAtMs > nowMs ? blockingWindow : void 0;
|
|
173
166
|
const blockingPeriod = formatBlockingLimitPeriod(blockingWindowEntry, blockingEntries);
|
|
174
|
-
const blockedUntilText = blockingReset ? formatAccountResetTime(blockingReset.resetsAtMs, nowMs) : void 0;
|
|
175
|
-
const blockedResetRelative = blockingReset ? `in ${formatRelativeDuration(blockingReset.resetsAtMs - nowMs)}` : void 0;
|
|
176
167
|
const blockingReason = blockingPeriod ? `${blockingPeriod} Codex usage limit is reached` : blockingSnapshot ? "Codex usage limit is reached" : void 0;
|
|
177
168
|
return {
|
|
178
169
|
usageLine: formatUsageLine(usageSnapshot),
|
|
179
170
|
blocked: Boolean(blockingSnapshot),
|
|
180
|
-
...blockingReset ? {
|
|
181
|
-
|
|
182
|
-
|
|
171
|
+
...blockingReset ? {
|
|
172
|
+
blockedUntilMs: blockingReset.resetsAtMs,
|
|
173
|
+
blockedUntilText: `${formatCalendarResetTime(blockingReset.resetsAtMs, nowMs)} (in ${formatRelativeDuration(blockingReset.resetsAtMs - nowMs)})`,
|
|
174
|
+
blockedResetRelative: `in ${formatRelativeDuration(blockingReset.resetsAtMs - nowMs)}`
|
|
175
|
+
} : {},
|
|
183
176
|
...blockingPeriod ? { blockingPeriod } : {},
|
|
184
177
|
...blockingReason ? { blockingReason } : {}
|
|
185
178
|
};
|
|
@@ -220,11 +213,6 @@ function buildCodexAppServerUsageSnapshot(value, options = {}) {
|
|
|
220
213
|
}
|
|
221
214
|
return result;
|
|
222
215
|
}
|
|
223
|
-
function selectNextRateLimitReset(value, nowMs) {
|
|
224
|
-
const futureWindows = collectCodexRateLimitSnapshots(value).flatMap((snapshot) => LIMIT_WINDOW_KEYS.flatMap((key) => snapshot[key] ?? [])).filter((window) => window.resetsAtMs > nowMs);
|
|
225
|
-
const exhaustedWindows = futureWindows.filter((window) => window.usedPercent !== void 0 && window.usedPercent >= 100);
|
|
226
|
-
return (exhaustedWindows.length > 0 ? exhaustedWindows : futureWindows).toSorted((left, right) => left.resetsAtMs - right.resetsAtMs)[0];
|
|
227
|
-
}
|
|
228
216
|
function selectBlockingRateLimitSnapshot(snapshots, ordinaryUsageAllowed) {
|
|
229
217
|
const blockedSnapshots = snapshots.filter((snapshot) => snapshotHasLimitBlock(snapshot) && (ordinaryUsageAllowed !== true && ordinaryUsageAllowed !== null || !isCodexLimitSnapshot(snapshot)));
|
|
230
218
|
return blockedSnapshots.find(isCodexLimitSnapshot) ?? blockedSnapshots[0];
|
|
@@ -281,12 +269,6 @@ function formatLimitLabel(snapshot) {
|
|
|
281
269
|
function formatReachedType(value) {
|
|
282
270
|
return value.replace(/[_-]+/gu, " ").replace(/\s+/gu, " ").trim();
|
|
283
271
|
}
|
|
284
|
-
function formatResetTime(resetsAtMs, nowMs) {
|
|
285
|
-
return `in ${formatRelativeDuration(resetsAtMs - nowMs)}, ${formatCalendarResetTime(resetsAtMs, nowMs)}`;
|
|
286
|
-
}
|
|
287
|
-
function formatAccountResetTime(resetsAtMs, nowMs) {
|
|
288
|
-
return `${formatCalendarResetTime(resetsAtMs, nowMs)} (in ${formatRelativeDuration(resetsAtMs - nowMs)})`;
|
|
289
|
-
}
|
|
290
272
|
function snapshotHasLimitBlock(snapshot) {
|
|
291
273
|
return Boolean(snapshot.rateLimitReachedType ?? readWindowEntries(snapshot).some((entry) => entry.window.usedPercent !== void 0 && entry.window.usedPercent >= 100));
|
|
292
274
|
}
|
|
@@ -326,14 +308,15 @@ function formatCodexCreditSummary(credits) {
|
|
|
326
308
|
return roundedBalance > 0 ? `${roundedBalance} credits` : void 0;
|
|
327
309
|
}
|
|
328
310
|
function selectSnapshotBlockingReset(snapshot, nowMs) {
|
|
329
|
-
const window =
|
|
311
|
+
const window = selectRateLimitWindowEntry(readWindowEntries(snapshot), nowMs)?.window;
|
|
330
312
|
return window && window.resetsAtMs > nowMs ? window : void 0;
|
|
331
313
|
}
|
|
332
|
-
function
|
|
314
|
+
function selectRateLimitWindowEntry(entries, nowMs, selection = "blocking") {
|
|
333
315
|
const futureEntries = entries.filter((entry) => entry.window.resetsAtMs > nowMs);
|
|
334
316
|
const exhaustedFutureEntries = futureEntries.filter((entry) => entry.window.usedPercent !== void 0 && entry.window.usedPercent >= 100);
|
|
335
317
|
const resetCandidates = exhaustedFutureEntries.length > 0 ? exhaustedFutureEntries : futureEntries;
|
|
336
|
-
if (resetCandidates.length > 0) return resetCandidates.toSorted((left, right) => exhaustedFutureEntries.length > 0 ? right.window.resetsAtMs - left.window.resetsAtMs : left.window.resetsAtMs - right.window.resetsAtMs)[0];
|
|
318
|
+
if (resetCandidates.length > 0) return resetCandidates.toSorted((left, right) => selection === "blocking" && exhaustedFutureEntries.length > 0 ? right.window.resetsAtMs - left.window.resetsAtMs : left.window.resetsAtMs - right.window.resetsAtMs)[0];
|
|
319
|
+
if (selection === "next") return;
|
|
337
320
|
return entries.filter((entry) => entry.window.usedPercent !== void 0 && entry.window.usedPercent >= 100).toSorted((left, right) => (right.window.windowDurationMins ?? 0) - (left.window.windowDurationMins ?? 0))[0];
|
|
338
321
|
}
|
|
339
322
|
function readWindowEntries(snapshot) {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { selectSupportedReasoningEffort } from "openclaw/plugin-sdk/agent-harness-attempt-runtime";
|
|
2
|
+
//#region extensions/codex/src/app-server/reasoning-effort.ts
|
|
3
|
+
const CODEX_REASONING_EFFORTS = [
|
|
4
|
+
"minimal",
|
|
5
|
+
"low",
|
|
6
|
+
"medium",
|
|
7
|
+
"high",
|
|
8
|
+
"xhigh",
|
|
9
|
+
"max"
|
|
10
|
+
];
|
|
11
|
+
const LEGACY_PRO_REASONING_EFFORTS = [
|
|
12
|
+
"medium",
|
|
13
|
+
"high",
|
|
14
|
+
"xhigh"
|
|
15
|
+
];
|
|
16
|
+
const LEGACY_PRO_MODEL_ID_RE = /^gpt-5\.[45]-pro$/u;
|
|
17
|
+
const MODERN_GPT_5_MODEL_ID_RE = /^gpt-5\.(?:[3-9]|[1-9]\d)(?:$|-)/u;
|
|
18
|
+
/** Read reasoning metadata after the Codex app-server route has been selected. */
|
|
19
|
+
function readCodexSupportedReasoningEfforts(compat) {
|
|
20
|
+
return compat && "supportedReasoningEfforts" in compat ? compat.supportedReasoningEfforts : void 0;
|
|
21
|
+
}
|
|
22
|
+
function resolveCodexAppServerReasoningEffort(params) {
|
|
23
|
+
if (params.thinkLevel === "ultra") return "ultra";
|
|
24
|
+
if (params.thinkLevel === "off") return params.supportedReasoningEfforts?.includes("none") ? "none" : null;
|
|
25
|
+
if (params.thinkLevel === "adaptive") return null;
|
|
26
|
+
const modelId = params.modelId.trim().toLowerCase();
|
|
27
|
+
const supportedReasoningEfforts = params.supportedReasoningEfforts ?? (LEGACY_PRO_MODEL_ID_RE.test(modelId) ? LEGACY_PRO_REASONING_EFFORTS : void 0);
|
|
28
|
+
if (supportedReasoningEfforts) return selectSupportedReasoningEffort({
|
|
29
|
+
requested: params.thinkLevel,
|
|
30
|
+
supportedEfforts: supportedReasoningEfforts.map((effort) => effort.trim().toLowerCase()),
|
|
31
|
+
effortOrder: CODEX_REASONING_EFFORTS
|
|
32
|
+
}) ?? null;
|
|
33
|
+
if (params.thinkLevel === "minimal" && MODERN_GPT_5_MODEL_ID_RE.test(modelId)) return "low";
|
|
34
|
+
return params.thinkLevel === "max" ? null : params.thinkLevel;
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { resolveCodexAppServerReasoningEffort as n, readCodexSupportedReasoningEfforts as t };
|