@openclaw/codex 2026.7.2-beta.5 → 2026.7.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/README.md +3 -27
- package/dist/{command-formatters-ico4ZFnk.js → .setup/app-server-policy-C_qTMEMy.mjs} +51 -9
- package/dist/{attempt-notifications-CMR2_fmR.js → .setup/attempt-notifications-F8krwWL4.mjs} +6 -3
- package/dist/{command-handlers-CRmnwI2N.js → .setup/command-handlers-DSRFfor4.mjs} +1156 -1319
- package/dist/.setup/command-rpc-BvYsfQ7G.mjs +786 -0
- package/dist/{compact-dEN49UH6.js → .setup/compact-BNgh7I4t.mjs} +10 -40
- package/dist/.setup/computer-use-C3QkmSO3.mjs +377 -0
- package/dist/.setup/config-CYEDnLJ2.mjs +1138 -0
- package/dist/{conversation-binding-data-BHRpYbX3.js → .setup/conversation-binding-data-CrRxtDBu.mjs} +1 -1
- package/dist/{bounded-turn-FEbUXoYT.js → .setup/media-understanding-provider-EbJCyDqe.mjs} +193 -92
- package/dist/{models-BA01NEez.js → .setup/models-C_aZk03A.mjs} +11 -6
- package/dist/.setup/notification-correlation-iYs4WieS.mjs +35 -0
- package/dist/.setup/plugin-app-cache-key-DR8jV9oS.mjs +99 -0
- package/dist/.setup/protocol-2POPqAY4.mjs +13 -0
- package/dist/{protocol-validators-Dm4eXZmt.js → .setup/protocol-validators-dZQ-UTOa.mjs} +111 -334
- package/dist/{rate-limits-S_PXs0ul.js → .setup/provider-DGxDs6g8.mjs} +269 -13
- package/dist/{dynamic-tools-LIt9ojep.js → .setup/provider-capabilities-DS2N_zc1.mjs} +5465 -3399
- package/dist/.setup/request-DFR0JyoV.mjs +36 -0
- package/dist/.setup/run-attempt-C7xEKFVB.mjs +8180 -0
- package/dist/{sandbox-guard-D1Wky__S.js → .setup/sandbox-guard-DA2TQfZW.mjs} +1 -10
- package/dist/.setup/session-binding-DuihlMJc.mjs +628 -0
- package/dist/.setup/shared-client-B2KmLPRw.mjs +1854 -0
- package/dist/{side-question-CO12sHxo.js → .setup/side-question-Cv6JXWCS.mjs} +84 -159
- package/dist/{thread-lifecycle-DRg_FdzC.js → .setup/thread-lifecycle-u6CZdOOH.mjs} +1159 -1799
- package/dist/{web-search-provider.runtime-CaQMYDbp.js → .setup/web-search-provider.runtime-Ce2zOHxW.mjs} +3 -3
- package/dist/doctor-contract-api.js +122 -88
- package/dist/harness.js +20 -85
- package/dist/index.js +381 -1537
- package/dist/media-understanding-provider.js +1 -173
- package/dist/prompt-overlay.js +15 -0
- package/dist/provider-catalog.js +79 -0
- package/dist/provider-discovery.js +34 -0
- package/dist/provider.js +2 -0
- package/dist/web-search-contract-api.js +1 -1
- package/openclaw.plugin.json +178 -221
- package/package.json +8 -10
- package/dist/app-server-policy-BmDgseo_.js +0 -49
- package/dist/attempt-client-cleanup-Ia52yRWc.js +0 -127
- package/dist/auth-binding-B4FfbcCg.js +0 -62
- package/dist/capabilities-BHRSI6Cn.js +0 -36
- package/dist/cli-metadata.js +0 -20
- package/dist/computer-use-BjGylO-E.js +0 -695
- package/dist/conversation-control-DE7d9DOj.js +0 -287
- package/dist/event-projector-assistant-message-DTgnPPVF.js +0 -101
- package/dist/event-projector-usage-tvgb1NCX.js +0 -69
- package/dist/incognito-session-ET_ufDH-.js +0 -2
- package/dist/notification-correlation-Bj_Ak_jI.js +0 -67
- package/dist/plugin-app-cache-key-DSXX-rXO.js +0 -315
- package/dist/realtime-voice-api-BPcA1uN9.js +0 -494
- package/dist/realtime-voice-api.js +0 -2
- package/dist/request-CXpPennK.js +0 -157
- package/dist/run-attempt-C5GTPJOE.js +0 -11935
- package/dist/runtime-artifact-C2ITXdhM.js +0 -488
- package/dist/session-binding-DlVQ-Pxs.js +0 -2161
- package/dist/session-catalog-CP2oCcEb.js +0 -2444
- package/dist/session-cli-CqZ0Fp2a.js +0 -175
- package/dist/session-upstream-marker-QE-m5QFG.js +0 -82
- package/dist/settled-turn-finalizer-CA_2QXIE.js +0 -303
- package/dist/shared-client-BVKE40c-.js +0 -2952
- package/dist/transcript-mirror-uKA-A4tB.js +0 -550
- package/dist/transport-stdio-DXgGZ7Ib.js +0 -88
- package/dist/upstream-session-fork-_Vrz4WJr.js +0 -320
- package/dist/usage-UpVbdX5G.js +0 -25
- /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
package/dist/{conversation-binding-data-BHRpYbX3.js → .setup/conversation-binding-data-CrRxtDBu.mjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
|
|
2
2
|
import { createHash, randomUUID } from "node:crypto";
|
|
3
3
|
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
4
|
import process from "node:process";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
1
|
+
import { CODEX_PROVIDER_ID, FALLBACK_CODEX_MODELS } from "../provider-catalog.js";
|
|
2
|
+
import { r as isJsonObject } from "./protocol-2POPqAY4.mjs";
|
|
3
|
+
import { _ as readCodexNotificationItem } from "./attempt-notifications-F8krwWL4.mjs";
|
|
4
|
+
import { d as resolveCodexAppServerRuntimeOptions } from "./config-CYEDnLJ2.mjs";
|
|
5
|
+
import { i as assertCodexTurnStartResponse, l as readCodexTurnCompletedNotification, o as readCodexErrorNotification, r as assertCodexThreadStartResponse } from "./protocol-validators-dZQ-UTOa.mjs";
|
|
6
|
+
import { i as readModelListResult } from "./models-C_aZk03A.mjs";
|
|
7
|
+
import { H as mergeCodexThreadConfigs, r as buildCodexRuntimeThreadConfig } from "./thread-lifecycle-u6CZdOOH.mjs";
|
|
8
|
+
import { validateJsonSchemaValue } from "openclaw/plugin-sdk/json-schema-runtime";
|
|
9
9
|
import fs from "node:fs/promises";
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
@@ -16,7 +16,7 @@ const CODEX_PRIVATE_STDIO_ARGS = [
|
|
|
16
16
|
"--listen",
|
|
17
17
|
"stdio://"
|
|
18
18
|
];
|
|
19
|
-
const
|
|
19
|
+
const OPENCLAW_CODEX_APP_SERVER_ARGS_ENV_VAR = "OPENCLAW_CODEX_APP_SERVER_ARGS";
|
|
20
20
|
const CODEX_BOUNDED_THREAD_CONFIG = {
|
|
21
21
|
"features.multi_agent": false,
|
|
22
22
|
"features.apps": false,
|
|
@@ -29,15 +29,8 @@ const CODEX_PRIVATE_BOUNDED_THREAD_CONFIG = {
|
|
|
29
29
|
"features.hooks": false,
|
|
30
30
|
notify: []
|
|
31
31
|
};
|
|
32
|
-
const CODEX_SETTLED_FINALIZER_THREAD_CONFIG = {
|
|
33
|
-
"skills.include_instructions": false,
|
|
34
|
-
include_environment_context: false
|
|
35
|
-
};
|
|
36
32
|
async function runBoundedCodexAppServerTurn(params) {
|
|
37
|
-
const appServer = resolveCodexAppServerRuntimeOptions({
|
|
38
|
-
pluginConfig: params.options.pluginConfig,
|
|
39
|
-
managedCommandOrder: params.isolation === "private-stdio" ? "package-first" : void 0
|
|
40
|
-
});
|
|
33
|
+
const appServer = resolveCodexAppServerRuntimeOptions({ pluginConfig: params.options.pluginConfig });
|
|
41
34
|
if (params.isolation === "configured-transport") return await runBoundedCodexAppServerTurnInWorkspace(params, appServer, { cwd: params.agentDir?.trim() || process.cwd() });
|
|
42
35
|
if (appServer.start.transport !== "stdio") throw new Error("Bounded Codex turns require stdio transport so native tools can be isolated.");
|
|
43
36
|
return await withTempWorkspace({
|
|
@@ -53,11 +46,8 @@ async function runBoundedCodexAppServerTurn(params) {
|
|
|
53
46
|
});
|
|
54
47
|
});
|
|
55
48
|
}
|
|
56
|
-
async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, workspace
|
|
57
|
-
const
|
|
58
|
-
const deadline = timing?.deadline ?? Date.now() + totalTimeoutMs;
|
|
59
|
-
const timeoutMs = deadline - Date.now();
|
|
60
|
-
if (timeoutMs <= 0) throw new Error(`${params.taskLabel} timed out`);
|
|
49
|
+
async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, workspace) {
|
|
50
|
+
const timeoutMs = resolveTimerTimeoutMs(params.timeoutMs, 100, 100);
|
|
61
51
|
const agentDir = params.agentDir?.trim() || void 0;
|
|
62
52
|
const startOptions = workspace.codexHome ? buildPrivateCodexAppServerStartOptions(appServer.start, workspace.codexHome) : appServer.start;
|
|
63
53
|
const ownsClient = !params.options.clientFactory;
|
|
@@ -66,41 +56,21 @@ async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, worksp
|
|
|
66
56
|
authProfileId: params.profile,
|
|
67
57
|
agentDir,
|
|
68
58
|
config: params.config,
|
|
69
|
-
timeoutMs
|
|
70
|
-
|
|
71
|
-
}) : await import("./shared-client-BVKE40c-.js").then((n) => n.p).then(({ createIsolatedCodexAppServerClient }) => createIsolatedCodexAppServerClient({
|
|
59
|
+
timeoutMs
|
|
60
|
+
}) : await import("./shared-client-B2KmLPRw.mjs").then((n) => n.c).then(({ createIsolatedCodexAppServerClient }) => createIsolatedCodexAppServerClient({
|
|
72
61
|
startOptions,
|
|
73
62
|
timeoutMs,
|
|
74
63
|
authProfileId: params.profile,
|
|
75
64
|
agentDir,
|
|
76
65
|
authProfileStore: params.authProfileStore,
|
|
77
|
-
config: params.config
|
|
78
|
-
...params.signal ? { abandonSignal: params.signal } : {}
|
|
66
|
+
config: params.config
|
|
79
67
|
}));
|
|
80
68
|
const abortController = new AbortController();
|
|
81
|
-
|
|
82
|
-
let activeTurnId = "";
|
|
83
|
-
let interruptPromise;
|
|
84
|
-
const requestInterrupt = () => {
|
|
85
|
-
if (!activeThreadId || interruptPromise) return;
|
|
86
|
-
interruptPromise = interruptCodexTurnAndWaitBestEffort(client, {
|
|
87
|
-
threadId: activeThreadId,
|
|
88
|
-
turnId: activeTurnId,
|
|
89
|
-
timeoutMs: CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS
|
|
90
|
-
});
|
|
91
|
-
};
|
|
92
|
-
const abortRun = (reason) => {
|
|
93
|
-
abortController.abort(reason);
|
|
94
|
-
requestInterrupt();
|
|
95
|
-
};
|
|
96
|
-
const abortFromCaller = () => abortRun(params.signal?.reason ?? "aborted");
|
|
69
|
+
const abortFromCaller = () => abortController.abort(params.signal?.reason ?? "aborted");
|
|
97
70
|
if (params.signal?.aborted) abortFromCaller();
|
|
98
71
|
else params.signal?.addEventListener("abort", abortFromCaller, { once: true });
|
|
99
|
-
const
|
|
100
|
-
if (remainingRunMs <= 0) abortRun("timeout");
|
|
101
|
-
const timeout = setTimeout(() => abortRun("timeout"), Math.max(1, remainingRunMs));
|
|
72
|
+
const timeout = setTimeout(() => abortController.abort("timeout"), timeoutMs);
|
|
102
73
|
timeout.unref?.();
|
|
103
|
-
let retrySelection = false;
|
|
104
74
|
try {
|
|
105
75
|
const model = await resolveCodexBoundedTurnModel({
|
|
106
76
|
client,
|
|
@@ -109,8 +79,6 @@ async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, worksp
|
|
|
109
79
|
timeoutMs,
|
|
110
80
|
signal: abortController.signal
|
|
111
81
|
});
|
|
112
|
-
const inheritedMcpServerNames = params.requireNoExternalCapabilities ? await readCodexInheritedMcpServerNames(client, workspace.cwd, abortController.signal) : [];
|
|
113
|
-
if (params.requireNoExternalCapabilities) await assertCodexRingZeroHasNoManagedHooks(client, abortController.signal);
|
|
114
82
|
const thread = assertCodexThreadStartResponse(await client.request("thread/start", {
|
|
115
83
|
model,
|
|
116
84
|
modelProvider: "openai",
|
|
@@ -118,9 +86,8 @@ async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, worksp
|
|
|
118
86
|
approvalPolicy: "on-request",
|
|
119
87
|
sandbox: "read-only",
|
|
120
88
|
serviceName: "OpenClaw",
|
|
121
|
-
...params.requireNoExternalCapabilities ? { baseInstructions: "" } : {},
|
|
122
89
|
developerInstructions: params.developerInstructions,
|
|
123
|
-
config: buildCodexRuntimeThreadConfig(resolveBoundedThreadConfig(params, workspace
|
|
90
|
+
config: buildCodexRuntimeThreadConfig(resolveBoundedThreadConfig(params, workspace), { nativeCodeModeEnabled: false }),
|
|
124
91
|
environments: [],
|
|
125
92
|
dynamicTools: [],
|
|
126
93
|
experimentalRawEvents: true,
|
|
@@ -129,16 +96,6 @@ async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, worksp
|
|
|
129
96
|
timeoutMs,
|
|
130
97
|
signal: abortController.signal
|
|
131
98
|
}));
|
|
132
|
-
activeThreadId = thread.thread.id;
|
|
133
|
-
if (abortController.signal.aborted) requestInterrupt();
|
|
134
|
-
if (params.requireNoExternalCapabilities) await attestCodexRingZeroThreadHasNoMcpServers(client, thread.thread.id, abortController.signal);
|
|
135
|
-
if (params.historyItems?.length) await client.request("thread/inject_items", {
|
|
136
|
-
threadId: thread.thread.id,
|
|
137
|
-
items: params.historyItems
|
|
138
|
-
}, {
|
|
139
|
-
timeoutMs,
|
|
140
|
-
signal: abortController.signal
|
|
141
|
-
});
|
|
142
99
|
const collector = createCodexBoundedTurnCollector(thread.thread.id, params.taskLabel);
|
|
143
100
|
const cleanup = client.addNotificationHandler(collector.handleNotification);
|
|
144
101
|
const requestCleanup = client.addRequestHandler(createCodexBoundedApprovalHandler(params.taskLabel));
|
|
@@ -154,8 +111,6 @@ async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, worksp
|
|
|
154
111
|
timeoutMs,
|
|
155
112
|
signal: abortController.signal
|
|
156
113
|
}));
|
|
157
|
-
activeTurnId = turn.turn.id;
|
|
158
|
-
if (abortController.signal.aborted) requestInterrupt();
|
|
159
114
|
return {
|
|
160
115
|
...await collector.collect(turn.turn, {
|
|
161
116
|
timeoutMs,
|
|
@@ -167,32 +122,21 @@ async function runBoundedCodexAppServerTurnInWorkspace(params, appServer, worksp
|
|
|
167
122
|
requestCleanup();
|
|
168
123
|
cleanup();
|
|
169
124
|
}
|
|
170
|
-
} catch (error) {
|
|
171
|
-
if (ownsClient && isCodexAppServerStartSelectionChangedError(error) && selectionAttempt === 0) retrySelection = true;
|
|
172
|
-
else throw error;
|
|
173
125
|
} finally {
|
|
174
126
|
clearTimeout(timeout);
|
|
175
127
|
params.signal?.removeEventListener("abort", abortFromCaller);
|
|
176
|
-
await interruptPromise;
|
|
177
128
|
if (ownsClient) client.close();
|
|
178
129
|
}
|
|
179
|
-
if (retrySelection) return await runBoundedCodexAppServerTurnInWorkspace(params, appServer, workspace, selectionAttempt + 1, {
|
|
180
|
-
deadline,
|
|
181
|
-
timeoutMs: totalTimeoutMs
|
|
182
|
-
});
|
|
183
|
-
throw new Error("Codex bounded turn selection retry exited unexpectedly");
|
|
184
130
|
}
|
|
185
|
-
function resolveBoundedThreadConfig(params, workspace
|
|
131
|
+
function resolveBoundedThreadConfig(params, workspace) {
|
|
186
132
|
const boundedConfig = mergeCodexThreadConfigs(CODEX_BOUNDED_THREAD_CONFIG, params.threadConfig) ?? CODEX_BOUNDED_THREAD_CONFIG;
|
|
187
|
-
|
|
188
|
-
if (!params.requireNoExternalCapabilities) return privateConfig;
|
|
189
|
-
return mergeCodexThreadConfigs(privateConfig, CODEX_SETTLED_FINALIZER_THREAD_CONFIG, buildCodexRingZeroThreadConfigPatch({ toolsAllow: ["openclaw"] }, true, inheritedMcpServerNames)) ?? privateConfig;
|
|
133
|
+
return workspace.codexHome ? mergeCodexThreadConfigs(boundedConfig, CODEX_PRIVATE_BOUNDED_THREAD_CONFIG) ?? boundedConfig : boundedConfig;
|
|
190
134
|
}
|
|
191
135
|
function buildPrivateCodexAppServerStartOptions(start, codexHome) {
|
|
192
|
-
const privateEnv = Object.fromEntries(Object.entries(start.env ?? {}).filter(([name]) => name.trim().toUpperCase() !==
|
|
136
|
+
const privateEnv = Object.fromEntries(Object.entries(start.env ?? {}).filter(([name]) => name.trim().toUpperCase() !== OPENCLAW_CODEX_APP_SERVER_ARGS_ENV_VAR));
|
|
193
137
|
const clearEnv = (start.clearEnv ?? []).filter((name) => {
|
|
194
138
|
const normalized = name.trim().toUpperCase();
|
|
195
|
-
return normalized !== "CODEX_HOME" && normalized !==
|
|
139
|
+
return normalized !== "CODEX_HOME" && normalized !== OPENCLAW_CODEX_APP_SERVER_ARGS_ENV_VAR;
|
|
196
140
|
});
|
|
197
141
|
return {
|
|
198
142
|
...start,
|
|
@@ -201,7 +145,7 @@ function buildPrivateCodexAppServerStartOptions(start, codexHome) {
|
|
|
201
145
|
...privateEnv,
|
|
202
146
|
CODEX_HOME: codexHome
|
|
203
147
|
},
|
|
204
|
-
clearEnv: [...clearEnv,
|
|
148
|
+
clearEnv: [...clearEnv, OPENCLAW_CODEX_APP_SERVER_ARGS_ENV_VAR]
|
|
205
149
|
};
|
|
206
150
|
}
|
|
207
151
|
function createCodexBoundedApprovalHandler(taskLabel) {
|
|
@@ -222,14 +166,15 @@ function createCodexBoundedApprovalHandler(taskLabel) {
|
|
|
222
166
|
};
|
|
223
167
|
}
|
|
224
168
|
async function resolveCodexBoundedTurnModel(params) {
|
|
225
|
-
const
|
|
169
|
+
const result = await params.client.request("model/list", {
|
|
226
170
|
limit: null,
|
|
227
171
|
cursor: null,
|
|
228
172
|
includeHidden: false
|
|
229
173
|
}, {
|
|
230
174
|
timeoutMs: Math.min(params.timeoutMs, 5e3),
|
|
231
175
|
signal: params.signal
|
|
232
|
-
})
|
|
176
|
+
});
|
|
177
|
+
const listed = readModelListResult(result).models;
|
|
233
178
|
if (params.selection.mode === "live-default") {
|
|
234
179
|
const supported = listed.filter((entry) => params.requiredModalities.every((modality) => entry.inputModalities.includes(modality)));
|
|
235
180
|
const selected = supported.find((entry) => entry.isDefault) ?? supported[0];
|
|
@@ -247,7 +192,6 @@ function createCodexBoundedTurnCollector(threadId, taskLabel) {
|
|
|
247
192
|
let turnId;
|
|
248
193
|
let completedTurn;
|
|
249
194
|
let promptError;
|
|
250
|
-
let responseUsage;
|
|
251
195
|
const pending = [];
|
|
252
196
|
const completedItems = /* @__PURE__ */ new Map();
|
|
253
197
|
const assistantTextByItem = /* @__PURE__ */ new Map();
|
|
@@ -283,18 +227,12 @@ function createCodexBoundedTurnCollector(threadId, taskLabel) {
|
|
|
283
227
|
rememberAssistantText(itemId, `${assistantTextByItem.get(itemId) ?? ""}${delta}`);
|
|
284
228
|
return;
|
|
285
229
|
}
|
|
286
|
-
if (notification.method === "rawResponse/completed") {
|
|
287
|
-
const usage = isJsonObject(params.usage) ? params.usage : void 0;
|
|
288
|
-
responseUsage = usage ? normalizeCodexResponseTokenUsage(usage) : void 0;
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
230
|
if (notification.method === "turn/completed") {
|
|
292
231
|
completedTurn = readCodexTurnCompletedNotification(notification.params)?.turn ?? completedTurn;
|
|
293
232
|
resolveCompletion?.();
|
|
294
233
|
return;
|
|
295
234
|
}
|
|
296
235
|
if (notification.method === "error") {
|
|
297
|
-
if (isRetryableErrorNotification(notification.params)) return;
|
|
298
236
|
promptError = readCodexErrorNotification(notification.params)?.error.message ?? `codex app-server ${taskLabel} turn failed`;
|
|
299
237
|
resolveCompletion?.();
|
|
300
238
|
}
|
|
@@ -313,7 +251,6 @@ function createCodexBoundedTurnCollector(threadId, taskLabel) {
|
|
|
313
251
|
});
|
|
314
252
|
if (promptError) throw new Error(promptError);
|
|
315
253
|
if (completedTurn?.status === "failed") throw new Error(completedTurn.error?.message ?? `codex app-server ${taskLabel} turn failed`);
|
|
316
|
-
if (completedTurn?.status !== "completed") throw new Error(`codex app-server ${taskLabel} turn ended with status ${completedTurn?.status ?? "unknown"}`);
|
|
317
254
|
const items = collectCompletedItems(completedTurn?.items, completedItems);
|
|
318
255
|
const itemText = collectAssistantTextFromItems(items);
|
|
319
256
|
const deltaText = assistantItemOrder.map((itemId) => assistantTextByItem.get(itemId)?.trim()).filter((text) => Boolean(text)).join("\n\n").trim();
|
|
@@ -321,8 +258,7 @@ function createCodexBoundedTurnCollector(threadId, taskLabel) {
|
|
|
321
258
|
if (!text) throw new Error(`Codex app-server ${taskLabel} turn returned no text.`);
|
|
322
259
|
return {
|
|
323
260
|
text,
|
|
324
|
-
items
|
|
325
|
-
...responseUsage ? { usage: responseUsage } : {}
|
|
261
|
+
items
|
|
326
262
|
};
|
|
327
263
|
}
|
|
328
264
|
};
|
|
@@ -365,4 +301,169 @@ function isTerminalTurn(turn) {
|
|
|
365
301
|
return turn.status === "completed" || turn.status === "interrupted" || turn.status === "failed";
|
|
366
302
|
}
|
|
367
303
|
//#endregion
|
|
368
|
-
|
|
304
|
+
//#region extensions/codex/media-understanding-provider.ts
|
|
305
|
+
/**
|
|
306
|
+
* Codex-backed media understanding provider for bounded image description and
|
|
307
|
+
* structured extraction turns.
|
|
308
|
+
*/
|
|
309
|
+
const DEFAULT_CODEX_IMAGE_MODEL = FALLBACK_CODEX_MODELS.find((model) => model.inputModalities.includes("image"))?.id ?? FALLBACK_CODEX_MODELS[0]?.id;
|
|
310
|
+
const DEFAULT_CODEX_IMAGE_PROMPT = "Describe the image.";
|
|
311
|
+
/**
|
|
312
|
+
* Builds the media-understanding provider that delegates image tasks to an
|
|
313
|
+
* isolated Codex app-server session.
|
|
314
|
+
*/
|
|
315
|
+
function buildCodexMediaUnderstandingProvider(options = {}) {
|
|
316
|
+
return {
|
|
317
|
+
id: CODEX_PROVIDER_ID,
|
|
318
|
+
capabilities: ["image"],
|
|
319
|
+
...DEFAULT_CODEX_IMAGE_MODEL ? { defaultModels: { image: DEFAULT_CODEX_IMAGE_MODEL } } : {},
|
|
320
|
+
describeImage: async (req) => describeCodexImages({
|
|
321
|
+
images: [{
|
|
322
|
+
buffer: req.buffer,
|
|
323
|
+
fileName: req.fileName,
|
|
324
|
+
mime: req.mime
|
|
325
|
+
}],
|
|
326
|
+
provider: req.provider,
|
|
327
|
+
model: req.model,
|
|
328
|
+
prompt: req.prompt,
|
|
329
|
+
maxTokens: req.maxTokens,
|
|
330
|
+
timeoutMs: req.timeoutMs,
|
|
331
|
+
profile: req.profile,
|
|
332
|
+
preferredProfile: req.preferredProfile,
|
|
333
|
+
authStore: req.authStore,
|
|
334
|
+
agentDir: req.agentDir,
|
|
335
|
+
cfg: req.cfg
|
|
336
|
+
}, options),
|
|
337
|
+
describeImages: async (req) => describeCodexImages(req, options),
|
|
338
|
+
extractStructured: async (req) => extractCodexStructured(req, options)
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
async function describeCodexImages(req, options) {
|
|
342
|
+
const model = req.model.trim();
|
|
343
|
+
if (!model) throw new Error("Codex image understanding requires model id.");
|
|
344
|
+
const { text } = await runBoundedCodexAppServerTurn({
|
|
345
|
+
config: req.cfg,
|
|
346
|
+
model: {
|
|
347
|
+
mode: "required",
|
|
348
|
+
id: model
|
|
349
|
+
},
|
|
350
|
+
profile: req.profile,
|
|
351
|
+
timeoutMs: req.timeoutMs,
|
|
352
|
+
agentDir: req.agentDir,
|
|
353
|
+
authProfileStore: req.authStore,
|
|
354
|
+
options,
|
|
355
|
+
taskLabel: "image understanding",
|
|
356
|
+
developerInstructions: "You are OpenClaw's bounded image-understanding worker. Describe only the provided image content. Do not call tools, edit files, or ask follow-up questions.",
|
|
357
|
+
input: [{
|
|
358
|
+
type: "text",
|
|
359
|
+
text: buildCodexImagePrompt(req),
|
|
360
|
+
text_elements: []
|
|
361
|
+
}, ...req.images.map((image) => ({
|
|
362
|
+
type: "image",
|
|
363
|
+
url: `data:${image.mime ?? "image/png"};base64,${image.buffer.toString("base64")}`
|
|
364
|
+
}))],
|
|
365
|
+
requiredModalities: ["text", "image"],
|
|
366
|
+
isolation: "configured-transport"
|
|
367
|
+
});
|
|
368
|
+
return {
|
|
369
|
+
text,
|
|
370
|
+
model
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
async function extractCodexStructured(req, options) {
|
|
374
|
+
const model = req.model.trim();
|
|
375
|
+
if (!model) throw new Error("Codex structured extraction requires model id.");
|
|
376
|
+
if (!req.instructions.trim()) throw new Error("Codex structured extraction requires instructions.");
|
|
377
|
+
if (req.input.length === 0) throw new Error("Codex structured extraction requires at least one input.");
|
|
378
|
+
if (!req.input.some((entry) => entry.type === "image")) throw new Error("Codex structured extraction requires at least one image input.");
|
|
379
|
+
const { text } = await runBoundedCodexAppServerTurn({
|
|
380
|
+
config: req.cfg,
|
|
381
|
+
model: {
|
|
382
|
+
mode: "required",
|
|
383
|
+
id: model
|
|
384
|
+
},
|
|
385
|
+
profile: req.profile,
|
|
386
|
+
timeoutMs: req.timeoutMs,
|
|
387
|
+
agentDir: req.agentDir,
|
|
388
|
+
authProfileStore: req.authStore,
|
|
389
|
+
options,
|
|
390
|
+
taskLabel: "structured extraction",
|
|
391
|
+
developerInstructions: "You are OpenClaw's bounded structured-extraction worker. Return only the requested extraction. Do not call tools, edit files, ask follow-up questions, or include secrets.",
|
|
392
|
+
input: buildCodexStructuredInput(req),
|
|
393
|
+
requiredModalities: requiredStructuredModalities(),
|
|
394
|
+
isolation: "configured-transport"
|
|
395
|
+
});
|
|
396
|
+
return normalizeStructuredExtractionResult({
|
|
397
|
+
text,
|
|
398
|
+
model,
|
|
399
|
+
provider: req.provider,
|
|
400
|
+
req
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
function buildCodexImagePrompt(req) {
|
|
404
|
+
const prompt = req.prompt?.trim() || DEFAULT_CODEX_IMAGE_PROMPT;
|
|
405
|
+
if (req.images.length <= 1) return prompt;
|
|
406
|
+
return `${prompt}\n\nAnalyze all ${req.images.length} images together.`;
|
|
407
|
+
}
|
|
408
|
+
function requiredStructuredModalities() {
|
|
409
|
+
return ["text", "image"];
|
|
410
|
+
}
|
|
411
|
+
function buildCodexStructuredInput(req) {
|
|
412
|
+
return [{
|
|
413
|
+
type: "text",
|
|
414
|
+
text: buildStructuredExtractionPrompt(req),
|
|
415
|
+
text_elements: []
|
|
416
|
+
}, ...req.input.map((entry) => {
|
|
417
|
+
if (entry.type === "text") return {
|
|
418
|
+
type: "text",
|
|
419
|
+
text: entry.text,
|
|
420
|
+
text_elements: []
|
|
421
|
+
};
|
|
422
|
+
return {
|
|
423
|
+
type: "image",
|
|
424
|
+
url: `data:${entry.mime ?? "image/png"};base64,${entry.buffer.toString("base64")}`
|
|
425
|
+
};
|
|
426
|
+
})];
|
|
427
|
+
}
|
|
428
|
+
function buildStructuredExtractionPrompt(req) {
|
|
429
|
+
return [
|
|
430
|
+
req.instructions.trim(),
|
|
431
|
+
req.schemaName ? `Schema name: ${req.schemaName}` : void 0,
|
|
432
|
+
req.jsonSchema ? `JSON schema:\n${JSON.stringify(req.jsonSchema)}` : void 0,
|
|
433
|
+
req.jsonMode === false ? "Return the extraction as concise text." : "Return valid JSON only. Do not wrap the JSON in Markdown fences."
|
|
434
|
+
].filter((part) => Boolean(part)).join("\n\n");
|
|
435
|
+
}
|
|
436
|
+
function isJsonSchemaObject(value) {
|
|
437
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
438
|
+
}
|
|
439
|
+
function normalizeStructuredExtractionResult(params) {
|
|
440
|
+
const result = {
|
|
441
|
+
text: params.text,
|
|
442
|
+
model: params.model,
|
|
443
|
+
provider: params.provider,
|
|
444
|
+
contentType: params.req.jsonMode === false ? "text" : "json"
|
|
445
|
+
};
|
|
446
|
+
if (params.req.jsonMode !== false) {
|
|
447
|
+
try {
|
|
448
|
+
result.parsed = JSON.parse(params.text);
|
|
449
|
+
} catch {
|
|
450
|
+
throw new Error("Codex structured extraction returned invalid JSON.");
|
|
451
|
+
}
|
|
452
|
+
if (isJsonSchemaObject(params.req.jsonSchema)) {
|
|
453
|
+
const validation = validateJsonSchemaValue({
|
|
454
|
+
schema: params.req.jsonSchema,
|
|
455
|
+
cacheKey: "codex.media-understanding.extractStructured",
|
|
456
|
+
value: result.parsed,
|
|
457
|
+
cache: false
|
|
458
|
+
});
|
|
459
|
+
if (!validation.ok) {
|
|
460
|
+
const message = validation.errors.map((error) => error.text).join("; ") || "invalid";
|
|
461
|
+
throw new Error(`Codex structured extraction JSON did not match schema: ${message}`);
|
|
462
|
+
}
|
|
463
|
+
result.parsed = validation.value;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
return result;
|
|
467
|
+
}
|
|
468
|
+
//#endregion
|
|
469
|
+
export { runBoundedCodexAppServerTurn as n, buildCodexMediaUnderstandingProvider as t };
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
|
|
2
|
+
import { s as readCodexModelListResponse } from "./protocol-validators-dZQ-UTOa.mjs";
|
|
2
3
|
import { uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
4
|
//#region extensions/codex/src/app-server/models.ts
|
|
4
5
|
/**
|
|
5
6
|
* Lists and normalizes models exposed by the Codex app-server `model/list`
|
|
6
7
|
* endpoint, including pagination and shared-client lease handling.
|
|
7
8
|
*/
|
|
9
|
+
var models_exports = /* @__PURE__ */ __exportAll({
|
|
10
|
+
listAllCodexAppServerModels: () => listAllCodexAppServerModels,
|
|
11
|
+
listCodexAppServerModels: () => listCodexAppServerModels,
|
|
12
|
+
readModelListResult: () => readModelListResult
|
|
13
|
+
});
|
|
8
14
|
/** Lists one Codex app-server model page using the configured auth/client options. */
|
|
9
15
|
async function listCodexAppServerModels(options = {}) {
|
|
10
16
|
return await withCodexAppServerModelClient(options, async ({ client, timeoutMs }) => requestModelListPage(client, {
|
|
@@ -40,19 +46,17 @@ async function listAllCodexAppServerModels(options = {}) {
|
|
|
40
46
|
async function withCodexAppServerModelClient(options, run) {
|
|
41
47
|
const timeoutMs = options.timeoutMs ?? 2500;
|
|
42
48
|
const useSharedClient = options.sharedClient !== false;
|
|
43
|
-
const { createIsolatedCodexAppServerClient, getLeasedSharedCodexAppServerClient, releaseLeasedSharedCodexAppServerClient } = await import("./shared-client-
|
|
49
|
+
const { createIsolatedCodexAppServerClient, getLeasedSharedCodexAppServerClient, releaseLeasedSharedCodexAppServerClient } = await import("./shared-client-B2KmLPRw.mjs").then((n) => n.c);
|
|
44
50
|
const client = useSharedClient ? await getLeasedSharedCodexAppServerClient({
|
|
45
51
|
startOptions: options.startOptions,
|
|
46
52
|
timeoutMs,
|
|
47
53
|
authProfileId: options.authProfileId,
|
|
48
|
-
authRequirement: options.authRequirement,
|
|
49
54
|
agentDir: options.agentDir,
|
|
50
55
|
config: options.config
|
|
51
56
|
}) : await createIsolatedCodexAppServerClient({
|
|
52
57
|
startOptions: options.startOptions,
|
|
53
58
|
timeoutMs,
|
|
54
59
|
authProfileId: options.authProfileId,
|
|
55
|
-
authRequirement: options.authRequirement,
|
|
56
60
|
agentDir: options.agentDir,
|
|
57
61
|
config: options.config
|
|
58
62
|
});
|
|
@@ -101,7 +105,8 @@ function readCodexModel(value) {
|
|
|
101
105
|
};
|
|
102
106
|
}
|
|
103
107
|
function readReasoningEfforts(value) {
|
|
104
|
-
|
|
108
|
+
const efforts = value.map((entry) => readNonEmptyString(entry.reasoningEffort)).filter((entry) => entry !== void 0);
|
|
109
|
+
return uniqueStrings(efforts);
|
|
105
110
|
}
|
|
106
111
|
function readNonEmptyString(value) {
|
|
107
112
|
if (typeof value !== "string") return;
|
|
@@ -111,4 +116,4 @@ function normalizeMaxPages(value) {
|
|
|
111
116
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : 20;
|
|
112
117
|
}
|
|
113
118
|
//#endregion
|
|
114
|
-
export { listCodexAppServerModels as n,
|
|
119
|
+
export { readModelListResult as i, listCodexAppServerModels as n, models_exports as r, listAllCodexAppServerModels as t };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { r as isJsonObject } from "./protocol-2POPqAY4.mjs";
|
|
2
|
+
//#region extensions/codex/src/app-server/notification-correlation.ts
|
|
3
|
+
/**
|
|
4
|
+
* Correlates Codex app-server notifications with the active thread/turn so
|
|
5
|
+
* projectors can ignore global or stale events without losing diagnostics.
|
|
6
|
+
*/
|
|
7
|
+
/** Returns true when a notification payload belongs to the exact active thread and turn. */
|
|
8
|
+
function isCodexNotificationForTurn(value, threadId, turnId) {
|
|
9
|
+
if (!isJsonObject(value)) return false;
|
|
10
|
+
return readCodexNotificationThreadId(value) === threadId && readCodexNotificationTurnId(value) === turnId;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Reads a thread id from canonical top-level or nested thread payloads.
|
|
14
|
+
* The generated v2 schemas require top-level `threadId` on turn/item-scoped
|
|
15
|
+
* notifications and define `Turn` without one, so `turn.threadId` is not a
|
|
16
|
+
* wire shape and is deliberately not read here.
|
|
17
|
+
*/
|
|
18
|
+
function readCodexNotificationThreadId(record) {
|
|
19
|
+
const thread = isJsonObject(record.thread) ? record.thread : void 0;
|
|
20
|
+
return readString(record, "threadId") ?? (thread ? readString(thread, "id") : void 0);
|
|
21
|
+
}
|
|
22
|
+
/** Reads a turn id from either top-level notification params or nested turn payloads. */
|
|
23
|
+
function readCodexNotificationTurnId(record) {
|
|
24
|
+
return readNestedTurnId(record) ?? readString(record, "turnId");
|
|
25
|
+
}
|
|
26
|
+
function readNestedTurnId(record) {
|
|
27
|
+
const turn = record.turn;
|
|
28
|
+
return isJsonObject(turn) ? readString(turn, "id") : void 0;
|
|
29
|
+
}
|
|
30
|
+
function readString(record, key) {
|
|
31
|
+
const value = record[key];
|
|
32
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { readCodexNotificationThreadId as n, readCodexNotificationTurnId as r, isCodexNotificationForTurn as t };
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { K as buildCodexAppInventoryCacheKey } from "./thread-lifecycle-u6CZdOOH.mjs";
|
|
2
|
+
import { u as CodexAppServerRpcError, x as resolveCodexAppServerHomeDir } from "./shared-client-B2KmLPRw.mjs";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
import { OPENCLAW_VERSION } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
6
|
+
import { readPluginPackageVersion } from "openclaw/plugin-sdk/extension-shared";
|
|
7
|
+
//#region extensions/codex/src/app-server/capabilities.ts
|
|
8
|
+
/**
|
|
9
|
+
* Capability helpers for optional Codex app-server control-plane methods.
|
|
10
|
+
*/
|
|
11
|
+
/** Known app-server methods used by OpenClaw control surfaces. */
|
|
12
|
+
const CODEX_CONTROL_METHODS = {
|
|
13
|
+
account: "account/read",
|
|
14
|
+
compact: "thread/compact/start",
|
|
15
|
+
feedback: "feedback/upload",
|
|
16
|
+
forkThread: "thread/fork",
|
|
17
|
+
listMcpServers: "mcpServerStatus/list",
|
|
18
|
+
listSkills: "skills/list",
|
|
19
|
+
listThreads: "thread/list",
|
|
20
|
+
readThread: "thread/read",
|
|
21
|
+
rateLimits: "account/rateLimits/read",
|
|
22
|
+
archiveThread: "thread/archive",
|
|
23
|
+
renameThread: "thread/name/set",
|
|
24
|
+
resumeThread: "thread/resume",
|
|
25
|
+
review: "review/start",
|
|
26
|
+
unarchiveThread: "thread/unarchive"
|
|
27
|
+
};
|
|
28
|
+
/** Formats unsupported control calls differently from ordinary RPC failures. */
|
|
29
|
+
function describeControlFailure(error) {
|
|
30
|
+
if (isUnsupportedControlError(error)) return "unsupported by this Codex app-server";
|
|
31
|
+
return error instanceof Error ? error.message : String(error);
|
|
32
|
+
}
|
|
33
|
+
function isUnsupportedControlError(error) {
|
|
34
|
+
return error instanceof CodexAppServerRpcError && error.code === -32601;
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region extensions/codex/src/app-server/plugin-app-cache-key.ts
|
|
38
|
+
/**
|
|
39
|
+
* Builds stable Codex plugin/app inventory cache keys from app-server startup,
|
|
40
|
+
* auth, account, and version inputs without storing secret material.
|
|
41
|
+
*/
|
|
42
|
+
const require = createRequire(import.meta.url);
|
|
43
|
+
const CODEX_PLUGIN_VERSION = readPluginPackageVersion({ require });
|
|
44
|
+
/** Builds the full app inventory cache key for Codex plugin/app discovery. */
|
|
45
|
+
function buildCodexPluginAppCacheKey(params) {
|
|
46
|
+
return buildCodexAppInventoryCacheKey({
|
|
47
|
+
codexHome: params.runtimeIdentity?.codexHome ?? resolveCodexPluginAppCacheCodexHome(params.appServer, params.agentDir),
|
|
48
|
+
endpoint: resolveCodexPluginAppCacheEndpoint(params.appServer),
|
|
49
|
+
authProfileId: params.authProfileId,
|
|
50
|
+
accountId: params.accountId,
|
|
51
|
+
envApiKeyFingerprint: params.envApiKeyFingerprint,
|
|
52
|
+
appServerVersion: params.appServerVersion ?? params.runtimeIdentity?.serverVersion,
|
|
53
|
+
runtimeIdentity: params.runtimeIdentity
|
|
54
|
+
}, OPENCLAW_VERSION, CODEX_PLUGIN_VERSION);
|
|
55
|
+
}
|
|
56
|
+
/** Builds a durable thread-binding fingerprint for one initialized app-server runtime. */
|
|
57
|
+
function buildCodexAppServerRuntimeFingerprint(params) {
|
|
58
|
+
return JSON.stringify({
|
|
59
|
+
endpoint: resolveCodexPluginAppCacheEndpoint(params.appServer),
|
|
60
|
+
connectionClass: params.appServer.connectionClass,
|
|
61
|
+
remoteWorkspaceRoot: params.appServer.remoteWorkspaceRoot ?? null,
|
|
62
|
+
appServerVersion: params.appServerVersion ?? params.runtimeIdentity?.serverVersion ?? null,
|
|
63
|
+
runtimeIdentity: params.runtimeIdentity ?? null
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/** Serializes app-server endpoint identity, including credential fingerprints. */
|
|
67
|
+
function resolveCodexPluginAppCacheEndpoint(appServer) {
|
|
68
|
+
return JSON.stringify({
|
|
69
|
+
transport: appServer.start.transport,
|
|
70
|
+
command: appServer.start.command,
|
|
71
|
+
args: appServer.start.args,
|
|
72
|
+
url: appServer.start.url ?? null,
|
|
73
|
+
credentialFingerprint: fingerprintCodexPluginAppCacheCredentials(appServer.start)
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/** Resolves the CODEX_HOME value that scopes local app-server inventory. */
|
|
77
|
+
function resolveCodexPluginAppCacheCodexHome(appServer, agentDir) {
|
|
78
|
+
const configuredCodexHome = appServer.start.env?.CODEX_HOME?.trim();
|
|
79
|
+
if (configuredCodexHome) return configuredCodexHome;
|
|
80
|
+
return appServer.start.transport === "stdio" && agentDir ? resolveCodexAppServerHomeDir(agentDir) : void 0;
|
|
81
|
+
}
|
|
82
|
+
function fingerprintCodexPluginAppCacheCredentials(startOptions) {
|
|
83
|
+
const authToken = startOptions.authToken ?? "";
|
|
84
|
+
const headers = Object.entries(startOptions.headers).map(([key, value]) => [key.toLowerCase(), value]).toSorted(([left], [right]) => left.localeCompare(right));
|
|
85
|
+
if (!authToken && headers.length === 0) return null;
|
|
86
|
+
const hash = createHash("sha256");
|
|
87
|
+
hash.update("openclaw:codex:plugin-app-cache-credentials:v1");
|
|
88
|
+
hash.update("\0");
|
|
89
|
+
hash.update(authToken);
|
|
90
|
+
for (const [key, value] of headers) {
|
|
91
|
+
hash.update("\0");
|
|
92
|
+
hash.update(key);
|
|
93
|
+
hash.update("\0");
|
|
94
|
+
hash.update(value);
|
|
95
|
+
}
|
|
96
|
+
return `sha256:${hash.digest("hex")}`;
|
|
97
|
+
}
|
|
98
|
+
//#endregion
|
|
99
|
+
export { describeControlFailure as i, buildCodexPluginAppCacheKey as n, CODEX_CONTROL_METHODS as r, buildCodexAppServerRuntimeFingerprint as t };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region extensions/codex/src/app-server/protocol.ts
|
|
2
|
+
function flattenCodexDynamicToolFunctions(tools) {
|
|
3
|
+
return (tools ?? []).flatMap((tool) => tool.type === "namespace" ? tool.tools : [tool]);
|
|
4
|
+
}
|
|
5
|
+
const CODEX_INTERACTIVE_THREAD_SOURCE_KINDS = ["cli", "vscode"];
|
|
6
|
+
function isJsonObject(value) {
|
|
7
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
8
|
+
}
|
|
9
|
+
function isRpcResponse(message) {
|
|
10
|
+
return "id" in message && !("method" in message);
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { isRpcResponse as i, flattenCodexDynamicToolFunctions as n, isJsonObject as r, CODEX_INTERACTIVE_THREAD_SOURCE_KINDS as t };
|