mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-20 17:41:33 -06:00
fix(codex): unblock Computer Use after plugin install (#126699)
* fix(codex): release config fence before readiness probe * chore(codex): upgrade managed app-server to 0.148.0
This commit is contained in:
committed by
GitHub
parent
eb84b56766
commit
02c08bba71
@@ -258,7 +258,7 @@ reconciliation so OpenClaw does not override that selection.
|
||||
## Remote marketplaces
|
||||
|
||||
Remote marketplace support was introduced in Codex 0.146.1 and remains
|
||||
available in OpenClaw's pinned Codex 0.147.0. OpenClaw passes the opaque remote
|
||||
available in OpenClaw's pinned Codex 0.148.0. OpenClaw passes the opaque remote
|
||||
plugin ID returned by Codex to `plugin/read` and `plugin/install`; a
|
||||
human-readable plugin name is not a valid substitute.
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ flags, and plugin allow/deny references into this block. Explicit canonical
|
||||
## App-server transport
|
||||
|
||||
For ordinary harness turns, OpenClaw starts the managed Codex binary shipped
|
||||
with the official plugin (currently `@openai/codex` `0.147.0`):
|
||||
with the official plugin (currently `@openai/codex` `0.148.0`):
|
||||
|
||||
```bash
|
||||
codex app-server --listen stdio://
|
||||
@@ -317,8 +317,8 @@ If the normal app-server runtime would be `danger-full-access`, enabling
|
||||
permission profile instead. Codex-managed network enforcement is sandboxed
|
||||
networking, so a full-access profile would not protect outbound traffic.
|
||||
|
||||
The plugin ships Codex app-server `0.147.0` and accepts external versions at or
|
||||
above that minimum. Older, malformed, and unversioned handshakes are rejected.
|
||||
The plugin ships Codex app-server `0.148.0` and accepts external versions at or
|
||||
above `0.147.0`. Older, malformed, and unversioned handshakes are rejected.
|
||||
Build metadata does not affect SemVer precedence. The same minimum applies to
|
||||
explicit custom executables, remote app-servers, and macOS desktop binaries;
|
||||
admission is not readiness proof.
|
||||
@@ -446,7 +446,7 @@ The stable default is fail-closed: active OpenClaw sandboxing disables native
|
||||
Codex execution surfaces that would otherwise run from the Codex app-server
|
||||
host. Use `appServer.experimental.sandboxExecServer: true` only when you want
|
||||
to try Codex's remote environment support with OpenClaw's sandbox backend.
|
||||
This preview path uses the pinned Codex `0.147.0` app-server.
|
||||
This preview path uses the pinned Codex `0.148.0` app-server.
|
||||
|
||||
```json5
|
||||
{
|
||||
@@ -746,21 +746,17 @@ response remains authoritative even if it contains no visible models; HTTP
|
||||
`401` and `403` return an empty catalog rather than exposing fallback models.
|
||||
|
||||
<Note>
|
||||
The current bundled harness is `@openai/codex` `0.147.0`. A live `model/list`
|
||||
probe against the official `0.147.0` app-server returned these public picker
|
||||
The current bundled harness is `@openai/codex` `0.148.0`. A live `model/list`
|
||||
probe against the official `0.148.0` app-server returned these public picker
|
||||
rows:
|
||||
|
||||
| Model id | Input modalities | Reasoning efforts |
|
||||
| --------------- | ---------------- | ------------------------------- |
|
||||
| `gpt-5.5` | text, image | low, medium, high, xhigh |
|
||||
| `gpt-5.6` | text, image | low, medium, high, xhigh, ultra |
|
||||
| `gpt-5.6-luna` | text, image | low, medium, high, xhigh, ultra |
|
||||
| `gpt-5.6-terra` | text, image | low, medium, high, xhigh, ultra |
|
||||
| `gpt-5.6-sol` | text, image | low, medium, high, xhigh, ultra |
|
||||
| `gpt-5.4` | text, image | low, medium, high, xhigh |
|
||||
| `gpt-5.4-mini` | text, image | low, medium, high, xhigh |
|
||||
| `gpt-5.3-codex` | text, image | low, medium, high, xhigh |
|
||||
| `gpt-5.2` | text, image | low, medium, high, xhigh |
|
||||
| Model id | Input modalities | Reasoning efforts |
|
||||
| --------------- | ---------------- | ------------------------------------ |
|
||||
| `gpt-5.6-sol` | text, image | low, medium, high, xhigh, max, ultra |
|
||||
| `gpt-5.6-terra` | text, image | low, medium, high, xhigh, max, ultra |
|
||||
| `gpt-5.6-luna` | text, image | low, medium, high, xhigh, max |
|
||||
| `gpt-5.5` | text, image | low, medium, high, xhigh |
|
||||
| `gpt-5.2` | text, image | low, medium, high, xhigh |
|
||||
|
||||
Available model IDs, input modalities, and reasoning efforts remain
|
||||
account-scoped. Run `/codex models` after starting or upgrading the gateway to
|
||||
|
||||
@@ -89,12 +89,12 @@ channel is the communication surface.
|
||||
|
||||
- The official `@openclaw/codex` plugin installed. Include `codex` in
|
||||
`plugins.allow` if your config uses an allowlist.
|
||||
- Codex app-server `0.147.0` or newer. The plugin still ships and manages the
|
||||
exact `@openai/codex` `0.147.0` artifact, so a `codex` command on `PATH` does
|
||||
not affect normal startup. Explicit custom, remote, and macOS desktop-owned
|
||||
app-servers must report valid SemVer at or above that managed baseline.
|
||||
Newer versions initialize with a warning; acceptance permits an attempt and
|
||||
is not readiness or capability proof.
|
||||
- Codex app-server `0.147.0` or newer. The plugin ships and manages the exact
|
||||
`@openai/codex` `0.148.0` artifact, so a `codex` command on `PATH` does not
|
||||
affect normal startup. Explicit custom, remote, and macOS desktop-owned
|
||||
app-servers must report valid SemVer at or above the supported minimum.
|
||||
Versions newer than the managed artifact initialize with a warning;
|
||||
acceptance permits an attempt and is not readiness or capability proof.
|
||||
- Node.js on the remote Codex app-server host when `remoteWorkspaceRoot` is set
|
||||
and cross-machine workspace attachments must be transferred.
|
||||
- Codex auth through `openclaw models auth login --provider openai`, an
|
||||
|
||||
@@ -23,8 +23,8 @@ working.
|
||||
- `plugins.entries.codex.enabled` is `true`.
|
||||
- `plugins.entries.codex.config.codexPlugins.enabled` is `true`.
|
||||
- Codex app-server reports version `0.147.0` or newer. The official plugin
|
||||
still ships `@openai/codex` `0.147.0`; accepted external versions remain
|
||||
subject to normal startup and capability validation.
|
||||
ships `@openai/codex` `0.148.0`; accepted external versions remain subject to
|
||||
normal startup and capability validation.
|
||||
- The target Codex app-server can see the expected marketplace, plugin, and
|
||||
app inventory.
|
||||
- Migration supports only `openai-curated` plugins that it observed as
|
||||
|
||||
@@ -18,7 +18,7 @@ import type { CodexSessionCatalogControlFactory } from "./src/session-catalog-ty
|
||||
// New runtime identity uses the `openai` provider.
|
||||
const DEFAULT_CODEX_HARNESS_PROVIDER_IDS = new Set(["codex", "openai"]);
|
||||
const SHARED_CODEX_APP_SERVER_CLIENT_DISPOSER = Symbol.for("openclaw.codexAppServerClientDisposer");
|
||||
// Audited against @openai/codex 0.147.0 (rust-v0.147.0). These exact denies
|
||||
// Audited against @openai/codex 0.148.0 (rust-v0.148.0). These exact denies
|
||||
// either have no Codex-native equivalent or are enforced by the harness. Keep
|
||||
// the list positive and conservative: an omitted tool isolates the native surface.
|
||||
const CODEX_TOOL_POLICY_SAFE_DENY_NAMES = [
|
||||
|
||||
@@ -48,7 +48,7 @@ function threadStartResult() {
|
||||
status: { type: "idle" },
|
||||
path: null,
|
||||
cwd: "/tmp/openclaw-agent",
|
||||
cliVersion: "0.147.0",
|
||||
cliVersion: "0.148.0",
|
||||
source: "unknown",
|
||||
agentNickname: null,
|
||||
agentRole: null,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@openai/codex": "0.147.0",
|
||||
"@openai/codex": "0.148.0",
|
||||
"semver": "7.8.5",
|
||||
"smol-toml": "1.7.1",
|
||||
"typebox": "1.3.6",
|
||||
|
||||
@@ -15,7 +15,10 @@ import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { resolveCodexAppServerRuntimeOptions } from "./config.js";
|
||||
import type { CodexModelListResponse } from "./protocol.js";
|
||||
import { runCodexAppServerAttempt } from "./run-attempt.js";
|
||||
import { createCodexTestBindingStore } from "./session-binding.test-helpers.js";
|
||||
import {
|
||||
createCodexTestBindingStore,
|
||||
sessionBindingIdentity,
|
||||
} from "./session-binding.test-helpers.js";
|
||||
import { createIsolatedCodexAppServerClient } from "./shared-client.js";
|
||||
|
||||
const LIVE =
|
||||
@@ -132,14 +135,18 @@ describeLive("Codex app-server approval requester real-binary bridge", () => {
|
||||
params.hostCapabilities = host.capabilities;
|
||||
closeHost = host.close;
|
||||
|
||||
const bindingStore = createCodexTestBindingStore();
|
||||
const result = await runCodexAppServerAttempt(params, {
|
||||
bindingStore: createCodexTestBindingStore(),
|
||||
bindingStore,
|
||||
pluginConfig: { appServer: { homeScope: "user" } },
|
||||
nativeHookRelay: { enabled: true, events: ["pre_tool_use"] },
|
||||
clientFactory: async () => client,
|
||||
});
|
||||
|
||||
expect(result.terminal.kind, JSON.stringify(result.terminal)).toBe("ok");
|
||||
const binding = await bindingStore.read(sessionBindingIdentity(params));
|
||||
expect(binding).toMatchObject({ cwd: workspace, model: modelId });
|
||||
expect(binding?.threadId).toEqual(expect.any(String));
|
||||
expect(await fs.readFile(target, "utf8")).toBe("REAL_BINARY_OWNER_OK\n");
|
||||
expect(
|
||||
serverRequestMethods.filter((method) => method.endsWith("/requestApproval")),
|
||||
|
||||
@@ -184,7 +184,7 @@ async function captureExpectedRuntimeArtifact(
|
||||
before,
|
||||
startOptions: appServer.start,
|
||||
spawnIdentity,
|
||||
runtimeIdentity: { serverVersion: "0.147.0", userAgent: "openclaw/0.147.0 (macOS; test)" },
|
||||
runtimeIdentity: { serverVersion: "0.148.0", userAgent: "openclaw/0.148.0 (macOS; test)" },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ async function answerInitialize(harness: ClientHarness): Promise<void> {
|
||||
timeout: HARNESS_REQUEST_TIMEOUT_MS,
|
||||
});
|
||||
const initialize = JSON.parse(harness.writes[0] ?? "{}") as { id?: number };
|
||||
harness.send({ id: initialize.id, result: { userAgent: "openclaw/0.147.0 (macOS; test)" } });
|
||||
harness.send({ id: initialize.id, result: { userAgent: "openclaw/0.148.0 (macOS; test)" } });
|
||||
}
|
||||
|
||||
async function waitForRequest(
|
||||
|
||||
@@ -331,7 +331,7 @@ describe("CodexAppServerClient", () => {
|
||||
const { harness, initializing, outbound } = startInitialize();
|
||||
harness.send({
|
||||
id: outbound.id,
|
||||
result: { userAgent: "openclaw/0.147.0 (macOS; test)" },
|
||||
result: { userAgent: `openclaw/${CODEX_APP_SERVER_VERSION} (macOS; test)` },
|
||||
});
|
||||
|
||||
await expect(initializing).resolves.toBeUndefined();
|
||||
@@ -436,28 +436,34 @@ describe("CodexAppServerClient", () => {
|
||||
expect(harness.writes).toHaveLength(1);
|
||||
});
|
||||
|
||||
it.each(["0.148.0-alpha.9", "0.148.0-alpha.15", "0.148.0-alpha.23", "0.148.0", "1.0.0"])(
|
||||
"accepts a newer app-server version %s for normal startup validation",
|
||||
async (newerVersion) => {
|
||||
const warn = vi.spyOn(embeddedAgentLog, "warn").mockImplementation(() => undefined);
|
||||
const { harness, initializing, outbound } = startInitialize();
|
||||
harness.send({
|
||||
id: outbound.id,
|
||||
result: { userAgent: `openclaw/${newerVersion} (macOS; test)` },
|
||||
});
|
||||
it.each([
|
||||
["0.148.0-alpha.9", 0],
|
||||
["0.148.0-alpha.15", 0],
|
||||
["0.148.0-alpha.23", 0],
|
||||
["0.148.0", 0],
|
||||
["1.0.0", 1],
|
||||
])("accepts app-server version %s for normal startup validation", async (version, warnings) => {
|
||||
const warn = vi.spyOn(embeddedAgentLog, "warn").mockImplementation(() => undefined);
|
||||
const { harness, initializing, outbound } = startInitialize();
|
||||
harness.send({
|
||||
id: outbound.id,
|
||||
result: { userAgent: `openclaw/${version} (macOS; test)` },
|
||||
});
|
||||
|
||||
await expect(initializing).resolves.toBeUndefined();
|
||||
expect(harness.client.getServerVersion()).toBe(newerVersion);
|
||||
expect(JSON.parse(harness.writes[1] ?? "{}")).toEqual({ method: "initialized" });
|
||||
await expect(initializing).resolves.toBeUndefined();
|
||||
expect(harness.client.getServerVersion()).toBe(version);
|
||||
expect(JSON.parse(harness.writes[1] ?? "{}")).toEqual({ method: "initialized" });
|
||||
expect(warn).toHaveBeenCalledTimes(warnings);
|
||||
if (warnings > 0) {
|
||||
expect(warn).toHaveBeenCalledWith(
|
||||
"codex app-server is newer than OpenClaw's managed runtime; continuing with normal startup validation",
|
||||
{
|
||||
detectedVersion: newerVersion,
|
||||
detectedVersion: version,
|
||||
validatedVersion: CODEX_APP_SERVER_VERSION,
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it.each(["0.147.00", "0.148.0-alpha..9", "0.148.0-alpha.09"])(
|
||||
"blocks malformed app-server version %s during initialize",
|
||||
|
||||
@@ -33,7 +33,7 @@ export function threadStartResult(threadId = "thread-1", cwd = "/tmp/openclaw-co
|
||||
status: { type: "idle" },
|
||||
path: null,
|
||||
cwd,
|
||||
cliVersion: "0.147.0",
|
||||
cliVersion: CODEX_APP_SERVER_VERSION,
|
||||
source: "unknown",
|
||||
agentNickname: null,
|
||||
agentRole: null,
|
||||
|
||||
@@ -156,6 +156,74 @@ describe("Codex Computer Use setup", () => {
|
||||
expect(sharedClientMocks.releaseLeasedSharedCodexAppServerClient).toHaveBeenCalledWith(client);
|
||||
});
|
||||
|
||||
it("releases the install mutation fence before the guarded readiness thread", async () => {
|
||||
const agentDir = "/tmp/openclaw-computer-use-guarded-install-agent";
|
||||
const pluginConfig = {
|
||||
computerUse: { marketplaceName: "desktop-tools", liveTestTimeoutMs: 150 },
|
||||
};
|
||||
const startOptions = resolveCodexAppServerRuntimeOptions({
|
||||
pluginConfig,
|
||||
managedCommandOrder: "desktop-first",
|
||||
}).start;
|
||||
const fenceKey = resolveCodexNativeConfigFenceKey({ startOptions, agentDir });
|
||||
expect(fenceKey).toBeTypeOf("string");
|
||||
|
||||
const harness = createClientHarness();
|
||||
harness.client.setThreadSessionRequestGuard((options) =>
|
||||
acquireCodexNativeConfigFence(fenceKey as string, options),
|
||||
);
|
||||
sharedClientMocks.getLeasedSharedCodexAppServerClient.mockResolvedValueOnce(harness.client);
|
||||
const fixture = createComputerUseRequest({ installed: false });
|
||||
let cursor = 0;
|
||||
const readFrame = async (method: string) => {
|
||||
await vi.waitFor(() => expect(harness.writes.length).toBeGreaterThan(cursor), {
|
||||
timeout: 1_000,
|
||||
});
|
||||
const frame = JSON.parse(harness.writes[cursor++] ?? "{}") as {
|
||||
id: number;
|
||||
method: string;
|
||||
params?: unknown;
|
||||
};
|
||||
expect(frame.method).toBe(method);
|
||||
return frame;
|
||||
};
|
||||
const answerFrame = async (frame: { id: number; method: string; params?: unknown }) => {
|
||||
const result = await fixture(frame.method, frame.params);
|
||||
harness.send({ id: frame.id, result: result ?? null });
|
||||
};
|
||||
const answer = async (method: string) => answerFrame(await readFrame(method));
|
||||
|
||||
const install = installCodexComputerUse({ pluginConfig, agentDir, timeoutMs: 2_000 });
|
||||
void install.catch(() => undefined);
|
||||
await answer("experimentalFeature/enablement/set");
|
||||
await answer("plugin/list");
|
||||
await answer("plugin/read");
|
||||
const mutation = await readFrame("plugin/install");
|
||||
await expect(
|
||||
acquireCodexNativeConfigFence(fenceKey as string, {
|
||||
timeoutMs: 10,
|
||||
timeoutMessage: "mutation fence held",
|
||||
}),
|
||||
).rejects.toThrow("mutation fence held");
|
||||
await answerFrame(mutation);
|
||||
await answer("config/mcpServer/reload");
|
||||
await answer("plugin/read");
|
||||
await answer("mcpServerStatus/list");
|
||||
await answer("thread/start");
|
||||
await answer("mcpServer/tool/call");
|
||||
await answer("thread/unsubscribe");
|
||||
await answer("thread/archive");
|
||||
|
||||
await expect(install).resolves.toMatchObject({
|
||||
ready: true,
|
||||
liveTest: { status: "passed", attempts: 1 },
|
||||
});
|
||||
expect(sharedClientMocks.releaseLeasedSharedCodexAppServerClient).toHaveBeenCalledWith(
|
||||
harness.client,
|
||||
);
|
||||
harness.client.close();
|
||||
});
|
||||
|
||||
it.each(["abort", "timeout"] as const)(
|
||||
"holds the install fence through process exit after a post-write %s",
|
||||
async (mode) => {
|
||||
|
||||
@@ -153,6 +153,7 @@ type CodexComputerUseInspectionParams = {
|
||||
defaultBundledMarketplacePath?: string;
|
||||
defaultBundledMarketplacePathCandidates?: readonly string[];
|
||||
repairComputerUseMcpChildren?: () => Promise<CodexComputerUseRepairStatus>;
|
||||
releaseNativeConfigFence?: () => void;
|
||||
};
|
||||
|
||||
type MarketplaceRef =
|
||||
@@ -331,6 +332,7 @@ async function inspectCodexComputerUse(
|
||||
try {
|
||||
return await inspectCodexComputerUseWithoutFence({
|
||||
...params,
|
||||
releaseNativeConfigFence: release,
|
||||
...(client
|
||||
? {
|
||||
client,
|
||||
@@ -411,6 +413,7 @@ async function inspectCodexComputerUseWithoutFence(
|
||||
plugin: pluginInspection.plugin,
|
||||
installPlugin: params.installPlugin,
|
||||
repairComputerUseMcpChildren,
|
||||
releaseNativeConfigFence: params.releaseNativeConfigFence,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -470,6 +473,7 @@ async function readComputerUseTools(params: {
|
||||
plugin: CodexPluginDetail;
|
||||
installPlugin: boolean;
|
||||
repairComputerUseMcpChildren?: () => Promise<CodexComputerUseRepairStatus>;
|
||||
releaseNativeConfigFence?: () => void;
|
||||
}): Promise<CodexComputerUseStatus> {
|
||||
let server = await readMcpServerStatus(params.request, params.config.mcpServerName);
|
||||
let tools = Object.keys(server?.tools ?? {}).toSorted();
|
||||
@@ -504,6 +508,8 @@ async function readComputerUseTools(params: {
|
||||
reason: "ready",
|
||||
message: "Computer Use is ready.",
|
||||
});
|
||||
// The readiness thread reacquires this fence before loading native config.
|
||||
params.releaseNativeConfigFence?.();
|
||||
const { liveTest, repair } = await runCodexComputerUseLiveTest({
|
||||
request: params.request,
|
||||
config: params.config,
|
||||
|
||||
@@ -205,6 +205,7 @@ describe("CodexAppServerEventProjector terminal errors", () => {
|
||||
{ codexErrorInfo: "serverOverloaded", expected: true },
|
||||
{ codexErrorInfo: "usageLimitExceeded", expected: false },
|
||||
{ codexErrorInfo: "unauthorized", expected: false },
|
||||
{ codexErrorInfo: "misalignmentPolicyViolation", expected: false },
|
||||
{ codexErrorInfo: "other", expected: false },
|
||||
])(
|
||||
"projects $codexErrorInfo terminal error recovery eligibility as $expected",
|
||||
|
||||
@@ -149,7 +149,7 @@ describe("listCodexAppServerModels", () => {
|
||||
const initialize = JSON.parse(harness.writes[0] ?? "{}") as { id?: number };
|
||||
harness.send({
|
||||
id: initialize.id,
|
||||
result: { userAgent: "openclaw/0.147.0 (macOS; test)" },
|
||||
result: { userAgent: "openclaw/0.148.0 (macOS; test)" },
|
||||
});
|
||||
await vi.waitFor(() => expect(harness.writes.length).toBeGreaterThanOrEqual(3));
|
||||
const list = JSON.parse(harness.writes[2] ?? "{}") as { id?: number; method?: string };
|
||||
@@ -170,7 +170,7 @@ describe("listCodexAppServerModels", () => {
|
||||
const initialize = JSON.parse(harness.writes[0] ?? "{}") as { id?: number };
|
||||
harness.send({
|
||||
id: initialize.id,
|
||||
result: { userAgent: "openclaw/0.147.0 (macOS; test)" },
|
||||
result: { userAgent: "openclaw/0.148.0 (macOS; test)" },
|
||||
});
|
||||
await vi.waitFor(() => expect(harness.writes.length).toBeGreaterThanOrEqual(3));
|
||||
const list = JSON.parse(harness.writes[2] ?? "{}") as { id?: number; method?: string };
|
||||
@@ -184,7 +184,13 @@ describe("listCodexAppServerModels", () => {
|
||||
id: "gpt-5.4",
|
||||
model: "gpt-5.4",
|
||||
upgrade: null,
|
||||
upgradeInfo: null,
|
||||
upgradeInfo: {
|
||||
model: "gpt-5.6",
|
||||
upgradeCopy: "Try GPT-5.6",
|
||||
modelLink: null,
|
||||
migrationMarkdown: null,
|
||||
retirementAt: 1_800_000_000,
|
||||
},
|
||||
availabilityNux: null,
|
||||
displayName: "gpt-5.4",
|
||||
description: "GPT-5.4",
|
||||
@@ -196,6 +202,7 @@ describe("listCodexAppServerModels", () => {
|
||||
],
|
||||
defaultReasoningEffort: "medium",
|
||||
supportsPersonality: false,
|
||||
multiAgentVersion: "v2",
|
||||
additionalSpeedTiers: [],
|
||||
isDefault: true,
|
||||
},
|
||||
@@ -232,7 +239,7 @@ describe("listCodexAppServerModels", () => {
|
||||
const initialize = JSON.parse(harness.writes[0] ?? "{}") as { id?: number };
|
||||
harness.send({
|
||||
id: initialize.id,
|
||||
result: { userAgent: "openclaw/0.147.0 (macOS; test)" },
|
||||
result: { userAgent: "openclaw/0.148.0 (macOS; test)" },
|
||||
});
|
||||
await vi.waitFor(() => expect(harness.writes.length).toBeGreaterThanOrEqual(3));
|
||||
const firstList = JSON.parse(harness.writes[2] ?? "{}") as {
|
||||
@@ -312,7 +319,7 @@ describe("listCodexAppServerModels", () => {
|
||||
const initialize = JSON.parse(harness.writes[0] ?? "{}") as { id?: number };
|
||||
harness.send({
|
||||
id: initialize.id,
|
||||
result: { userAgent: "openclaw/0.147.0 (macOS; test)" },
|
||||
result: { userAgent: "openclaw/0.148.0 (macOS; test)" },
|
||||
});
|
||||
await vi.waitFor(() => expect(harness.writes.length).toBeGreaterThanOrEqual(3));
|
||||
const firstList = JSON.parse(harness.writes[2] ?? "{}") as { id?: number };
|
||||
|
||||
@@ -33,7 +33,7 @@ describe("Codex plugin metadata cache", () => {
|
||||
expect(request).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("coalesces installed plugins through the exact Codex 0.146 endpoint", async () => {
|
||||
it("coalesces installed plugins through the canonical endpoint", async () => {
|
||||
const cache = new CodexPluginMetadataCache();
|
||||
let release: ((response: v2.PluginInstalledResponse) => void) | undefined;
|
||||
const request = vi.fn(
|
||||
|
||||
@@ -235,6 +235,7 @@ export type CodexConfigBatchWriteParams = {
|
||||
};
|
||||
|
||||
type CodexConfigLayerSource =
|
||||
| { type: "packagedDefaults"; file: string }
|
||||
| { type: "mdm"; domain: string; key: string }
|
||||
| { type: "system"; file: string }
|
||||
| { type: "enterpriseManaged"; id: string; name: string }
|
||||
|
||||
+101
@@ -299,6 +299,7 @@
|
||||
"usageLimitExceeded",
|
||||
"serverOverloaded",
|
||||
"cyberPolicy",
|
||||
"misalignmentPolicyViolation",
|
||||
"internalServerError",
|
||||
"unauthorized",
|
||||
"badRequest",
|
||||
@@ -623,6 +624,37 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ImageGenerationFailure": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"limitId": {
|
||||
"type": "string"
|
||||
},
|
||||
"resetsAt": {
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"usageLimitExceeded"
|
||||
],
|
||||
"title": "UsageLimitExceededImageGenerationFailureType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"limitId",
|
||||
"type"
|
||||
],
|
||||
"title": "UsageLimitExceededImageGenerationFailure",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"InputModality": {
|
||||
"description": "Canonical user-input modality tags advertised by a model.",
|
||||
"oneOf": [
|
||||
@@ -853,6 +885,17 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"multiAgentVersion": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MultiAgentVersion"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Multi-agent runtime declared by this model, when available."
|
||||
},
|
||||
"serviceTiers": {
|
||||
"default": [],
|
||||
"items": {
|
||||
@@ -946,6 +989,14 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"retirementAt": {
|
||||
"description": "Informational Unix timestamp for this upgrade's scheduled retirement, if known.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"upgradeCopy": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -983,6 +1034,15 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"MultiAgentVersion": {
|
||||
"description": "Multi-agent runtime supported by a model.",
|
||||
"enum": [
|
||||
"disabled",
|
||||
"v1",
|
||||
"v2"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"NetworkAccess": {
|
||||
"enum": [
|
||||
"restricted",
|
||||
@@ -2236,6 +2296,17 @@
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"failure": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ImageGenerationFailure"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -2358,6 +2429,18 @@
|
||||
"ThreadSection": {
|
||||
"description": "An independently persisted, user-visible thread section.",
|
||||
"properties": {
|
||||
"appearance": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ThreadSectionAppearance"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null,
|
||||
"description": "Optional appearance synchronized across clients."
|
||||
},
|
||||
"id": {
|
||||
"description": "Opaque UUIDv7 identity that remains stable when the section is renamed.",
|
||||
"type": "string"
|
||||
@@ -2373,6 +2456,24 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadSectionAppearance": {
|
||||
"description": "Extensible visual presentation for a custom thread section.",
|
||||
"properties": {
|
||||
"color": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"icon": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadSource": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
+2
-2
@@ -49,7 +49,7 @@
|
||||
},
|
||||
"itemsBackwardsCursor": {
|
||||
"default": null,
|
||||
"description": "Opaque head cursor for hydrating paginated items backwards.\n\nPass this as `cursor` to `thread/items/list` with `sortDirection: \"desc\"`. The first page includes the cursor's head item.",
|
||||
"description": "Opaque cursor for hydrating paginated items backwards.\n\nPass this as `cursor` to `thread/items/list` with `sortDirection: \"desc\"`. The first page includes the item identified by the cursor.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
@@ -107,7 +107,7 @@
|
||||
},
|
||||
"turnsBackwardsCursor": {
|
||||
"default": null,
|
||||
"description": "Opaque head cursor for hydrating paginated turns backwards.\n\nPass this as `cursor` to `thread/turns/list` with `sortDirection: \"desc\"`. The first page includes the cursor's head turn.",
|
||||
"description": "Opaque cursor for hydrating paginated turns backwards.\n\nPass this as `cursor` to `thread/turns/list` with `sortDirection: \"desc\"`. The first page includes the turn identified by the cursor.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
|
||||
@@ -78,7 +78,7 @@ function threadStartResult(threadId = "thread-1", serviceTier: string | null = n
|
||||
status: { type: "idle" },
|
||||
path: null,
|
||||
cwd: tempDir,
|
||||
cliVersion: "0.147.0",
|
||||
cliVersion: "0.148.0",
|
||||
source: "unknown",
|
||||
agentNickname: null,
|
||||
agentRole: null,
|
||||
|
||||
@@ -508,7 +508,7 @@ describe("shared Codex app-server client", () => {
|
||||
expect(pluginLocal.process.stdin.destroyed).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps a newer desktop app-server instead of falling back by version", async () => {
|
||||
it("keeps a supported desktop prerelease instead of falling back by version", async () => {
|
||||
const desktop = createClientHarness();
|
||||
const startSpy = vi.spyOn(CodexAppServerClient, "start").mockReturnValueOnce(desktop.client);
|
||||
const startOptions = configureManagedDesktopFallback();
|
||||
@@ -525,13 +525,7 @@ describe("shared Codex app-server client", () => {
|
||||
managedFallbackCommandPaths: ["/cache/openclaw/codex"],
|
||||
});
|
||||
expect(desktop.process.stdin.destroyed).toBe(false);
|
||||
expect(mocks.embeddedAgentLog.warn).toHaveBeenCalledWith(
|
||||
"codex app-server is newer than OpenClaw's managed runtime; continuing with normal startup validation",
|
||||
{
|
||||
detectedVersion: "0.148.0-alpha.23",
|
||||
validatedVersion: CODEX_APP_SERVER_VERSION,
|
||||
},
|
||||
);
|
||||
expect(mocks.embeddedAgentLog.warn).not.toHaveBeenCalled();
|
||||
|
||||
await clearSharedCodexAppServerClientAndWait({ exitTimeoutMs: 25, forceKillDelayMs: 5 });
|
||||
expect(desktop.process.stdin.destroyed).toBe(true);
|
||||
|
||||
@@ -283,7 +283,7 @@ function threadResult(threadId: string) {
|
||||
status: { type: "idle" },
|
||||
path: null,
|
||||
cwd: "/tmp/workspace",
|
||||
cliVersion: "0.147.0",
|
||||
cliVersion: "0.148.0",
|
||||
source: "unknown",
|
||||
agentNickname: null,
|
||||
agentRole: null,
|
||||
|
||||
@@ -1285,7 +1285,14 @@ describe("Codex app-server thread lifecycle bindings", () => {
|
||||
const request = vi.fn(async (method: string, _requestParams?: unknown) => {
|
||||
if (method === "config/read") {
|
||||
return {
|
||||
layers: [],
|
||||
layers: [
|
||||
{
|
||||
name: {
|
||||
type: "packagedDefaults",
|
||||
file: "/managed/codex/defaults.toml",
|
||||
},
|
||||
},
|
||||
],
|
||||
config: {
|
||||
mcp_servers: {
|
||||
"arbitrary.server": { command: "ignored" },
|
||||
|
||||
@@ -77,7 +77,7 @@ export function threadStartResult(threadId = "thread-1"): Record<string, unknown
|
||||
status: { type: "idle" },
|
||||
path: null,
|
||||
cwd: "/tmp",
|
||||
cliVersion: "0.147.0",
|
||||
cliVersion: "0.148.0",
|
||||
source: "unknown",
|
||||
agentNickname: null,
|
||||
agentRole: null,
|
||||
|
||||
@@ -882,7 +882,7 @@ function threadStartResult(threadId = "thread-1") {
|
||||
status: { type: "idle" },
|
||||
path: null,
|
||||
cwd: tempDir,
|
||||
cliVersion: "0.147.0",
|
||||
cliVersion: "0.148.0",
|
||||
source: "unknown",
|
||||
agentNickname: null,
|
||||
agentRole: null,
|
||||
|
||||
@@ -70,7 +70,7 @@ const CODEX_DELEGATION_DISABLED_THREAD_CONFIG: JsonObject = {
|
||||
"features.multi_agent_v2": false,
|
||||
};
|
||||
|
||||
// Exact Codex 0.147 registry features that can expose a model-visible tool or
|
||||
// Exact Codex 0.148 registry features that can expose a model-visible tool or
|
||||
// host capability. One list owns both the thread deny patch and requirement pin rejection.
|
||||
const CODEX_RING_ZERO_RESTRICTED_FEATURES = new Set([
|
||||
"apps",
|
||||
@@ -141,6 +141,7 @@ const CODEX_RING_ZERO_RESTRICTED_FEATURE_ALIASES = new Map<string, string>([
|
||||
]);
|
||||
|
||||
const CODEX_RING_ZERO_OVERRIDABLE_LAYER_TYPES = new Set([
|
||||
"packagedDefaults",
|
||||
"mdm",
|
||||
"system",
|
||||
"enterpriseManaged",
|
||||
|
||||
@@ -55,7 +55,10 @@ describe("Codex app-server websocket transport", () => {
|
||||
const message = JSON.parse(rawDataToText(data)) as { id?: number; method?: string };
|
||||
if (message.method === "initialize") {
|
||||
socket.send(
|
||||
JSON.stringify({ id: message.id, result: { userAgent: "openclaw/0.147.0" } }),
|
||||
JSON.stringify({
|
||||
id: message.id,
|
||||
result: { userAgent: `openclaw/${CODEX_APP_SERVER_VERSION}` },
|
||||
}),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ function forkResponse(threadId = "thread-forked") {
|
||||
thread: {
|
||||
id: threadId,
|
||||
sessionId: "session-forked",
|
||||
cliVersion: "0.147.0",
|
||||
cliVersion: "0.148.0",
|
||||
createdAt: 1715299200,
|
||||
updatedAt: 1715299200,
|
||||
cwd: "/tmp",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Version and package pins for the managed Codex app-server runtime.
|
||||
*/
|
||||
/** Exact Codex app-server version shipped by the OpenClaw Codex bridge. */
|
||||
export const CODEX_APP_SERVER_VERSION = "0.147.0";
|
||||
export const CODEX_APP_SERVER_VERSION = "0.148.0";
|
||||
/** Inclusive runtime compatibility floor for external app-server binaries. */
|
||||
export const MIN_SUPPORTED_CODEX_APP_SERVER_VERSION = "0.147.0";
|
||||
/** npm package name for the managed Codex app-server binary. */
|
||||
|
||||
@@ -368,7 +368,7 @@ function conversationThreadStartResult(threadId: string) {
|
||||
status: { type: "idle" },
|
||||
path: null,
|
||||
cwd: tempDir,
|
||||
cliVersion: "0.147.0",
|
||||
cliVersion: "0.148.0",
|
||||
source: "unknown",
|
||||
agentNickname: null,
|
||||
agentRole: null,
|
||||
|
||||
@@ -48,7 +48,7 @@ function threadStartResult() {
|
||||
status: { type: "idle" },
|
||||
path: null,
|
||||
cwd: "/tmp/openclaw-agent",
|
||||
cliVersion: "0.147.0",
|
||||
cliVersion: "0.148.0",
|
||||
source: "unknown",
|
||||
agentNickname: null,
|
||||
agentRole: null,
|
||||
|
||||
@@ -91,7 +91,7 @@ function classifyOpenAiFailoverCode(code: string | undefined) {
|
||||
const OPENAI_MODELS_ENDPOINT = "https://api.openai.com/v1/models";
|
||||
// Keep synchronized with extensions/codex's exact @openai/codex dependency;
|
||||
// the provider contract test fails when that managed-runtime pin changes.
|
||||
const OPENAI_CODEX_CLIENT_VERSION = "0.147.0";
|
||||
const OPENAI_CODEX_CLIENT_VERSION = "0.148.0";
|
||||
const OPENAI_CODEX_MODELS_ENDPOINT = `${OPENAI_CODEX_RESPONSES_BASE_URL}/models?client_version=${OPENAI_CODEX_CLIENT_VERSION}`;
|
||||
const OPENAI_MODELS_CACHE_TTL_MS = 60_000;
|
||||
const OPENAI_CODEX_MODELS_CACHE_TTL_MS = 60_000;
|
||||
|
||||
Generated
+31
-31
@@ -5,7 +5,7 @@ settings:
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
overrides:
|
||||
'@agentclientprotocol/codex-acp@1.1.7>@openai/codex': 0.147.0
|
||||
'@agentclientprotocol/codex-acp@1.1.7>@openai/codex': 0.148.0
|
||||
'@anthropic-ai/sdk': 0.115.0
|
||||
'@opentelemetry/core': 2.10.0
|
||||
'@opentelemetry/propagator-jaeger': 2.10.0
|
||||
@@ -639,8 +639,8 @@ importers:
|
||||
extensions/codex:
|
||||
dependencies:
|
||||
'@openai/codex':
|
||||
specifier: 0.147.0
|
||||
version: 0.147.0
|
||||
specifier: 0.148.0
|
||||
version: 0.148.0
|
||||
semver:
|
||||
specifier: 7.8.5
|
||||
version: 7.8.5
|
||||
@@ -3948,43 +3948,43 @@ packages:
|
||||
resolution: {integrity: sha512-3zcN5Q3yEmeyxXBzqB6fXPQFzYa2ROsGFSr69W0ArXIAGJqxl/aFECOVPD2kbkYPm0U/EHxFKgclK3UA9WQg5A==}
|
||||
engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0}
|
||||
|
||||
'@openai/codex@0.147.0':
|
||||
resolution: {integrity: sha512-EQLEXecAG2ptxI7UpBMo2TR/ga5596/c/OsYF/0LoUDh5JANZ7IoGqlzBEWbuEVQ76JePIbtTW/ihCkp1a7Z3w==}
|
||||
'@openai/codex@0.148.0':
|
||||
resolution: {integrity: sha512-bh5kH9+BMrFaHGmLeoSansPdfRksvr4UXzjQInns/KRO7r8VJ+6AAW+SqUsE8XcG3+OW/mI4EEy8Gpo9UDXGvQ==}
|
||||
engines: {node: '>=16'}
|
||||
hasBin: true
|
||||
|
||||
'@openai/codex@0.147.0-darwin-arm64':
|
||||
resolution: {integrity: sha512-BEUVkiOW7kLcRyrMLfAr/h9wF8sRVJyZDy6OHtVn6QGDXiv3BvAZVTY1Pu9xF7KdIdkYXbp4uayN0aDQQaAUJw==}
|
||||
'@openai/codex@0.148.0-darwin-arm64':
|
||||
resolution: {integrity: sha512-xgBPFiF1fHUlRS7HE6wGB56LjBJh16kGD7b4TTbwdVBZNB4QDkTok+vdkAGrfpVkfKcwGNhPSKDgCw+KMZOVug==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@openai/codex@0.147.0-darwin-x64':
|
||||
resolution: {integrity: sha512-Tb8McE5SvJIH0Vs5R6sq7u+quiC931yan2KOOl6km1OdZ82+Wi7eF5XrSFPs5CF7xCgoIK4Vs+byMbT5hN+ZUw==}
|
||||
'@openai/codex@0.148.0-darwin-x64':
|
||||
resolution: {integrity: sha512-qepQolhJutfOp+e9i7L3xsi8aoWeCUiiRq274WMWqRj50rKTrXxsuAgkAwDbqEfT3G5VynhYZuQvDsW37JgdNQ==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@openai/codex@0.147.0-linux-arm64':
|
||||
resolution: {integrity: sha512-SLC1JXw2TYfr/c3HhrJubyyLelq7vTOLWVmiThFA+z0+WgzCPmaseJ/kzDD3Gge/TO7fCnnj7UcPmC0d2c8XAg==}
|
||||
'@openai/codex@0.148.0-linux-arm64':
|
||||
resolution: {integrity: sha512-51DCd+izzk6n4mMh4w2utWj3lTLhSTnCOEJQfRh0LS9nBDkcYZcK3iSKOST6fByRIlLSXuLO33LlYYA1VPot6A==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@openai/codex@0.147.0-linux-x64':
|
||||
resolution: {integrity: sha512-0W9MBxPpWW0cSkNqrTDN2jR7rzzT7oNMhQY5446lT2Lw5cz5yhDTck4Va9rjkQEm+HlFzP/dmEMSZbXfJsINmw==}
|
||||
'@openai/codex@0.148.0-linux-x64':
|
||||
resolution: {integrity: sha512-uDT9s7AfMr9xLuJX3ZLVWHgHkUpCnZ33CZjZEdVQhrYCIErkDHsCW5TG290nNjaKngK0WxGt5uCcxeUHv9MWWA==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@openai/codex@0.147.0-win32-arm64':
|
||||
resolution: {integrity: sha512-e2ZstJ8zT8Rm1nvR7CUVO+Gr3cTChE41+VfOzGhynzDXEoW0wfbjUQbc2bWbh1arG94LMm4y3dqBtUIbSrfeGA==}
|
||||
'@openai/codex@0.148.0-win32-arm64':
|
||||
resolution: {integrity: sha512-a8iOwLzs8UdnlWDHjgK3W/YSBBsUImG8X5XLBjengp3XGJRruhiIsQtUDUOYimCmotKPM4aX7Ub6zjl/KPxMQQ==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@openai/codex@0.147.0-win32-x64':
|
||||
resolution: {integrity: sha512-oT7Ss5fAPf2fiWE9QNURqZcQGAAawSVxmIUdgPzckq4KFZAM+pRz9JbM4Rr498CjtbNgTOjWvDJ+DXvIBSfOPA==}
|
||||
'@openai/codex@0.148.0-win32-x64':
|
||||
resolution: {integrity: sha512-/Jg8eYw0BqTGNUpnrzzWlK2kbu29NWg7t6pnUDEfxqpTUf+mK8r3okXQn60Zjbk9InYZ4d8SwSjrtOa+i5hSPw==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
@@ -9105,7 +9105,7 @@ snapshots:
|
||||
'@agentclientprotocol/codex-acp@1.1.7':
|
||||
dependencies:
|
||||
'@agentclientprotocol/sdk': 1.3.0(zod@4.4.3)
|
||||
'@openai/codex': 0.147.0
|
||||
'@openai/codex': 0.148.0
|
||||
diff: 9.0.0
|
||||
open: 11.0.0
|
||||
vscode-jsonrpc: 9.0.1
|
||||
@@ -10912,31 +10912,31 @@ snapshots:
|
||||
|
||||
'@npmcli/redact@5.0.0': {}
|
||||
|
||||
'@openai/codex@0.147.0':
|
||||
'@openai/codex@0.148.0':
|
||||
optionalDependencies:
|
||||
'@openai/codex-darwin-arm64': '@openai/codex@0.147.0-darwin-arm64'
|
||||
'@openai/codex-darwin-x64': '@openai/codex@0.147.0-darwin-x64'
|
||||
'@openai/codex-linux-arm64': '@openai/codex@0.147.0-linux-arm64'
|
||||
'@openai/codex-linux-x64': '@openai/codex@0.147.0-linux-x64'
|
||||
'@openai/codex-win32-arm64': '@openai/codex@0.147.0-win32-arm64'
|
||||
'@openai/codex-win32-x64': '@openai/codex@0.147.0-win32-x64'
|
||||
'@openai/codex-darwin-arm64': '@openai/codex@0.148.0-darwin-arm64'
|
||||
'@openai/codex-darwin-x64': '@openai/codex@0.148.0-darwin-x64'
|
||||
'@openai/codex-linux-arm64': '@openai/codex@0.148.0-linux-arm64'
|
||||
'@openai/codex-linux-x64': '@openai/codex@0.148.0-linux-x64'
|
||||
'@openai/codex-win32-arm64': '@openai/codex@0.148.0-win32-arm64'
|
||||
'@openai/codex-win32-x64': '@openai/codex@0.148.0-win32-x64'
|
||||
|
||||
'@openai/codex@0.147.0-darwin-arm64':
|
||||
'@openai/codex@0.148.0-darwin-arm64':
|
||||
optional: true
|
||||
|
||||
'@openai/codex@0.147.0-darwin-x64':
|
||||
'@openai/codex@0.148.0-darwin-x64':
|
||||
optional: true
|
||||
|
||||
'@openai/codex@0.147.0-linux-arm64':
|
||||
'@openai/codex@0.148.0-linux-arm64':
|
||||
optional: true
|
||||
|
||||
'@openai/codex@0.147.0-linux-x64':
|
||||
'@openai/codex@0.148.0-linux-x64':
|
||||
optional: true
|
||||
|
||||
'@openai/codex@0.147.0-win32-arm64':
|
||||
'@openai/codex@0.148.0-win32-arm64':
|
||||
optional: true
|
||||
|
||||
'@openai/codex@0.147.0-win32-x64':
|
||||
'@openai/codex@0.148.0-win32-x64':
|
||||
optional: true
|
||||
|
||||
'@openclaw/crabline@0.1.11':
|
||||
|
||||
+1
-1
@@ -127,7 +127,7 @@ verifyDepsBeforeRun: false
|
||||
blockExoticSubdeps: true
|
||||
|
||||
overrides:
|
||||
"@agentclientprotocol/codex-acp@1.1.7>@openai/codex": 0.147.0
|
||||
"@agentclientprotocol/codex-acp@1.1.7>@openai/codex": 0.148.0
|
||||
"@anthropic-ai/sdk": 0.115.0
|
||||
"@opentelemetry/core": 2.10.0
|
||||
"@opentelemetry/propagator-jaeger": 2.10.0
|
||||
|
||||
@@ -456,21 +456,19 @@ const openClawThreadStartResponse: Omit<CodexThreadStartResponse, "thread"> =
|
||||
export {};
|
||||
`;
|
||||
await fs.writeFile(probePath, probe);
|
||||
const probeConfigPath = path.join(sourceRoot, "openclaw-protocol-compatibility.tsconfig.json");
|
||||
await fs.writeFile(
|
||||
probeConfigPath,
|
||||
JSON.stringify({
|
||||
extends: path.resolve("tsconfig.json"),
|
||||
compilerOptions: { rootDir: process.cwd() },
|
||||
files: [probePath],
|
||||
include: [],
|
||||
}),
|
||||
);
|
||||
const result = spawnSync(
|
||||
process.execPath,
|
||||
[
|
||||
"scripts/run-tsgo.mjs",
|
||||
"--ignoreConfig",
|
||||
"--noEmit",
|
||||
"--allowImportingTsExtensions",
|
||||
"--strict",
|
||||
"--skipLibCheck",
|
||||
"--module",
|
||||
"nodenext",
|
||||
"--moduleResolution",
|
||||
"nodenext",
|
||||
probePath,
|
||||
],
|
||||
["scripts/run-tsgo.mjs", "--project", probeConfigPath],
|
||||
{ cwd: process.cwd(), encoding: "utf8" },
|
||||
);
|
||||
if (result.error) {
|
||||
|
||||
Reference in New Issue
Block a user