@openclaw/codex 2026.7.2-beta.1 → 2026.7.2-beta.2
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 +1 -1
- package/dist/{app-server-policy-DVcxdse_.js → app-server-policy-Scc-Wevo.js} +1 -1
- package/dist/{attempt-notifications-DEv9h7iC.js → attempt-notifications-BFmNhqFl.js} +3 -6
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-D6ZlGNmb.js → command-formatters-Dq9InZUK.js} +34 -3
- package/dist/{command-handlers-Cpl9fUWv.js → command-handlers-IgqmL_kv.js} +10 -13
- package/dist/{compact-FnJmiPNA.js → compact-DCTmg3id.js} +4 -5
- package/dist/{computer-use-DVzr8OP1.js → computer-use-CPcU8TjG.js} +4 -4
- package/dist/{conversation-control-DtQ-E7mr.js → conversation-control-CGkBlfc5.js} +5 -7
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{dynamic-tools-BMLoaTeG.js → dynamic-tools-C_1tEs34.js} +608 -330
- package/dist/harness.js +9 -5
- package/dist/index.js +52 -31
- package/dist/{media-understanding-provider-D580L0P8.js → media-understanding-provider-D31dOJwb.js} +11 -12
- package/dist/media-understanding-provider.js +1 -1
- package/dist/{models-DuKzZA6G.js → models-uh26C8QU.js} +5 -9
- package/dist/{notification-correlation-DfaCm0mx.js → notification-correlation-KmfV4EkP.js} +3 -3
- package/dist/{plugin-app-cache-key-BKNjHMEs.js → plugin-app-cache-key-Ceb-lm2c.js} +2 -2
- package/dist/{rate-limits-Dhp04Rqo.js → rate-limits-DyXaYAxU.js} +7 -6
- package/dist/{request-DborTWgw.js → request-B_oQsCXy.js} +54 -8
- package/dist/{run-attempt-VPVJoYDP.js → run-attempt-MLzoMe_m.js} +499 -295
- package/dist/{config-c48K5HP9.js → session-binding-h1mmCGnl.js} +786 -3
- package/dist/{session-catalog-7H112Tr_.js → session-catalog-CEvoXWHA.js} +45 -29
- package/dist/{session-cli-B28RhCyp.js → session-cli-XsEuWb_C.js} +1 -1
- package/dist/{shared-client-D4mFI9al.js → shared-client-JiAnW6pc.js} +255 -81
- package/dist/{side-question-CgJBz52s.js → side-question-DqDvIwSU.js} +15 -13
- package/dist/{thread-lifecycle-BgLXzjvV.js → thread-lifecycle-CN_pPtPh.js} +1787 -1579
- package/dist/{protocol-validators-dZQ-UTOa.js → transcript-mirror-D9rTxx2P.js} +485 -2
- package/dist/usage-D5Rohxoc.js +25 -0
- package/dist/{web-search-provider.runtime-Bs-eTn5U.js → web-search-provider.runtime-CKVBn3fP.js} +3 -3
- package/npm-shrinkwrap.json +30 -30
- package/openclaw.plugin.json +10 -5
- package/package.json +6 -6
- package/dist/capabilities-42Dfn2TV.js +0 -33
- package/dist/prompt-overlay.js +0 -15
- package/dist/protocol-BMifTfdW.js +0 -15
- package/dist/provider-catalog.js +0 -118
- package/dist/provider-discovery.js +0 -34
- package/dist/provider.js +0 -307
- package/dist/session-binding-BMfX1OX-.js +0 -786
- package/dist/transcript-mirror-DhLwFIL4.js +0 -485
package/openclaw.plugin.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "codex",
|
|
3
3
|
"name": "Codex",
|
|
4
|
-
"description": "Codex app-server harness
|
|
5
|
-
"providers": ["codex"],
|
|
4
|
+
"description": "Codex app-server harness and native session catalog.",
|
|
6
5
|
"contracts": {
|
|
7
6
|
"mediaUnderstandingProviders": ["codex"],
|
|
8
7
|
"migrationProviders": ["codex"],
|
|
@@ -24,9 +23,6 @@
|
|
|
24
23
|
}
|
|
25
24
|
}
|
|
26
25
|
},
|
|
27
|
-
"providerCatalogEntry": "./provider-discovery.ts",
|
|
28
|
-
"syntheticAuthRefs": ["codex"],
|
|
29
|
-
"nonSecretAuthMarkers": ["codex-app-server"],
|
|
30
26
|
"activation": {
|
|
31
27
|
"onStartup": false,
|
|
32
28
|
"onAgentHarnesses": ["codex"],
|
|
@@ -269,6 +265,10 @@
|
|
|
269
265
|
"type": "boolean",
|
|
270
266
|
"default": false
|
|
271
267
|
},
|
|
268
|
+
"loopDetectionPreToolUseRelay": {
|
|
269
|
+
"type": "boolean",
|
|
270
|
+
"default": true
|
|
271
|
+
},
|
|
272
272
|
"requestTimeoutMs": {
|
|
273
273
|
"type": "number",
|
|
274
274
|
"minimum": 1,
|
|
@@ -586,6 +586,11 @@
|
|
|
586
586
|
"help": "Expose Codex's code-mode-only tool surface. OpenClaw dynamic tools remain available through Codex nested tool calls.",
|
|
587
587
|
"advanced": true
|
|
588
588
|
},
|
|
589
|
+
"appServer.loopDetectionPreToolUseRelay": {
|
|
590
|
+
"label": "Loop Detection Pre-tool Relay",
|
|
591
|
+
"help": "Install the Codex PreToolUse subprocess used only for OpenClaw loop detection and its no-policy marker. Disable to reduce per-tool process fan-out; before-tool and trusted policy relays remain enforced.",
|
|
592
|
+
"advanced": true
|
|
593
|
+
},
|
|
589
594
|
"appServer.requestTimeoutMs": {
|
|
590
595
|
"label": "Request Timeout",
|
|
591
596
|
"help": "Maximum time to wait for Codex app-server control-plane requests.",
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/codex",
|
|
3
|
-
"version": "2026.7.2-beta.
|
|
4
|
-
"description": "OpenClaw Codex app-server harness
|
|
3
|
+
"version": "2026.7.2-beta.2",
|
|
4
|
+
"description": "OpenClaw Codex app-server harness and native session supervision plugin.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/openclaw/openclaw"
|
|
8
8
|
},
|
|
9
9
|
"type": "module",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@openai/codex": "0.144.
|
|
11
|
+
"@openai/codex": "0.144.5",
|
|
12
12
|
"semver": "7.8.5",
|
|
13
13
|
"smol-toml": "1.7.0",
|
|
14
14
|
"typebox": "1.3.3",
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
]
|
|
37
37
|
},
|
|
38
38
|
"compat": {
|
|
39
|
-
"pluginApi": ">=2026.7.2-beta.
|
|
39
|
+
"pluginApi": ">=2026.7.2-beta.2"
|
|
40
40
|
},
|
|
41
41
|
"build": {
|
|
42
|
-
"openclawVersion": "2026.7.2-beta.
|
|
42
|
+
"openclawVersion": "2026.7.2-beta.2"
|
|
43
43
|
},
|
|
44
44
|
"release": {
|
|
45
45
|
"publishToClawHub": true,
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"README.md"
|
|
61
61
|
],
|
|
62
62
|
"peerDependencies": {
|
|
63
|
-
"openclaw": ">=2026.7.2-beta.
|
|
63
|
+
"openclaw": ">=2026.7.2-beta.2"
|
|
64
64
|
},
|
|
65
65
|
"peerDependenciesMeta": {
|
|
66
66
|
"openclaw": {
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { O as CodexAppServerRpcError } from "./shared-client-D4mFI9al.js";
|
|
2
|
-
//#region extensions/codex/src/app-server/capabilities.ts
|
|
3
|
-
/**
|
|
4
|
-
* Capability helpers for optional Codex app-server control-plane methods.
|
|
5
|
-
*/
|
|
6
|
-
/** Known app-server methods used by OpenClaw control surfaces. */
|
|
7
|
-
const CODEX_CONTROL_METHODS = {
|
|
8
|
-
account: "account/read",
|
|
9
|
-
compact: "thread/compact/start",
|
|
10
|
-
feedback: "feedback/upload",
|
|
11
|
-
forkThread: "thread/fork",
|
|
12
|
-
listMcpServers: "mcpServerStatus/list",
|
|
13
|
-
listSkills: "skills/list",
|
|
14
|
-
listThreads: "thread/list",
|
|
15
|
-
listThreadTurns: "thread/turns/list",
|
|
16
|
-
readThread: "thread/read",
|
|
17
|
-
rateLimits: "account/rateLimits/read",
|
|
18
|
-
archiveThread: "thread/archive",
|
|
19
|
-
renameThread: "thread/name/set",
|
|
20
|
-
resumeThread: "thread/resume",
|
|
21
|
-
review: "review/start",
|
|
22
|
-
unarchiveThread: "thread/unarchive"
|
|
23
|
-
};
|
|
24
|
-
/** Formats unsupported control calls differently from ordinary RPC failures. */
|
|
25
|
-
function describeControlFailure(error) {
|
|
26
|
-
if (isUnsupportedControlError(error)) return "unsupported by this Codex app-server";
|
|
27
|
-
return error instanceof Error ? error.message : String(error);
|
|
28
|
-
}
|
|
29
|
-
function isUnsupportedControlError(error) {
|
|
30
|
-
return error instanceof CodexAppServerRpcError && error.code === -32601;
|
|
31
|
-
}
|
|
32
|
-
//#endregion
|
|
33
|
-
export { describeControlFailure as n, CODEX_CONTROL_METHODS as t };
|
package/dist/prompt-overlay.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { GPT5_BEHAVIOR_CONTRACT, GPT5_HEARTBEAT_PROMPT_OVERLAY, resolveGpt5SystemPromptContribution } from "openclaw/plugin-sdk/provider-model-shared";
|
|
2
|
-
//#region extensions/codex/prompt-overlay.ts
|
|
3
|
-
/**
|
|
4
|
-
* Codex prompt-overlay facade for GPT-5 behavior and heartbeat guidance.
|
|
5
|
-
*/
|
|
6
|
-
/** GPT-5 behavior contract re-exported under the Codex provider namespace. */
|
|
7
|
-
const CODEX_GPT5_BEHAVIOR_CONTRACT = GPT5_BEHAVIOR_CONTRACT;
|
|
8
|
-
/** Heartbeat prompt overlay re-exported under the Codex provider namespace. */
|
|
9
|
-
const CODEX_GPT5_HEARTBEAT_PROMPT_OVERLAY = GPT5_HEARTBEAT_PROMPT_OVERLAY;
|
|
10
|
-
/** Resolves the Codex system-prompt contribution for GPT-5-family models. */
|
|
11
|
-
function resolveCodexSystemPromptContribution(params) {
|
|
12
|
-
return resolveGpt5SystemPromptContribution(params);
|
|
13
|
-
}
|
|
14
|
-
//#endregion
|
|
15
|
-
export { CODEX_GPT5_BEHAVIOR_CONTRACT, CODEX_GPT5_HEARTBEAT_PROMPT_OVERLAY, resolveCodexSystemPromptContribution };
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
//#region extensions/codex/src/app-server/protocol.ts
|
|
2
|
-
/** Namespace Codex keeps directly model-visible without exposing it to Code Mode guests. */
|
|
3
|
-
const CODEX_OPENCLAW_DIRECT_DYNAMIC_TOOL_NAMESPACE = "openclaw_direct";
|
|
4
|
-
function flattenCodexDynamicToolFunctions(tools) {
|
|
5
|
-
return (tools ?? []).flatMap((tool) => tool.type === "namespace" ? tool.tools : [tool]);
|
|
6
|
-
}
|
|
7
|
-
const CODEX_INTERACTIVE_THREAD_SOURCE_KINDS = ["cli", "vscode"];
|
|
8
|
-
function isJsonObject(value) {
|
|
9
|
-
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
10
|
-
}
|
|
11
|
-
function isRpcResponse(message) {
|
|
12
|
-
return "id" in message && !("method" in message);
|
|
13
|
-
}
|
|
14
|
-
//#endregion
|
|
15
|
-
export { isRpcResponse as a, isJsonObject as i, CODEX_OPENCLAW_DIRECT_DYNAMIC_TOOL_NAMESPACE as n, flattenCodexDynamicToolFunctions as r, CODEX_INTERACTIVE_THREAD_SOURCE_KINDS as t };
|
package/dist/provider-catalog.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
//#region extensions/codex/provider-catalog.ts
|
|
2
|
-
/** Provider id used by Codex model refs. */
|
|
3
|
-
const CODEX_PROVIDER_ID = "codex";
|
|
4
|
-
/** Synthetic base URL used to route Codex app-server model requests. */
|
|
5
|
-
const CODEX_BASE_URL = "https://chatgpt.com/backend-api";
|
|
6
|
-
/** Synthetic auth marker understood by Codex app-server runtime paths. */
|
|
7
|
-
const CODEX_APP_SERVER_AUTH_MARKER = "codex-app-server";
|
|
8
|
-
const DEFAULT_CONTEXT_WINDOW = 272e3;
|
|
9
|
-
const DEFAULT_MAX_TOKENS = 128e3;
|
|
10
|
-
const KNOWN_CONTEXT_WINDOW_BY_MODEL_ID = Object.freeze({
|
|
11
|
-
"gpt-5.6-sol": 372e3,
|
|
12
|
-
"gpt-5.6-terra": 372e3,
|
|
13
|
-
"gpt-5.6-luna": 372e3
|
|
14
|
-
});
|
|
15
|
-
/** Offline fallback catalog used when live app-server discovery is unavailable. */
|
|
16
|
-
const FALLBACK_CODEX_MODELS = [
|
|
17
|
-
{
|
|
18
|
-
id: "gpt-5.6-sol",
|
|
19
|
-
model: "gpt-5.6-sol",
|
|
20
|
-
displayName: "GPT-5.6 Sol",
|
|
21
|
-
description: "Latest frontier agentic coding model.",
|
|
22
|
-
isDefault: true,
|
|
23
|
-
contextWindow: 372e3,
|
|
24
|
-
inputModalities: ["text", "image"],
|
|
25
|
-
supportedReasoningEfforts: [
|
|
26
|
-
"low",
|
|
27
|
-
"medium",
|
|
28
|
-
"high",
|
|
29
|
-
"xhigh",
|
|
30
|
-
"max",
|
|
31
|
-
"ultra"
|
|
32
|
-
]
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
id: "gpt-5.6-luna",
|
|
36
|
-
model: "gpt-5.6-luna",
|
|
37
|
-
displayName: "GPT-5.6 Luna",
|
|
38
|
-
description: "High-throughput frontier agentic coding model.",
|
|
39
|
-
contextWindow: 372e3,
|
|
40
|
-
inputModalities: ["text", "image"],
|
|
41
|
-
supportedReasoningEfforts: [
|
|
42
|
-
"low",
|
|
43
|
-
"medium",
|
|
44
|
-
"high",
|
|
45
|
-
"xhigh",
|
|
46
|
-
"max"
|
|
47
|
-
]
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
id: "gpt-5.5",
|
|
51
|
-
model: "gpt-5.5",
|
|
52
|
-
displayName: "GPT-5.5",
|
|
53
|
-
description: "Previous frontier agentic coding model.",
|
|
54
|
-
inputModalities: ["text", "image"],
|
|
55
|
-
supportedReasoningEfforts: [
|
|
56
|
-
"low",
|
|
57
|
-
"medium",
|
|
58
|
-
"high",
|
|
59
|
-
"xhigh"
|
|
60
|
-
]
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
id: "gpt-5.4-mini",
|
|
64
|
-
model: "gpt-5.4-mini",
|
|
65
|
-
displayName: "GPT-5.4-Mini",
|
|
66
|
-
description: "Smaller frontier agentic coding model.",
|
|
67
|
-
inputModalities: ["text", "image"],
|
|
68
|
-
supportedReasoningEfforts: [
|
|
69
|
-
"low",
|
|
70
|
-
"medium",
|
|
71
|
-
"high",
|
|
72
|
-
"xhigh"
|
|
73
|
-
]
|
|
74
|
-
}
|
|
75
|
-
];
|
|
76
|
-
/**
|
|
77
|
-
* Converts a Codex app-server model record into OpenClaw provider model config.
|
|
78
|
-
*/
|
|
79
|
-
function buildCodexModelDefinition(model) {
|
|
80
|
-
const id = model.id.trim() || model.model.trim();
|
|
81
|
-
const supportedReasoningEfforts = model.supportedReasoningEfforts;
|
|
82
|
-
return {
|
|
83
|
-
id,
|
|
84
|
-
name: model.displayName?.trim() || id,
|
|
85
|
-
api: "openai-chatgpt-responses",
|
|
86
|
-
reasoning: supportedReasoningEfforts !== void 0 ? supportedReasoningEfforts.length > 0 : shouldDefaultToReasoningModel(id),
|
|
87
|
-
input: model.inputModalities.includes("image") ? ["text", "image"] : ["text"],
|
|
88
|
-
cost: {
|
|
89
|
-
input: 0,
|
|
90
|
-
output: 0,
|
|
91
|
-
cacheRead: 0,
|
|
92
|
-
cacheWrite: 0
|
|
93
|
-
},
|
|
94
|
-
contextWindow: model.contextWindow ?? KNOWN_CONTEXT_WINDOW_BY_MODEL_ID[id] ?? DEFAULT_CONTEXT_WINDOW,
|
|
95
|
-
maxTokens: DEFAULT_MAX_TOKENS,
|
|
96
|
-
compat: {
|
|
97
|
-
...supportedReasoningEfforts !== void 0 ? { supportsReasoningEffort: supportedReasoningEfforts.length > 0 } : {},
|
|
98
|
-
...supportedReasoningEfforts && supportedReasoningEfforts.length > 0 ? { supportedReasoningEfforts: [...supportedReasoningEfforts] } : {},
|
|
99
|
-
supportsUsageInStreaming: true
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
/** Builds the synthetic Codex provider config for a model list. */
|
|
104
|
-
function buildCodexProviderConfig(models) {
|
|
105
|
-
return {
|
|
106
|
-
baseUrl: CODEX_BASE_URL,
|
|
107
|
-
apiKey: CODEX_APP_SERVER_AUTH_MARKER,
|
|
108
|
-
auth: "token",
|
|
109
|
-
api: "openai-chatgpt-responses",
|
|
110
|
-
models: models.map(buildCodexModelDefinition)
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
function shouldDefaultToReasoningModel(modelId) {
|
|
114
|
-
const lower = modelId.toLowerCase();
|
|
115
|
-
return lower.startsWith("gpt-5") || lower.startsWith("o1") || lower.startsWith("o3") || lower.startsWith("o4");
|
|
116
|
-
}
|
|
117
|
-
//#endregion
|
|
118
|
-
export { CODEX_APP_SERVER_AUTH_MARKER, CODEX_BASE_URL, CODEX_PROVIDER_ID, FALLBACK_CODEX_MODELS, buildCodexModelDefinition, buildCodexProviderConfig };
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { CODEX_APP_SERVER_AUTH_MARKER, CODEX_PROVIDER_ID, FALLBACK_CODEX_MODELS, buildCodexProviderConfig } from "./provider-catalog.js";
|
|
2
|
-
//#region extensions/codex/provider-discovery.ts
|
|
3
|
-
function resolveCodexPluginConfig(ctx) {
|
|
4
|
-
return (ctx.config.plugins?.entries)?.codex?.config;
|
|
5
|
-
}
|
|
6
|
-
async function runCodexCatalog(ctx) {
|
|
7
|
-
const { buildCodexProviderCatalog } = await import("./provider.js");
|
|
8
|
-
return await buildCodexProviderCatalog({
|
|
9
|
-
env: ctx.env,
|
|
10
|
-
pluginConfig: resolveCodexPluginConfig(ctx)
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
/** Provider discovery descriptor with static fallback and synthetic auth. */
|
|
14
|
-
const codexProviderDiscovery = {
|
|
15
|
-
id: CODEX_PROVIDER_ID,
|
|
16
|
-
label: "Codex",
|
|
17
|
-
docsPath: "/providers/models",
|
|
18
|
-
auth: [],
|
|
19
|
-
catalog: {
|
|
20
|
-
order: "late",
|
|
21
|
-
run: runCodexCatalog
|
|
22
|
-
},
|
|
23
|
-
staticCatalog: {
|
|
24
|
-
order: "late",
|
|
25
|
-
run: async () => ({ provider: buildCodexProviderConfig(FALLBACK_CODEX_MODELS) })
|
|
26
|
-
},
|
|
27
|
-
resolveSyntheticAuth: () => ({
|
|
28
|
-
apiKey: CODEX_APP_SERVER_AUTH_MARKER,
|
|
29
|
-
source: "codex-app-server",
|
|
30
|
-
mode: "token"
|
|
31
|
-
})
|
|
32
|
-
};
|
|
33
|
-
//#endregion
|
|
34
|
-
export { codexProviderDiscovery, codexProviderDiscovery as default };
|
package/dist/provider.js
DELETED
|
@@ -1,307 +0,0 @@
|
|
|
1
|
-
import { CODEX_APP_SERVER_AUTH_MARKER, CODEX_BASE_URL, CODEX_PROVIDER_ID, FALLBACK_CODEX_MODELS, buildCodexModelDefinition, buildCodexProviderConfig } from "./provider-catalog.js";
|
|
2
|
-
import { d as readCodexPluginConfig, f as resolveCodexAppServerRuntimeOptions } from "./config-c48K5HP9.js";
|
|
3
|
-
import { resolveCodexSystemPromptContribution } from "./prompt-overlay.js";
|
|
4
|
-
import { t as buildCodexAppServerUsageSnapshot } from "./rate-limits-Dhp04Rqo.js";
|
|
5
|
-
import { resolvePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
6
|
-
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
7
|
-
import { normalizeModelCompat } from "openclaw/plugin-sdk/provider-model-shared";
|
|
8
|
-
import { createSubsystemLogger } from "openclaw/plugin-sdk/core";
|
|
9
|
-
//#region extensions/codex/provider.ts
|
|
10
|
-
/**
|
|
11
|
-
* Codex provider plugin and live app-server model catalog discovery.
|
|
12
|
-
*/
|
|
13
|
-
const DEFAULT_DISCOVERY_TIMEOUT_MS = 2500;
|
|
14
|
-
const LIVE_DISCOVERY_ENV = "OPENCLAW_CODEX_DISCOVERY_LIVE";
|
|
15
|
-
const MODEL_DISCOVERY_PAGE_LIMIT = 100;
|
|
16
|
-
const CODEX_APP_SERVER_SETUP_METHOD_ID = "app-server";
|
|
17
|
-
const CODEX_DEFAULT_MODEL_REF = `${CODEX_PROVIDER_ID}/${expectDefined(FALLBACK_CODEX_MODELS[0], "Codex fallback model catalog must not be empty").id}`;
|
|
18
|
-
const codexCatalogLog = createSubsystemLogger("codex/catalog");
|
|
19
|
-
const CODEX_REASONING_EFFORTS = [
|
|
20
|
-
"minimal",
|
|
21
|
-
"low",
|
|
22
|
-
"medium",
|
|
23
|
-
"high",
|
|
24
|
-
"xhigh",
|
|
25
|
-
"max",
|
|
26
|
-
"ultra"
|
|
27
|
-
];
|
|
28
|
-
const GPT_56_MAX_REASONING_EFFORTS = [
|
|
29
|
-
"low",
|
|
30
|
-
"medium",
|
|
31
|
-
"high",
|
|
32
|
-
"xhigh",
|
|
33
|
-
"max"
|
|
34
|
-
];
|
|
35
|
-
const GPT_56_ULTRA_REASONING_EFFORTS = [...GPT_56_MAX_REASONING_EFFORTS, "ultra"];
|
|
36
|
-
const GPT_56_ULTRA_MODEL_IDS = /* @__PURE__ */ new Set(["gpt-5.6-sol", "gpt-5.6-terra"]);
|
|
37
|
-
const GPT_56_MAX_MODEL_IDS = /* @__PURE__ */ new Set([...GPT_56_ULTRA_MODEL_IDS, "gpt-5.6-luna"]);
|
|
38
|
-
const GPT_56_DEFAULT_REASONING_EFFORTS = /* @__PURE__ */ new Map([
|
|
39
|
-
["gpt-5.6-sol", "low"],
|
|
40
|
-
["gpt-5.6-terra", "medium"],
|
|
41
|
-
["gpt-5.6-luna", "medium"]
|
|
42
|
-
]);
|
|
43
|
-
const GPT_5_PRO_REASONING_EFFORTS = [
|
|
44
|
-
"medium",
|
|
45
|
-
"high",
|
|
46
|
-
"xhigh"
|
|
47
|
-
];
|
|
48
|
-
/**
|
|
49
|
-
* Builds the Codex provider plugin, including setup metadata, catalog discovery,
|
|
50
|
-
* dynamic model resolution, and prompt/thinking hooks.
|
|
51
|
-
*/
|
|
52
|
-
function buildCodexProvider(options = {}) {
|
|
53
|
-
return {
|
|
54
|
-
id: CODEX_PROVIDER_ID,
|
|
55
|
-
label: "Codex",
|
|
56
|
-
docsPath: "/providers/models",
|
|
57
|
-
auth: [{
|
|
58
|
-
id: CODEX_APP_SERVER_SETUP_METHOD_ID,
|
|
59
|
-
label: "Codex app-server",
|
|
60
|
-
hint: "Use the Codex app-server runtime and managed model catalog.",
|
|
61
|
-
kind: "custom",
|
|
62
|
-
wizard: {
|
|
63
|
-
choiceId: CODEX_PROVIDER_ID,
|
|
64
|
-
choiceLabel: "Codex app-server",
|
|
65
|
-
choiceHint: "Use the Codex app-server runtime and managed model catalog.",
|
|
66
|
-
assistantPriority: -40,
|
|
67
|
-
groupId: CODEX_PROVIDER_ID,
|
|
68
|
-
groupLabel: "Codex",
|
|
69
|
-
groupHint: "Codex app-server model provider",
|
|
70
|
-
onboardingScopes: ["text-inference"]
|
|
71
|
-
},
|
|
72
|
-
run: async () => ({
|
|
73
|
-
profiles: [],
|
|
74
|
-
defaultModel: CODEX_DEFAULT_MODEL_REF
|
|
75
|
-
})
|
|
76
|
-
}],
|
|
77
|
-
catalog: {
|
|
78
|
-
order: "late",
|
|
79
|
-
run: async (ctx) => {
|
|
80
|
-
const pluginConfig = resolvePluginConfigObject(ctx.config, "codex") ?? (ctx.config ? void 0 : options.pluginConfig);
|
|
81
|
-
return await buildCodexProviderCatalog({
|
|
82
|
-
env: ctx.env,
|
|
83
|
-
pluginConfig,
|
|
84
|
-
listModels: options.listModels
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
staticCatalog: {
|
|
89
|
-
order: "late",
|
|
90
|
-
run: async () => ({ provider: buildCodexProviderConfig(FALLBACK_CODEX_MODELS) })
|
|
91
|
-
},
|
|
92
|
-
resolveDynamicModel: (ctx) => resolveCodexDynamicModel(ctx.modelId),
|
|
93
|
-
resolveSyntheticAuth: () => ({
|
|
94
|
-
apiKey: CODEX_APP_SERVER_AUTH_MARKER,
|
|
95
|
-
source: "codex-app-server",
|
|
96
|
-
mode: "token"
|
|
97
|
-
}),
|
|
98
|
-
fetchUsageSnapshot: async (ctx) => {
|
|
99
|
-
if (ctx.token !== "codex-app-server") return null;
|
|
100
|
-
const appServer = resolveCodexAppServerRuntimeOptions({ pluginConfig: resolvePluginConfigObject(ctx.config, "codex") ?? (ctx.config ? void 0 : options.pluginConfig) });
|
|
101
|
-
const usage = await (options.readUsage ?? requestCodexAppServerUsageLazy)({
|
|
102
|
-
timeoutMs: ctx.timeoutMs,
|
|
103
|
-
agentDir: ctx.agentDir,
|
|
104
|
-
...ctx.authProfileId ? { authProfileId: ctx.authProfileId } : {},
|
|
105
|
-
config: ctx.config,
|
|
106
|
-
startOptions: appServer.start
|
|
107
|
-
});
|
|
108
|
-
const snapshot = buildCodexAppServerUsageSnapshot(usage.rateLimits);
|
|
109
|
-
const accountEmail = ctx.email ?? usage.accountEmail;
|
|
110
|
-
return accountEmail && !snapshot.error ? {
|
|
111
|
-
...snapshot,
|
|
112
|
-
accountEmail
|
|
113
|
-
} : snapshot;
|
|
114
|
-
},
|
|
115
|
-
resolveThinkingProfile: ({ modelId, compat }) => {
|
|
116
|
-
const efforts = resolveCodexThinkingEfforts({
|
|
117
|
-
modelId,
|
|
118
|
-
supportedReasoningEfforts: readCodexSupportedReasoningEfforts(compat)
|
|
119
|
-
});
|
|
120
|
-
const defaultLevel = GPT_56_DEFAULT_REASONING_EFFORTS.get(modelId.trim().toLowerCase());
|
|
121
|
-
return {
|
|
122
|
-
levels: [{ id: "off" }, ...efforts.map((id) => ({ id }))],
|
|
123
|
-
...defaultLevel && efforts.includes(defaultLevel) ? { defaultLevel } : {}
|
|
124
|
-
};
|
|
125
|
-
},
|
|
126
|
-
resolveSystemPromptContribution: ({ config, modelId }) => resolveCodexSystemPromptContribution({
|
|
127
|
-
config,
|
|
128
|
-
modelId
|
|
129
|
-
}),
|
|
130
|
-
isModernModelRef: ({ modelId }) => isModernCodexModel(modelId)
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Builds the Codex model catalog from live app-server discovery, falling back
|
|
135
|
-
* to built-in model records when discovery is disabled or unavailable.
|
|
136
|
-
*/
|
|
137
|
-
async function buildCodexProviderCatalog(options = {}) {
|
|
138
|
-
const config = readCodexPluginConfig(options.pluginConfig);
|
|
139
|
-
const appServer = resolveCodexAppServerRuntimeOptions({ pluginConfig: options.pluginConfig });
|
|
140
|
-
const timeoutMs = normalizeTimeoutMs(config.discovery?.timeoutMs);
|
|
141
|
-
let discovered = [];
|
|
142
|
-
if (config.discovery?.enabled !== false && !shouldSkipLiveDiscovery(options.env)) discovered = await listModelsBestEffort({
|
|
143
|
-
listModels: options.listModels ?? listCodexAppServerModelsLazy,
|
|
144
|
-
timeoutMs,
|
|
145
|
-
startOptions: appServer.start,
|
|
146
|
-
onDiscoveryFailure: options.onDiscoveryFailure
|
|
147
|
-
});
|
|
148
|
-
return { provider: buildCodexProviderConfig(discovered.length > 0 ? discovered : FALLBACK_CODEX_MODELS) };
|
|
149
|
-
}
|
|
150
|
-
function resolveCodexDynamicModel(modelId) {
|
|
151
|
-
const id = modelId.trim();
|
|
152
|
-
if (!id) return;
|
|
153
|
-
const fallbackModel = FALLBACK_CODEX_MODELS.find((model) => model.id === id);
|
|
154
|
-
return normalizeModelCompat({
|
|
155
|
-
...buildCodexModelDefinition({
|
|
156
|
-
id,
|
|
157
|
-
model: id,
|
|
158
|
-
inputModalities: fallbackModel?.inputModalities ?? ["text"],
|
|
159
|
-
supportedReasoningEfforts: fallbackModel?.supportedReasoningEfforts
|
|
160
|
-
}),
|
|
161
|
-
provider: CODEX_PROVIDER_ID,
|
|
162
|
-
baseUrl: CODEX_BASE_URL
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
async function listModelsBestEffort(params) {
|
|
166
|
-
try {
|
|
167
|
-
const models = [];
|
|
168
|
-
let cursor;
|
|
169
|
-
do {
|
|
170
|
-
const result = await params.listModels({
|
|
171
|
-
timeoutMs: params.timeoutMs,
|
|
172
|
-
limit: MODEL_DISCOVERY_PAGE_LIMIT,
|
|
173
|
-
cursor,
|
|
174
|
-
startOptions: params.startOptions,
|
|
175
|
-
sharedClient: false
|
|
176
|
-
});
|
|
177
|
-
models.push(...result.models.filter((model) => !model.hidden));
|
|
178
|
-
cursor = result.nextCursor;
|
|
179
|
-
} while (cursor);
|
|
180
|
-
return models;
|
|
181
|
-
} catch (error) {
|
|
182
|
-
params.onDiscoveryFailure?.(error);
|
|
183
|
-
codexCatalogLog.debug("codex model discovery failed; using fallback catalog", { error: error instanceof Error ? error.message : String(error) });
|
|
184
|
-
return [];
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
async function listCodexAppServerModelsLazy(options) {
|
|
188
|
-
const { listCodexAppServerModels } = await import("./models-DuKzZA6G.js").then((n) => n.r);
|
|
189
|
-
return listCodexAppServerModels(options);
|
|
190
|
-
}
|
|
191
|
-
function extractCodexAccountEmail(value) {
|
|
192
|
-
if (!value || typeof value !== "object") return;
|
|
193
|
-
const record = value;
|
|
194
|
-
const account = record.account && typeof record.account === "object" ? record.account : record;
|
|
195
|
-
const email = account.email ?? account.accountEmail;
|
|
196
|
-
return typeof email === "string" && email.trim() ? email.trim() : void 0;
|
|
197
|
-
}
|
|
198
|
-
async function requestCodexAppServerUsageLazy(options) {
|
|
199
|
-
const { withCodexAppServerJsonClient } = await import("./request-DborTWgw.js").then((n) => n.r);
|
|
200
|
-
const deadline = Date.now() + options.timeoutMs;
|
|
201
|
-
return await withCodexAppServerJsonClient({
|
|
202
|
-
timeoutMs: options.timeoutMs,
|
|
203
|
-
timeoutMessage: "codex app-server usage read timed out",
|
|
204
|
-
agentDir: options.agentDir,
|
|
205
|
-
...options.authProfileId ? { authProfileId: options.authProfileId } : {},
|
|
206
|
-
config: options.config,
|
|
207
|
-
startOptions: options.startOptions,
|
|
208
|
-
isolated: true,
|
|
209
|
-
isolatedShutdown: CODEX_USAGE_ISOLATED_SHUTDOWN
|
|
210
|
-
}, async (request) => {
|
|
211
|
-
const rateLimits = await request({ method: "account/rateLimits/read" });
|
|
212
|
-
const accountEmail = await readCodexAccountEmailBestEffort(request, deadline);
|
|
213
|
-
return {
|
|
214
|
-
rateLimits,
|
|
215
|
-
...accountEmail ? { accountEmail } : {}
|
|
216
|
-
};
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
const CODEX_USAGE_ISOLATED_SHUTDOWN = {
|
|
220
|
-
forceKillDelayMs: 200,
|
|
221
|
-
exitTimeoutMs: 300
|
|
222
|
-
};
|
|
223
|
-
const CODEX_ACCOUNT_READ_MAX_TIMEOUT_MS = 4e3;
|
|
224
|
-
const CODEX_USAGE_DEADLINE_RESERVE_MS = CODEX_USAGE_ISOLATED_SHUTDOWN.forceKillDelayMs + CODEX_USAGE_ISOLATED_SHUTDOWN.exitTimeoutMs + 250;
|
|
225
|
-
async function readCodexAccountEmailBestEffort(request, deadline) {
|
|
226
|
-
const boundMs = Math.min(CODEX_ACCOUNT_READ_MAX_TIMEOUT_MS, deadline - Date.now() - CODEX_USAGE_DEADLINE_RESERVE_MS);
|
|
227
|
-
if (boundMs <= 0) return;
|
|
228
|
-
const read = request({
|
|
229
|
-
method: "account/read",
|
|
230
|
-
requestParams: {}
|
|
231
|
-
}).then((account) => extractCodexAccountEmail(account), () => void 0);
|
|
232
|
-
let timer;
|
|
233
|
-
const timeout = new Promise((resolve) => {
|
|
234
|
-
timer = setTimeout(() => resolve(void 0), boundMs);
|
|
235
|
-
timer.unref?.();
|
|
236
|
-
});
|
|
237
|
-
try {
|
|
238
|
-
return await Promise.race([read, timeout]);
|
|
239
|
-
} finally {
|
|
240
|
-
if (timer) clearTimeout(timer);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
function normalizeTimeoutMs(value) {
|
|
244
|
-
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : DEFAULT_DISCOVERY_TIMEOUT_MS;
|
|
245
|
-
}
|
|
246
|
-
function shouldSkipLiveDiscovery(env = process.env) {
|
|
247
|
-
const override = env[LIVE_DISCOVERY_ENV]?.trim().toLowerCase();
|
|
248
|
-
if (override === "0" || override === "false") return true;
|
|
249
|
-
return Boolean(env.VITEST) && override !== "1";
|
|
250
|
-
}
|
|
251
|
-
function isKnownXHighCodexModel(modelId) {
|
|
252
|
-
const lower = modelId.trim().toLowerCase();
|
|
253
|
-
return lower.startsWith("gpt-5") || lower.startsWith("o3") || lower.startsWith("o4") || lower.includes("codex");
|
|
254
|
-
}
|
|
255
|
-
function normalizeCodexReasoningEfforts(efforts) {
|
|
256
|
-
if (!efforts) return [];
|
|
257
|
-
const supported = new Set(efforts.map((effort) => effort.trim().toLowerCase()));
|
|
258
|
-
return CODEX_REASONING_EFFORTS.filter((effort) => supported.has(effort));
|
|
259
|
-
}
|
|
260
|
-
/** Read app-server reasoning metadata from a runtime model compat union. */
|
|
261
|
-
function readCodexSupportedReasoningEfforts(compat) {
|
|
262
|
-
if (!compat || typeof compat !== "object" || Array.isArray(compat)) return;
|
|
263
|
-
const efforts = compat.supportedReasoningEfforts;
|
|
264
|
-
if (!Array.isArray(efforts)) return;
|
|
265
|
-
const strings = efforts.filter((effort) => typeof effort === "string");
|
|
266
|
-
return strings.some((effort) => effort.trim().toLowerCase() === "none") ? void 0 : strings;
|
|
267
|
-
}
|
|
268
|
-
function resolveCodexThinkingEfforts(params) {
|
|
269
|
-
if (params.supportedReasoningEfforts) return normalizeCodexReasoningEfforts(params.supportedReasoningEfforts);
|
|
270
|
-
const fallbackEfforts = resolveCodexFallbackReasoningEfforts(params.modelId);
|
|
271
|
-
if (fallbackEfforts) return [...fallbackEfforts];
|
|
272
|
-
return [
|
|
273
|
-
"minimal",
|
|
274
|
-
"low",
|
|
275
|
-
"medium",
|
|
276
|
-
"high",
|
|
277
|
-
...isKnownXHighCodexModel(params.modelId) ? ["xhigh"] : [],
|
|
278
|
-
...isMaxReasoningCodexModel(params.modelId) ? ["max"] : []
|
|
279
|
-
];
|
|
280
|
-
}
|
|
281
|
-
/** Map a requested effort onto the authoritative app-server model contract. */
|
|
282
|
-
function resolveCodexSupportedReasoningEffort(params) {
|
|
283
|
-
const supported = normalizeCodexReasoningEfforts(params.supportedReasoningEfforts);
|
|
284
|
-
if (supported.includes(params.requested)) return params.requested;
|
|
285
|
-
const fallbackEfforts = params.requested === "ultra" ? supported : supported.filter((effort) => effort !== "ultra");
|
|
286
|
-
const requestedRank = CODEX_REASONING_EFFORTS.indexOf(params.requested);
|
|
287
|
-
return fallbackEfforts.find((effort) => CODEX_REASONING_EFFORTS.indexOf(effort) >= requestedRank) ?? fallbackEfforts.at(-1);
|
|
288
|
-
}
|
|
289
|
-
/** Return the known effort contract when app-server model metadata is unavailable. */
|
|
290
|
-
function resolveCodexFallbackReasoningEfforts(modelId) {
|
|
291
|
-
const normalized = modelId.trim().toLowerCase();
|
|
292
|
-
if (GPT_56_ULTRA_MODEL_IDS.has(normalized)) return GPT_56_ULTRA_REASONING_EFFORTS;
|
|
293
|
-
if (normalized === "gpt-5.6-luna") return GPT_56_MAX_REASONING_EFFORTS;
|
|
294
|
-
if (normalized === "gpt-5.5-pro" || normalized === "gpt-5.4-pro") return GPT_5_PRO_REASONING_EFFORTS;
|
|
295
|
-
}
|
|
296
|
-
/** Return whether the model uses the modern Codex reasoning profile. */
|
|
297
|
-
function isModernCodexModel(modelId) {
|
|
298
|
-
const lower = modelId.trim().toLowerCase();
|
|
299
|
-
return GPT_56_MAX_MODEL_IDS.has(lower) || lower === "gpt-5.5" || lower === "gpt-5.5-pro" || lower === "gpt-5.4" || lower === "gpt-5.4-pro" || lower === "gpt-5.4-mini" || lower === "gpt-5.3-codex-spark";
|
|
300
|
-
}
|
|
301
|
-
/** Return whether Codex accepts the preview GPT-5.6 `max` reasoning effort. */
|
|
302
|
-
function isMaxReasoningCodexModel(modelId) {
|
|
303
|
-
const lower = modelId.trim().toLowerCase();
|
|
304
|
-
return GPT_56_MAX_MODEL_IDS.has(lower);
|
|
305
|
-
}
|
|
306
|
-
//#endregion
|
|
307
|
-
export { buildCodexProvider, buildCodexProviderCatalog, isMaxReasoningCodexModel, isModernCodexModel, readCodexSupportedReasoningEfforts, resolveCodexFallbackReasoningEfforts, resolveCodexSupportedReasoningEffort };
|