@openclaw/codex 2026.9.2 → 2026.9.3
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/dist/api.js +14 -19
- package/dist/apply-B6el6hdO.js +357 -0
- package/dist/{attempt-client-cleanup-Bp1ZOnk2.js → attempt-client-cleanup-D6cR54TV.js} +39 -19
- package/dist/{attempt-context-CSazkWns.js → attempt-context-AO4DSjE0.js} +8 -6
- package/dist/{event-projector-usage-ZqEVbAEY.js → attempt-notifications--H8zXR5-.js} +3 -106
- package/dist/auth-cache-key-Kq6oerr6.js +498 -0
- package/dist/auth-profile-CwzO4_RG.js +43 -0
- package/dist/auth-profile-selection-DFu9e167.js +45 -0
- package/dist/binding-connection-QqgcPCgk.js +60 -0
- package/dist/{bounded-turn-DxGJRYbY.js → bounded-turn-lRpmZHFv.js} +25 -122
- package/dist/build-state-6RL6qohz.js +19 -0
- package/dist/{capabilities-B1mgvpP8.js → capabilities-BeqLPbtM.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/client-BEKu4yDx.js +3983 -0
- package/dist/command-dispatch-CisT9Jqq.js +21 -0
- package/dist/{command-formatters-DSbGMXA0.js → command-formatters-DeTfrapr.js} +2 -2
- package/dist/{command-handlers-DOJvGv6-.js → command-handlers-BfIsJEuA.js} +31 -21
- package/dist/command-rpc-BMqRQOFX.js +226 -0
- package/dist/{compact-Y_xBqrHN.js → compact-CGJZ2rlb.js} +19 -14
- package/dist/config-JDfTI4VI.js +106 -0
- package/dist/{config-CyapYSji.js → config-options-jnIFvwxD.js} +204 -592
- package/dist/config-runtime-BWf6JLWG.js +11 -0
- package/dist/conversation-binding-CxOlHiix.js +889 -0
- package/dist/{plugin-marketplace-discovery-B7gHXJ3d.js → conversation-control-CUCrSIQI.js} +10 -142
- package/dist/doctor-contract-api.js +5 -5
- package/dist/{dynamic-tools-BwpvTxaX.js → dynamic-tools-D-JBoaLt.js} +66 -70
- package/dist/{effective-mcp-catalog-CY9Jn4bA.js → effective-mcp-catalog-J_5Ep5Um.js} +3 -3
- package/dist/{elicitation-input-DMkeki8d.js → elicitation-input-DPoK8F7w.js} +8 -22
- package/dist/ephemeral-turn-DSwzP8YY.js +101 -0
- package/dist/{event-projector-assistant-message-B9kp6iGC.js → event-projector-assistant-message-BmBM4qBV.js} +12 -25
- package/dist/event-projector-usage-CIyrYYid.js +102 -0
- package/dist/{harness-Czh2Sdoc.js → harness-FR6eQgyO.js} +31 -24
- package/dist/harness.js +1 -1
- package/dist/history-rejection-B4nOXNXF.js +13 -0
- package/dist/incognito-session-uhrBF6wJ.js +15 -0
- package/dist/index.js +411 -2875
- package/dist/{isolated-completion-CRh-51AK.js → isolated-completion-DHBefrzg.js} +7 -4
- package/dist/launch-args-RXQwn8zV.js +90 -0
- package/dist/{managed-binary-DcpnJF9x.js → managed-binary-DrjjRRUD.js} +4 -103
- package/dist/managed-thread-store-D1t5jh3G.js +66 -0
- package/dist/media-understanding-provider.js +4 -1
- package/dist/{model-catalog-DT5vo6qo.js → model-catalog-B_6M04Wo.js} +6 -5
- package/dist/{models-CcrgSMQR.js → models-P9k2qAof.js} +3 -3
- package/dist/native-execution-policy-umd0tgh4.js +128 -0
- package/dist/{native-subagent-monitor-B3bvQGcg.js → native-subagent-monitor-BbCUKRwC.js} +69 -42
- package/dist/node-cli-sessions-rj0ysJwM.js +527 -0
- package/dist/{node-exec-server.runtime-nfbUOtUB.js → node-exec-server.runtime-BY_ctYnT.js} +53 -22
- package/dist/plan-BMJdMOEF.js +711 -0
- package/dist/plugin-activation-BQK-f5sV.js +133 -0
- package/dist/{thread-resume-BLgqkUc1.js → plugin-app-cache-key-CdSQzWyX.js} +4 -52
- package/dist/{plugin-approval-roundtrip-aQVdyL5g.js → plugin-approval-roundtrip-DeW95wB5.js} +1 -1
- package/dist/plugin-inventory-CoRCzWW4.js +325 -0
- package/dist/plugin-marketplace-discovery-3akBizzF.js +134 -0
- package/dist/{plugin-metadata-cache-BwCLTY_U.js → plugin-metadata-cache-DgNfRAGA.js} +13 -9
- package/dist/protocol-CAAcVIKF.js +275 -0
- package/dist/{provider-capabilities-BpG9Ltc5.js → provider-capabilities-W4tfK5Y5.js} +2 -2
- package/dist/{rate-limits-Fx_l4eNa.js → rate-limits-Bqnx1N4z.js} +1 -1
- package/dist/request-CGvGOpeR.js +198 -0
- package/dist/{run-attempt-BzthFQSM.js → run-attempt-DwKds3DN.js} +589 -373
- package/dist/{runtime-artifact-Bh_gf6-t.js → runtime-artifact-T-NwqeSH.js} +27 -27
- package/dist/sandbox-guard-BcT66fWy.js +165 -0
- package/dist/{session-binding-4Ki04sW-.js → session-binding-CKSepwIC.js} +29 -47
- package/dist/{session-binding-record-CyaXZvTe.js → session-binding-record-CaZjYwNS.js} +11 -25
- package/dist/session-catalog-HaDcp7Sv.js +1533 -0
- package/dist/session-catalog-adoption-BKLtSrwi.js +251 -0
- package/dist/session-catalog-archive-D0i2pGj2.js +56 -0
- package/dist/session-catalog-home-id-D7-aLiNt.js +190 -0
- package/dist/session-catalog-node-adoption-BUuDYY8R.js +182 -0
- package/dist/session-catalog-node-continue-CBtc4wkI.js +238 -0
- package/dist/session-catalog-parsing-CdD3JhdM.js +280 -0
- package/dist/session-catalog-provenance-DkJHo735.js +124 -0
- package/dist/{session-cli-BjLhpmS1.js → session-cli-CbgaHh0f.js} +3 -2
- package/dist/{session-history-DWmMqiqW.js → session-history-Cz-tOOYj.js} +6 -3
- package/dist/{session-upstream-marker-DReTpGz6.js → session-history-import-DFN7sWRU.js} +5 -50
- package/dist/{session-history-read-LHldwvyh.js → session-history-read-cxPUxyVV.js} +21 -7
- package/dist/session-history-worker-runtime.js +18 -6
- package/dist/{session-history.worker-zZVcx0ME.js → session-history.worker-CNEvGaU5.js} +58 -51
- package/dist/session-history.worker.js +1 -1
- package/dist/{session-initialization-BCFVnLL4.js → session-initialization-Jo86C60I.js} +2 -2
- package/dist/{session-permission-policy-BaueHmSj.js → session-permission-policy-B22InTp_.js} +4 -7
- package/dist/{session-retirement-DNdmYdFc.js → session-retirement-BSNG_mhf.js} +6 -5
- package/dist/session-upstream-marker-D15C9NHp.js +46 -0
- package/dist/{settled-turn-context-BOM3Y1pl.js → settled-turn-context-Du6gdUDd.js} +9 -9
- package/dist/{settled-turn-finalizer-BI-b1sry.js → settled-turn-finalizer-BuLUrZl2.js} +7 -6
- package/dist/shared-client-CVhez2Uo.js +2911 -0
- package/dist/{side-question-B6DWAw1A.js → side-question-DLbr2vUU.js} +64 -169
- package/dist/source-Da-h6f7e.js +518 -0
- package/dist/thread-archive-guard-D1bP04Tf.js +53 -0
- package/dist/{thread-lifecycle-DPK30jad.js → thread-lifecycle-D1pzRwHB.js} +112 -616
- package/dist/{thread-ownership-CbucAmmp.js → thread-ownership-D6oASVRu.js} +13 -15
- package/dist/thread-policy-D8kI7yAO.js +54 -0
- package/dist/thread-resume-T5cveyxA.js +52 -0
- package/dist/timeout-BVw8aaM1.js +33 -0
- package/dist/{transcript-mirror-attestation-Byl34PC-.js → transcript-mirror-attestation-DibE0krH.js} +17 -4
- package/dist/{transcript-mirror-_njEB84z.js → transcript-mirror-t5TOccct.js} +50 -260
- package/dist/{transport-stdio-CzTngV0j.js → transport-stdio-BGjHoYLr.js} +73 -43
- package/dist/{upstream-session-fork-1fwbNKzQ.js → upstream-session-fork-De-sLJ2r.js} +26 -18
- package/dist/{usage-i9fv5-4m.js → usage-CPPTmBvZ.js} +4 -3
- package/dist/version-omm6IPI3.js +12 -0
- package/dist/{web-search-provider.runtime-DKQn67A7.js → web-search-provider.runtime-CSVgQL0w.js} +3 -3
- package/openclaw.plugin.json +22 -1
- package/package.json +4 -4
- package/dist/request-C8H22rPi.js +0 -475
- package/dist/session-catalog-B47uwekb.js +0 -3272
- package/dist/shared-client-CKhX2kFt.js +0 -7505
- package/dist/thread-policy-CTalhWFy.js +0 -105
- package/dist/{auth-binding-Ds_QVm-X.js → auth-binding-Co2Vfcf_.js} +1 -1
|
@@ -1,486 +1,51 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
1
|
+
import { l as sessionBindingIdentity, n as assertCodexBindingMayBeReplaced } from "./session-binding-record-CaZjYwNS.js";
|
|
2
|
+
import { f as assertCodexModelBackedReviewerEffectiveConfig, g as readCodexEffectiveConfig, h as CODEX_SESSION_OVERRIDABLE_LAYER_TYPES, n as codexSandboxPolicyForTurn } from "./config-options-jnIFvwxD.js";
|
|
3
|
+
import { S as resolveCodexPluginsPolicy, a as flattenCodexDynamicToolFunctions, c as resolveCodexAppServerLocalHomeDir, o as isJsonObject, s as resolveCodexAppServerHomeDir } from "./protocol-CAAcVIKF.js";
|
|
4
|
+
import { L as resolveCodexToolAbortTerminalReason, _ as assertCodexThreadAcceptsDirectInput, b as assertCodexThreadStartResponse, d as isCodexAppServerRequestTimeoutError, l as isCodexAppServerOverloadError, p as resolveCodexAppServerClientInstanceId, r as getCodexAppServerClientInstanceId, v as assertCodexThreadForkResponse } from "./client-BEKu4yDx.js";
|
|
5
|
+
import { i as markStartedCodexManagedThread } from "./managed-thread-store-D1t5jh3G.js";
|
|
6
|
+
import { n as withCodexAppServerThreadMutation, t as isIncognitoSessionKey } from "./incognito-session-uhrBF6wJ.js";
|
|
7
|
+
import { i as isCodexThreadReadMissingError, n as readCodexSessionMeta, r as CodexAppServerRpcError } from "./session-catalog-provenance-DkJHo735.js";
|
|
8
|
+
import { n as codexCatalogHomeId, r as projectBoundedCodexThreadHistory } from "./session-catalog-home-id-D7-aLiNt.js";
|
|
9
|
+
import { c as serializeCodexAppInventoryError, o as CodexAppInventoryCache, s as defaultCodexAppInventoryCache, t as buildCodexAppServerConnectionFingerprint } from "./plugin-app-cache-key-CdSQzWyX.js";
|
|
10
|
+
import { t as withAbortableTimeout } from "./timeout-BVw8aaM1.js";
|
|
11
|
+
import "./config-JDfTI4VI.js";
|
|
11
12
|
import { r as sanitizeInlineImageDataUrl, t as invalidInlineImageText } from "./image-payload-sanitizer-tupAr-2o.js";
|
|
13
|
+
import { t as assertCodexSessionRuntimeOwnership } from "./binding-connection-QqgcPCgk.js";
|
|
14
|
+
import { n as normalizeCodexAppServerBindingModelProvider, t as isCodexAppServerNativeAuthProfile } from "./auth-profile-CwzO4_RG.js";
|
|
15
|
+
import { C as CodexThreadBindingConflictError, G as unsubscribeCodexAppServerLiveThread, H as readCodexClientSessionMeta, P as consumeCodexAppServerLiveThread, R as isCodexAppServerClientRuntimeLive, S as CodexAdoptedThreadActiveError, U as releaseCodexAppServerLiveThread, _ as retainSharedCodexAppServerClientByInstanceId, n as captureCodexAppServerClientLifetime, w as CodexThreadStartRequestError, z as isCodexAppServerLiveThreadClaimed } from "./shared-client-CVhez2Uo.js";
|
|
16
|
+
import { a as closeCodexStartupClientBestEffort, d as unsubscribeCodexThreadBestEffort, l as retireUnsafeCodexTurnClientBestEffort, n as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, r as CodexAppServerUnsafeSubscriptionError, s as isCodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-D6cR54TV.js";
|
|
17
|
+
import { a as readCodexPluginInventory, o as resolveOwnedAppApprovalOverrideKeys } from "./plugin-inventory-CoRCzWW4.js";
|
|
18
|
+
import { t as ensureCodexPluginActivation } from "./plugin-activation-BQK-f5sV.js";
|
|
19
|
+
import { o as resolveCodexSessionBinding, r as hashCodexAppServerBindingFingerprint } from "./session-binding-CKSepwIC.js";
|
|
20
|
+
import { i as refreshCodexThreadPolicy, n as CodexThreadPolicyHandoffError, r as assertCodexSupervisionThreadLineage, t as CodexIncognitoPolicyChangeError } from "./thread-policy-D8kI7yAO.js";
|
|
21
|
+
import { t as resumeCodexAppServerThread } from "./thread-resume-T5cveyxA.js";
|
|
22
|
+
import { r as retainCodexAppServerBindingSubscription, s as withExclusiveCodexAppServerThread } from "./thread-ownership-D6oASVRu.js";
|
|
23
|
+
import "./transcript-mirror-t5TOccct.js";
|
|
12
24
|
import { asOptionalRecord, isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
13
25
|
import * as crypto$1 from "node:crypto";
|
|
14
26
|
import crypto, { createHash } from "node:crypto";
|
|
15
27
|
import { resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
|
|
16
|
-
import { z } from "zod";
|
|
17
28
|
import { addTimerTimeoutGraceMs, finiteSecondsToTimerSafeMilliseconds } from "openclaw/plugin-sdk/number-runtime";
|
|
18
|
-
import fs from "node:fs/promises";
|
|
19
29
|
import path from "node:path";
|
|
30
|
+
import os from "node:os";
|
|
31
|
+
import fs from "node:fs/promises";
|
|
32
|
+
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
33
|
+
import { sliceUtf16Safe, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
20
34
|
import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
|
|
21
|
-
import {
|
|
35
|
+
import { createStageTimingTracker, formatStageTimings } from "openclaw/plugin-sdk/time-runtime";
|
|
22
36
|
import { isPathInside } from "openclaw/plugin-sdk/file-access-runtime";
|
|
23
|
-
import os from "node:os";
|
|
24
37
|
import { isDeepStrictEqual } from "node:util";
|
|
25
|
-
import { resolveAgentDir as resolveAgentDir$
|
|
26
|
-
import {
|
|
27
|
-
import { sliceUtf16Safe, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
38
|
+
import { resolveAgentDir as resolveAgentDir$1 } from "openclaw/plugin-sdk/agent-runtime";
|
|
39
|
+
import { AgentHarnessPreflightError, SKILL_WORKSHOP_TOOL_NAME, buildCredentialSafetyPrompt, buildDelegationGuidanceSection, buildHarnessVisibleReplyGuidance, buildSkillWorkshopPromptSection, buildTemporalContextText, buildUiPresentationPrompt, embeddedAgentLog, formatErrorMessage, isActiveHarnessContextEngine, isHostScopedAgentToolActive, isOpenClawRuntimeContextCustomMessage, resolveMainSessionDelegationMode } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
28
40
|
import { emitTrustedDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime";
|
|
29
|
-
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
30
41
|
import { redactSensitiveFieldValue, redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
|
|
42
|
+
import { IMAGE_BLOCK_TOKENS } from "openclaw/plugin-sdk/agent-core";
|
|
31
43
|
import { resolveRequiredHomeDir, resolveStateDir } from "openclaw/plugin-sdk/state-paths";
|
|
32
44
|
import { buildCodexUserMcpServersThreadConfigPatchForRun } from "openclaw/plugin-sdk/codex-mcp-projection";
|
|
33
45
|
import { registerRetainedNativeHookRelayForBundledRuntime } from "openclaw/plugin-sdk/native-hook-relay-runtime";
|
|
34
46
|
import { isDiagnosticFlagEnabled } from "openclaw/plugin-sdk/diagnostic-flags";
|
|
35
47
|
import { listRegisteredPluginAgentPromptGuidance } from "openclaw/plugin-sdk/plugin-runtime";
|
|
36
48
|
import { buildHostnameAllowlistPolicyFromSuffixAllowlist } from "openclaw/plugin-sdk/ssrf-policy";
|
|
37
|
-
//#region extensions/codex/src/app-server/plugin-inventory.ts
|
|
38
|
-
/**
|
|
39
|
-
* Reads Codex plugin marketplace state and app inventory to decide which
|
|
40
|
-
* plugin-owned apps can be exposed to a native Codex thread.
|
|
41
|
-
*/
|
|
42
|
-
const CODEX_PLUGINS_REMOTE_MARKETPLACE_NAME = `${CODEX_PLUGINS_MARKETPLACE_NAME}-remote`;
|
|
43
|
-
const CODEX_PLUGINS_API_MARKETPLACE_NAME = "openai-api-curated";
|
|
44
|
-
/** Reads configured Codex plugin state and maps owned apps to readiness diagnostics. */
|
|
45
|
-
async function readCodexPluginInventory(params) {
|
|
46
|
-
const policy = params.policy ?? resolveCodexPluginsPolicy(params.pluginConfig);
|
|
47
|
-
if (!policy.enabled) return {
|
|
48
|
-
policy,
|
|
49
|
-
records: [],
|
|
50
|
-
diagnostics: [{
|
|
51
|
-
code: "disabled",
|
|
52
|
-
message: "Native Codex plugin support is disabled."
|
|
53
|
-
}]
|
|
54
|
-
};
|
|
55
|
-
const appInventory = readCachedAppInventory(params);
|
|
56
|
-
const installedPlugins = await readInstalledCodexPluginMetadata({
|
|
57
|
-
...params,
|
|
58
|
-
policy
|
|
59
|
-
});
|
|
60
|
-
const pluginCatalogs = /* @__PURE__ */ new Map();
|
|
61
|
-
const diagnostics = [];
|
|
62
|
-
const records = [];
|
|
63
|
-
if (appInventory?.state === "missing") diagnostics.push({
|
|
64
|
-
code: "app_inventory_missing",
|
|
65
|
-
message: "Cached Codex app inventory is missing; plugin apps are excluded for this setup."
|
|
66
|
-
});
|
|
67
|
-
else if (appInventory?.state === "stale") diagnostics.push({
|
|
68
|
-
code: "app_inventory_stale",
|
|
69
|
-
message: "Cached Codex app inventory is stale; using stale app readiness and refreshing."
|
|
70
|
-
});
|
|
71
|
-
for (const pluginPolicy of policy.pluginPolicies) {
|
|
72
|
-
if (!pluginPolicy.enabled && !policy.allowAllPlugins) continue;
|
|
73
|
-
let listed = installedPlugins;
|
|
74
|
-
let resolvedPlugin = findConfiguredMarketplacePlugin(listed, pluginPolicy);
|
|
75
|
-
if (!resolvedPlugin && pluginPolicy.enabled && pluginPolicy.marketplaceName !== "workspace-directory") {
|
|
76
|
-
const requestParams = buildPluginCatalogRequestParams(params, pluginPolicy.marketplaceName);
|
|
77
|
-
const catalogKey = JSON.stringify([requestParams, pluginMetadataCatalogScope(pluginPolicy.marketplaceName)]);
|
|
78
|
-
let catalog = pluginCatalogs.get(catalogKey);
|
|
79
|
-
if (!catalog) {
|
|
80
|
-
catalog = listCodexPluginMetadata(params, pluginPolicy.marketplaceName);
|
|
81
|
-
pluginCatalogs.set(catalogKey, catalog);
|
|
82
|
-
}
|
|
83
|
-
listed = await catalog;
|
|
84
|
-
resolvedPlugin = findConfiguredMarketplacePlugin(listed, pluginPolicy);
|
|
85
|
-
}
|
|
86
|
-
if (!listed.marketplaces.some((marketplace) => marketplaceMatchesConfiguredName(marketplace, pluginPolicy.marketplaceName))) {
|
|
87
|
-
diagnostics.push({
|
|
88
|
-
code: "marketplace_missing",
|
|
89
|
-
plugin: pluginPolicy,
|
|
90
|
-
message: `Codex marketplace ${pluginPolicy.marketplaceName} was not found.`
|
|
91
|
-
});
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
if (!resolvedPlugin) {
|
|
95
|
-
diagnostics.push({
|
|
96
|
-
code: "plugin_missing",
|
|
97
|
-
plugin: pluginPolicy,
|
|
98
|
-
message: `${pluginPolicy.pluginName} was not found in ${pluginPolicy.marketplaceName}.`
|
|
99
|
-
});
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
const { summary } = resolvedPlugin;
|
|
103
|
-
const unavailableByMarketplacePolicy = summary.availability === "DISABLED_BY_ADMIN" || summary.installPolicy === "NOT_AVAILABLE";
|
|
104
|
-
if (unavailableByMarketplacePolicy) {
|
|
105
|
-
diagnostics.push({
|
|
106
|
-
code: "plugin_disabled",
|
|
107
|
-
plugin: pluginPolicy,
|
|
108
|
-
message: `${pluginPolicy.pluginName} is unavailable in ${pluginPolicy.marketplaceName}.`
|
|
109
|
-
});
|
|
110
|
-
if (!summary.installed) continue;
|
|
111
|
-
}
|
|
112
|
-
const detail = await readPluginDetail(params, marketplaceRef(resolvedPlugin.marketplace, pluginPolicy.marketplaceName), pluginPolicy, summary, diagnostics);
|
|
113
|
-
const ownedAppIds = detail?.apps.map((app) => app.id).filter(Boolean).toSorted() ?? [];
|
|
114
|
-
const appOwnership = resolveAppOwnership({
|
|
115
|
-
detail,
|
|
116
|
-
appInventory,
|
|
117
|
-
summary
|
|
118
|
-
});
|
|
119
|
-
if (appOwnership === "ambiguous") diagnostics.push({
|
|
120
|
-
code: "app_ownership_ambiguous",
|
|
121
|
-
plugin: pluginPolicy,
|
|
122
|
-
message: `${pluginPolicy.pluginName} has only display-name app matches; apps are not exposed until ownership is stable.`
|
|
123
|
-
});
|
|
124
|
-
if (summary.installed && !summary.enabled) diagnostics.push({
|
|
125
|
-
code: "plugin_disabled",
|
|
126
|
-
plugin: pluginPolicy,
|
|
127
|
-
message: `${pluginPolicy.pluginName} is installed in Codex but disabled.`
|
|
128
|
-
});
|
|
129
|
-
const apps = resolveOwnedApps({
|
|
130
|
-
pluginPolicy,
|
|
131
|
-
detail,
|
|
132
|
-
appInventory
|
|
133
|
-
});
|
|
134
|
-
records.push({
|
|
135
|
-
policy: pluginPolicy,
|
|
136
|
-
summary,
|
|
137
|
-
...detail ? { detail } : {},
|
|
138
|
-
activationRequired: pluginPolicy.enabled && (unavailableByMarketplacePolicy || !summary.installed || !summary.enabled),
|
|
139
|
-
authRequired: apps.some((app) => app.needsAuth || !app.accessible),
|
|
140
|
-
appOwnership,
|
|
141
|
-
ownedAppIds,
|
|
142
|
-
apps
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
return {
|
|
146
|
-
policy,
|
|
147
|
-
records,
|
|
148
|
-
diagnostics,
|
|
149
|
-
...appInventory ? { appInventory } : {}
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
/** Finds a configured plugin only in its authorized marketplace identity. */
|
|
153
|
-
function findCodexMarketplacePluginSummary(listed, marketplaceName, pluginName) {
|
|
154
|
-
const resolved = findConfiguredMarketplacePlugin(listed, {
|
|
155
|
-
marketplaceName,
|
|
156
|
-
pluginName
|
|
157
|
-
});
|
|
158
|
-
return resolved ? {
|
|
159
|
-
marketplace: marketplaceRef(resolved.marketplace, marketplaceName),
|
|
160
|
-
summary: resolved.summary
|
|
161
|
-
} : void 0;
|
|
162
|
-
}
|
|
163
|
-
/** Builds plugin/read or plugin/install params from a marketplace reference. */
|
|
164
|
-
function pluginReadParams(marketplace, pluginName) {
|
|
165
|
-
return {
|
|
166
|
-
...marketplace.path ? { marketplacePath: marketplace.path } : {},
|
|
167
|
-
...marketplace.remoteMarketplaceName ? { remoteMarketplaceName: marketplace.remoteMarketplaceName } : {},
|
|
168
|
-
pluginName
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
/** Returns configured plugin keys whose current metadata may still recover. */
|
|
172
|
-
function resolveRecoverableCodexPluginConfigKeys(params) {
|
|
173
|
-
return params.policy.pluginPolicies.filter((pluginPolicy) => pluginPolicy.enabled && !isSettledMissingPluginPolicy({
|
|
174
|
-
pluginPolicy,
|
|
175
|
-
metadataCache: params.metadataCache,
|
|
176
|
-
appCacheKey: params.appCacheKey,
|
|
177
|
-
configCwd: params.configCwd
|
|
178
|
-
})).map((pluginPolicy) => pluginPolicy.configKey).toSorted();
|
|
179
|
-
}
|
|
180
|
-
async function listCodexPluginMetadata(params, marketplaceName) {
|
|
181
|
-
const requestParams = buildPluginCatalogRequestParams(params, marketplaceName);
|
|
182
|
-
if (!params.metadataCache || !params.appCacheKey) return await params.request("plugin/list", requestParams);
|
|
183
|
-
return (await params.metadataCache.load({
|
|
184
|
-
appCacheKey: params.appCacheKey,
|
|
185
|
-
queryKind: "curated-global",
|
|
186
|
-
requestParams,
|
|
187
|
-
catalogScope: pluginMetadataCatalogScope(marketplaceName),
|
|
188
|
-
request: async (method, listedParams) => await params.request(method, listedParams),
|
|
189
|
-
cacheable: (response) => response.marketplaces.some((marketplace) => marketplaceMatchesConfiguredName(marketplace, marketplaceName))
|
|
190
|
-
})).response;
|
|
191
|
-
}
|
|
192
|
-
async function readInstalledCodexPluginMetadata(params) {
|
|
193
|
-
const requestParams = params.configCwd ? { cwds: [params.configCwd] } : {};
|
|
194
|
-
if (!params.metadataCache || !params.appCacheKey) return await params.request("plugin/installed", requestParams);
|
|
195
|
-
return (await params.metadataCache.load({
|
|
196
|
-
appCacheKey: params.appCacheKey,
|
|
197
|
-
queryKind: "installed",
|
|
198
|
-
requestParams,
|
|
199
|
-
request: async (method, installedParams) => await params.request(method, installedParams),
|
|
200
|
-
cacheable: (response) => params.policy.pluginPolicies.every((pluginPolicy) => {
|
|
201
|
-
if (!pluginPolicy.enabled && !params.policy.allowAllPlugins) return true;
|
|
202
|
-
return Boolean(findConfiguredMarketplacePlugin(response, pluginPolicy));
|
|
203
|
-
})
|
|
204
|
-
})).response;
|
|
205
|
-
}
|
|
206
|
-
function isSettledMissingPluginPolicy(params) {
|
|
207
|
-
const queryKind = params.pluginPolicy.marketplaceName === "workspace-directory" ? "installed" : "curated-global";
|
|
208
|
-
const requestParams = queryKind === "installed" ? params.configCwd ? { cwds: [params.configCwd] } : {} : buildPluginCatalogRequestParams(params, params.pluginPolicy.marketplaceName);
|
|
209
|
-
const listed = params.metadataCache.read(params.appCacheKey, queryKind, requestParams, queryKind === "curated-global" ? pluginMetadataCatalogScope(params.pluginPolicy.marketplaceName) : void 0)?.response;
|
|
210
|
-
if (!listed) return false;
|
|
211
|
-
return !findConfiguredMarketplacePlugin(listed, params.pluginPolicy);
|
|
212
|
-
}
|
|
213
|
-
function pluginMetadataCatalogScope(marketplaceName) {
|
|
214
|
-
return isOpenAiCuratedMarketplaceName(marketplaceName) ? void 0 : marketplaceName;
|
|
215
|
-
}
|
|
216
|
-
function buildPluginCatalogRequestParams(params, marketplaceName) {
|
|
217
|
-
const marketplaceKinds = marketplaceName === "created-by-me-remote" ? ["created-by-me-remote"] : marketplaceName.startsWith("workspace-shared-with-me") ? ["shared-with-me"] : void 0;
|
|
218
|
-
return {
|
|
219
|
-
...params.configCwd ? { cwds: [params.configCwd] } : {},
|
|
220
|
-
...marketplaceKinds ? { marketplaceKinds: [...marketplaceKinds] } : {}
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
function readCachedAppInventory(params) {
|
|
224
|
-
if (!params.appCache || !params.appCacheKey) return;
|
|
225
|
-
const request = async (method, requestParams) => await params.request(method, requestParams);
|
|
226
|
-
return params.appCache.read({
|
|
227
|
-
key: params.appCacheKey,
|
|
228
|
-
request,
|
|
229
|
-
nowMs: params.nowMs,
|
|
230
|
-
suppressRefresh: params.suppressAppInventoryRefresh
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
async function readPluginDetail(params, marketplace, pluginPolicy, summary, diagnostics) {
|
|
234
|
-
if (params.readPluginDetails === false) return;
|
|
235
|
-
if (marketplace.remoteMarketplaceName && !summary.remotePluginId) {
|
|
236
|
-
diagnostics.push({
|
|
237
|
-
code: "plugin_detail_unavailable",
|
|
238
|
-
plugin: pluginPolicy,
|
|
239
|
-
message: `${pluginPolicy.pluginName} detail unavailable: Codex did not return a remote plugin id.`
|
|
240
|
-
});
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
try {
|
|
244
|
-
return (await params.request("plugin/read", pluginReadParams(marketplace, marketplace.remoteMarketplaceName && summary.remotePluginId ? summary.remotePluginId : pluginPolicy.pluginName))).plugin;
|
|
245
|
-
} catch (error) {
|
|
246
|
-
diagnostics.push({
|
|
247
|
-
code: "plugin_detail_unavailable",
|
|
248
|
-
plugin: pluginPolicy,
|
|
249
|
-
message: `${pluginPolicy.pluginName} detail unavailable: ${error instanceof Error ? error.message : String(error)}`
|
|
250
|
-
});
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
function resolveAppOwnership(params) {
|
|
255
|
-
if (params.detail && params.detail.apps.length > 0) return "proven";
|
|
256
|
-
return (params.appInventory?.snapshot?.apps ?? []).filter((app) => app.pluginDisplayNames.some((displayName) => displayName === params.summary.name)).length > 0 ? "ambiguous" : "none";
|
|
257
|
-
}
|
|
258
|
-
function resolveOwnedApps(params) {
|
|
259
|
-
const detailApps = params.detail?.apps ?? [];
|
|
260
|
-
if (detailApps.length === 0) return [];
|
|
261
|
-
if (params.appInventory?.state === "missing") {
|
|
262
|
-
embeddedAgentLog.warn("codex plugin inventory missing app inventory for detail apps", {
|
|
263
|
-
configKey: params.pluginPolicy.configKey,
|
|
264
|
-
pluginName: params.pluginPolicy.pluginName,
|
|
265
|
-
appIds: detailApps.map((app) => app.id).toSorted()
|
|
266
|
-
});
|
|
267
|
-
return [];
|
|
268
|
-
}
|
|
269
|
-
const appInfoById = new Map((params.appInventory?.snapshot?.apps ?? []).map((app) => [app.id, app]));
|
|
270
|
-
return detailApps.map((app) => {
|
|
271
|
-
const info = appInfoById.get(app.id);
|
|
272
|
-
if (!info) return {
|
|
273
|
-
id: app.id,
|
|
274
|
-
name: app.name,
|
|
275
|
-
accessible: false,
|
|
276
|
-
enabled: false,
|
|
277
|
-
needsAuth: true
|
|
278
|
-
};
|
|
279
|
-
return Object.assign({
|
|
280
|
-
id: app.id,
|
|
281
|
-
name: app.name,
|
|
282
|
-
accessible: info.isAccessible,
|
|
283
|
-
enabled: info.isEnabled,
|
|
284
|
-
needsAuth: !info.isAccessible
|
|
285
|
-
}, resolveOwnedAppApprovalOverrideKeys(info));
|
|
286
|
-
}).toSorted((left, right) => left.id.localeCompare(right.id));
|
|
287
|
-
}
|
|
288
|
-
/** Returns current tool keys whose overrides could bypass the requested reviewer. */
|
|
289
|
-
function resolveOwnedAppApprovalOverrideKeys(app) {
|
|
290
|
-
if (!app.toolSummaries) return {};
|
|
291
|
-
const appName = app.name.trim();
|
|
292
|
-
const appNameLower = appName.toLowerCase();
|
|
293
|
-
const keys = app.toolSummaries.filter((tool) => !tool.isReadOnly).flatMap((tool) => resolveAppToolConfigKeys({
|
|
294
|
-
appName,
|
|
295
|
-
appNameLower,
|
|
296
|
-
tool
|
|
297
|
-
}));
|
|
298
|
-
return { approvalOverrideToolConfigKeys: Array.from(new Set(keys)).toSorted() };
|
|
299
|
-
}
|
|
300
|
-
function resolveAppToolConfigKeys(params) {
|
|
301
|
-
const keys = [params.tool.name];
|
|
302
|
-
if (params.tool.title) keys.push(params.tool.title);
|
|
303
|
-
if (params.appName) keys.push(`${params.appName}_${params.tool.name}`);
|
|
304
|
-
if (params.appNameLower && params.appNameLower !== params.appName) keys.push(`${params.appNameLower}_${params.tool.name}`);
|
|
305
|
-
return keys;
|
|
306
|
-
}
|
|
307
|
-
function findPluginSummary(marketplace, pluginName) {
|
|
308
|
-
const exact = marketplace.plugins.find((plugin) => plugin.id === pluginName || plugin.id === `${pluginName}@${marketplace.name}`);
|
|
309
|
-
if (exact) return exact;
|
|
310
|
-
const matches = marketplace.plugins.filter((plugin) => plugin.name === pluginName || pluginNameFromPluginId(plugin.id, marketplace.name) === pluginName);
|
|
311
|
-
return matches.length === 1 ? matches[0] : void 0;
|
|
312
|
-
}
|
|
313
|
-
function findConfiguredMarketplacePlugin(listed, plugin) {
|
|
314
|
-
if (plugin.marketplaceName === "workspace-directory") return findWorkspaceMarketplacePlugin(listed, plugin.pluginName);
|
|
315
|
-
for (const marketplace of listed.marketplaces) {
|
|
316
|
-
if (!marketplaceMatchesConfiguredName(marketplace, plugin.marketplaceName)) continue;
|
|
317
|
-
const summary = findPluginSummary(marketplace, plugin.pluginName);
|
|
318
|
-
if (summary) return {
|
|
319
|
-
marketplace,
|
|
320
|
-
summary
|
|
321
|
-
};
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
function marketplaceMatchesConfiguredName(marketplace, configuredMarketplaceName) {
|
|
325
|
-
return isOpenAiCuratedMarketplaceName(configuredMarketplaceName) ? isOpenAiCuratedMarketplace(marketplace) : marketplace.name === configuredMarketplaceName;
|
|
326
|
-
}
|
|
327
|
-
function findWorkspaceMarketplacePlugin(listed, pluginName) {
|
|
328
|
-
const marketplace = listed.marketplaces.find((entry) => entry.name === CODEX_PLUGINS_WORKSPACE_MARKETPLACE_NAME);
|
|
329
|
-
const summary = marketplace?.plugins.find((plugin) => plugin.id === pluginName);
|
|
330
|
-
return marketplace && summary ? {
|
|
331
|
-
marketplace,
|
|
332
|
-
summary
|
|
333
|
-
} : void 0;
|
|
334
|
-
}
|
|
335
|
-
function pluginNameFromPluginId(pluginId, marketplaceName) {
|
|
336
|
-
const trimmed = pluginId.trim();
|
|
337
|
-
if (!trimmed) return;
|
|
338
|
-
const marketplaceSuffix = `@${marketplaceName}`;
|
|
339
|
-
return (trimmed.endsWith(marketplaceSuffix) ? trimmed.slice(0, -marketplaceSuffix.length) : trimmed).split("/").at(-1)?.trim() || void 0;
|
|
340
|
-
}
|
|
341
|
-
function marketplaceRef(marketplace, name) {
|
|
342
|
-
return {
|
|
343
|
-
name,
|
|
344
|
-
...marketplace.path ? { path: marketplace.path } : {},
|
|
345
|
-
...!marketplace.path ? { remoteMarketplaceName: marketplace.name } : {}
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
|
-
/** True for any supported OpenAI curated marketplace wire name, matching Codex's own curated predicate. */
|
|
349
|
-
function isOpenAiCuratedMarketplace(marketplace) {
|
|
350
|
-
return isOpenAiCuratedMarketplaceName(marketplace.name);
|
|
351
|
-
}
|
|
352
|
-
/** True for all Codex wire aliases of the same OpenAI-curated catalog. */
|
|
353
|
-
function isOpenAiCuratedMarketplaceName(marketplaceName) {
|
|
354
|
-
return marketplaceName === "openai-curated" || marketplaceName === CODEX_PLUGINS_REMOTE_MARKETPLACE_NAME || marketplaceName === CODEX_PLUGINS_API_MARKETPLACE_NAME;
|
|
355
|
-
}
|
|
356
|
-
//#endregion
|
|
357
|
-
//#region extensions/codex/src/app-server/plugin-activation.ts
|
|
358
|
-
/**
|
|
359
|
-
* Activates legacy curated Codex plugins while requiring owner-managed
|
|
360
|
-
* installation for every other marketplace.
|
|
361
|
-
*/
|
|
362
|
-
/** Activates legacy curated plugins without granting install authority to other marketplaces. */
|
|
363
|
-
async function ensureCodexPluginActivation(params) {
|
|
364
|
-
if (params.identity.marketplaceName === "workspace-directory") return activationFailure(params.identity, "disabled", { message: "workspace-directory plugins must be installed and enabled outside OpenClaw before use." });
|
|
365
|
-
if (!isOpenAiCuratedMarketplaceName(params.identity.marketplaceName)) {
|
|
366
|
-
const target = params.identity.pluginName.endsWith(`@${params.identity.marketplaceName}`) ? params.identity.pluginName : `${params.identity.pluginName}@${params.identity.marketplaceName}`;
|
|
367
|
-
return activationFailure(params.identity, "disabled", { message: `${params.identity.marketplaceName} plugins must be installed and enabled by an owner before use. Run /codex plugins install ${target}.` });
|
|
368
|
-
}
|
|
369
|
-
const listed = await listCuratedCodexPluginMetadata(params);
|
|
370
|
-
const resolved = findCodexMarketplacePluginSummary(listed, params.identity.marketplaceName, params.identity.pluginName);
|
|
371
|
-
if (!resolved) {
|
|
372
|
-
if (!listed.marketplaces.some((marketplace) => isOpenAiCuratedMarketplace(marketplace))) return activationFailure(params.identity, "marketplace_missing", { message: `Codex marketplace ${CODEX_PLUGINS_MARKETPLACE_NAME} was not found.` });
|
|
373
|
-
return activationFailure(params.identity, "plugin_missing", { message: `${params.identity.pluginName} was not found in ${CODEX_PLUGINS_MARKETPLACE_NAME}.` });
|
|
374
|
-
}
|
|
375
|
-
if (resolved.marketplace.remoteMarketplaceName && !resolved.summary.remotePluginId) return activationFailure(params.identity, "plugin_missing", { message: `${params.identity.pluginName} detail unavailable: Codex did not return a remote plugin id.` });
|
|
376
|
-
if (resolved.summary.availability === "DISABLED_BY_ADMIN" || resolved.summary.installPolicy === "NOT_AVAILABLE") return activationFailure(params.identity, "disabled", { message: `${params.identity.pluginName} was disabled or made unavailable by its marketplace administrator.` });
|
|
377
|
-
if (resolved.summary.installed && resolved.summary.enabled && !params.installEvenIfActive) return {
|
|
378
|
-
identity: params.identity,
|
|
379
|
-
ok: true,
|
|
380
|
-
reason: "already_active",
|
|
381
|
-
installAttempted: false,
|
|
382
|
-
marketplace: resolved.marketplace,
|
|
383
|
-
diagnostics: []
|
|
384
|
-
};
|
|
385
|
-
const remotePluginId = resolved.marketplace.remoteMarketplaceName ? resolved.summary.remotePluginId : void 0;
|
|
386
|
-
let installResponse;
|
|
387
|
-
try {
|
|
388
|
-
installResponse = await params.request("plugin/install", pluginReadParams(resolved.marketplace, remotePluginId ?? params.identity.pluginName));
|
|
389
|
-
} catch (error) {
|
|
390
|
-
if (!(error instanceof CodexAppServerRpcError) || error.code !== -32600 || !remotePluginId || error.message !== `remote plugin ${remotePluginId} is disabled by admin` && error.message !== `remote plugin ${remotePluginId} is not available for install`) throw error;
|
|
391
|
-
return {
|
|
392
|
-
identity: params.identity,
|
|
393
|
-
ok: false,
|
|
394
|
-
reason: "install_failed",
|
|
395
|
-
installAttempted: true,
|
|
396
|
-
marketplace: resolved.marketplace,
|
|
397
|
-
diagnostics: [{ message: `Codex plugin install failed: ${coerceErrorMessage(error)}` }]
|
|
398
|
-
};
|
|
399
|
-
}
|
|
400
|
-
if (params.metadataCache && params.appCacheKey) params.metadataCache.invalidate(params.appCacheKey);
|
|
401
|
-
const refreshDiagnostics = [];
|
|
402
|
-
let refreshFailed = false;
|
|
403
|
-
try {
|
|
404
|
-
const refreshResult = await refreshCodexPluginRuntimeState({
|
|
405
|
-
request: params.request,
|
|
406
|
-
appCache: params.appCache,
|
|
407
|
-
appCacheKey: params.appCacheKey,
|
|
408
|
-
configCwd: params.configCwd,
|
|
409
|
-
metadataCache: params.metadataCache,
|
|
410
|
-
deferAppInventoryRefresh: params.deferAppInventoryRefresh,
|
|
411
|
-
targetAppIds: params.targetAppIds
|
|
412
|
-
});
|
|
413
|
-
refreshDiagnostics.push(...refreshResult.diagnostics);
|
|
414
|
-
} catch (error) {
|
|
415
|
-
refreshFailed = true;
|
|
416
|
-
refreshDiagnostics.push({ message: `Codex plugin runtime refresh failed after install: ${coerceErrorMessage(error)}` });
|
|
417
|
-
}
|
|
418
|
-
const authRequired = installResponse.appsNeedingAuth.length > 0;
|
|
419
|
-
return {
|
|
420
|
-
identity: params.identity,
|
|
421
|
-
ok: !authRequired && !refreshFailed,
|
|
422
|
-
reason: refreshFailed ? "refresh_failed" : authRequired ? "auth_required" : resolved.summary.installed && resolved.summary.enabled ? "already_active" : "installed",
|
|
423
|
-
installAttempted: true,
|
|
424
|
-
marketplace: resolved.marketplace,
|
|
425
|
-
installResponse,
|
|
426
|
-
diagnostics: [...refreshDiagnostics, ...installResponse.appsNeedingAuth.map((app) => ({ message: `${app.name} requires app authentication before plugin tools are exposed.` }))]
|
|
427
|
-
};
|
|
428
|
-
}
|
|
429
|
-
/** Forces Codex plugin, skill, hook, MCP, and app inventory refreshes after activation. */
|
|
430
|
-
async function refreshCodexPluginRuntimeState(params) {
|
|
431
|
-
const diagnostics = [];
|
|
432
|
-
await listCuratedCodexPluginMetadata(params, { forceRefetch: true });
|
|
433
|
-
await params.request("skills/list", {
|
|
434
|
-
cwds: params.configCwd ? [params.configCwd] : [],
|
|
435
|
-
forceReload: true
|
|
436
|
-
});
|
|
437
|
-
try {
|
|
438
|
-
await params.request("hooks/list", { cwds: params.configCwd ? [params.configCwd] : [] });
|
|
439
|
-
} catch (error) {
|
|
440
|
-
diagnostics.push({ message: `Codex hooks refresh skipped: ${coerceErrorMessage(error)}` });
|
|
441
|
-
}
|
|
442
|
-
await params.request("config/mcpServer/reload", void 0);
|
|
443
|
-
if (params.appCache && params.appCacheKey) {
|
|
444
|
-
params.appCache.invalidate(params.appCacheKey, "Codex plugin activation changed app inventory", void 0, params.targetAppIds);
|
|
445
|
-
if (params.deferAppInventoryRefresh) return { diagnostics };
|
|
446
|
-
const request = async (method, requestParams) => await params.request(method, requestParams);
|
|
447
|
-
try {
|
|
448
|
-
await params.appCache.refreshNow({
|
|
449
|
-
key: params.appCacheKey,
|
|
450
|
-
request,
|
|
451
|
-
forceRefetch: true,
|
|
452
|
-
targetAppIds: params.targetAppIds
|
|
453
|
-
});
|
|
454
|
-
} catch (error) {
|
|
455
|
-
diagnostics.push({ message: `Codex app inventory refresh skipped: ${coerceErrorMessage(error)}` });
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
return { diagnostics };
|
|
459
|
-
}
|
|
460
|
-
async function listCuratedCodexPluginMetadata(params, options = {}) {
|
|
461
|
-
const requestParams = {
|
|
462
|
-
...params.configCwd ? { cwds: [params.configCwd] } : {},
|
|
463
|
-
...options.forceRefetch ? { forceRefetch: true } : {}
|
|
464
|
-
};
|
|
465
|
-
if (!params.metadataCache || !params.appCacheKey) return await params.request("plugin/list", requestParams);
|
|
466
|
-
return (await params.metadataCache.load({
|
|
467
|
-
appCacheKey: params.appCacheKey,
|
|
468
|
-
queryKind: "curated-global",
|
|
469
|
-
requestParams,
|
|
470
|
-
request: async (method, listedParams) => await params.request(method, listedParams),
|
|
471
|
-
cacheable: (response) => response.marketplaces.some((marketplace) => isOpenAiCuratedMarketplace(marketplace))
|
|
472
|
-
})).response;
|
|
473
|
-
}
|
|
474
|
-
function activationFailure(identity, reason, diagnostic, extraDiagnostics = []) {
|
|
475
|
-
return {
|
|
476
|
-
identity,
|
|
477
|
-
ok: false,
|
|
478
|
-
reason,
|
|
479
|
-
installAttempted: false,
|
|
480
|
-
diagnostics: [diagnostic, ...extraDiagnostics]
|
|
481
|
-
};
|
|
482
|
-
}
|
|
483
|
-
//#endregion
|
|
484
49
|
//#region extensions/codex/src/app-server/plugin-app-approval-overrides.ts
|
|
485
50
|
/** Projects ask approvals into the native session layer without changing saved settings. */
|
|
486
51
|
function buildCodexAppApprovalOverrides(config, app) {
|
|
@@ -1050,6 +615,12 @@ function stringifyCodexPluginPolicy(value) {
|
|
|
1050
615
|
}
|
|
1051
616
|
//#endregion
|
|
1052
617
|
//#region extensions/codex/src/app-server/context-engine-projection.ts
|
|
618
|
+
/**
|
|
619
|
+
* Projects OpenClaw context-engine assemblies into Codex prompt text while
|
|
620
|
+
* preserving safety boundaries and redacting tool payloads.
|
|
621
|
+
*/
|
|
622
|
+
/** Attachment preparation must not degrade to a prompt that silently loses the saved input. */
|
|
623
|
+
var CodexContextAttachmentError = class extends Error {};
|
|
1053
624
|
const CONTEXT_HEADER = "OpenClaw assembled context for this turn:";
|
|
1054
625
|
const CONTEXT_OPEN = "<conversation_context>";
|
|
1055
626
|
const CONTEXT_CLOSE = "</conversation_context>";
|
|
@@ -1068,16 +639,22 @@ const MIN_PROMPT_BUDGET_TOKENS = 8e3;
|
|
|
1068
639
|
function neutralizeCodexExplicitMentionSigils(text) {
|
|
1069
640
|
return text.replace(/\$(?=[A-Za-z0-9_:-])/gu, "$").replace(/\[@(?=[A-Za-z0-9_:-]+\]\()/gu, "[@");
|
|
1070
641
|
}
|
|
642
|
+
/** Hidden durable notes are context; transient runtime carriers are current-turn only. */
|
|
643
|
+
function isCodexDurableCustomMessage(message) {
|
|
644
|
+
return message.role === "custom" && message.excludeFromContext !== true && !isOpenClawRuntimeContextCustomMessage(message);
|
|
645
|
+
}
|
|
1071
646
|
/** Projects assembled OpenClaw context-engine messages into Codex prompt inputs. */
|
|
1072
|
-
function projectContextEngineAssemblyForCodex(params) {
|
|
647
|
+
async function projectContextEngineAssemblyForCodex(params) {
|
|
1073
648
|
const prompt = params.prompt.trim();
|
|
1074
|
-
const contextMessages = dropDuplicateTrailingPrompt(params.assembledMessages, prompt);
|
|
1075
649
|
const maxRenderedContextChars = normalizeRenderedContextMaxChars(params.maxRenderedContextChars);
|
|
1076
|
-
const
|
|
650
|
+
const context = await renderMessagesForCodexContext(params.assembledMessages.filter((message) => message.role !== "custom" || isCodexDurableCustomMessage(message)), {
|
|
1077
651
|
maxTextPartChars: resolveTextPartMaxChars(maxRenderedContextChars),
|
|
1078
652
|
toolPayloadMode: params.toolPayloadMode ?? "elide",
|
|
1079
|
-
maxRenderedContextChars
|
|
653
|
+
maxRenderedContextChars,
|
|
654
|
+
prepareFileContext: params.prepareFileContext,
|
|
655
|
+
currentUserTurnIdempotencyKey: params.currentUserTurnIdempotencyKey
|
|
1080
656
|
});
|
|
657
|
+
const boundedContext = context.text;
|
|
1081
658
|
const promptPrefix = boundedContext ? [
|
|
1082
659
|
CONTEXT_HEADER,
|
|
1083
660
|
CONTEXT_SAFETY_NOTE,
|
|
@@ -1095,7 +672,8 @@ function projectContextEngineAssemblyForCodex(params) {
|
|
|
1095
672
|
promptText,
|
|
1096
673
|
...promptContextRange ? { promptContextRange } : {},
|
|
1097
674
|
assembledMessages: params.assembledMessages,
|
|
1098
|
-
prePromptMessageCount: params.originalHistoryMessages.length
|
|
675
|
+
prePromptMessageCount: params.originalHistoryMessages.length,
|
|
676
|
+
...context.images.length ? { images: context.images } : {}
|
|
1099
677
|
};
|
|
1100
678
|
}
|
|
1101
679
|
/** Resolves rendered context size from a token budget and reserve. */
|
|
@@ -1183,30 +761,43 @@ function resolveProjectionPromptBudgetTokens(params) {
|
|
|
1183
761
|
const effectiveReserveTokens = Math.min(requestedReserveTokens, Math.max(0, params.contextTokenBudget - minPromptBudget));
|
|
1184
762
|
return Math.max(1, params.contextTokenBudget - effectiveReserveTokens);
|
|
1185
763
|
}
|
|
1186
|
-
function
|
|
1187
|
-
if (!prompt) return messages;
|
|
1188
|
-
const trailing = messages.at(-1);
|
|
1189
|
-
if (!trailing || trailing.role !== "user") return messages;
|
|
1190
|
-
return extractMessageText(trailing).trim() === prompt ? messages.slice(0, -1) : messages;
|
|
1191
|
-
}
|
|
1192
|
-
function renderMessagesForCodexContext(messages, options) {
|
|
764
|
+
async function renderMessagesForCodexContext(messages, options) {
|
|
1193
765
|
const tail = [];
|
|
766
|
+
const images = [];
|
|
767
|
+
let retainedImageChars = 0;
|
|
1194
768
|
let totalChars = 0;
|
|
1195
769
|
let retainedChars = 0;
|
|
1196
770
|
for (let index = messages.length - 1; index >= 0; index--) {
|
|
1197
771
|
const message = messages[index];
|
|
1198
|
-
|
|
1199
|
-
|
|
772
|
+
if (message.role === "user" && options.currentUserTurnIdempotencyKey && Reflect.get(message, "idempotencyKey") === options.currentUserTurnIdempotencyKey) continue;
|
|
773
|
+
const remaining = options.maxRenderedContextChars - retainedChars;
|
|
774
|
+
const files = remaining > 0 && message.role === "user" ? await options.prepareFileContext?.(message, Math.min(remaining, options.maxTextPartChars)) : void 0;
|
|
775
|
+
const imageChars = (files?.images.length ?? 0) * IMAGE_BLOCK_TOKENS * APPROX_RENDERED_CHARS_PER_TOKEN;
|
|
776
|
+
const imagesFit = imageChars < remaining;
|
|
777
|
+
const acceptedImageChars = imagesFit ? imageChars : 0;
|
|
778
|
+
const text = [
|
|
779
|
+
renderMessageBody(message, {
|
|
780
|
+
...options,
|
|
781
|
+
mediaPrepared: files !== void 0
|
|
782
|
+
}),
|
|
783
|
+
files?.text ? truncateText(files.text, options.maxTextPartChars) : void 0,
|
|
784
|
+
imageChars > 0 && !imagesFit ? "[Attachment images omitted: context budget exceeded]" : void 0
|
|
785
|
+
].filter(Boolean).join("\n\n");
|
|
786
|
+
if (!text && acceptedImageChars === 0) continue;
|
|
1200
787
|
const chunk = `[${message.role}]\n${text}${totalChars > 0 ? "\n\n" : ""}`;
|
|
1201
788
|
totalChars += chunk.length;
|
|
1202
|
-
const remaining = options.maxRenderedContextChars - retainedChars;
|
|
1203
789
|
if (remaining > 0) {
|
|
1204
|
-
const retained = neutralizeCodexExplicitMentionSigils(chunk).slice(-remaining);
|
|
790
|
+
const retained = neutralizeCodexExplicitMentionSigils(chunk).slice(-(remaining - acceptedImageChars));
|
|
1205
791
|
tail.push(retained);
|
|
1206
|
-
retainedChars += retained.length;
|
|
792
|
+
retainedChars += retained.length + acceptedImageChars;
|
|
793
|
+
retainedImageChars += acceptedImageChars;
|
|
794
|
+
if (imagesFit && files?.images.length) images.unshift(...files.images);
|
|
1207
795
|
}
|
|
1208
796
|
}
|
|
1209
|
-
return
|
|
797
|
+
return {
|
|
798
|
+
text: truncateOlderContext(tail.toReversed().join(""), options.maxRenderedContextChars - retainedImageChars, totalChars),
|
|
799
|
+
images
|
|
800
|
+
};
|
|
1210
801
|
}
|
|
1211
802
|
function renderMessageBody(message, options) {
|
|
1212
803
|
if (message.role === "compactionSummary" || message.role === "branchSummary") return truncateText(message.summary.trim(), options.maxTextPartChars);
|
|
@@ -1220,7 +811,7 @@ function renderMessagePart(part, options) {
|
|
|
1220
811
|
const record = part;
|
|
1221
812
|
const type = typeof record.type === "string" ? record.type : void 0;
|
|
1222
813
|
if (type === "text") return typeof record.text === "string" ? truncateText(record.text.trim(), options.maxTextPartChars) : "";
|
|
1223
|
-
if (type === "image") return "[image omitted]";
|
|
814
|
+
if (type === "image") return options.mediaPrepared ? "" : "[image omitted]";
|
|
1224
815
|
if (type === "toolCall" || type === "tool_use") {
|
|
1225
816
|
const label = `tool call${typeof record.name === "string" ? `: ${record.name}` : ""}`;
|
|
1226
817
|
if (options.toolPayloadMode === "preserve") return truncateText(`${label}\n${stableJson(renderToolCallPayload(record))}`, options.maxTextPartChars);
|
|
@@ -1303,16 +894,6 @@ function stableJson(value) {
|
|
|
1303
894
|
return "[unserializable payload omitted]";
|
|
1304
895
|
}
|
|
1305
896
|
}
|
|
1306
|
-
function extractMessageText(message) {
|
|
1307
|
-
if (!hasMessageContent(message)) return "";
|
|
1308
|
-
if (typeof message.content === "string") return message.content;
|
|
1309
|
-
if (!Array.isArray(message.content)) return "";
|
|
1310
|
-
return message.content.flatMap((part) => {
|
|
1311
|
-
if (!part || typeof part !== "object" || !("type" in part)) return [];
|
|
1312
|
-
const record = part;
|
|
1313
|
-
return record.type === "text" ? [typeof record.text === "string" ? record.text : ""] : [];
|
|
1314
|
-
}).join("\n");
|
|
1315
|
-
}
|
|
1316
897
|
function hasMessageContent(message) {
|
|
1317
898
|
return "content" in message;
|
|
1318
899
|
}
|
|
@@ -1549,7 +1130,7 @@ function shouldRecheckRecoverablePluginBinding(params) {
|
|
|
1549
1130
|
//#endregion
|
|
1550
1131
|
//#region extensions/codex/src/app-server/thread-fingerprints.ts
|
|
1551
1132
|
function codexDynamicToolsFingerprint(dynamicTools) {
|
|
1552
|
-
return
|
|
1133
|
+
return hashCodexAppServerBindingFingerprint(legacyFingerprintDynamicTools(dynamicTools));
|
|
1553
1134
|
}
|
|
1554
1135
|
function codexLegacyDynamicToolsFingerprint(dynamicTools) {
|
|
1555
1136
|
return legacyFingerprintDynamicTools(dynamicTools);
|
|
@@ -1557,11 +1138,8 @@ function codexLegacyDynamicToolsFingerprint(dynamicTools) {
|
|
|
1557
1138
|
function areCodexDynamicToolFingerprintsCompatible(params) {
|
|
1558
1139
|
return areDynamicToolFingerprintsCompatible(params.previous, params.next, params.nextLegacy);
|
|
1559
1140
|
}
|
|
1560
|
-
function fingerprintDynamicTools(dynamicTools) {
|
|
1561
|
-
return hashCodexAppServerBindingFingerprint(legacyFingerprintDynamicTools(dynamicTools));
|
|
1562
|
-
}
|
|
1563
1141
|
function legacyFingerprintDynamicTools(dynamicTools) {
|
|
1564
|
-
return JSON.stringify(dynamicTools.map(
|
|
1142
|
+
return JSON.stringify(dynamicTools.map(stabilizeJsonValue).toSorted(compareJsonFingerprint));
|
|
1565
1143
|
}
|
|
1566
1144
|
function legacyFingerprintUserMcpServersConfigPatch(configPatch) {
|
|
1567
1145
|
return configPatch ? JSON.stringify(stabilizeJsonValue(configPatch)) : void 0;
|
|
@@ -1600,9 +1178,6 @@ function fingerprintCodexThreadConfig(request, authProfileId, dynamicToolsFinger
|
|
|
1600
1178
|
function fingerprintEnvironmentSelection(environments) {
|
|
1601
1179
|
return environments ? JSON.stringify(environments.map(stabilizeJsonValue)) : void 0;
|
|
1602
1180
|
}
|
|
1603
|
-
function fingerprintDynamicToolSpec(tool) {
|
|
1604
|
-
return stabilizeJsonValue(tool);
|
|
1605
|
-
}
|
|
1606
1181
|
function stabilizeJsonValue(value) {
|
|
1607
1182
|
if (Array.isArray(value)) return value.map(stabilizeJsonValue);
|
|
1608
1183
|
if (!isJsonObject(value)) return value;
|
|
@@ -1893,68 +1468,6 @@ async function loadCodexNativeToolCatalog(params) {
|
|
|
1893
1468
|
return parseCodexNativeToolCatalog(metadata, binding.threadId, binding.dynamicToolsFingerprint);
|
|
1894
1469
|
}
|
|
1895
1470
|
//#endregion
|
|
1896
|
-
//#region extensions/codex/src/app-server/managed-thread-store.ts
|
|
1897
|
-
const CODEX_MANAGED_THREAD_NAMESPACE = "app-server-managed-threads";
|
|
1898
|
-
const CODEX_MANAGED_THREAD_MAX_ENTRIES = 2e4;
|
|
1899
|
-
const managedThreadSchema = z.object({
|
|
1900
|
-
version: z.literal(1),
|
|
1901
|
-
kind: z.literal("managed-thread"),
|
|
1902
|
-
sourceHomeId: z.string().min(1),
|
|
1903
|
-
threadId: z.string().min(1),
|
|
1904
|
-
rolloutPath: z.string().min(1).optional()
|
|
1905
|
-
});
|
|
1906
|
-
async function markStartedCodexManagedThread(store, params) {
|
|
1907
|
-
if (!store) return;
|
|
1908
|
-
try {
|
|
1909
|
-
await store.mark({
|
|
1910
|
-
sourceHomeId: params.sourceHomeId,
|
|
1911
|
-
threadId: params.threadId,
|
|
1912
|
-
...params.rolloutPath ? { rolloutPath: params.rolloutPath } : {}
|
|
1913
|
-
});
|
|
1914
|
-
} catch (error) {
|
|
1915
|
-
embeddedAgentLog.warn("failed to record Codex managed thread ownership", { error });
|
|
1916
|
-
}
|
|
1917
|
-
}
|
|
1918
|
-
function managedThreadStoreKey(sourceHomeId, threadId) {
|
|
1919
|
-
return `sha256:${createHash("sha256").update("openclaw:codex-managed-thread:v1\0").update(sourceHomeId).update("\0").update(threadId).digest("hex")}`;
|
|
1920
|
-
}
|
|
1921
|
-
/** Durable ownership index for Codex threads created by OpenClaw. */
|
|
1922
|
-
function createCodexManagedThreadStore(state) {
|
|
1923
|
-
return {
|
|
1924
|
-
async has(sourceHomeId, threadId) {
|
|
1925
|
-
const parsed = managedThreadSchema.safeParse(state.lookup(managedThreadStoreKey(sourceHomeId, threadId)));
|
|
1926
|
-
return parsed.success && parsed.data.sourceHomeId === sourceHomeId && parsed.data.threadId === threadId;
|
|
1927
|
-
},
|
|
1928
|
-
async mark(params) {
|
|
1929
|
-
try {
|
|
1930
|
-
const value = managedThreadSchema.parse({
|
|
1931
|
-
version: 1,
|
|
1932
|
-
kind: "managed-thread",
|
|
1933
|
-
sourceHomeId: params.sourceHomeId.trim(),
|
|
1934
|
-
threadId: params.threadId.trim(),
|
|
1935
|
-
...params.rolloutPath?.trim() ? { rolloutPath: params.rolloutPath.trim() } : {}
|
|
1936
|
-
});
|
|
1937
|
-
state.registerIfAbsent(managedThreadStoreKey(value.sourceHomeId, value.threadId), value);
|
|
1938
|
-
return true;
|
|
1939
|
-
} catch (error) {
|
|
1940
|
-
embeddedAgentLog.warn("failed to record Codex managed thread ownership", { error });
|
|
1941
|
-
return false;
|
|
1942
|
-
}
|
|
1943
|
-
},
|
|
1944
|
-
async snapshot() {
|
|
1945
|
-
const byHome = /* @__PURE__ */ new Map();
|
|
1946
|
-
for (const entry of state.entries()) {
|
|
1947
|
-
const parsed = managedThreadSchema.safeParse(entry.value);
|
|
1948
|
-
if (!parsed.success) continue;
|
|
1949
|
-
const ids = byHome.get(parsed.data.sourceHomeId) ?? /* @__PURE__ */ new Set();
|
|
1950
|
-
ids.add(parsed.data.threadId);
|
|
1951
|
-
byHome.set(parsed.data.sourceHomeId, ids);
|
|
1952
|
-
}
|
|
1953
|
-
return byHome;
|
|
1954
|
-
}
|
|
1955
|
-
};
|
|
1956
|
-
}
|
|
1957
|
-
//#endregion
|
|
1958
1471
|
//#region extensions/codex/src/app-server/thread-mcp-attestation.ts
|
|
1959
1472
|
async function attestCodexRestrictedToolSurfaceMcpServersDisabled(client, threadId, threadConfig, signal, expectedActiveServerNames = []) {
|
|
1960
1473
|
const configuredServers = threadConfig?.mcp_servers;
|
|
@@ -2541,7 +2054,6 @@ function buildDeveloperInstructions(params, options = {}) {
|
|
|
2541
2054
|
let hasSubagentsList = false;
|
|
2542
2055
|
let hasSessionsSend = false;
|
|
2543
2056
|
let hasSeenDirectNamespace = false;
|
|
2544
|
-
let messageToolAvailable = options.dynamicTools ? false : params.disableMessageTool !== true;
|
|
2545
2057
|
for (const spec of options.dynamicTools ?? []) {
|
|
2546
2058
|
const isDirectNamespace = spec.type === "namespace" && !hasSeenDirectNamespace && spec.name.trim() === "openclaw_direct";
|
|
2547
2059
|
if (isDirectNamespace) hasSeenDirectNamespace = true;
|
|
@@ -2558,7 +2070,6 @@ function buildDeveloperInstructions(params, options = {}) {
|
|
|
2558
2070
|
hasSessionsYield ||= isDirectNamespace && name === "sessions_yield";
|
|
2559
2071
|
hasSubagentsList ||= name === "subagents";
|
|
2560
2072
|
hasSessionsSend ||= name === "sessions_send";
|
|
2561
|
-
messageToolAvailable ||= name === "message";
|
|
2562
2073
|
}
|
|
2563
2074
|
}
|
|
2564
2075
|
const nativeCommandGuidance = listRegisteredPluginAgentPromptGuidance({
|
|
@@ -2588,15 +2099,11 @@ function buildDeveloperInstructions(params, options = {}) {
|
|
|
2588
2099
|
hasSubagentsList,
|
|
2589
2100
|
hasSessionsSend
|
|
2590
2101
|
}).join("\n") : void 0,
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
dashboardToolName,
|
|
2597
|
-
portalToolName
|
|
2598
|
-
} : void 0
|
|
2599
|
-
}),
|
|
2102
|
+
params.disableTools !== true && params.promptMode !== "minimal" && params.promptMode !== "none" ? buildUiPresentationPrompt({
|
|
2103
|
+
showWidgetToolName,
|
|
2104
|
+
dashboardToolName,
|
|
2105
|
+
portalToolName
|
|
2106
|
+
}) : void 0,
|
|
2600
2107
|
buildCredentialSafetyPrompt(secretsToolName),
|
|
2601
2108
|
nativeCommandGuidance,
|
|
2602
2109
|
params.extraSystemPrompt
|
|
@@ -3383,51 +2890,26 @@ function shouldWarnCodexThreadLifecycleTimingSummary(summary, options = {}) {
|
|
|
3383
2890
|
return summary.totalMs >= totalThresholdMs || summary.spans.some((span) => span.durationMs >= stageThresholdMs);
|
|
3384
2891
|
}
|
|
3385
2892
|
function formatCodexThreadLifecycleTimingSummary(params) {
|
|
3386
|
-
const spans = params.summary.spans
|
|
2893
|
+
const spans = formatStageTimings(params.summary.spans);
|
|
3387
2894
|
return `[trace:codex-app-server] thread lifecycle: runId=${params.runId} sessionId=${params.sessionId} sessionKey=${params.sessionKey ?? "unknown"} action=${params.action} totalMs=${params.summary.totalMs} stages=${spans}`;
|
|
3388
2895
|
}
|
|
3389
2896
|
function createCodexThreadLifecycleTimingTracker(options = {}) {
|
|
3390
2897
|
const log = options.log ?? embeddedAgentLog;
|
|
3391
|
-
const
|
|
3392
|
-
const startedAt = now();
|
|
2898
|
+
const timing = createStageTimingTracker(options.now ?? Date.now);
|
|
3393
2899
|
let didLog = false;
|
|
3394
|
-
const spans = [];
|
|
3395
|
-
const toMs = (value) => Math.max(0, Math.round(value));
|
|
3396
|
-
const record = (name, spanStartedAt) => {
|
|
3397
|
-
const currentAt = now();
|
|
3398
|
-
spans.push({
|
|
3399
|
-
name,
|
|
3400
|
-
durationMs: toMs(currentAt - spanStartedAt),
|
|
3401
|
-
elapsedMs: toMs(currentAt - startedAt)
|
|
3402
|
-
});
|
|
3403
|
-
};
|
|
3404
|
-
const snapshot = () => ({
|
|
3405
|
-
totalMs: toMs(now() - startedAt),
|
|
3406
|
-
spans: spans.slice()
|
|
3407
|
-
});
|
|
3408
2900
|
return {
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
try {
|
|
3412
|
-
return await run();
|
|
3413
|
-
} finally {
|
|
3414
|
-
record(name, spanStartedAt);
|
|
3415
|
-
}
|
|
3416
|
-
},
|
|
3417
|
-
measureSync(name, run) {
|
|
3418
|
-
const spanStartedAt = now();
|
|
3419
|
-
try {
|
|
3420
|
-
return run();
|
|
3421
|
-
} finally {
|
|
3422
|
-
record(name, spanStartedAt);
|
|
3423
|
-
}
|
|
3424
|
-
},
|
|
2901
|
+
measure: timing.measure,
|
|
2902
|
+
measureSync: timing.measureSync,
|
|
3425
2903
|
mark(name) {
|
|
3426
|
-
|
|
2904
|
+
timing.measureSync(name, () => void 0);
|
|
3427
2905
|
},
|
|
3428
2906
|
logSummary(params) {
|
|
3429
2907
|
if (didLog) return;
|
|
3430
|
-
const
|
|
2908
|
+
const { totalMs, stages: spans } = timing.snapshot();
|
|
2909
|
+
const summary = {
|
|
2910
|
+
totalMs,
|
|
2911
|
+
spans
|
|
2912
|
+
};
|
|
3431
2913
|
const shouldWarn = shouldWarnCodexThreadLifecycleTimingSummary(summary, {
|
|
3432
2914
|
...options,
|
|
3433
2915
|
log
|
|
@@ -3463,7 +2945,7 @@ function resolveCodexThreadAgentDir(params) {
|
|
|
3463
2945
|
sessionKey: params.params.sessionKey,
|
|
3464
2946
|
agentId: params.agentId ?? params.params.agentId
|
|
3465
2947
|
}).sessionAgentId;
|
|
3466
|
-
return params.agentDir ?? params.params.agentDir ?? resolveAgentDir$
|
|
2948
|
+
return params.agentDir ?? params.params.agentDir ?? resolveAgentDir$1(params.params.config ?? {}, agentId);
|
|
3467
2949
|
}
|
|
3468
2950
|
async function prepareCodexThreadLifecyclePreflight(params) {
|
|
3469
2951
|
let effectiveConfig = await assertCodexModelBackedReviewerEffectiveConfig({
|
|
@@ -3624,6 +3106,7 @@ async function resumeExistingCodexThread(params, context) {
|
|
|
3624
3106
|
acceptedConfiguration = configuration;
|
|
3625
3107
|
assertCodexThreadAcceptsDirectInput(response.thread);
|
|
3626
3108
|
configuration.assertConfigured();
|
|
3109
|
+
if (requestModelProvider && response.modelProvider !== requestModelProvider) throw new Error("Codex resumed a different model provider than the one selected for this turn");
|
|
3627
3110
|
const loadedPluginThreadConfig = await context.buildLoadedPluginThreadConfig?.(resumeBinding);
|
|
3628
3111
|
if (loadedPluginThreadConfig && loadedPluginThreadConfig.fingerprint !== (pluginThreadConfig?.fingerprint ?? resumeBinding.pluginAppsFingerprint)) {
|
|
3629
3112
|
ordinaryAppConfigChanged = resumeBinding.connectionScope !== "supervision" && !resumeBinding.pendingResumeConfiguration;
|
|
@@ -3657,7 +3140,7 @@ async function resumeExistingCodexThread(params, context) {
|
|
|
3657
3140
|
cwd: params.cwd,
|
|
3658
3141
|
rolloutPath: resolveCodexThreadRolloutPath(response.thread) ?? resumeBinding.rolloutPath,
|
|
3659
3142
|
authProfileId,
|
|
3660
|
-
model:
|
|
3143
|
+
model: resumeParams.model ?? response.model ?? params.params.modelId,
|
|
3661
3144
|
preserveNativeModel: resumeBinding.preserveNativeModel === true ? true : void 0,
|
|
3662
3145
|
modelProvider: normalizeBindingModelProvider(authProfileId, response.modelProvider ?? requestModelProvider ?? startModelProvider),
|
|
3663
3146
|
dynamicToolsFingerprint,
|
|
@@ -4239,8 +3722,7 @@ async function preparePendingCodexThreadResume(params, binding, dynamicToolsFing
|
|
|
4239
3722
|
assertCurrent
|
|
4240
3723
|
});
|
|
4241
3724
|
assertCurrent();
|
|
4242
|
-
|
|
4243
|
-
if (thread.id !== binding.threadId || statusType !== "idle" && statusType !== "notLoaded") throw fail("the native thread is not idle; wait for its current run to finish");
|
|
3725
|
+
if (thread.id !== binding.threadId || !isCodexThreadNonRunning(thread.status)) throw fail("the native thread is not idle; wait for its current run to finish");
|
|
4244
3726
|
assertCodexThreadAcceptsDirectInput(thread);
|
|
4245
3727
|
const observation = observeCodexThreadConfiguration(params, thread, assertCurrent);
|
|
4246
3728
|
const dispose = observation.dispose;
|
|
@@ -4284,8 +3766,11 @@ async function prepareCodexThreadResume(params, binding, context) {
|
|
|
4284
3766
|
assertCurrent
|
|
4285
3767
|
};
|
|
4286
3768
|
}
|
|
3769
|
+
function isCodexThreadNonRunning(status) {
|
|
3770
|
+
return status?.type === "idle" || status?.type === "notLoaded" || status?.type === "systemError";
|
|
3771
|
+
}
|
|
4287
3772
|
function observeCodexThreadConfiguration(params, thread, assertCurrent) {
|
|
4288
|
-
if (thread.status
|
|
3773
|
+
if (!isCodexThreadNonRunning(thread.status)) throw new CodexAdoptedThreadActiveError();
|
|
4289
3774
|
let unloaded = thread.status.type === "notLoaded";
|
|
4290
3775
|
return {
|
|
4291
3776
|
dispose: params.client.addNotificationHandler((notification) => {
|
|
@@ -5133,6 +4618,17 @@ function buildTurnStartParams(params, options) {
|
|
|
5133
4618
|
const useThreadPermissionProfile = options.appServer.networkProxy && !options.sandboxPolicy;
|
|
5134
4619
|
const currentSenderContext = params.trigger === "user" ? buildCodexCurrentSenderContextValue(params) : void 0;
|
|
5135
4620
|
let additionalContext = buildCodexTemporalAdditionalContext(params, { sessionStatusAvailable: options.sessionStatusAvailable === true });
|
|
4621
|
+
additionalContext = {
|
|
4622
|
+
...additionalContext,
|
|
4623
|
+
openclaw_source_delivery: {
|
|
4624
|
+
kind: "application",
|
|
4625
|
+
value: ["Current source-delivery policy for this turn (replaces earlier source-delivery guidance):", buildHarnessVisibleReplyGuidance({
|
|
4626
|
+
sourceReplyDeliveryMode: params.sourceReplyDeliveryMode,
|
|
4627
|
+
messageToolAvailable: options.messageToolAvailable === true,
|
|
4628
|
+
requireExplicitMessageTarget: options.requireExplicitMessageTarget
|
|
4629
|
+
})].join("\n")
|
|
4630
|
+
}
|
|
4631
|
+
};
|
|
5136
4632
|
if (currentSenderContext) additionalContext = {
|
|
5137
4633
|
...additionalContext,
|
|
5138
4634
|
openclaw_current_sender: {
|
|
@@ -5225,4 +4721,4 @@ function joinPresentSections(...sections) {
|
|
|
5225
4721
|
return sections.filter((section) => Boolean(section?.trim())).join("\n\n");
|
|
5226
4722
|
}
|
|
5227
4723
|
//#endregion
|
|
5228
|
-
export {
|
|
4724
|
+
export { codexLegacyDynamicToolsFingerprint as $, readCodexMcpToolConnectorId as A, emitCodexNativePreToolUseFailureDiagnostic as B, buildDeveloperInstructions as C, buildCodexPluginThreadConfigTimeoutFallback as Ct, resolveCodexAppServerThreadModelSelection as D, shouldBuildCodexPluginThreadConfig as Dt, resolveCodexAppServerRequestModelSelection as E, refreshCodexPluginAppApprovalPolicy as Et, assertCodexNativeHookRelayAllowed as F, attestCodexRestrictedToolSurfaceMcpServersDisabled as G, resolveCodexNativeHookRelayTtlMs as H, buildCodexNativeHookRelayConfig as I, parseCodexNativeToolCatalog as J, hasCodexNativeToolCatalog as K, buildCodexNativeHookRelayDisabledConfig as L, isCodexAppServerProfilerEnabled as M, CODEX_NATIVE_HOOK_RELAY_EVENTS as N, resolveCodexBindingModelProviderFallback as O, CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS as P, codexDynamicToolsFingerprint as Q, buildCodexNativeHookRelayId as R, resolveCodexWebSearchPlan as S, buildCodexPluginThreadConfigInputFingerprint as St, resolveCodexAppServerModelProvider as T, mergeCodexThreadConfigs as Tt, scheduleCodexNativeHookRelayUnregister as U, resolveCodexNativeHookRelayEvents as V, checkCodexThreadAppAvailability as W, resolveCodexNativeSkillIsolation as X, applyCodexNativeSkillIsolation as Y, areCodexDynamicToolFingerprintsCompatible as Z, buildCodexRingZeroThreadConfigPatch as _, projectContextEngineAssemblyForCodex as _t, readCodexSupportedReasoningEfforts as a, isMessageOnlyCodexSourceReply as at, readCodexInheritedMcpServerNames as b, resolveCodexContinuityProjectionMaxChars as bt, assertScheduledCodexAppAuthorityRuntime as c, resolveCodexDynamicToolsLoading as ct, buildScheduledCodexAppServerConnectionIdentity as d, isContextEngineBindingCompatible as dt, fingerprintJsonObject as et, captureScheduledCodexAppAuthority as f, CodexContextAttachmentError as ft, assertCodexManagedRequirementsDoNotOverrideToolPolicy as g, neutralizeCodexExplicitMentionSigils as gt, resolveScheduledCodexAppCreatorCaptureDecision as h, isCodexDurableCustomMessage as ht, buildCodexUserInput as i, isForcedPrivateQaCodexRuntime as it, readCodexMcpToolUiVisibility as j, buildCodexProjectDocThreadConfig as k, buildLegacyScheduledCodexAppRecoveryPrompt as l, resolveCodexDynamicToolsLoadingForRuntime as lt, readCurrentCodexScheduledAppPolicy as m, fitCodexProjectedContextForTurnStart as mt, buildTurnCollaborationMode as n, filterCodexDynamicTools as nt, resolveCodexAppServerReasoningEffort as o, isSystemAgentOnlyCodexDynamicToolAllowlist as ot, intersectCodexPluginThreadConfigWithScheduledAuthority as p, buildCodexContinuityCalibration as pt, loadCodexNativeToolCatalog as q, buildTurnStartParams as r, filterCodexDynamicToolsForDisabledNativeSurface as rt, startOrResumeThread as s, normalizeCodexDynamicToolName as st, buildCodexTemporalAdditionalContext as t, fingerprintUserMcpServersConfigPatch as tt, buildScheduledCodexAppAuthorityInputFingerprint as u, buildContextEngineBinding as ut, buildCodexRuntimeThreadConfig as v, resolveCodexContextEngineProjectionMaxChars as vt, CODEX_NATIVE_PERSONALITY_NONE as w, buildDisabledAppsConfigPatch as wt, buildCodexNativeWebSearchThreadConfig as x, buildCodexPluginThreadConfig as xt, buildCodexThreadConfiguration as y, resolveCodexContextEngineProjectionReserveTokens as yt, createCodexNativeHookRelay as z };
|