@openclaw/codex 2026.8.1 → 2026.8.33
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/{attempt-client-cleanup-CVPvp9dL.js → .setup/attempt-client-cleanup-FBnDjmtX.mjs} +1 -1
- package/dist/{auth-binding-Ds_QVm-X.js → .setup/auth-binding-oyIUSaFi.mjs} +1 -1
- package/dist/{binding-connection-CCQFs8lf.js → .setup/binding-connection-BgiXAp29.mjs} +2 -2
- package/dist/{bounded-turn-rq5tiSXk.js → .setup/bounded-turn-kWYLbaDH.mjs} +12 -11
- package/dist/{capabilities-CGm_94eL.js → .setup/capabilities-oLHKpYRj.mjs} +1 -1
- package/dist/{command-formatters-C54Yg3eA.js → .setup/command-formatters-DylXEqck.mjs} +4 -3
- package/dist/{command-handlers-BvOAHTrA.js → .setup/command-handlers-PRe4WEmx.mjs} +42 -34
- package/dist/{compact-Hd7SAc0N.js → .setup/compact-K2iOmzQp.mjs} +14 -12
- package/dist/{config-Cxw3Cl3k.js → .setup/config-ClwHKKTN.mjs} +7 -5
- package/dist/{conversation-binding-data-CW2GuupV.js → .setup/conversation-binding-data-CrcyZk6O.mjs} +3 -2
- package/dist/{dynamic-tools-BFoUcRdx.js → .setup/dynamic-tools-XNStyzzb.mjs} +105 -108
- package/dist/{effective-mcp-catalog-BTJHnDSx.js → .setup/effective-mcp-catalog-BHpifbgx.mjs} +2 -2
- package/dist/{event-projector-assistant-message-C5-Ds8mA.js → .setup/event-projector-assistant-message-BCnzlajn.mjs} +1 -1
- package/dist/{event-projector-usage-D3PHFFXh.js → .setup/event-projector-usage-h7P0Raok.mjs} +7 -12
- package/dist/{harness-DVfUQBlQ.js → .setup/harness-CawBdltH.mjs} +14 -14
- package/dist/{isolated-completion-Cbbx_5Ed.js → .setup/isolated-completion-rL3zrcAe.mjs} +4 -4
- package/dist/{managed-binary-ZkGodW19.js → .setup/managed-binary-DlGr2kYu.mjs} +1 -1
- package/dist/{model-catalog-o6Cgjoss.js → .setup/model-catalog--miA1cod.mjs} +5 -5
- package/dist/{models-DgFWSuxA.js → .setup/models-BNPc8Vr2.mjs} +5 -4
- package/dist/{native-subagent-monitor-CwFyoylz.js → .setup/native-subagent-monitor-mhFvLcPG.mjs} +25 -105
- package/dist/{node-exec-server.runtime-DXrqpw1c.js → .setup/node-exec-server.runtime-BmAZPmrd.mjs} +3 -3
- package/dist/{plugin-approval-roundtrip-D80UZiJ_.js → .setup/plugin-approval-roundtrip-Dlq4n0n8.mjs} +2 -1
- package/dist/{plugin-marketplace-discovery-mdmScYOj.js → .setup/plugin-marketplace-discovery-KyJdBtCC.mjs} +14 -13
- package/dist/{plugin-metadata-cache-CulOABwu.js → .setup/plugin-metadata-cache-RRQ_VJrs.mjs} +6 -6
- package/dist/{rate-limits-hFtzt2Up.js → .setup/rate-limits-CQUmEcUk.mjs} +3 -2
- package/dist/{request-CCm4LaED.js → .setup/request-fEUi95EK.mjs} +3 -3
- package/dist/{run-attempt-BwNQDH2u.js → .setup/run-attempt-BJ6tOQeE.mjs} +138 -187
- package/dist/{runtime-artifact-DeBvleJw.js → .setup/runtime-artifact-D0ssVSlz.mjs} +3 -3
- package/dist/{session-binding-q2WSTVmC.js → .setup/session-binding-Bd9dh1Er.mjs} +3 -3
- package/dist/{session-catalog-C2Tae4rI.js → .setup/session-catalog-eQhJDU41.mjs} +234 -206
- package/dist/{session-catalog-home-id-DAKUrm3C.js → .setup/session-catalog-home-id-CjyBDShn.mjs} +3 -3
- package/dist/{session-cli-BuDjm5Ou.js → .setup/session-cli-mJePHTAs.mjs} +1 -1
- package/dist/.setup/session-history-Cg8PzgeU.mjs +87 -0
- package/dist/{session-permission-policy-gLm40Vtq.js → .setup/session-permission-policy-C0bdhR_I.mjs} +1 -1
- package/dist/{session-retirement-CdkI0bvb.js → .setup/session-retirement-osjW6zy5.mjs} +4 -4
- package/dist/{session-upstream-marker-Bcy33kam.js → .setup/session-upstream-marker-CIgMzZku.mjs} +1 -1
- package/dist/.setup/settled-turn-context-OxoGQWJK.mjs +290 -0
- package/dist/.setup/settled-turn-finalizer-D9SoKTb-.mjs +104 -0
- package/dist/{shared-client-kNkljY-R.js → .setup/shared-client-DG1kAfGq.mjs} +37 -39
- package/dist/{side-question-GwD73tX6.js → .setup/side-question-Bi9chAvD.mjs} +25 -17
- package/dist/{thread-lifecycle-Ss-uwnC4.js → .setup/thread-lifecycle-Cc6I-gbl.mjs} +273 -232
- package/dist/{thread-ownership-CeYBqg_4.js → .setup/thread-ownership-B3vjUi0P.mjs} +2 -2
- package/dist/{thread-resume-DF54hagX.js → .setup/thread-resume-OMjvue9F.mjs} +8 -7
- package/dist/{transcript-mirror-CkEQIna-.js → .setup/transcript-mirror-DN-ed7Kf.mjs} +14 -7
- package/dist/{transport-stdio-C7-s9TLG.js → .setup/transport-stdio-Cu0xKDRo.mjs} +41 -25
- package/dist/{upstream-prompt-provenance-CFmsKwr9.js → .setup/upstream-prompt-provenance-LphB8slG.mjs} +8 -4
- package/dist/{upstream-session-fork-BACGlOFa.js → .setup/upstream-session-fork-DL7QQ1e_.mjs} +14 -20
- package/dist/{usage-C2l8Mils.js → .setup/usage-dsPLHd8O.mjs} +3 -3
- package/dist/{web-search-provider.runtime-B2XgRdFv.js → .setup/web-search-provider.runtime-BRH3ahFN.mjs} +3 -3
- package/dist/api.js +4 -4
- package/dist/cli-metadata.js +1 -1
- package/dist/doctor-contract-api.js +9 -5
- package/dist/harness.js +1 -1
- package/dist/index.js +60 -41
- package/dist/media-understanding-provider.js +1 -1
- package/dist/web-search-contract-api.js +1 -1
- package/package.json +6 -6
- package/dist/settled-turn-finalizer-B8JJcxCi.js +0 -329
- /package/dist/{context-compaction-activity-BOeJf7yo.js → .setup/context-compaction-activity-BOeJf7yo.mjs} +0 -0
- /package/dist/{elicitation-input-DMkeki8d.js → .setup/elicitation-input-DMkeki8d.mjs} +0 -0
- /package/dist/{image-payload-sanitizer-CnfoUPCE.js → .setup/image-payload-sanitizer-CnfoUPCE.mjs} +0 -0
- /package/dist/{launch-args-sXOAg0SX.js → .setup/launch-args-sXOAg0SX.mjs} +0 -0
- /package/dist/{local-runtime-attribution-B_2mnqhb.js → .setup/local-runtime-attribution-B_2mnqhb.mjs} +0 -0
- /package/dist/{protocol-validators-Bg5rpNxk.js → .setup/protocol-validators-Bg5rpNxk.mjs} +0 -0
- /package/dist/{rolldown-runtime-8H4AJuhK.js → .setup/rolldown-runtime-8H4AJuhK.mjs} +0 -0
- /package/dist/{session-binding-meta-B7aEMU7g.js → .setup/session-binding-meta-B7aEMU7g.mjs} +0 -0
- /package/dist/{web-search-provider.shared-BrZmlqyR.js → .setup/web-search-provider.shared-BrZmlqyR.mjs} +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { E as resolveCodexPluginsPolicy, F as resolveCodexAppServerLocalHomeDir, M as CODEX_PLUGINS_WORKSPACE_MARKETPLACE_NAME, P as resolveCodexAppServerHomeDir, f as assertCodexModelBackedReviewerEffectiveConfig, j as CODEX_PLUGINS_MARKETPLACE_NAME, n as codexSandboxPolicyForTurn } from "./config-
|
|
2
|
-
import { $ as CodexAppServerRpcError, D as CodexThreadStartRequestError, E as CodexThreadBindingConflictError, H as getCodexAppServerClientInstanceId, Ht as isJsonObject, J as isCodexAppServerOverloadError, Q as resolveCodexAppServerClientInstanceId, St as releaseCodexAppServerLiveThread, T as CodexRestrictedToolSurfaceAttestationError, Vt as flattenCodexDynamicToolFunctions, _ as retainSharedCodexAppServerClientByInstanceId, bt as isCodexAppServerLiveThreadClaimed, dt as resolveCodexToolAbortTerminalReason, gt as consumeCodexAppServerLiveThread, n as captureExclusiveSharedCodexAppServerClient, w as CodexAdoptedThreadActiveError, wt as unsubscribeCodexAppServerLiveThread } from "./shared-client-
|
|
3
|
-
import { a as hashCodexAppServerBindingFingerprint, c as reclaimCurrentCodexSessionGeneration, d as sessionBindingIdentity, i as createCodexSessionGenerationSupersededError, n as assertCodexBindingMayBeReplaced, o as isCodexAppServerNativeAuthProfile, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-
|
|
4
|
-
import { a as assertCodexThreadForkResponse, r as assertCodexThreadAcceptsDirectInput, s as assertCodexThreadStartResponse, t as CodexThreadDirectInputError } from "./protocol-validators-Bg5rpNxk.
|
|
5
|
-
import { a as closeCodexStartupClientBestEffort, c as isCodexAppServerUnsafeSubscriptionError, f as unsubscribeCodexThreadBestEffort, n as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-
|
|
6
|
-
import { c as serializeCodexAppInventoryError, n as buildCodexAppServerConnectionFingerprint, s as defaultCodexAppInventoryCache, t as resumeCodexAppServerThread } from "./thread-resume-
|
|
7
|
-
import { c as withExclusiveCodexAppServerThread, l as isIncognitoSessionKey } from "./thread-ownership-
|
|
8
|
-
import { i as readCodexSessionMeta, n as codexCatalogHomeId } from "./session-catalog-home-id-
|
|
9
|
-
import {
|
|
10
|
-
import { r as sanitizeInlineImageDataUrl, t as invalidInlineImageText } from "./image-payload-sanitizer-CnfoUPCE.
|
|
1
|
+
import { E as resolveCodexPluginsPolicy, F as resolveCodexAppServerLocalHomeDir, M as CODEX_PLUGINS_WORKSPACE_MARKETPLACE_NAME, P as resolveCodexAppServerHomeDir, f as assertCodexModelBackedReviewerEffectiveConfig, j as CODEX_PLUGINS_MARKETPLACE_NAME, n as codexSandboxPolicyForTurn } from "./config-ClwHKKTN.mjs";
|
|
2
|
+
import { $ as CodexAppServerRpcError, D as CodexThreadStartRequestError, E as CodexThreadBindingConflictError, H as getCodexAppServerClientInstanceId, Ht as isJsonObject, J as isCodexAppServerOverloadError, Q as resolveCodexAppServerClientInstanceId, St as releaseCodexAppServerLiveThread, T as CodexRestrictedToolSurfaceAttestationError, Vt as flattenCodexDynamicToolFunctions, _ as retainSharedCodexAppServerClientByInstanceId, bt as isCodexAppServerLiveThreadClaimed, dt as resolveCodexToolAbortTerminalReason, gt as consumeCodexAppServerLiveThread, n as captureExclusiveSharedCodexAppServerClient, w as CodexAdoptedThreadActiveError, wt as unsubscribeCodexAppServerLiveThread, yt as isCodexAppServerClientRuntimeLive } from "./shared-client-DG1kAfGq.mjs";
|
|
3
|
+
import { a as hashCodexAppServerBindingFingerprint, c as reclaimCurrentCodexSessionGeneration, d as sessionBindingIdentity, i as createCodexSessionGenerationSupersededError, n as assertCodexBindingMayBeReplaced, o as isCodexAppServerNativeAuthProfile, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-Bd9dh1Er.mjs";
|
|
4
|
+
import { a as assertCodexThreadForkResponse, r as assertCodexThreadAcceptsDirectInput, s as assertCodexThreadStartResponse, t as CodexThreadDirectInputError } from "./protocol-validators-Bg5rpNxk.mjs";
|
|
5
|
+
import { a as closeCodexStartupClientBestEffort, c as isCodexAppServerUnsafeSubscriptionError, f as unsubscribeCodexThreadBestEffort, n as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-FBnDjmtX.mjs";
|
|
6
|
+
import { c as serializeCodexAppInventoryError, n as buildCodexAppServerConnectionFingerprint, s as defaultCodexAppInventoryCache, t as resumeCodexAppServerThread } from "./thread-resume-OMjvue9F.mjs";
|
|
7
|
+
import { c as withExclusiveCodexAppServerThread, l as isIncognitoSessionKey } from "./thread-ownership-B3vjUi0P.mjs";
|
|
8
|
+
import { i as readCodexSessionMeta, n as codexCatalogHomeId } from "./session-catalog-home-id-CjyBDShn.mjs";
|
|
9
|
+
import { f as projectBoundedCodexThreadHistory } from "./transcript-mirror-DN-ed7Kf.mjs";
|
|
10
|
+
import { r as sanitizeInlineImageDataUrl, t as invalidInlineImageText } from "./image-payload-sanitizer-CnfoUPCE.mjs";
|
|
11
11
|
import { asOptionalRecord, isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
12
12
|
import fs from "node:fs/promises";
|
|
13
13
|
import path from "node:path";
|
|
@@ -1198,6 +1198,7 @@ function renderMessagesForCodexContext(messages, options) {
|
|
|
1198
1198
|
}).filter((value) => Boolean(value)).join("\n\n");
|
|
1199
1199
|
}
|
|
1200
1200
|
function renderMessageBody(message, options) {
|
|
1201
|
+
if (message.role === "compactionSummary" || message.role === "branchSummary") return truncateText(message.summary.trim(), options.maxTextPartChars);
|
|
1201
1202
|
if (!hasMessageContent(message)) return "";
|
|
1202
1203
|
if (typeof message.content === "string") return truncateText(message.content.trim(), options.maxTextPartChars);
|
|
1203
1204
|
if (!Array.isArray(message.content)) return "[non-text content omitted]";
|
|
@@ -1666,7 +1667,8 @@ async function collectPersonalSkillRealPaths(homes, codexHome) {
|
|
|
1666
1667
|
}
|
|
1667
1668
|
const configuredCodexHome = codexHome?.trim() || process.env.CODEX_HOME?.trim();
|
|
1668
1669
|
if (configuredCodexHome) {
|
|
1669
|
-
const
|
|
1670
|
+
const realCodexHome = await canonicalizeExistingPath(configuredCodexHome);
|
|
1671
|
+
const stateOwned = isPathInside(realStateDir, realCodexHome);
|
|
1670
1672
|
roots.push({
|
|
1671
1673
|
dir: path.join(configuredCodexHome, "skills"),
|
|
1672
1674
|
onlyEscapedStateTargets: stateOwned
|
|
@@ -1729,12 +1731,14 @@ async function collectPersonalSkillRealPaths(homes, codexHome) {
|
|
|
1729
1731
|
try {
|
|
1730
1732
|
const stat = await fs.stat(entryPath);
|
|
1731
1733
|
if (entry.name === "SKILL.md" && stat.isFile()) await recordSkillFile(entryPath, current.onlyEscapedStateTargets);
|
|
1732
|
-
else if (stat.isDirectory())
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1734
|
+
else if (stat.isDirectory()) {
|
|
1735
|
+
if (current.depth < MAX_PERSONAL_SKILL_DEPTH) queue.push({
|
|
1736
|
+
dir: entryPath,
|
|
1737
|
+
depth: current.depth + 1,
|
|
1738
|
+
onlyEscapedStateTargets: current.onlyEscapedStateTargets
|
|
1739
|
+
});
|
|
1740
|
+
else complete = false;
|
|
1741
|
+
}
|
|
1738
1742
|
} catch (error) {
|
|
1739
1743
|
if (!isMissingPathError(error)) complete = false;
|
|
1740
1744
|
}
|
|
@@ -1852,6 +1856,10 @@ function managedThreadStoreKey(sourceHomeId, threadId) {
|
|
|
1852
1856
|
/** Durable ownership index for Codex threads created by OpenClaw. */
|
|
1853
1857
|
function createCodexManagedThreadStore(state) {
|
|
1854
1858
|
return {
|
|
1859
|
+
async has(sourceHomeId, threadId) {
|
|
1860
|
+
const parsed = managedThreadSchema.safeParse(state.lookup(managedThreadStoreKey(sourceHomeId, threadId)));
|
|
1861
|
+
return parsed.success && parsed.data.sourceHomeId === sourceHomeId && parsed.data.threadId === threadId;
|
|
1862
|
+
},
|
|
1855
1863
|
async mark(params) {
|
|
1856
1864
|
try {
|
|
1857
1865
|
const value = managedThreadSchema.parse({
|
|
@@ -1981,56 +1989,6 @@ function buildStartedCodexThreadBinding(input) {
|
|
|
1981
1989
|
};
|
|
1982
1990
|
}
|
|
1983
1991
|
//#endregion
|
|
1984
|
-
//#region extensions/codex/src/app-server/reasoning-effort.ts
|
|
1985
|
-
const CODEX_REASONING_EFFORTS = [
|
|
1986
|
-
"minimal",
|
|
1987
|
-
"low",
|
|
1988
|
-
"medium",
|
|
1989
|
-
"high",
|
|
1990
|
-
"xhigh",
|
|
1991
|
-
"max",
|
|
1992
|
-
"ultra"
|
|
1993
|
-
];
|
|
1994
|
-
const LEGACY_PRO_REASONING_EFFORTS = [
|
|
1995
|
-
"medium",
|
|
1996
|
-
"high",
|
|
1997
|
-
"xhigh"
|
|
1998
|
-
];
|
|
1999
|
-
const LEGACY_PRO_MODEL_ID_RE = /^gpt-5\.[45]-pro$/u;
|
|
2000
|
-
const MODERN_GPT_5_MODEL_ID_RE = /^gpt-5\.(?:[3-9]|[1-9]\d)(?:$|-)/u;
|
|
2001
|
-
/** Read reasoning metadata after the Codex app-server route has been selected. */
|
|
2002
|
-
function readCodexSupportedReasoningEfforts(compat) {
|
|
2003
|
-
if (!compat || typeof compat !== "object" || Array.isArray(compat)) return;
|
|
2004
|
-
const efforts = compat.supportedReasoningEfforts;
|
|
2005
|
-
if (!Array.isArray(efforts)) return;
|
|
2006
|
-
return efforts.filter((effort) => typeof effort === "string");
|
|
2007
|
-
}
|
|
2008
|
-
function resolveSupportedReasoningEffort(params) {
|
|
2009
|
-
const declared = new Set(params.supportedReasoningEfforts.map((effort) => effort.trim().toLowerCase()));
|
|
2010
|
-
const supported = CODEX_REASONING_EFFORTS.filter((effort) => declared.has(effort));
|
|
2011
|
-
if (supported.includes(params.requested)) return params.requested;
|
|
2012
|
-
const fallbackEfforts = params.requested === "ultra" ? supported : supported.filter((effort) => effort !== "ultra");
|
|
2013
|
-
const requestedRank = CODEX_REASONING_EFFORTS.indexOf(params.requested);
|
|
2014
|
-
return fallbackEfforts.find((effort) => CODEX_REASONING_EFFORTS.indexOf(effort) >= requestedRank) ?? fallbackEfforts.at(-1);
|
|
2015
|
-
}
|
|
2016
|
-
/** Resolve a turn effort from the selected model's provider-owned metadata. */
|
|
2017
|
-
function resolveCodexAppServerReasoningEffort(params) {
|
|
2018
|
-
if (params.thinkLevel === "off") return params.supportedReasoningEfforts?.includes("none") ? "none" : null;
|
|
2019
|
-
if (params.thinkLevel === "adaptive") return null;
|
|
2020
|
-
if (params.supportedReasoningEfforts) return resolveSupportedReasoningEffort({
|
|
2021
|
-
requested: params.thinkLevel,
|
|
2022
|
-
supportedReasoningEfforts: params.supportedReasoningEfforts
|
|
2023
|
-
}) ?? null;
|
|
2024
|
-
const modelId = params.modelId.trim().toLowerCase();
|
|
2025
|
-
if (LEGACY_PRO_MODEL_ID_RE.test(modelId)) return resolveSupportedReasoningEffort({
|
|
2026
|
-
requested: params.thinkLevel,
|
|
2027
|
-
supportedReasoningEfforts: LEGACY_PRO_REASONING_EFFORTS
|
|
2028
|
-
}) ?? null;
|
|
2029
|
-
if (params.thinkLevel === "minimal" && MODERN_GPT_5_MODEL_ID_RE.test(modelId)) return "low";
|
|
2030
|
-
if (params.thinkLevel === "minimal" || params.thinkLevel === "low" || params.thinkLevel === "medium" || params.thinkLevel === "high" || params.thinkLevel === "xhigh") return params.thinkLevel;
|
|
2031
|
-
return null;
|
|
2032
|
-
}
|
|
2033
|
-
//#endregion
|
|
2034
1992
|
//#region extensions/codex/src/app-server/thread-model-selection.ts
|
|
2035
1993
|
const CODEX_NATIVE_PERSONALITY_NONE = "none";
|
|
2036
1994
|
function resolveCodexBindingModelProviderFallback(params) {
|
|
@@ -2098,16 +2056,9 @@ function resolveCodexAppServerModelProvider(params) {
|
|
|
2098
2056
|
if (isCodexAppServerNativeAuthProfile(params) && normalizedLower === "openai") return;
|
|
2099
2057
|
return normalizedLower === "openai" ? "openai" : normalized;
|
|
2100
2058
|
}
|
|
2101
|
-
function resolveReasoningEffort(thinkLevel, modelId, supportedReasoningEfforts) {
|
|
2102
|
-
return resolveCodexAppServerReasoningEffort({
|
|
2103
|
-
thinkLevel,
|
|
2104
|
-
modelId,
|
|
2105
|
-
supportedReasoningEfforts
|
|
2106
|
-
});
|
|
2107
|
-
}
|
|
2108
2059
|
//#endregion
|
|
2109
2060
|
//#region extensions/codex/src/app-server/project-doc-thread-config.ts
|
|
2110
|
-
const CODEX_NATIVE_PROJECT_DOC_MAX_BYTES =
|
|
2061
|
+
const CODEX_NATIVE_PROJECT_DOC_MAX_BYTES = 131072;
|
|
2111
2062
|
function buildCodexProjectDocThreadConfig(config) {
|
|
2112
2063
|
const defaults = { project_doc_max_bytes: CODEX_NATIVE_PROJECT_DOC_MAX_BYTES };
|
|
2113
2064
|
return mergeCodexThreadConfigs(defaults, config) ?? defaults;
|
|
@@ -2634,6 +2585,7 @@ async function resumeExistingCodexThread(params, context) {
|
|
|
2634
2585
|
const { binding: resumeBinding, bindingIdentity, startModelSelection, startModelProvider, userMcpServersConfigPatch, dynamicToolsFingerprint, dynamicToolsContainDeferred, webSearchThreadConfigFingerprint, nativeSkillIsolationFingerprint, userMcpServersFingerprint, ringZeroConfigFingerprint, ringZeroClientInstanceId, networkProxyConfigFingerprint, contextEngineBinding, environmentSelectionFingerprint, hostSystemAgentActive, ringZeroActive, restrictedToolSurface, restrictedToolSurfaceInheritedMcpServerNames, nativeSkillIsolation, lifecycleTiming, normalizeBindingModelProvider, throwIfAborted, clearCurrentBinding } = context;
|
|
2635
2586
|
let resumeReservation;
|
|
2636
2587
|
let resumeResponseAccepted = false;
|
|
2588
|
+
let checkingLoadedPluginThreadConfig = false;
|
|
2637
2589
|
const abandonClient = params.abandonClient ?? (() => closeCodexStartupClientBestEffort(params.client));
|
|
2638
2590
|
try {
|
|
2639
2591
|
const authProfileId = resumeBinding.connectionScope === "supervision" ? void 0 : params.params.authProfileId ?? resumeBinding.authProfileId;
|
|
@@ -2644,7 +2596,8 @@ async function resumeExistingCodexThread(params, context) {
|
|
|
2644
2596
|
configPatch: params.finalConfigPatch,
|
|
2645
2597
|
nativeHookRelayGeneration: params.nativeHookRelayGeneration
|
|
2646
2598
|
};
|
|
2647
|
-
const
|
|
2599
|
+
const pluginThreadConfig = context.prebuiltPluginThreadConfig ?? (params.pluginThreadConfig?.requiresCurrentPolicyCheck ? await lifecycleTiming.measure("plugin-config-build", () => params.pluginThreadConfig?.build()) : void 0);
|
|
2600
|
+
const pluginAppsConfigPatch = pluginThreadConfig?.configPatch ?? (params.pluginThreadConfig?.enabled && resumeBinding.pluginAppPolicyContext ? buildCodexPluginAppsConfigPatchFromPolicyContext(resumeBinding.pluginAppPolicyContext) : void 0);
|
|
2648
2601
|
const resumeConfig = applyCodexNativeSkillIsolation(mergeCodexThreadConfigs(params.config, userMcpServersConfigPatch, pluginAppsConfigPatch, finalConfigPatch.configPatch), nativeSkillIsolation);
|
|
2649
2602
|
const resumeParams = lifecycleTiming.measureSync("thread-resume-params", () => buildThreadResumeParams(params.params, {
|
|
2650
2603
|
threadId: resumeBinding.threadId,
|
|
@@ -2680,12 +2633,19 @@ async function resumeExistingCodexThread(params, context) {
|
|
|
2680
2633
|
resumeResponseAccepted = true;
|
|
2681
2634
|
assertCodexThreadAcceptsDirectInput(response.thread);
|
|
2682
2635
|
context.assertResumeConfiguration?.();
|
|
2683
|
-
|
|
2636
|
+
checkingLoadedPluginThreadConfig = true;
|
|
2637
|
+
const loadedPluginThreadConfig = await context.buildLoadedPluginThreadConfig?.(resumeBinding);
|
|
2638
|
+
if (loadedPluginThreadConfig && loadedPluginThreadConfig.fingerprint !== (pluginThreadConfig?.fingerprint ?? resumeBinding.pluginAppsFingerprint)) {
|
|
2639
|
+
checkingLoadedPluginThreadConfig = false;
|
|
2640
|
+
throw new Error("Codex thread app policy changed; a fresh thread configuration is required");
|
|
2641
|
+
}
|
|
2642
|
+
await attestCodexPluginThreadApps({
|
|
2684
2643
|
client: params.client,
|
|
2685
2644
|
threadId: response.thread.id,
|
|
2686
|
-
appIds:
|
|
2645
|
+
appIds: loadedPluginThreadConfig?.provisionalAppIds ?? pluginThreadConfig?.provisionalAppIds ?? [],
|
|
2687
2646
|
signal: params.signal
|
|
2688
2647
|
});
|
|
2648
|
+
checkingLoadedPluginThreadConfig = false;
|
|
2689
2649
|
if (ringZeroActive || isMessageOnlyCodexSourceReply(params.params) || params.params.pluginHarnessToolPolicyRestricted === true) try {
|
|
2690
2650
|
await lifecycleTiming.measure("restricted-tool-surface-mcp-attestation", () => attestCodexRestrictedToolSurfaceMcpServersDisabled(params.client, response.thread.id, resumeParams.config, params.signal));
|
|
2691
2651
|
} catch (error) {
|
|
@@ -2719,9 +2679,9 @@ async function resumeExistingCodexThread(params, context) {
|
|
|
2719
2679
|
networkProxyConfigFingerprint,
|
|
2720
2680
|
nativeHookRelayGeneration: finalConfigPatch.nativeHookRelayGeneration ?? resumeBinding.nativeHookRelayGeneration,
|
|
2721
2681
|
appServerRuntimeFingerprint: resumeBinding.connectionScope === "supervision" ? buildCodexAppServerConnectionFingerprint(params.appServer, params.params.agentDir) : params.appServerRuntimeFingerprint,
|
|
2722
|
-
pluginAppsFingerprint:
|
|
2723
|
-
pluginAppsInputFingerprint:
|
|
2724
|
-
pluginAppPolicyContext:
|
|
2682
|
+
pluginAppsFingerprint: pluginThreadConfig?.fingerprint ?? resumeBinding.pluginAppsFingerprint,
|
|
2683
|
+
pluginAppsInputFingerprint: pluginThreadConfig?.inputFingerprint ?? resumeBinding.pluginAppsInputFingerprint,
|
|
2684
|
+
pluginAppPolicyContext: pluginThreadConfig?.policyContext ?? resumeBinding.pluginAppPolicyContext,
|
|
2725
2685
|
contextEngine: contextEngineBinding,
|
|
2726
2686
|
environmentSelectionFingerprint
|
|
2727
2687
|
};
|
|
@@ -2785,7 +2745,7 @@ async function resumeExistingCodexThread(params, context) {
|
|
|
2785
2745
|
throw new CodexAppServerUnsafeSubscriptionError("Codex thread/resume subscription cleanup failed", { cause: error });
|
|
2786
2746
|
}
|
|
2787
2747
|
}
|
|
2788
|
-
if (resumeBinding.pendingResumeConfiguration || error instanceof CodexThreadDirectInputError || params.signal?.aborted) throw error;
|
|
2748
|
+
if (checkingLoadedPluginThreadConfig || resumeBinding.pendingResumeConfiguration || error instanceof CodexThreadDirectInputError || params.signal?.aborted) throw error;
|
|
2789
2749
|
embeddedAgentLog.warn("codex app-server thread resume failed; starting a new thread", { error });
|
|
2790
2750
|
await clearCurrentBinding("rotating a stale thread binding");
|
|
2791
2751
|
}
|
|
@@ -2818,14 +2778,15 @@ async function startFreshCodexThread(params, context) {
|
|
|
2818
2778
|
disableLoginShell: params.disableLoginShell
|
|
2819
2779
|
}));
|
|
2820
2780
|
const requestModelProvider = typeof startParams.modelProvider === "string" && startParams.modelProvider.trim() ? startParams.modelProvider : void 0;
|
|
2821
|
-
const
|
|
2781
|
+
const threadStartResponse = await lifecycleTiming.measure("thread-start-request", async () => {
|
|
2822
2782
|
try {
|
|
2823
2783
|
return await params.client.request("thread/start", startParams, { signal: params.signal });
|
|
2824
2784
|
} catch (error) {
|
|
2825
2785
|
if (error instanceof CodexAppServerRpcError) throw new CodexThreadStartRequestError(error);
|
|
2826
2786
|
throw error;
|
|
2827
2787
|
}
|
|
2828
|
-
})
|
|
2788
|
+
});
|
|
2789
|
+
const response = assertCodexThreadStartResponse(threadStartResponse);
|
|
2829
2790
|
const provisionalAppIds = pluginThreadConfig?.provisionalAppIds;
|
|
2830
2791
|
if (provisionalAppIds?.length) try {
|
|
2831
2792
|
await lifecycleTiming.measure("plugin-app-attestation", () => attestCodexPluginThreadApps({
|
|
@@ -3010,52 +2971,67 @@ async function releaseCodexRetainedLiveThread(options) {
|
|
|
3010
2971
|
}
|
|
3011
2972
|
/** Reuses one safely owned, fully matching subscription on its original client. */
|
|
3012
2973
|
async function tryReuseCodexLiveThread(options) {
|
|
3013
|
-
const { params, binding, bindingIdentity, clientId, dynamicToolsFingerprint, environmentSelectionFingerprint, hostSystemAgentActive, lifecycleTiming, nativeSkillIsolation,
|
|
3014
|
-
if (!binding.clientId || binding.clientId !== clientId || binding.preserveNativeModel === true || binding.connectionScope === "supervision" || ringZeroActive) return {};
|
|
3015
|
-
const
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
nativeHookRelayGeneration: params.nativeHookRelayGeneration
|
|
2974
|
+
const { params, binding, bindingIdentity, clientId, dynamicToolsFingerprint, environmentSelectionFingerprint, hostSystemAgentActive, lifecycleTiming, nativeSkillIsolation, ringZeroActive, restrictedToolSurfaceInheritedMcpServerNames, startModelProvider, startModelSelection, throwIfAborted, userMcpServersConfigPatch } = options;
|
|
2975
|
+
if (!binding.clientId || binding.clientId !== clientId || binding.preserveNativeModel === true || binding.connectionScope === "supervision" || ringZeroActive) return { kind: "resume" };
|
|
2976
|
+
const retainedThread = await consumeCodexAppServerLiveThread(params.client, binding.threadId);
|
|
2977
|
+
if (!retainedThread) return { kind: "resume" };
|
|
2978
|
+
const assertCurrentClient = () => {
|
|
2979
|
+
throwIfAborted();
|
|
2980
|
+
if (!isCodexAppServerClientRuntimeLive(params.client)) throw params.client.getCloseError() ?? /* @__PURE__ */ new Error("codex app-server client is closed");
|
|
3021
2981
|
};
|
|
3022
|
-
|
|
3023
|
-
const resumeAuthProfileId = params.params.authProfileId ?? binding.authProfileId;
|
|
3024
|
-
const resumeConfig = mergeCodexThreadConfigs(params.config, userMcpServersConfigPatch, pluginAppsConfigPatch, prebuiltFinalConfigPatch.configPatch);
|
|
3025
|
-
const resumeParams = lifecycleTiming.measureSync("warm-thread-resume-params", () => buildThreadResumeParams(params.params, {
|
|
3026
|
-
threadId: binding.threadId,
|
|
3027
|
-
cwd: params.cwd,
|
|
3028
|
-
authProfileId: resumeAuthProfileId,
|
|
3029
|
-
model: startModelSelection.model,
|
|
3030
|
-
modelProvider: startModelProvider,
|
|
3031
|
-
preserveNativeModel: false,
|
|
3032
|
-
appServer: params.appServer,
|
|
3033
|
-
dynamicTools: params.dynamicTools,
|
|
3034
|
-
developerInstructions: params.developerInstructions,
|
|
3035
|
-
config: applyCodexNativeSkillIsolation(resumeConfig, nativeSkillIsolation),
|
|
3036
|
-
nativeCodeModeEnabled: params.nativeCodeModeEnabled,
|
|
3037
|
-
nativeProviderWebSearchSupport: params.nativeProviderWebSearchSupport,
|
|
3038
|
-
nativeCodeModeOnlyEnabled: params.nativeCodeModeOnlyEnabled,
|
|
3039
|
-
webSearchAllowed: params.webSearchAllowed,
|
|
3040
|
-
hostSystemAgentActive,
|
|
3041
|
-
restrictedToolSurfaceInheritedMcpServerNames,
|
|
3042
|
-
shellEnvironment: params.shellEnvironment,
|
|
3043
|
-
disableLoginShell: params.disableLoginShell
|
|
3044
|
-
}));
|
|
3045
|
-
const liveThreadConfigFingerprint = fingerprintCodexThreadConfig({
|
|
3046
|
-
...resumeParams,
|
|
3047
|
-
model: binding.model ?? resumeParams.model ?? null,
|
|
3048
|
-
requestedModel: resumeParams.model ?? null,
|
|
3049
|
-
modelProvider: binding.modelProvider ?? resumeParams.modelProvider ?? null,
|
|
3050
|
-
requestedModelProvider: resumeParams.modelProvider ?? binding.modelProvider ?? null
|
|
3051
|
-
}, resumeAuthProfileId, dynamicToolsFingerprint);
|
|
3052
|
-
const retainedThread = await consumeCodexAppServerLiveThread(params.client, binding.threadId, liveThreadConfigFingerprint);
|
|
3053
|
-
if (!retainedThread) {
|
|
3054
|
-
const incompatibleOwnership = await consumeCodexAppServerLiveThread(params.client, binding.threadId);
|
|
3055
|
-
if (incompatibleOwnership) await incompatibleOwnership.release(binding.threadId);
|
|
3056
|
-
return { prebuiltFinalConfigPatch };
|
|
3057
|
-
}
|
|
2982
|
+
let ownershipTransferred = false;
|
|
3058
2983
|
try {
|
|
2984
|
+
const pluginThreadConfig = await options.buildLoadedPluginThreadConfig(binding);
|
|
2985
|
+
assertCurrentClient();
|
|
2986
|
+
if (pluginThreadConfig && pluginThreadConfig.fingerprint !== binding.pluginAppsFingerprint) return { kind: "rotate" };
|
|
2987
|
+
const prebuiltFinalConfigPatch = params.buildFinalConfigPatch?.({
|
|
2988
|
+
action: "resume",
|
|
2989
|
+
binding
|
|
2990
|
+
}) ?? {
|
|
2991
|
+
configPatch: params.finalConfigPatch,
|
|
2992
|
+
nativeHookRelayGeneration: params.nativeHookRelayGeneration
|
|
2993
|
+
};
|
|
2994
|
+
const pluginAppsConfigPatch = pluginThreadConfig?.configPatch ?? (params.pluginThreadConfig?.enabled && binding.pluginAppPolicyContext ? buildCodexPluginAppsConfigPatchFromPolicyContext(binding.pluginAppPolicyContext) : void 0);
|
|
2995
|
+
const resumeAuthProfileId = params.params.authProfileId ?? binding.authProfileId;
|
|
2996
|
+
const resumeConfig = mergeCodexThreadConfigs(params.config, userMcpServersConfigPatch, pluginAppsConfigPatch, prebuiltFinalConfigPatch.configPatch);
|
|
2997
|
+
const resumeParams = lifecycleTiming.measureSync("warm-thread-resume-params", () => buildThreadResumeParams(params.params, {
|
|
2998
|
+
threadId: binding.threadId,
|
|
2999
|
+
cwd: params.cwd,
|
|
3000
|
+
authProfileId: resumeAuthProfileId,
|
|
3001
|
+
model: startModelSelection.model,
|
|
3002
|
+
modelProvider: startModelProvider,
|
|
3003
|
+
preserveNativeModel: false,
|
|
3004
|
+
appServer: params.appServer,
|
|
3005
|
+
dynamicTools: params.dynamicTools,
|
|
3006
|
+
developerInstructions: params.developerInstructions,
|
|
3007
|
+
config: applyCodexNativeSkillIsolation(resumeConfig, nativeSkillIsolation),
|
|
3008
|
+
nativeCodeModeEnabled: params.nativeCodeModeEnabled,
|
|
3009
|
+
nativeProviderWebSearchSupport: params.nativeProviderWebSearchSupport,
|
|
3010
|
+
nativeCodeModeOnlyEnabled: params.nativeCodeModeOnlyEnabled,
|
|
3011
|
+
webSearchAllowed: params.webSearchAllowed,
|
|
3012
|
+
hostSystemAgentActive,
|
|
3013
|
+
restrictedToolSurfaceInheritedMcpServerNames,
|
|
3014
|
+
shellEnvironment: params.shellEnvironment,
|
|
3015
|
+
disableLoginShell: params.disableLoginShell
|
|
3016
|
+
}));
|
|
3017
|
+
const liveThreadConfigFingerprint = fingerprintCodexThreadConfig({
|
|
3018
|
+
...resumeParams,
|
|
3019
|
+
model: binding.model ?? resumeParams.model ?? null,
|
|
3020
|
+
requestedModel: resumeParams.model ?? null,
|
|
3021
|
+
modelProvider: binding.modelProvider ?? resumeParams.modelProvider ?? null,
|
|
3022
|
+
requestedModelProvider: resumeParams.modelProvider ?? binding.modelProvider ?? null
|
|
3023
|
+
}, resumeAuthProfileId, dynamicToolsFingerprint);
|
|
3024
|
+
if (retainedThread.configFingerprint !== liveThreadConfigFingerprint) return {
|
|
3025
|
+
kind: "resume",
|
|
3026
|
+
prebuiltFinalConfigPatch
|
|
3027
|
+
};
|
|
3028
|
+
await attestCodexPluginThreadApps({
|
|
3029
|
+
client: params.client,
|
|
3030
|
+
threadId: binding.threadId,
|
|
3031
|
+
appIds: pluginThreadConfig?.provisionalAppIds ?? [],
|
|
3032
|
+
signal: params.signal
|
|
3033
|
+
});
|
|
3034
|
+
assertCurrentClient();
|
|
3059
3035
|
const nativeHookRelayGeneration = prebuiltFinalConfigPatch.nativeHookRelayGeneration ?? binding.nativeHookRelayGeneration;
|
|
3060
3036
|
const model = startModelSelection.model;
|
|
3061
3037
|
if (!await lifecycleTiming.measure("warm-thread-write-binding", () => params.bindingStore.mutate(bindingIdentity, {
|
|
@@ -3067,8 +3043,8 @@ async function tryReuseCodexLiveThread(options) {
|
|
|
3067
3043
|
nativeHookRelayGeneration,
|
|
3068
3044
|
environmentSelectionFingerprint
|
|
3069
3045
|
}
|
|
3070
|
-
}))) throw new CodexThreadBindingConflictError(binding.threadId, "committing a reused thread");
|
|
3071
|
-
|
|
3046
|
+
}, assertCurrentClient))) throw new CodexThreadBindingConflictError(binding.threadId, "committing a reused thread");
|
|
3047
|
+
assertCurrentClient();
|
|
3072
3048
|
lifecycleTiming.mark("thread-ready");
|
|
3073
3049
|
lifecycleTiming.logSummary({
|
|
3074
3050
|
runId: params.params.runId,
|
|
@@ -3077,7 +3053,9 @@ async function tryReuseCodexLiveThread(options) {
|
|
|
3077
3053
|
threadId: binding.threadId,
|
|
3078
3054
|
action: "resumed"
|
|
3079
3055
|
});
|
|
3056
|
+
ownershipTransferred = true;
|
|
3080
3057
|
return {
|
|
3058
|
+
kind: "ready",
|
|
3081
3059
|
binding: {
|
|
3082
3060
|
...binding,
|
|
3083
3061
|
cwd: params.cwd,
|
|
@@ -3088,12 +3066,19 @@ async function tryReuseCodexLiveThread(options) {
|
|
|
3088
3066
|
liveThreadOwnership: retainedThread,
|
|
3089
3067
|
...retainedThread.serviceTier && resumeParams.serviceTier === void 0 ? { clearInheritedServiceTier: true } : {},
|
|
3090
3068
|
lifecycle: { action: "resumed" }
|
|
3091
|
-
}
|
|
3092
|
-
prebuiltFinalConfigPatch
|
|
3069
|
+
}
|
|
3093
3070
|
};
|
|
3094
|
-
}
|
|
3095
|
-
|
|
3096
|
-
|
|
3071
|
+
} finally {
|
|
3072
|
+
if (!ownershipTransferred) try {
|
|
3073
|
+
await retainedThread.release(binding.threadId);
|
|
3074
|
+
} catch (error) {
|
|
3075
|
+
await abandonCodexLiveThreadRelease({
|
|
3076
|
+
client: params.client,
|
|
3077
|
+
abandonClient: params.abandonClient,
|
|
3078
|
+
lifecycleTiming,
|
|
3079
|
+
threadId: binding.threadId
|
|
3080
|
+
}, error);
|
|
3081
|
+
}
|
|
3097
3082
|
}
|
|
3098
3083
|
}
|
|
3099
3084
|
//#endregion
|
|
@@ -3244,9 +3229,9 @@ const CODEX_NATIVE_HOOK_RELAY_EVENTS = [
|
|
|
3244
3229
|
"before_agent_finalize"
|
|
3245
3230
|
];
|
|
3246
3231
|
const CODEX_NATIVE_HOOK_RELAY_EVENTS_WITH_APP_SERVER_APPROVALS = CODEX_NATIVE_HOOK_RELAY_EVENTS.filter((event) => event !== "permission_request");
|
|
3247
|
-
const CODEX_NATIVE_HOOK_RELAY_MIN_TTL_MS =
|
|
3232
|
+
const CODEX_NATIVE_HOOK_RELAY_MIN_TTL_MS = 18e5;
|
|
3248
3233
|
/** Extra relay lifetime after the expected turn budget, preventing late hook drops. */
|
|
3249
|
-
const CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS =
|
|
3234
|
+
const CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS = 3e5;
|
|
3250
3235
|
const CODEX_NATIVE_HOOK_RELAY_COMMAND_MIN_PARENT_MARGIN_MS = 250;
|
|
3251
3236
|
const CODEX_NATIVE_HOOK_RELAY_COMMAND_MAX_PARENT_MARGIN_MS = 1e3;
|
|
3252
3237
|
const CODEX_NATIVE_HOOK_RELAY_DEFAULT_TIMEOUT_SEC = 10;
|
|
@@ -4311,10 +4296,28 @@ async function startOrResumeThread(params) {
|
|
|
4311
4296
|
binding = void 0;
|
|
4312
4297
|
}
|
|
4313
4298
|
const requestContext = resolveRequestContext();
|
|
4314
|
-
const { startModelSelection, startModelProvider } = requestContext;
|
|
4315
4299
|
let preserveExistingBinding = transientDelegationRestriction || !ringZeroActive && params.nativeProviderWebSearchSupport === "unknown" && !binding?.threadId;
|
|
4316
4300
|
let rotatedContextEngineBinding = false;
|
|
4317
4301
|
let prebuiltPluginThreadConfig;
|
|
4302
|
+
const buildLoadedPluginThreadConfig = async (current) => {
|
|
4303
|
+
if (!params.pluginThreadConfig?.requiresCurrentPolicyCheck && !shouldRecheckRecoverablePluginBinding({
|
|
4304
|
+
binding: current,
|
|
4305
|
+
pluginThreadConfig: params.pluginThreadConfig
|
|
4306
|
+
})) return;
|
|
4307
|
+
try {
|
|
4308
|
+
prebuiltPluginThreadConfig = await lifecycleTiming.measure("plugin-config-recovery", () => params.pluginThreadConfig?.build({ threadId: current.threadId }));
|
|
4309
|
+
} catch (error) {
|
|
4310
|
+
throwIfAborted();
|
|
4311
|
+
if (params.pluginThreadConfig?.requiresCurrentPolicyCheck) throw error;
|
|
4312
|
+
embeddedAgentLog.warn("codex app-server plugin app config recovery check failed", {
|
|
4313
|
+
error,
|
|
4314
|
+
threadId: current.threadId
|
|
4315
|
+
});
|
|
4316
|
+
return;
|
|
4317
|
+
}
|
|
4318
|
+
throwIfAborted();
|
|
4319
|
+
return prebuiltPluginThreadConfig;
|
|
4320
|
+
};
|
|
4318
4321
|
const webSearchBindingChanged = binding?.threadId && binding.webSearchThreadConfigFingerprint !== webSearchThreadConfigFingerprint;
|
|
4319
4322
|
const explicitTransientWebSearchRestriction = params.webSearchAllowed === false && params.persistentWebSearchAllowed !== false && transientWebSearchRestriction;
|
|
4320
4323
|
const unknownProviderWebSearchSupport = params.nativeProviderWebSearchSupport === "unknown";
|
|
@@ -4393,28 +4396,13 @@ async function startOrResumeThread(params) {
|
|
|
4393
4396
|
binding = void 0;
|
|
4394
4397
|
}
|
|
4395
4398
|
if (binding?.threadId) {
|
|
4396
|
-
|
|
4399
|
+
if (isCodexPluginThreadBindingStale({
|
|
4397
4400
|
codexPluginsEnabled: params.pluginThreadConfig?.enabled ?? false,
|
|
4398
4401
|
bindingFingerprint: binding.pluginAppsFingerprint,
|
|
4399
4402
|
bindingInputFingerprint: binding.pluginAppsInputFingerprint,
|
|
4400
4403
|
currentInputFingerprint: params.pluginThreadConfig?.inputFingerprint,
|
|
4401
4404
|
hasBindingPolicyContext: Boolean(binding.pluginAppPolicyContext)
|
|
4402
|
-
})
|
|
4403
|
-
if (!pluginBindingStale && (params.pluginThreadConfig?.requiresCurrentPolicyCheck || shouldRecheckRecoverablePluginBinding({
|
|
4404
|
-
binding,
|
|
4405
|
-
pluginThreadConfig: params.pluginThreadConfig
|
|
4406
|
-
}))) try {
|
|
4407
|
-
const bindingThreadId = binding.threadId;
|
|
4408
|
-
prebuiltPluginThreadConfig = await lifecycleTiming.measure("plugin-config-recovery", () => params.pluginThreadConfig?.build({ threadId: bindingThreadId }));
|
|
4409
|
-
pluginBindingStale = prebuiltPluginThreadConfig?.fingerprint !== binding.pluginAppsFingerprint;
|
|
4410
|
-
} catch (error) {
|
|
4411
|
-
if (params.pluginThreadConfig?.requiresCurrentPolicyCheck) throw error;
|
|
4412
|
-
embeddedAgentLog.warn("codex app-server plugin app config recovery check failed", {
|
|
4413
|
-
error,
|
|
4414
|
-
threadId: binding.threadId
|
|
4415
|
-
});
|
|
4416
|
-
}
|
|
4417
|
-
if (pluginBindingStale) {
|
|
4405
|
+
})) {
|
|
4418
4406
|
embeddedAgentLog.debug("codex app-server plugin app config changed; starting a new thread", { threadId: binding.threadId });
|
|
4419
4407
|
await clearCurrentBinding("rotating a stale thread binding");
|
|
4420
4408
|
binding = void 0;
|
|
@@ -4427,75 +4415,66 @@ async function startOrResumeThread(params) {
|
|
|
4427
4415
|
binding = void 0;
|
|
4428
4416
|
}
|
|
4429
4417
|
}
|
|
4430
|
-
if (binding?.threadId)
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
if (preserveExistingBinding) embeddedAgentLog.debug("codex app-server dynamic tools unavailable for turn; starting transient thread", { threadId: binding.threadId });
|
|
4437
|
-
else {
|
|
4438
|
-
embeddedAgentLog.debug("codex app-server dynamic tool catalog changed; starting a new thread", { threadId: binding.threadId });
|
|
4439
|
-
await clearCurrentBinding("rotating a stale thread binding");
|
|
4440
|
-
}
|
|
4441
|
-
} else if (incognito) {
|
|
4442
|
-
if (binding.clientId && binding.clientId === clientId) {
|
|
4443
|
-
params.buildFinalConfigPatch?.({
|
|
4444
|
-
action: "resume",
|
|
4445
|
-
binding
|
|
4418
|
+
if (binding?.threadId) {
|
|
4419
|
+
if (binding.dynamicToolsFingerprint && !areDynamicToolFingerprintsCompatible(binding.dynamicToolsFingerprint, dynamicToolsFingerprint, legacyDynamicToolsFingerprint)) {
|
|
4420
|
+
assertCodexBindingMayBeReplaced(binding, "changing the dynamic tool catalog");
|
|
4421
|
+
preserveExistingBinding = shouldStartTransientNoToolThread({
|
|
4422
|
+
previous: binding.dynamicToolsFingerprint,
|
|
4423
|
+
nextHasDynamicTools: params.dynamicTools.length > 0
|
|
4446
4424
|
});
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4425
|
+
if (preserveExistingBinding) embeddedAgentLog.debug("codex app-server dynamic tools unavailable for turn; starting transient thread", { threadId: binding.threadId });
|
|
4426
|
+
else {
|
|
4427
|
+
embeddedAgentLog.debug("codex app-server dynamic tool catalog changed; starting a new thread", { threadId: binding.threadId });
|
|
4428
|
+
await clearCurrentBinding("rotating a stale thread binding");
|
|
4429
|
+
}
|
|
4430
|
+
} else if (incognito) {
|
|
4431
|
+
if (binding.clientId && binding.clientId === clientId && ((await buildLoadedPluginThreadConfig(binding))?.fingerprint ?? binding.pluginAppsFingerprint) === binding.pluginAppsFingerprint) {
|
|
4432
|
+
params.buildFinalConfigPatch?.({
|
|
4433
|
+
action: "resume",
|
|
4434
|
+
binding
|
|
4435
|
+
});
|
|
4436
|
+
throwIfAborted();
|
|
4437
|
+
lifecycleTiming.mark("thread-ready");
|
|
4438
|
+
lifecycleTiming.logSummary({
|
|
4439
|
+
runId: params.params.runId,
|
|
4440
|
+
sessionId: params.params.sessionId,
|
|
4441
|
+
sessionKey: params.params.sessionKey,
|
|
4442
|
+
threadId: binding.threadId,
|
|
4443
|
+
action: "resumed"
|
|
4444
|
+
});
|
|
4445
|
+
return {
|
|
4446
|
+
...binding,
|
|
4447
|
+
lifecycle: { action: "resumed" }
|
|
4448
|
+
};
|
|
4449
|
+
}
|
|
4450
|
+
await clearCurrentBinding("rotating an unavailable ephemeral thread binding");
|
|
4451
|
+
binding = void 0;
|
|
4452
|
+
} else {
|
|
4453
|
+
const warmReuse = await tryReuseCodexLiveThread({
|
|
4454
|
+
...requestContext,
|
|
4455
|
+
params,
|
|
4456
|
+
binding,
|
|
4457
|
+
clientId,
|
|
4458
|
+
buildLoadedPluginThreadConfig
|
|
4455
4459
|
});
|
|
4456
|
-
return
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
+
if (warmReuse.kind === "ready") return warmReuse.binding;
|
|
4461
|
+
if (warmReuse.kind === "rotate") {
|
|
4462
|
+
throwIfAborted();
|
|
4463
|
+
await clearCurrentBinding("rotating a stale plugin app binding");
|
|
4464
|
+
} else {
|
|
4465
|
+
if (binding.preserveNativeModel === true) await assertAdoptedCodexThreadResumeAllowed(params, binding.threadId, requestContext);
|
|
4466
|
+
await releaseRetainedThread(binding.threadId);
|
|
4467
|
+
const resumed = await resumeExistingCodexThread(params, {
|
|
4468
|
+
...requestContext,
|
|
4469
|
+
binding,
|
|
4470
|
+
clearCurrentBinding,
|
|
4471
|
+
prebuiltFinalConfigPatch: warmReuse.prebuiltFinalConfigPatch,
|
|
4472
|
+
prebuiltPluginThreadConfig,
|
|
4473
|
+
buildLoadedPluginThreadConfig
|
|
4474
|
+
});
|
|
4475
|
+
if (resumed) return resumed;
|
|
4476
|
+
}
|
|
4460
4477
|
}
|
|
4461
|
-
await clearCurrentBinding("rotating an unavailable ephemeral thread binding");
|
|
4462
|
-
binding = void 0;
|
|
4463
|
-
} else {
|
|
4464
|
-
const warmReuse = await tryReuseCodexLiveThread({
|
|
4465
|
-
params,
|
|
4466
|
-
binding,
|
|
4467
|
-
bindingIdentity,
|
|
4468
|
-
clientId,
|
|
4469
|
-
dynamicToolsFingerprint,
|
|
4470
|
-
environmentSelectionFingerprint,
|
|
4471
|
-
hostSystemAgentActive,
|
|
4472
|
-
lifecycleTiming,
|
|
4473
|
-
nativeSkillIsolation,
|
|
4474
|
-
releaseConsumedThread: (threadId, cause) => releaseCodexConsumedLiveThread({
|
|
4475
|
-
client: params.client,
|
|
4476
|
-
abandonClient: params.abandonClient,
|
|
4477
|
-
lifecycleTiming,
|
|
4478
|
-
threadId,
|
|
4479
|
-
cause
|
|
4480
|
-
}),
|
|
4481
|
-
ringZeroActive,
|
|
4482
|
-
restrictedToolSurfaceInheritedMcpServerNames,
|
|
4483
|
-
startModelProvider,
|
|
4484
|
-
startModelSelection,
|
|
4485
|
-
throwIfAborted,
|
|
4486
|
-
userMcpServersConfigPatch
|
|
4487
|
-
});
|
|
4488
|
-
if (warmReuse.binding) return warmReuse.binding;
|
|
4489
|
-
if (binding.preserveNativeModel === true) await assertAdoptedCodexThreadResumeAllowed(params, binding.threadId, requestContext);
|
|
4490
|
-
await releaseRetainedThread(binding.threadId);
|
|
4491
|
-
const resumed = await resumeExistingCodexThread(params, {
|
|
4492
|
-
...requestContext,
|
|
4493
|
-
binding,
|
|
4494
|
-
clearCurrentBinding,
|
|
4495
|
-
prebuiltFinalConfigPatch: warmReuse.prebuiltFinalConfigPatch,
|
|
4496
|
-
prebuiltPluginThreadConfig
|
|
4497
|
-
});
|
|
4498
|
-
if (resumed) return resumed;
|
|
4499
4478
|
}
|
|
4500
4479
|
if (initialBoundThreadId && !preserveExistingBinding && !replacementPredecessor) await releaseRetainedThread(initialBoundThreadId);
|
|
4501
4480
|
const started = await startFreshCodexThread(params, {
|
|
@@ -4510,6 +4489,54 @@ async function startOrResumeThread(params) {
|
|
|
4510
4489
|
});
|
|
4511
4490
|
}
|
|
4512
4491
|
//#endregion
|
|
4492
|
+
//#region extensions/codex/src/app-server/reasoning-effort.ts
|
|
4493
|
+
const CODEX_REASONING_EFFORTS = [
|
|
4494
|
+
"minimal",
|
|
4495
|
+
"low",
|
|
4496
|
+
"medium",
|
|
4497
|
+
"high",
|
|
4498
|
+
"xhigh",
|
|
4499
|
+
"max"
|
|
4500
|
+
];
|
|
4501
|
+
const LEGACY_PRO_REASONING_EFFORTS = [
|
|
4502
|
+
"medium",
|
|
4503
|
+
"high",
|
|
4504
|
+
"xhigh"
|
|
4505
|
+
];
|
|
4506
|
+
const LEGACY_PRO_MODEL_ID_RE = /^gpt-5\.[45]-pro$/u;
|
|
4507
|
+
const MODERN_GPT_5_MODEL_ID_RE = /^gpt-5\.(?:[3-9]|[1-9]\d)(?:$|-)/u;
|
|
4508
|
+
/** Read reasoning metadata after the Codex app-server route has been selected. */
|
|
4509
|
+
function readCodexSupportedReasoningEfforts(compat) {
|
|
4510
|
+
if (!compat || typeof compat !== "object" || Array.isArray(compat)) return;
|
|
4511
|
+
const efforts = compat.supportedReasoningEfforts;
|
|
4512
|
+
if (!Array.isArray(efforts)) return;
|
|
4513
|
+
return efforts.filter((effort) => typeof effort === "string");
|
|
4514
|
+
}
|
|
4515
|
+
function resolveSupportedReasoningEffort(params) {
|
|
4516
|
+
const declared = new Set(params.supportedReasoningEfforts.map((effort) => effort.trim().toLowerCase()));
|
|
4517
|
+
const supported = CODEX_REASONING_EFFORTS.filter((effort) => declared.has(effort));
|
|
4518
|
+
if (supported.includes(params.requested)) return params.requested;
|
|
4519
|
+
const requestedRank = CODEX_REASONING_EFFORTS.indexOf(params.requested);
|
|
4520
|
+
return supported.find((effort) => CODEX_REASONING_EFFORTS.indexOf(effort) >= requestedRank) ?? supported.at(-1);
|
|
4521
|
+
}
|
|
4522
|
+
function resolveCodexAppServerReasoningEffort(params) {
|
|
4523
|
+
if (params.thinkLevel === "ultra") return "ultra";
|
|
4524
|
+
if (params.thinkLevel === "off") return params.supportedReasoningEfforts?.includes("none") ? "none" : null;
|
|
4525
|
+
if (params.thinkLevel === "adaptive") return null;
|
|
4526
|
+
if (params.supportedReasoningEfforts) return resolveSupportedReasoningEffort({
|
|
4527
|
+
requested: params.thinkLevel,
|
|
4528
|
+
supportedReasoningEfforts: params.supportedReasoningEfforts
|
|
4529
|
+
}) ?? null;
|
|
4530
|
+
const modelId = params.modelId.trim().toLowerCase();
|
|
4531
|
+
if (LEGACY_PRO_MODEL_ID_RE.test(modelId)) return resolveSupportedReasoningEffort({
|
|
4532
|
+
requested: params.thinkLevel,
|
|
4533
|
+
supportedReasoningEfforts: LEGACY_PRO_REASONING_EFFORTS
|
|
4534
|
+
}) ?? null;
|
|
4535
|
+
if (params.thinkLevel === "minimal" && MODERN_GPT_5_MODEL_ID_RE.test(modelId)) return "low";
|
|
4536
|
+
if (params.thinkLevel === "minimal" || params.thinkLevel === "low" || params.thinkLevel === "medium" || params.thinkLevel === "high" || params.thinkLevel === "xhigh") return params.thinkLevel;
|
|
4537
|
+
return null;
|
|
4538
|
+
}
|
|
4539
|
+
//#endregion
|
|
4513
4540
|
//#region extensions/codex/src/app-server/user-input.ts
|
|
4514
4541
|
/** Builds ordered Codex user input for both new turns and same-turn steering. */
|
|
4515
4542
|
function buildCodexUserInput(text, images) {
|
|
@@ -4562,12 +4589,25 @@ function buildTurnStartParams(params, options) {
|
|
|
4562
4589
|
agentDir: params.agentDir,
|
|
4563
4590
|
config: params.config
|
|
4564
4591
|
});
|
|
4592
|
+
const collaborationMode = modelSelection ? buildTurnCollaborationMode(params, {
|
|
4593
|
+
model: modelSelection.model,
|
|
4594
|
+
turnScopedDeveloperInstructions: options.turnScopedDeveloperInstructions,
|
|
4595
|
+
skillsCollaborationInstructions: options.skillsCollaborationInstructions,
|
|
4596
|
+
memoryCollaborationInstructions: options.memoryCollaborationInstructions
|
|
4597
|
+
}) : void 0;
|
|
4565
4598
|
const useThreadPermissionProfile = options.appServer.networkProxy && !options.sandboxPolicy;
|
|
4566
4599
|
const currentSenderContext = params.trigger === "user" ? buildCodexCurrentSenderContextValue(params) : void 0;
|
|
4567
|
-
|
|
4600
|
+
let additionalContext = currentSenderContext ? { openclaw_current_sender: {
|
|
4568
4601
|
kind: "untrusted",
|
|
4569
4602
|
value: currentSenderContext
|
|
4570
4603
|
} } : void 0;
|
|
4604
|
+
if (params.permissionChange?.notice) additionalContext = {
|
|
4605
|
+
...additionalContext,
|
|
4606
|
+
openclaw_permission_change: {
|
|
4607
|
+
kind: "application",
|
|
4608
|
+
value: params.permissionChange.notice
|
|
4609
|
+
}
|
|
4610
|
+
};
|
|
4571
4611
|
return {
|
|
4572
4612
|
threadId: options.threadId,
|
|
4573
4613
|
input: [...buildCodexUserInput(options.promptText ?? params.prompt, params.images), ...options.explicitSkillInputs ?? []],
|
|
@@ -4582,14 +4622,11 @@ function buildTurnStartParams(params, options) {
|
|
|
4582
4622
|
personality: CODEX_NATIVE_PERSONALITY_NONE
|
|
4583
4623
|
} : {},
|
|
4584
4624
|
...options.appServer.serviceTier !== void 0 ? { serviceTier: options.appServer.serviceTier } : options.clearInheritedServiceTier ? { serviceTier: null } : {},
|
|
4585
|
-
...
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
skillsCollaborationInstructions: options.skillsCollaborationInstructions,
|
|
4591
|
-
memoryCollaborationInstructions: options.memoryCollaborationInstructions
|
|
4592
|
-
}) } : {}
|
|
4625
|
+
...collaborationMode ? {
|
|
4626
|
+
effort: collaborationMode.settings.reasoning_effort,
|
|
4627
|
+
collaborationMode
|
|
4628
|
+
} : {},
|
|
4629
|
+
...options.environmentSelection ? { environments: options.environmentSelection } : {}
|
|
4593
4630
|
};
|
|
4594
4631
|
}
|
|
4595
4632
|
function buildTurnCollaborationMode(params, options = {}) {
|
|
@@ -4598,7 +4635,11 @@ function buildTurnCollaborationMode(params, options = {}) {
|
|
|
4598
4635
|
mode: "default",
|
|
4599
4636
|
settings: {
|
|
4600
4637
|
model,
|
|
4601
|
-
reasoning_effort:
|
|
4638
|
+
reasoning_effort: resolveCodexAppServerReasoningEffort({
|
|
4639
|
+
thinkLevel: params.thinkLevel,
|
|
4640
|
+
modelId: model,
|
|
4641
|
+
supportedReasoningEfforts: readCodexSupportedReasoningEfforts(params.model?.compat)
|
|
4642
|
+
}),
|
|
4602
4643
|
developer_instructions: buildTurnScopedCollaborationInstructions(params, options)
|
|
4603
4644
|
}
|
|
4604
4645
|
};
|
|
@@ -4636,4 +4677,4 @@ function joinPresentSections(...sections) {
|
|
|
4636
4677
|
return sections.filter((section) => Boolean(section?.trim())).join("\n\n");
|
|
4637
4678
|
}
|
|
4638
4679
|
//#endregion
|
|
4639
|
-
export { resolveCodexContinuityProjectionMaxChars as $,
|
|
4680
|
+
export { resolveCodexContinuityProjectionMaxChars as $, resolveCodexBindingModelProviderFallback as A, isMessageOnlyCodexSourceReply as B, resolveCodexWebSearchPlan as C, resolveCodexAppServerModelProvider as D, CODEX_NATIVE_PERSONALITY_NONE as E, codexDynamicToolsFingerprint as F, buildContextEngineBinding as G, normalizeCodexDynamicToolName as H, codexLegacyDynamicToolsFingerprint as I, fitCodexProjectedContextForTurnStart as J, isContextEngineBindingCompatible as K, filterCodexDynamicTools as L, CODEX_MANAGED_THREAD_NAMESPACE as M, createCodexManagedThreadStore as N, resolveCodexAppServerRequestModelSelection as O, areCodexDynamicToolFingerprintsCompatible as P, resolveCodexContextEngineProjectionReserveTokens as Q, filterCodexDynamicToolsForDisabledNativeSurface as R, buildCodexNativeWebSearchThreadConfig as S, buildCodexProjectDocThreadConfig as T, resolveCodexDynamicToolsLoading as U, isSystemAgentOnlyCodexDynamicToolAllowlist as V, resolveCodexDynamicToolsLoadingForRuntime as W, projectContextEngineAssemblyForCodex as X, neutralizeCodexExplicitMentionSigils as Y, resolveCodexContextEngineProjectionMaxChars as Z, assertCodexManagedRequirementsDoNotOverrideToolPolicy as _, resolveCodexAppServerReasoningEffort as a, buildPluginAppPolicyContext as at, buildCodexRuntimeThreadConfig as b, CODEX_NATIVE_HOOK_RELAY_EVENTS as c, ensureCodexPluginActivation as ct, buildCodexNativeHookRelayDisabledConfig as d, isOpenAiCuratedMarketplaceName as dt, buildCodexPluginAppsConfigPatchFromPolicyContext as et, createCodexNativeHookRelay as f, pluginReadParams as ft, scheduleCodexNativeHookRelayUnregister as g, resolveCodexNativeHookRelayTtlMs as h, readCodexSupportedReasoningEfforts as i, buildDisabledAppsConfigPatch as it, CODEX_MANAGED_THREAD_MAX_ENTRIES as j, resolveCodexAppServerThreadModelSelection as k, CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS as l, refreshCodexPluginRuntimeState as lt, resolveCodexNativeHookRelayEvents as m, buildTurnStartParams as n, buildCodexPluginThreadConfigInputFingerprint as nt, startOrResumeThread as o, mergeCodexThreadConfigs as ot, emitCodexNativePreToolUseFailureDiagnostic as p, resolveRecoverableCodexPluginConfigKeys as pt, buildCodexContinuityCalibration as q, buildCodexUserInput as r, buildCodexPluginThreadConfigTimeoutFallback as rt, isCodexAppServerProfilerEnabled as s, shouldBuildCodexPluginThreadConfig as st, buildTurnCollaborationMode as t, buildCodexPluginThreadConfig as tt, buildCodexNativeHookRelayConfig as u, isOpenAiCuratedMarketplace as ut, attestCodexRestrictedToolSurfaceMcpServersDisabled as v, buildDeveloperInstructions as w, readCodexInheritedMcpServerNames as x, buildCodexRingZeroThreadConfigPatch as y, isForcedPrivateQaCodexRuntime as z };
|