@openclaw/codex 2026.7.2-beta.5 → 2026.8.1-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 +2 -0
- package/dist/{app-server-policy-BmDgseo_.js → app-server-policy-zcBDc1JU.js} +1 -1
- package/dist/attempt-client-cleanup-DMLXUfa8.js +735 -0
- package/dist/binding-connection-I5Bo-AsX.js +33 -0
- package/dist/{bounded-turn-FEbUXoYT.js → bounded-turn-qgZmzy_4.js} +71 -63
- package/dist/{capabilities-BHRSI6Cn.js → capabilities-CybGI1oz.js} +8 -2
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-ico4ZFnk.js → command-formatters-B1AEz8ZA.js} +18 -18
- package/dist/{command-handlers-CRmnwI2N.js → command-handlers-Db8pu_ds.js} +484 -95
- package/dist/{compact-dEN49UH6.js → compact-LspQaGfl.js} +213 -199
- package/dist/{conversation-binding-data-BHRpYbX3.js → conversation-binding-data-CW2GuupV.js} +6 -10
- package/dist/doctor-contract-api.js +40 -43
- package/dist/{dynamic-tools-LIt9ojep.js → dynamic-tools-BVdyWkUD.js} +2984 -1221
- package/dist/effective-mcp-catalog-DIIhAtOZ.js +119 -0
- package/dist/{event-projector-assistant-message-DTgnPPVF.js → event-projector-assistant-message-BwxV4d6N.js} +11 -23
- package/dist/{attempt-notifications-CMR2_fmR.js → event-projector-usage-e5huIQWu.js} +113 -29
- package/dist/harness.js +83 -13
- package/dist/image-payload-sanitizer-CnfoUPCE.js +65 -0
- package/dist/index.js +703 -329
- package/dist/isolated-completion-C58NbL40.js +75 -0
- package/dist/local-runtime-attribution-B_2mnqhb.js +19 -0
- package/dist/media-understanding-provider.js +5 -5
- package/dist/{models-BA01NEez.js → models-BFlpn1Ex.js} +12 -17
- package/dist/native-subagent-monitor-DyTGmTUx.js +3111 -0
- package/dist/{plugin-app-cache-key-DSXX-rXO.js → plugin-app-cache-key-C3H2CVp6.js} +135 -42
- package/dist/plugin-marketplace-discovery-CzrGJdCR.js +385 -0
- package/dist/{computer-use-BjGylO-E.js → plugin-metadata-cache-CNJPj4_b.js} +211 -113
- package/dist/protocol-validators-B4F7L8Rf.js +2346 -0
- package/dist/{rate-limits-S_PXs0ul.js → rate-limits-DZXmOL8-.js} +17 -35
- package/dist/{request-CXpPennK.js → request-BRl5_UfX.js} +4 -4
- package/dist/{run-attempt-C5GTPJOE.js → run-attempt-P8BdxC1I.js} +1996 -5728
- package/dist/{runtime-artifact-C2ITXdhM.js → runtime-artifact-BVSPdd6g.js} +91 -40
- package/dist/{sandbox-guard-D1Wky__S.js → sandbox-guard-Cmwc9eIk.js} +10 -13
- package/dist/{session-binding-DlVQ-Pxs.js → session-binding-DPxIvMgE.js} +305 -271
- package/dist/{session-catalog-CP2oCcEb.js → session-catalog-xwNi_SDM.js} +418 -144
- package/dist/{session-cli-CqZ0Fp2a.js → session-cli-7hgXZDV7.js} +1 -1
- package/dist/session-retirement-DoMMJFKm.js +36 -0
- package/dist/{session-upstream-marker-QE-m5QFG.js → session-upstream-marker-CrIFX06J.js} +1 -1
- package/dist/{settled-turn-finalizer-CA_2QXIE.js → settled-turn-finalizer-BRWBO4MO.js} +36 -15
- package/dist/{shared-client-BVKE40c-.js → shared-client-kIBbGjk4.js} +721 -240
- package/dist/{side-question-CO12sHxo.js → side-question-9HAL26l9.js} +102 -53
- package/dist/{thread-lifecycle-DRg_FdzC.js → thread-lifecycle-Bu1BTDXr.js} +1355 -660
- package/dist/thread-ownership-6kOQHlyC.js +92 -0
- package/dist/thread-resume-CPrJNQVM.js +30 -0
- package/dist/{transcript-mirror-uKA-A4tB.js → transcript-mirror-B9gGgnJS.js} +202 -182
- package/dist/{transport-stdio-DXgGZ7Ib.js → transport-stdio-DIImwDVS.js} +11 -0
- package/dist/upstream-prompt-provenance-ClRBije0.js +41 -0
- package/dist/{upstream-session-fork-_Vrz4WJr.js → upstream-session-fork-CE-_LdnP.js} +5 -5
- package/dist/{usage-UpVbdX5G.js → usage-CHlV0e-o.js} +3 -3
- package/dist/{web-search-provider.runtime-CaQMYDbp.js → web-search-provider.runtime-DRw2Vl42.js} +8 -9
- package/openclaw.plugin.json +18 -3
- package/package.json +6 -7
- package/dist/attempt-client-cleanup-Ia52yRWc.js +0 -127
- package/dist/conversation-control-DE7d9DOj.js +0 -287
- package/dist/event-projector-usage-tvgb1NCX.js +0 -69
- package/dist/notification-correlation-Bj_Ak_jI.js +0 -67
- package/dist/protocol-validators-Dm4eXZmt.js +0 -6337
- package/dist/realtime-voice-api-BPcA1uN9.js +0 -494
- package/dist/realtime-voice-api.js +0 -2
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { T as readCodexPluginConfig, g as resolveCodexAppServerRuntimeOptions, y as resolveCodexSupervisionAppServerRuntimeOptions } from "./session-binding-DPxIvMgE.js";
|
|
2
|
+
import { t as buildCodexAppServerConnectionFingerprint } from "./plugin-app-cache-key-C3H2CVp6.js";
|
|
3
|
+
//#region extensions/codex/src/app-server/binding-connection.ts
|
|
4
|
+
/** Requires the native model pair after a supervised pending branch has materialized. */
|
|
5
|
+
function requireCodexSupervisionModelSelection(binding) {
|
|
6
|
+
const model = binding.model?.trim();
|
|
7
|
+
const modelProvider = binding.modelProvider?.trim();
|
|
8
|
+
if (binding.connectionScope !== "supervision" || !model || !modelProvider) throw new Error("Codex supervised binding is missing its native model and provider; refusing request selection");
|
|
9
|
+
return {
|
|
10
|
+
model,
|
|
11
|
+
modelProvider
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/** Resolves connection and auth ownership exclusively from the private thread binding. */
|
|
15
|
+
function resolveCodexBindingAppServerConnection(params) {
|
|
16
|
+
const { binding, authProfileId, ...runtimeParams } = params;
|
|
17
|
+
const usesSupervisionConnection = binding?.connectionScope === "supervision";
|
|
18
|
+
if (usesSupervisionConnection && readCodexPluginConfig(runtimeParams.pluginConfig).supervision?.enabled !== true) throw new Error("Codex supervision is disabled; refusing to open a native user-home supervised session");
|
|
19
|
+
const appServer = (usesSupervisionConnection ? resolveCodexSupervisionAppServerRuntimeOptions : resolveCodexAppServerRuntimeOptions)(runtimeParams);
|
|
20
|
+
if (usesSupervisionConnection) {
|
|
21
|
+
const persistedFingerprint = binding.pendingSupervisionBranch?.connectionFingerprint ?? binding.appServerRuntimeFingerprint;
|
|
22
|
+
const currentFingerprint = buildCodexAppServerConnectionFingerprint(appServer, runtimeParams.agentDir);
|
|
23
|
+
if (!persistedFingerprint || persistedFingerprint !== currentFingerprint) throw new Error("Codex supervision connection changed; refusing to operate on its bound native thread");
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
appServer,
|
|
27
|
+
usesSupervisionConnection,
|
|
28
|
+
requestAuthProfileId: usesSupervisionConnection ? void 0 : authProfileId,
|
|
29
|
+
clientAuthProfileId: usesSupervisionConnection ? null : authProfileId
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { resolveCodexBindingAppServerConnection as n, requireCodexSupervisionModelSelection as t };
|
|
@@ -1,24 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { o as interruptCodexTurnAndWaitBestEffort, t as CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS } from "./attempt-client-cleanup-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
1
|
+
import { g as resolveCodexAppServerRuntimeOptions } from "./session-binding-DPxIvMgE.js";
|
|
2
|
+
import { ct as isJsonObject, s as isCodexAppServerStartSelectionChangedError } from "./shared-client-kIBbGjk4.js";
|
|
3
|
+
import { _ as readCodexNotificationTurnId, a as closeCodexStartupClientBestEffort, o as interruptCodexTurnAndWaitBestEffort, t as CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS } from "./attempt-client-cleanup-DMLXUfa8.js";
|
|
4
|
+
import { b as isTerminalTurnStatus, n as normalizeCodexResponseTokenUsage, x as readCodexNotificationItem, y as isRetryableErrorNotification } from "./event-projector-usage-e5huIQWu.js";
|
|
5
|
+
import { a as assertCodexThreadStartResponse, c as readCodexErrorNotification, o as assertCodexTurnStartResponse, u as readCodexTurnCompletedNotification } from "./protocol-validators-B4F7L8Rf.js";
|
|
6
|
+
import { r as readModelListResult } from "./models-BFlpn1Ex.js";
|
|
7
|
+
import { W as mergeCodexThreadConfigs, c as buildCodexRingZeroThreadConfigPatch, l as buildCodexRuntimeThreadConfig, o as assertCodexRestrictedToolSurfaceHasNoManagedHooks, s as attestCodexRestrictedToolSurfaceMcpServersDisabled, u as readCodexInheritedMcpServerNames } from "./thread-lifecycle-Bu1BTDXr.js";
|
|
8
|
+
import { readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
9
9
|
import fs from "node:fs/promises";
|
|
10
10
|
import path from "node:path";
|
|
11
|
+
import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
|
|
11
12
|
import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
12
13
|
import { resolvePreferredOpenClawTmpDir, withTempWorkspace } from "openclaw/plugin-sdk/temp-path";
|
|
13
14
|
//#region extensions/codex/src/app-server/bounded-turn.ts
|
|
14
|
-
const CODEX_PRIVATE_STDIO_ARGS = [
|
|
15
|
-
"app-server",
|
|
16
|
-
"--listen",
|
|
17
|
-
"stdio://"
|
|
18
|
-
];
|
|
19
15
|
const CODEX_APP_SERVER_ARGS_ENV_KEY = "OPENCLAW_CODEX_APP_SERVER_ARGS";
|
|
20
16
|
const CODEX_BOUNDED_THREAD_CONFIG = {
|
|
17
|
+
"agents.enabled": false,
|
|
21
18
|
"features.multi_agent": false,
|
|
19
|
+
"features.multi_agent_v2": false,
|
|
22
20
|
"features.apps": false,
|
|
23
21
|
"features.plugins": false,
|
|
24
22
|
"features.image_generation": false,
|
|
@@ -33,6 +31,13 @@ const CODEX_SETTLED_FINALIZER_THREAD_CONFIG = {
|
|
|
33
31
|
"skills.include_instructions": false,
|
|
34
32
|
include_environment_context: false
|
|
35
33
|
};
|
|
34
|
+
var CodexBoundedTurnTimeoutError = class extends Error {
|
|
35
|
+
constructor(taskLabel, timeoutMs) {
|
|
36
|
+
const bound = timeoutMs % 1e3 === 0 ? `${timeoutMs / 1e3}s` : `${timeoutMs}ms`;
|
|
37
|
+
super(`codex app-server ${taskLabel} turn timed out after ${bound}`);
|
|
38
|
+
this.name = "TimeoutError";
|
|
39
|
+
}
|
|
40
|
+
};
|
|
36
41
|
async function runBoundedCodexAppServerTurn(params) {
|
|
37
42
|
const appServer = resolveCodexAppServerRuntimeOptions({
|
|
38
43
|
pluginConfig: params.options.pluginConfig,
|
|
@@ -55,23 +60,31 @@ async function runBoundedCodexAppServerTurn(params) {
|
|
|
55
60
|
}
|
|
56
61
|
async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, workspace, selectionAttempt = 0, timing) {
|
|
57
62
|
const totalTimeoutMs = timing?.timeoutMs ?? resolveTimerTimeoutMs(params.timeoutMs, 100, 100);
|
|
63
|
+
const timeoutError = new CodexBoundedTurnTimeoutError(params.taskLabel, totalTimeoutMs);
|
|
58
64
|
const deadline = timing?.deadline ?? Date.now() + totalTimeoutMs;
|
|
59
65
|
const timeoutMs = deadline - Date.now();
|
|
60
|
-
if (timeoutMs <= 0) throw
|
|
66
|
+
if (timeoutMs <= 0) throw timeoutError;
|
|
61
67
|
const agentDir = params.agentDir?.trim() || void 0;
|
|
62
|
-
const
|
|
68
|
+
const isolatedStartOptions = workspace.codexHome ? buildPrivateCodexAppServerStartOptions(appServer.start, workspace.codexHome) : appServer.start;
|
|
69
|
+
const startOptions = workspace.codexHome && params.preparedAuth ? {
|
|
70
|
+
...isolatedStartOptions,
|
|
71
|
+
homeScope: "agent"
|
|
72
|
+
} : isolatedStartOptions;
|
|
63
73
|
const ownsClient = !params.options.clientFactory;
|
|
74
|
+
const authSelection = params.preparedAuth ? { preparedAuth: params.preparedAuth } : { authProfileId: params.profile };
|
|
64
75
|
const client = params.options.clientFactory ? await params.options.clientFactory({
|
|
65
76
|
startOptions,
|
|
66
|
-
|
|
77
|
+
...authSelection,
|
|
78
|
+
authRequirement: params.authRequirement,
|
|
67
79
|
agentDir,
|
|
68
80
|
config: params.config,
|
|
69
81
|
timeoutMs,
|
|
70
82
|
...params.signal ? { abandonSignal: params.signal } : {}
|
|
71
|
-
}) : await import("./shared-client-
|
|
83
|
+
}) : await import("./shared-client-kIBbGjk4.js").then((n) => n.m).then(({ createIsolatedCodexAppServerClient }) => createIsolatedCodexAppServerClient({
|
|
72
84
|
startOptions,
|
|
73
85
|
timeoutMs,
|
|
74
|
-
|
|
86
|
+
...authSelection,
|
|
87
|
+
authRequirement: params.authRequirement,
|
|
75
88
|
agentDir,
|
|
76
89
|
authProfileStore: params.authProfileStore,
|
|
77
90
|
config: params.config,
|
|
@@ -97,8 +110,8 @@ async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, worksp
|
|
|
97
110
|
if (params.signal?.aborted) abortFromCaller();
|
|
98
111
|
else params.signal?.addEventListener("abort", abortFromCaller, { once: true });
|
|
99
112
|
const remainingRunMs = deadline - Date.now();
|
|
100
|
-
if (remainingRunMs <= 0) abortRun(
|
|
101
|
-
const timeout = setTimeout(() => abortRun(
|
|
113
|
+
if (remainingRunMs <= 0) abortRun(timeoutError);
|
|
114
|
+
const timeout = setTimeout(() => abortRun(timeoutError), Math.max(1, remainingRunMs));
|
|
102
115
|
timeout.unref?.();
|
|
103
116
|
let retrySelection = false;
|
|
104
117
|
try {
|
|
@@ -110,17 +123,18 @@ async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, worksp
|
|
|
110
123
|
signal: abortController.signal
|
|
111
124
|
});
|
|
112
125
|
const inheritedMcpServerNames = params.requireNoExternalCapabilities ? await readCodexInheritedMcpServerNames(client, workspace.cwd, abortController.signal) : [];
|
|
113
|
-
if (params.requireNoExternalCapabilities) await
|
|
126
|
+
if (params.requireNoExternalCapabilities) await assertCodexRestrictedToolSurfaceHasNoManagedHooks(client, abortController.signal);
|
|
127
|
+
const threadConfig = buildCodexRuntimeThreadConfig(resolveBoundedThreadConfig(params, workspace, inheritedMcpServerNames), { nativeCodeModeEnabled: false });
|
|
114
128
|
const thread = assertCodexThreadStartResponse(await client.request("thread/start", {
|
|
115
129
|
model,
|
|
116
|
-
modelProvider:
|
|
130
|
+
...params.modelProvider ? { modelProvider: params.modelProvider } : {},
|
|
117
131
|
cwd: workspace.cwd,
|
|
118
132
|
approvalPolicy: "on-request",
|
|
119
133
|
sandbox: "read-only",
|
|
120
134
|
serviceName: "OpenClaw",
|
|
121
135
|
...params.requireNoExternalCapabilities ? { baseInstructions: "" } : {},
|
|
122
136
|
developerInstructions: params.developerInstructions,
|
|
123
|
-
config:
|
|
137
|
+
config: threadConfig,
|
|
124
138
|
environments: [],
|
|
125
139
|
dynamicTools: [],
|
|
126
140
|
experimentalRawEvents: true,
|
|
@@ -131,7 +145,7 @@ async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, worksp
|
|
|
131
145
|
}));
|
|
132
146
|
activeThreadId = thread.thread.id;
|
|
133
147
|
if (abortController.signal.aborted) requestInterrupt();
|
|
134
|
-
if (params.requireNoExternalCapabilities) await
|
|
148
|
+
if (params.requireNoExternalCapabilities) await attestCodexRestrictedToolSurfaceMcpServersDisabled(client, thread.thread.id, threadConfig, abortController.signal);
|
|
135
149
|
if (params.historyItems?.length) await client.request("thread/inject_items", {
|
|
136
150
|
threadId: thread.thread.id,
|
|
137
151
|
items: params.historyItems
|
|
@@ -139,14 +153,13 @@ async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, worksp
|
|
|
139
153
|
timeoutMs,
|
|
140
154
|
signal: abortController.signal
|
|
141
155
|
});
|
|
142
|
-
const collector = createCodexBoundedTurnCollector(thread.thread.id, params.taskLabel);
|
|
156
|
+
const collector = createCodexBoundedTurnCollector(thread.thread.id, params.taskLabel, params.allowEmptyText === true);
|
|
143
157
|
const cleanup = client.addNotificationHandler(collector.handleNotification);
|
|
144
158
|
const requestCleanup = client.addRequestHandler(createCodexBoundedApprovalHandler(params.taskLabel));
|
|
145
159
|
try {
|
|
146
160
|
const turn = assertCodexTurnStartResponse(await client.request("turn/start", {
|
|
147
161
|
threadId: thread.thread.id,
|
|
148
162
|
input: params.input,
|
|
149
|
-
cwd: workspace.cwd,
|
|
150
163
|
approvalPolicy: "on-request",
|
|
151
164
|
model,
|
|
152
165
|
effort: "low"
|
|
@@ -158,23 +171,25 @@ async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, worksp
|
|
|
158
171
|
if (abortController.signal.aborted) requestInterrupt();
|
|
159
172
|
return {
|
|
160
173
|
...await collector.collect(turn.turn, {
|
|
161
|
-
|
|
162
|
-
|
|
174
|
+
signal: abortController.signal,
|
|
175
|
+
timeoutError
|
|
163
176
|
}),
|
|
164
177
|
model
|
|
165
178
|
};
|
|
166
179
|
} finally {
|
|
180
|
+
await interruptPromise;
|
|
167
181
|
requestCleanup();
|
|
168
182
|
cleanup();
|
|
169
183
|
}
|
|
170
184
|
} catch (error) {
|
|
185
|
+
if (abortController.signal.aborted) throw resolveCodexBoundedTurnAbortError(abortController.signal, params.taskLabel, timeoutError);
|
|
171
186
|
if (ownsClient && isCodexAppServerStartSelectionChangedError(error) && selectionAttempt === 0) retrySelection = true;
|
|
172
187
|
else throw error;
|
|
173
188
|
} finally {
|
|
174
189
|
clearTimeout(timeout);
|
|
175
190
|
params.signal?.removeEventListener("abort", abortFromCaller);
|
|
176
191
|
await interruptPromise;
|
|
177
|
-
if (ownsClient) client
|
|
192
|
+
if (ownsClient) await closeCodexStartupClientBestEffort(client);
|
|
178
193
|
}
|
|
179
194
|
if (retrySelection) return await runBoundedCodexAppServerTurnInWorkspace(params, appServer, workspace, selectionAttempt + 1, {
|
|
180
195
|
deadline,
|
|
@@ -189,6 +204,10 @@ function resolveBoundedThreadConfig(params, workspace, inheritedMcpServerNames)
|
|
|
189
204
|
return mergeCodexThreadConfigs(privateConfig, CODEX_SETTLED_FINALIZER_THREAD_CONFIG, buildCodexRingZeroThreadConfigPatch({ toolsAllow: ["openclaw"] }, true, inheritedMcpServerNames)) ?? privateConfig;
|
|
190
205
|
}
|
|
191
206
|
function buildPrivateCodexAppServerStartOptions(start, codexHome) {
|
|
207
|
+
const providerArgs = start.args.flatMap((arg, index) => {
|
|
208
|
+
const override = arg === "-c" || arg === "--config" ? start.args[index + 1] : arg.startsWith("--config=") ? arg.slice(9) : void 0;
|
|
209
|
+
return override && /^\s*(?:openai_base_url|model_catalog_json)\s*=/u.test(override) ? ["-c", override] : [];
|
|
210
|
+
});
|
|
192
211
|
const privateEnv = Object.fromEntries(Object.entries(start.env ?? {}).filter(([name]) => name.trim().toUpperCase() !== CODEX_APP_SERVER_ARGS_ENV_KEY));
|
|
193
212
|
const clearEnv = (start.clearEnv ?? []).filter((name) => {
|
|
194
213
|
const normalized = name.trim().toUpperCase();
|
|
@@ -196,7 +215,12 @@ function buildPrivateCodexAppServerStartOptions(start, codexHome) {
|
|
|
196
215
|
});
|
|
197
216
|
return {
|
|
198
217
|
...start,
|
|
199
|
-
args: [
|
|
218
|
+
args: [
|
|
219
|
+
"app-server",
|
|
220
|
+
...providerArgs,
|
|
221
|
+
"--listen",
|
|
222
|
+
"stdio://"
|
|
223
|
+
],
|
|
200
224
|
env: {
|
|
201
225
|
...privateEnv,
|
|
202
226
|
CODEX_HOME: codexHome
|
|
@@ -243,7 +267,7 @@ async function resolveCodexBoundedTurnModel(params) {
|
|
|
243
267
|
if (params.requiredModalities.includes("text") && !match.inputModalities.includes("text")) throw new Error(`Codex app-server model does not support text: ${model}`);
|
|
244
268
|
return model;
|
|
245
269
|
}
|
|
246
|
-
function createCodexBoundedTurnCollector(threadId, taskLabel) {
|
|
270
|
+
function createCodexBoundedTurnCollector(threadId, taskLabel, allowEmptyText) {
|
|
247
271
|
let turnId;
|
|
248
272
|
let completedTurn;
|
|
249
273
|
let promptError;
|
|
@@ -252,10 +276,7 @@ function createCodexBoundedTurnCollector(threadId, taskLabel) {
|
|
|
252
276
|
const completedItems = /* @__PURE__ */ new Map();
|
|
253
277
|
const assistantTextByItem = /* @__PURE__ */ new Map();
|
|
254
278
|
const assistantItemOrder = [];
|
|
255
|
-
|
|
256
|
-
const completion = new Promise((resolve) => {
|
|
257
|
-
resolveCompletion = resolve;
|
|
258
|
-
});
|
|
279
|
+
const { promise: completion, resolve: resolveCompletion } = createDeferred();
|
|
259
280
|
const rememberAssistantText = (itemId, text) => {
|
|
260
281
|
if (!text) return;
|
|
261
282
|
if (!assistantTextByItem.has(itemId)) assistantItemOrder.push(itemId);
|
|
@@ -263,12 +284,12 @@ function createCodexBoundedTurnCollector(threadId, taskLabel) {
|
|
|
263
284
|
};
|
|
264
285
|
const handleNotification = (notification) => {
|
|
265
286
|
const params = isJsonObject(notification.params) ? notification.params : void 0;
|
|
266
|
-
if (!params ||
|
|
287
|
+
if (!params || readStringField(params, "threadId") !== threadId) return;
|
|
267
288
|
if (!turnId) {
|
|
268
289
|
pending.push(notification);
|
|
269
290
|
return;
|
|
270
291
|
}
|
|
271
|
-
if (
|
|
292
|
+
if (readCodexNotificationTurnId(params) !== turnId) return;
|
|
272
293
|
if (notification.method === "item/completed") {
|
|
273
294
|
const item = readCodexNotificationItem(notification.params);
|
|
274
295
|
if (item) {
|
|
@@ -278,8 +299,8 @@ function createCodexBoundedTurnCollector(threadId, taskLabel) {
|
|
|
278
299
|
return;
|
|
279
300
|
}
|
|
280
301
|
if (notification.method === "item/agentMessage/delta") {
|
|
281
|
-
const itemId =
|
|
282
|
-
const delta =
|
|
302
|
+
const itemId = readStringField(params, "itemId") ?? readStringField(params, "id") ?? "assistant";
|
|
303
|
+
const delta = readStringField(params, "delta") ?? "";
|
|
283
304
|
rememberAssistantText(itemId, `${assistantTextByItem.get(itemId) ?? ""}${delta}`);
|
|
284
305
|
return;
|
|
285
306
|
}
|
|
@@ -290,26 +311,26 @@ function createCodexBoundedTurnCollector(threadId, taskLabel) {
|
|
|
290
311
|
}
|
|
291
312
|
if (notification.method === "turn/completed") {
|
|
292
313
|
completedTurn = readCodexTurnCompletedNotification(notification.params)?.turn ?? completedTurn;
|
|
293
|
-
resolveCompletion
|
|
314
|
+
resolveCompletion();
|
|
294
315
|
return;
|
|
295
316
|
}
|
|
296
317
|
if (notification.method === "error") {
|
|
297
318
|
if (isRetryableErrorNotification(notification.params)) return;
|
|
298
319
|
promptError = readCodexErrorNotification(notification.params)?.error.message ?? `codex app-server ${taskLabel} turn failed`;
|
|
299
|
-
resolveCompletion
|
|
320
|
+
resolveCompletion();
|
|
300
321
|
}
|
|
301
322
|
};
|
|
302
323
|
return {
|
|
303
324
|
handleNotification,
|
|
304
325
|
async collect(startedTurn, options) {
|
|
305
326
|
turnId = startedTurn.id;
|
|
306
|
-
if (
|
|
327
|
+
if (isTerminalTurnStatus(startedTurn.status)) completedTurn = startedTurn;
|
|
307
328
|
for (const notification of pending.splice(0)) handleNotification(notification);
|
|
308
329
|
if (!completedTurn && !promptError) await waitForTurnCompletion({
|
|
309
330
|
completion,
|
|
310
|
-
timeoutMs: options.timeoutMs,
|
|
311
331
|
signal: options.signal,
|
|
312
|
-
taskLabel
|
|
332
|
+
taskLabel,
|
|
333
|
+
timeoutError: options.timeoutError
|
|
313
334
|
});
|
|
314
335
|
if (promptError) throw new Error(promptError);
|
|
315
336
|
if (completedTurn?.status === "failed") throw new Error(completedTurn.error?.message ?? `codex app-server ${taskLabel} turn failed`);
|
|
@@ -318,7 +339,7 @@ function createCodexBoundedTurnCollector(threadId, taskLabel) {
|
|
|
318
339
|
const itemText = collectAssistantTextFromItems(items);
|
|
319
340
|
const deltaText = assistantItemOrder.map((itemId) => assistantTextByItem.get(itemId)?.trim()).filter((text) => Boolean(text)).join("\n\n").trim();
|
|
320
341
|
const text = (itemText || deltaText).trim();
|
|
321
|
-
if (!text) throw new Error(`Codex app-server ${taskLabel} turn returned no text.`);
|
|
342
|
+
if (!text && !allowEmptyText) throw new Error(`Codex app-server ${taskLabel} turn returned no text.`);
|
|
322
343
|
return {
|
|
323
344
|
text,
|
|
324
345
|
items,
|
|
@@ -333,36 +354,23 @@ function collectCompletedItems(turnItems, notificationItems) {
|
|
|
333
354
|
return [...items.values()];
|
|
334
355
|
}
|
|
335
356
|
async function waitForTurnCompletion(params) {
|
|
336
|
-
if (params.signal.aborted) throw
|
|
337
|
-
let timeout;
|
|
357
|
+
if (params.signal.aborted) throw resolveCodexBoundedTurnAbortError(params.signal, params.taskLabel, params.timeoutError);
|
|
338
358
|
let cleanupAbort;
|
|
339
359
|
try {
|
|
340
360
|
await Promise.race([params.completion, new Promise((_, reject) => {
|
|
341
|
-
|
|
342
|
-
timeout.unref?.();
|
|
343
|
-
const abortListener = () => reject(/* @__PURE__ */ new Error(`codex app-server ${params.taskLabel} turn aborted`));
|
|
361
|
+
const abortListener = () => reject(resolveCodexBoundedTurnAbortError(params.signal, params.taskLabel, params.timeoutError));
|
|
344
362
|
params.signal.addEventListener("abort", abortListener, { once: true });
|
|
345
363
|
cleanupAbort = () => params.signal.removeEventListener("abort", abortListener);
|
|
346
364
|
})]);
|
|
347
365
|
} finally {
|
|
348
|
-
if (timeout) clearTimeout(timeout);
|
|
349
366
|
cleanupAbort?.();
|
|
350
367
|
}
|
|
351
368
|
}
|
|
369
|
+
function resolveCodexBoundedTurnAbortError(signal, taskLabel, timeoutError) {
|
|
370
|
+
return signal.reason === timeoutError ? timeoutError : /* @__PURE__ */ new Error(`codex app-server ${taskLabel} turn aborted`);
|
|
371
|
+
}
|
|
352
372
|
function collectAssistantTextFromItems(items) {
|
|
353
373
|
return (items ?? []).filter((item) => item.type === "agentMessage").map((item) => item.text.trim()).filter(Boolean).join("\n\n").trim();
|
|
354
374
|
}
|
|
355
|
-
function readNotificationTurnId(record) {
|
|
356
|
-
const direct = readString(record, "turnId");
|
|
357
|
-
if (direct) return direct;
|
|
358
|
-
return isJsonObject(record.turn) ? readString(record.turn, "id") : void 0;
|
|
359
|
-
}
|
|
360
|
-
function readString(record, key) {
|
|
361
|
-
const value = record[key];
|
|
362
|
-
return typeof value === "string" ? value : void 0;
|
|
363
|
-
}
|
|
364
|
-
function isTerminalTurn(turn) {
|
|
365
|
-
return turn.status === "completed" || turn.status === "interrupted" || turn.status === "failed";
|
|
366
|
-
}
|
|
367
375
|
//#endregion
|
|
368
376
|
export { runBoundedCodexAppServerTurn as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { z as CodexAppServerRpcError } from "./shared-client-kIBbGjk4.js";
|
|
2
2
|
//#region extensions/codex/src/app-server/capabilities.ts
|
|
3
3
|
/**
|
|
4
4
|
* Capability helpers for optional Codex app-server control-plane methods.
|
|
@@ -6,10 +6,14 @@ import { _ as CodexAppServerRpcError } from "./shared-client-BVKE40c-.js";
|
|
|
6
6
|
/** Known app-server methods used by OpenClaw control surfaces. */
|
|
7
7
|
const CODEX_CONTROL_METHODS = {
|
|
8
8
|
account: "account/read",
|
|
9
|
-
|
|
9
|
+
installedApps: "app/installed",
|
|
10
|
+
listApps: "app/list",
|
|
11
|
+
readApps: "app/read",
|
|
10
12
|
feedback: "feedback/upload",
|
|
11
13
|
forkThread: "thread/fork",
|
|
14
|
+
listHooks: "hooks/list",
|
|
12
15
|
listMcpServers: "mcpServerStatus/list",
|
|
16
|
+
listPlugins: "plugin/list",
|
|
13
17
|
listSkills: "skills/list",
|
|
14
18
|
listThreads: "thread/list",
|
|
15
19
|
listThreadTurns: "thread/turns/list",
|
|
@@ -19,6 +23,8 @@ const CODEX_CONTROL_METHODS = {
|
|
|
19
23
|
renameThread: "thread/name/set",
|
|
20
24
|
resumeThread: "thread/resume",
|
|
21
25
|
review: "review/start",
|
|
26
|
+
installPlugin: "plugin/install",
|
|
27
|
+
reloadMcpServers: "config/mcpServer/reload",
|
|
22
28
|
unarchiveThread: "thread/unarchive",
|
|
23
29
|
getThreadGoal: "thread/goal/get",
|
|
24
30
|
setThreadGoal: "thread/goal/set",
|
package/dist/cli-metadata.js
CHANGED
|
@@ -2,7 +2,7 @@ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
|
2
2
|
//#region extensions/codex/cli-metadata.ts
|
|
3
3
|
function registerCodexCliMetadata(api) {
|
|
4
4
|
api.registerCli(async ({ program }) => {
|
|
5
|
-
const { registerCodexSessionCli } = await import("./session-cli-
|
|
5
|
+
const { registerCodexSessionCli } = await import("./session-cli-7hgXZDV7.js");
|
|
6
6
|
registerCodexSessionCli(program);
|
|
7
7
|
}, { descriptors: [{
|
|
8
8
|
name: "codex",
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { c as summarizeCodexRateLimits, o as summarizeCodexAccountRateLimits, r as hasCodexRateLimitSnapshots } from "./rate-limits-
|
|
1
|
+
import { ct as isJsonObject } from "./shared-client-kIBbGjk4.js";
|
|
2
|
+
import { c as summarizeCodexRateLimits, o as summarizeCodexAccountRateLimits, r as hasCodexRateLimitSnapshots } from "./rate-limits-DZXmOL8-.js";
|
|
3
|
+
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
4
|
//#region extensions/codex/src/command-formatters.ts
|
|
5
|
+
/**
|
|
6
|
+
* Formats Codex command responses for safe chat display, including status,
|
|
7
|
+
* lists, account summaries, and user-facing help text.
|
|
8
|
+
*/
|
|
4
9
|
/** Formats the combined `/codex status` probe result. */
|
|
5
10
|
function formatCodexStatus(probes) {
|
|
6
11
|
const lines = [`Codex app-server: ${probes.models.ok || probes.account.ok || probes.limits.ok || probes.mcps.ok || probes.skills.ok ? "connected" : "unavailable"}`];
|
|
@@ -25,12 +30,12 @@ function formatThreads(response) {
|
|
|
25
30
|
if (threads.length === 0) return "No Codex threads returned.";
|
|
26
31
|
return ["Codex threads:", ...threads.slice(0, 10).map((thread) => {
|
|
27
32
|
const record = isJsonObject(thread) ? thread : {};
|
|
28
|
-
const id =
|
|
29
|
-
const title =
|
|
33
|
+
const id = normalizeOptionalString(record.threadId) ?? normalizeOptionalString(record.id) ?? "<unknown>";
|
|
34
|
+
const title = normalizeOptionalString(record.title) ?? normalizeOptionalString(record.name) ?? normalizeOptionalString(record.summary);
|
|
30
35
|
const details = [
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
normalizeOptionalString(record.model),
|
|
37
|
+
normalizeOptionalString(record.cwd),
|
|
38
|
+
normalizeOptionalString(record.updatedAt) ?? normalizeOptionalString(record.lastUpdatedAt)
|
|
34
39
|
].filter((value) => Boolean(value));
|
|
35
40
|
return `- ${formatCodexDisplayText(id)}${title ? ` - ${formatCodexDisplayText(title)}` : ""}${details.length > 0 ? ` (${details.map(formatCodexDisplayText).join(", ")})` : ""}\n Resume: ${formatCodexResumeHint(id)}`;
|
|
36
41
|
})].join("\n");
|
|
@@ -85,7 +90,7 @@ function formatList(response, label) {
|
|
|
85
90
|
if (entries.length === 0) return `${label}: none returned.`;
|
|
86
91
|
return [`${label}:`, ...entries.slice(0, 25).map((entry) => {
|
|
87
92
|
const record = isJsonObject(entry) ? entry : {};
|
|
88
|
-
return `- ${formatCodexDisplayText(
|
|
93
|
+
return `- ${formatCodexDisplayText(normalizeOptionalString(record.name) ?? normalizeOptionalString(record.id) ?? JSON.stringify(entry))}`;
|
|
89
94
|
})].join("\n");
|
|
90
95
|
}
|
|
91
96
|
/** Formats Codex skills grouped by scope, omitting disabled entries. */
|
|
@@ -113,7 +118,7 @@ function formatSkills(response) {
|
|
|
113
118
|
return lines.join("\n");
|
|
114
119
|
}
|
|
115
120
|
function formatCodexSkillEntry(entry) {
|
|
116
|
-
return `\`${formatCodexDisplayText(
|
|
121
|
+
return `\`${formatCodexDisplayText(normalizeOptionalString((isJsonObject(entry) ? entry : {}).name) ?? "<unknown>")}\``;
|
|
117
122
|
}
|
|
118
123
|
const CODEX_RESUME_SAFE_THREAD_ID_PATTERN = /^[A-Za-z0-9._:-]+$/;
|
|
119
124
|
function formatCodexResumeHint(threadId) {
|
|
@@ -200,8 +205,8 @@ function buildHelp() {
|
|
|
200
205
|
function summarizeAccount(value) {
|
|
201
206
|
if (!isJsonObject(value)) return "unavailable";
|
|
202
207
|
const account = isJsonObject(value.account) ? value.account : value;
|
|
203
|
-
if (
|
|
204
|
-
return
|
|
208
|
+
if (normalizeOptionalString(account.type) === "amazonBedrock") return "Amazon Bedrock";
|
|
209
|
+
return normalizeOptionalString(account.email) ?? normalizeOptionalString(account.accountEmail) ?? normalizeOptionalString(account.planType) ?? normalizeOptionalString(account.id) ?? "available";
|
|
205
210
|
}
|
|
206
211
|
function summarizeArrayLike(value) {
|
|
207
212
|
const entries = extractArray(value);
|
|
@@ -249,7 +254,7 @@ function summarizeRateLimits(value) {
|
|
|
249
254
|
}
|
|
250
255
|
function isMeaningfulRateLimitSnapshot(value) {
|
|
251
256
|
if (!isJsonObject(value)) return false;
|
|
252
|
-
if (
|
|
257
|
+
if (normalizeOptionalString(value.rateLimitReachedType) ?? normalizeOptionalString(value.rate_limit_reached_type)) return true;
|
|
253
258
|
return ["primary", "secondary"].some((key) => {
|
|
254
259
|
const window = value[key];
|
|
255
260
|
return isJsonObject(window) && Object.values(window).some((entry) => entry != null);
|
|
@@ -272,10 +277,5 @@ function extractArray(value) {
|
|
|
272
277
|
}
|
|
273
278
|
return [];
|
|
274
279
|
}
|
|
275
|
-
/** Reads and trims a non-empty string field from a JSON object. */
|
|
276
|
-
function readString(record, key) {
|
|
277
|
-
const value = record[key];
|
|
278
|
-
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
279
|
-
}
|
|
280
280
|
//#endregion
|
|
281
|
-
export { formatComputerUseStatus as a, formatSkills as c, formatCodexStatus as i, formatThreads as l, formatAccount as n, formatList as o, formatCodexDisplayText as r, formatModels as s, buildHelp as t
|
|
281
|
+
export { formatComputerUseStatus as a, formatSkills as c, formatCodexStatus as i, formatThreads as l, formatAccount as n, formatList as o, formatCodexDisplayText as r, formatModels as s, buildHelp as t };
|