@openclaw/codex 2026.9.1 → 2026.9.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/dist/api.js +6 -6
- package/dist/{attempt-client-cleanup-DYHcRQAa.js → attempt-client-cleanup-Bp1ZOnk2.js} +76 -32
- package/dist/{attempt-context-DmQUNWwT.js → attempt-context-CSazkWns.js} +6 -6
- package/dist/{bounded-turn-wzJrwKKe.js → bounded-turn-DxGJRYbY.js} +46 -45
- package/dist/{capabilities-dIjNVCYH.js → capabilities-B1mgvpP8.js} +2 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-CLHhEB1Q.js → command-formatters-DSbGMXA0.js} +2 -2
- package/dist/{command-handlers-CTGb2csu.js → command-handlers-DOJvGv6-.js} +146 -74
- package/dist/{compact-_t0HQrUS.js → compact-Y_xBqrHN.js} +83 -48
- package/dist/{config-BhmfC1s6.js → config-CyapYSji.js} +47 -105
- package/dist/config-utils-C57JiJrU.js +69 -0
- package/dist/doctor-contract-api.js +4 -5
- package/dist/{dynamic-tools-BU9tmlYm.js → dynamic-tools-BwpvTxaX.js} +678 -638
- package/dist/{effective-mcp-catalog-DzYBW4h1.js → effective-mcp-catalog-CY9Jn4bA.js} +4 -3
- package/dist/{event-projector-assistant-message-DHRFXKbS.js → event-projector-assistant-message-B9kp6iGC.js} +11 -2
- package/dist/{event-projector-usage-C5mcrGjp.js → event-projector-usage-ZqEVbAEY.js} +30 -13
- package/dist/{harness-DXVZ5II5.js → harness-Czh2Sdoc.js} +36 -13
- package/dist/harness.js +1 -1
- package/dist/{image-payload-sanitizer-CnfoUPCE.js → image-payload-sanitizer-tupAr-2o.js} +29 -15
- package/dist/index.js +68 -84
- package/dist/{isolated-completion-kg9kv4iH.js → isolated-completion-CRh-51AK.js} +9 -21
- package/dist/{managed-binary-4-Vjz5GH.js → managed-binary-DcpnJF9x.js} +105 -73
- package/dist/media-understanding-provider.js +1 -1
- package/dist/{model-catalog-CUM68Hkl.js → model-catalog-DT5vo6qo.js} +5 -5
- package/dist/{models-sYnEc0gd.js → models-CcrgSMQR.js} +4 -4
- package/dist/{native-subagent-monitor-CnH147jH.js → native-subagent-monitor-B3bvQGcg.js} +12 -11
- package/dist/{node-exec-server.runtime-CstNHCmC.js → node-exec-server.runtime-nfbUOtUB.js} +3 -3
- package/dist/{plugin-approval-roundtrip-CNe-Xrjx.js → plugin-approval-roundtrip-aQVdyL5g.js} +1 -1
- package/dist/{plugin-marketplace-discovery-CfFlKqDl.js → plugin-marketplace-discovery-B7gHXJ3d.js} +35 -22
- package/dist/{plugin-metadata-cache-BFrPhb2c.js → plugin-metadata-cache-BwCLTY_U.js} +5 -5
- package/dist/{provider-capabilities-DW5p4k9w.js → provider-capabilities-BpG9Ltc5.js} +2 -2
- package/dist/{rate-limits-CawQJfUS.js → rate-limits-Fx_l4eNa.js} +1 -1
- package/dist/{request-DYAI5FQE.js → request-C8H22rPi.js} +2 -2
- package/dist/{run-attempt-D1hJO4fX.js → run-attempt-BzthFQSM.js} +977 -723
- package/dist/{runtime-artifact-C3jVimFn.js → runtime-artifact-Bh_gf6-t.js} +3 -3
- package/dist/{session-binding-BHuTCRZQ.js → session-binding-4Ki04sW-.js} +94 -282
- package/dist/session-binding-record-CyaXZvTe.js +270 -0
- package/dist/{session-catalog-yyvTWFOw.js → session-catalog-B47uwekb.js} +266 -114
- package/dist/{session-cli-CmFEXMAM.js → session-cli-BjLhpmS1.js} +1 -1
- package/dist/session-history-DWmMqiqW.js +93 -0
- package/dist/session-history-read-LHldwvyh.js +36 -0
- package/dist/session-history-worker-runtime.js +48 -0
- package/dist/{settled-turn-context-D3SNWtUn.js → session-history.worker-zZVcx0ME.js} +30 -31
- package/dist/session-history.worker.js +2 -0
- package/dist/{session-initialization-BeWzjGiR.js → session-initialization-BCFVnLL4.js} +2 -1
- package/dist/{session-permission-policy-DeWVTCMj.js → session-permission-policy-BaueHmSj.js} +1 -1
- package/dist/{session-retirement-BujDjXVF.js → session-retirement-DNdmYdFc.js} +7 -7
- package/dist/{session-upstream-marker-C351-5Qw.js → session-upstream-marker-DReTpGz6.js} +4 -3
- package/dist/settled-turn-context-BOM3Y1pl.js +45 -0
- package/dist/{settled-turn-finalizer-BVJx4yoc.js → settled-turn-finalizer-BI-b1sry.js} +53 -42
- package/dist/{shared-client-DxcfF9KX.js → shared-client-CKhX2kFt.js} +279 -268
- package/dist/{side-question-BTZAII4l.js → side-question-B6DWAw1A.js} +85 -36
- package/dist/{thread-lifecycle-DAcEJ_Om.js → thread-lifecycle-DPK30jad.js} +382 -388
- package/dist/{thread-ownership-zGokd8i1.js → thread-ownership-CbucAmmp.js} +5 -5
- package/dist/thread-policy-CTalhWFy.js +105 -0
- package/dist/{thread-resume-C7pyVKeW.js → thread-resume-BLgqkUc1.js} +7 -7
- package/dist/{transcript-mirror-DTUxFWa_.js → transcript-mirror-_njEB84z.js} +67 -125
- package/dist/transcript-mirror-attestation-Byl34PC-.js +76 -0
- package/dist/{transport-stdio-CyPldczm.js → transport-stdio-CzTngV0j.js} +10 -8
- package/dist/{upstream-session-fork-CYlBIGVt.js → upstream-session-fork-1fwbNKzQ.js} +85 -165
- package/dist/{usage-Bj-rrzkR.js → usage-i9fv5-4m.js} +3 -3
- package/dist/{web-search-provider.runtime-D2FWSK4w.js → web-search-provider.runtime-DKQn67A7.js} +3 -3
- package/package.json +6 -6
- package/dist/binding-connection-E6uDsPlx.js +0 -45
- package/dist/launch-args-RXQwn8zV.js +0 -90
- package/dist/session-history-C5J1AKzG.js +0 -87
- package/dist/thread-policy-g4KbJPzp.js +0 -54
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
-
import { t as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { a as hasCodexAppServerNaturalExit, i as closeCodexAppServerTransportAndWait, n as resolveCodexAppServerSpawnEnv, r as closeCodexAppServerTransport, t as createStdioTransport } from "./transport-stdio-CyPldczm.js";
|
|
2
|
+
import { B as isJsonObject, F as withEphemeralCodexAuthStore, M as resolveCodexAppServerHomeDir, N as resolveCodexAppServerLocalHomeDir, P as resolveCodexAppServerUserHomeDir, V as isRpcResponse, a as resolveCodexAppServerStartOptionsForAgent, i as resolveCodexAppServerRuntimeOptions, o as resolveCodexComputerUseConfig, t as codexAppServerStartOptionsKey } from "./config-CyapYSji.js";
|
|
3
|
+
import { c as resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath, d as resolveMacOSDesktopCodexComputerUseServiceAppCandidates, f as isCodexAppServerProxyLaunch, l as resolveMacOSDesktopCodexAppPathCandidates, n as resolveManagedCodexAppServerStartOptions, o as CODEX_APP_SERVER_VERSION, r as resolveManagedCodexNativeCommand, s as MIN_SUPPORTED_CODEX_APP_SERVER_VERSION, t as isManagedCodexDesktopCommand, u as resolveMacOSDesktopCodexBundledMarketplaceCandidates } from "./managed-binary-DcpnJF9x.js";
|
|
4
|
+
import { a as isCodexAppServerNativeAuthProfile } from "./session-binding-4Ki04sW-.js";
|
|
5
|
+
import { a as hasCodexAppServerNaturalExit, i as closeCodexAppServerTransportAndWait, n as resolveCodexAppServerSpawnEnv, r as closeCodexAppServerTransport, t as createStdioTransport } from "./transport-stdio-CzTngV0j.js";
|
|
7
6
|
import { isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
8
|
+
import { addTimerTimeoutGraceMs, parseStrictNonNegativeInteger, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
9
|
+
import { runExec } from "openclaw/plugin-sdk/process-runtime";
|
|
8
10
|
import fs from "node:fs/promises";
|
|
9
11
|
import path from "node:path";
|
|
10
12
|
import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
|
|
11
|
-
import { addTimerTimeoutGraceMs, parseStrictNonNegativeInteger, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
12
13
|
import { AgentHarnessPreflightError, OPENCLAW_VERSION, embeddedAgentLog, formatErrorMessage, formatToolExecutionErrorMessage, normalizeQuestionTimeoutSeconds, resolveToolExecutionErrorKind } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
13
14
|
import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
|
|
14
15
|
import { createZstdDecompress } from "node:zlib";
|
|
15
16
|
import { root } from "openclaw/plugin-sdk/file-access-runtime";
|
|
16
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
17
17
|
import fsSync, { constants as constants$1, existsSync, watch } from "node:fs";
|
|
18
18
|
import os from "node:os";
|
|
19
19
|
import { isDeepStrictEqual } from "node:util";
|
|
@@ -21,7 +21,6 @@ import { ensureAuthProfileStore, findPersistedAuthProfileCredential, loadAuthPro
|
|
|
21
21
|
import { hasUsableOAuthCredential, resolveAuthProfileOrder, resolveOpenAICodexAuthIdentity } from "openclaw/plugin-sdk/provider-auth";
|
|
22
22
|
import { readSecretFile } from "openclaw/plugin-sdk/secret-file";
|
|
23
23
|
import { assertNoSymlinkParents, withTimeout } from "openclaw/plugin-sdk/security-runtime";
|
|
24
|
-
import { runExec } from "openclaw/plugin-sdk/process-runtime";
|
|
25
24
|
import { EventEmitter } from "node:events";
|
|
26
25
|
import { createInterface } from "node:readline";
|
|
27
26
|
import { coerceErrorMessage, toStringifiedError } from "openclaw/plugin-sdk/error-runtime";
|
|
@@ -33,21 +32,6 @@ import net from "node:net";
|
|
|
33
32
|
import { PassThrough, Writable } from "node:stream";
|
|
34
33
|
import { StringDecoder } from "node:string_decoder";
|
|
35
34
|
import WebSocket from "ws";
|
|
36
|
-
//#region extensions/codex/src/app-server/protocol.ts
|
|
37
|
-
/** Namespace Codex keeps directly model-visible without exposing it to Code Mode guests. */
|
|
38
|
-
const CODEX_OPENCLAW_DIRECT_DYNAMIC_TOOL_NAMESPACE = "openclaw_direct";
|
|
39
|
-
function flattenCodexDynamicToolFunctions(tools) {
|
|
40
|
-
return (tools ?? []).flatMap((tool) => tool.type === "namespace" ? tool.tools : [tool]);
|
|
41
|
-
}
|
|
42
|
-
const CODEX_INTERACTIVE_THREAD_SOURCE_KINDS = ["cli", "vscode"];
|
|
43
|
-
const CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES = ["atlas", "chatgpt"];
|
|
44
|
-
function isJsonObject(value) {
|
|
45
|
-
return isRecord(value);
|
|
46
|
-
}
|
|
47
|
-
function isRpcResponse(message) {
|
|
48
|
-
return "id" in message && !("method" in message);
|
|
49
|
-
}
|
|
50
|
-
//#endregion
|
|
51
35
|
//#region extensions/codex/src/session-catalog-provenance.ts
|
|
52
36
|
const MAX_SESSION_META_BYTES = 1048576;
|
|
53
37
|
const SESSION_META_READ_CHUNK_BYTES = 65536;
|
|
@@ -979,6 +963,7 @@ function resolveCodexAppServerAuthProfileIdForAgent(params) {
|
|
|
979
963
|
}
|
|
980
964
|
function ensureCodexAppServerAuthProfileStore(params) {
|
|
981
965
|
return ensureAuthProfileStore(params.agentDir, {
|
|
966
|
+
profileId: params.authProfileId,
|
|
982
967
|
allowKeychainPrompt: false,
|
|
983
968
|
config: params.config,
|
|
984
969
|
externalCliProviderIds: CODEX_APP_SERVER_EXTERNAL_CLI_PROVIDER_IDS,
|
|
@@ -1306,11 +1291,12 @@ function withoutClearedCodexHomeEnv(clearEnv) {
|
|
|
1306
1291
|
return filtered.length === clearEnv.length ? clearEnv : filtered;
|
|
1307
1292
|
}
|
|
1308
1293
|
async function applyCodexAppServerAuthProfile(params) {
|
|
1294
|
+
params.assertCurrent?.();
|
|
1309
1295
|
if (!params.preparedAuth && params.authProfileId === null) {
|
|
1310
|
-
await assertNativeCodexAccountMatchesRoute(params.client, params.authRequirement);
|
|
1296
|
+
await assertNativeCodexAccountMatchesRoute(params.client, params.authRequirement, params.assertCurrent);
|
|
1311
1297
|
return;
|
|
1312
1298
|
}
|
|
1313
|
-
|
|
1299
|
+
let loginParams = params.preparedAuth?.kind === "profile" ? params.preparedAuth.snapshot.loginParams : params.preparedAuth?.kind === "api-key" ? {
|
|
1314
1300
|
type: "apiKey",
|
|
1315
1301
|
apiKey: params.preparedAuth.apiKey
|
|
1316
1302
|
} : await resolveCodexAppServerAuthProfileLoginParams({
|
|
@@ -1320,18 +1306,16 @@ async function applyCodexAppServerAuthProfile(params) {
|
|
|
1320
1306
|
config: params.config
|
|
1321
1307
|
});
|
|
1322
1308
|
if (params.authRequirement === "subscription" && loginParams?.type !== "chatgptAuthTokens") throw createCodexAppServerAuthError("Codex subscription auth profile could not produce login credentials. Sign in with `openclaw models auth login --provider openai`, select that profile, then retry.");
|
|
1323
|
-
if (!loginParams) {
|
|
1324
|
-
if (params.authRequirement !== "api-key" || params.startOptions?.transport !== "stdio") return;
|
|
1309
|
+
if (!loginParams && params.authRequirement === "api-key" && params.startOptions?.transport === "stdio") {
|
|
1325
1310
|
const env = resolveCodexAppServerSpawnEnv(params.startOptions, process.env);
|
|
1326
|
-
|
|
1311
|
+
loginParams = await resolveCodexAppServerFallbackApiKeyLoginParams({
|
|
1327
1312
|
client: params.client,
|
|
1328
1313
|
env,
|
|
1329
|
-
codexCliAuthEnv: process.env
|
|
1314
|
+
codexCliAuthEnv: process.env,
|
|
1315
|
+
assertCurrent: params.assertCurrent
|
|
1330
1316
|
});
|
|
1331
|
-
if (fallbackLoginParams) await params.client.request("account/login/start", fallbackLoginParams);
|
|
1332
|
-
return;
|
|
1333
1317
|
}
|
|
1334
|
-
await params.client.request("account/login/start", loginParams);
|
|
1318
|
+
if (loginParams) await params.client.request("account/login/start", loginParams, { assertCurrent: params.assertCurrent });
|
|
1335
1319
|
}
|
|
1336
1320
|
/**
|
|
1337
1321
|
* Native-home connections are verified, never logged into. Both directions of the
|
|
@@ -1340,9 +1324,9 @@ async function applyCodexAppServerAuthProfile(params) {
|
|
|
1340
1324
|
* ChatGPT plan. An absent account is left alone because the native home may serve a
|
|
1341
1325
|
* custom model provider that reports no OpenAI account at all.
|
|
1342
1326
|
*/
|
|
1343
|
-
async function assertNativeCodexAccountMatchesRoute(client, authRequirement) {
|
|
1327
|
+
async function assertNativeCodexAccountMatchesRoute(client, authRequirement, assertCurrent) {
|
|
1344
1328
|
if (!authRequirement) return;
|
|
1345
|
-
const response = await client.request("account/read", { refreshToken: false });
|
|
1329
|
+
const response = await client.request("account/read", { refreshToken: false }, { assertCurrent });
|
|
1346
1330
|
const accountType = isJsonObject(response.account) ? response.account.type : void 0;
|
|
1347
1331
|
if (authRequirement === "subscription") {
|
|
1348
1332
|
if (accountType !== "chatgpt") throw createCodexAppServerAuthError("Codex subscription route requires ChatGPT auth in the native Codex home. Run `codex login` for that home, or use appServer.homeScope=\"agent\" with an OpenClaw OAuth profile, then retry.");
|
|
@@ -1430,7 +1414,7 @@ async function resolveCodexAppServerAuthProfileLoginParamsInternal(params) {
|
|
|
1430
1414
|
async function resolveCodexAppServerFallbackApiKeyLoginParams(params) {
|
|
1431
1415
|
const apiKey = readFirstNonEmptyEnv(params.env, CODEX_APP_SERVER_API_KEY_ENV_VARS) ?? await readCodexCliAuthFileApiKey(params.codexCliAuthEnv);
|
|
1432
1416
|
if (!apiKey) return;
|
|
1433
|
-
if ((await params.client.request("account/read", { refreshToken: false })).account) return;
|
|
1417
|
+
if ((await params.client.request("account/read", { refreshToken: false }, { assertCurrent: params.assertCurrent })).account) return;
|
|
1434
1418
|
return {
|
|
1435
1419
|
type: "apiKey",
|
|
1436
1420
|
apiKey
|
|
@@ -1478,7 +1462,10 @@ function resolveCodexCliAuthFileApiKeyCacheKey(env) {
|
|
|
1478
1462
|
async function resolveLoginParamsForCredential(profileId, credential, params) {
|
|
1479
1463
|
if (credential.type === "api_key") {
|
|
1480
1464
|
const apiKey = (await resolveApiKeyForProfile({
|
|
1481
|
-
store: params.preferStoreCredential ? params.store : ensureAuthProfileStore(params.agentDir, {
|
|
1465
|
+
store: params.preferStoreCredential ? params.store : ensureAuthProfileStore(params.agentDir, {
|
|
1466
|
+
allowKeychainPrompt: false,
|
|
1467
|
+
profileId
|
|
1468
|
+
}),
|
|
1482
1469
|
profileId,
|
|
1483
1470
|
agentDir: params.agentDir
|
|
1484
1471
|
}))?.apiKey?.trim();
|
|
@@ -1489,7 +1476,10 @@ async function resolveLoginParamsForCredential(profileId, credential, params) {
|
|
|
1489
1476
|
}
|
|
1490
1477
|
if (credential.type === "token") {
|
|
1491
1478
|
const accessToken = (await resolveApiKeyForProfile({
|
|
1492
|
-
store: params.preferStoreCredential ? params.store : ensureAuthProfileStore(params.agentDir, {
|
|
1479
|
+
store: params.preferStoreCredential ? params.store : ensureAuthProfileStore(params.agentDir, {
|
|
1480
|
+
allowKeychainPrompt: false,
|
|
1481
|
+
profileId
|
|
1482
|
+
}),
|
|
1493
1483
|
profileId,
|
|
1494
1484
|
agentDir: params.agentDir
|
|
1495
1485
|
}))?.apiKey?.trim();
|
|
@@ -1548,7 +1538,7 @@ async function resolveOAuthCredentialForCodexAppServer(profileId, credential, pa
|
|
|
1548
1538
|
agentDir: ownerAgentDir,
|
|
1549
1539
|
forceRefresh: params.forceRefresh && Boolean(persistedOAuthCredential)
|
|
1550
1540
|
});
|
|
1551
|
-
const refreshed = useScopedCredential ? void 0 : loadAuthProfileStoreForSecretsRuntime(ownerAgentDir).profiles[profileId];
|
|
1541
|
+
const refreshed = useScopedCredential ? void 0 : loadAuthProfileStoreForSecretsRuntime(ownerAgentDir, { profileId }).profiles[profileId];
|
|
1552
1542
|
const refreshedOAuthCredential = refreshed?.type === "oauth" && isCodexAppServerAuthProvider(refreshed.provider) ? refreshed : void 0;
|
|
1553
1543
|
if (refreshedOAuthCredential && isDeepStrictEqual(params.store.profiles[profileId], credential)) params.store.profiles[profileId] = refreshedOAuthCredential;
|
|
1554
1544
|
const storedCredential = store.profiles[profileId];
|
|
@@ -2555,8 +2545,9 @@ function hasPendingDynamicToolTerminalDiagnostic(params) {
|
|
|
2555
2545
|
/** Resolves per-tool timeout, applying media/message defaults and hard caps. */
|
|
2556
2546
|
function resolveDynamicToolCallTimeoutMs(params) {
|
|
2557
2547
|
const args = isJsonObject(params.call.arguments) ? params.call.arguments : void 0;
|
|
2558
|
-
if (params.call.tool === "ask_user" || params.call.tool === "secrets" && args?.action === "request") try {
|
|
2559
|
-
|
|
2548
|
+
if (params.call.tool === "openclaw" || params.call.tool === "ask_user" || params.call.tool === "secrets" && args?.action === "request") try {
|
|
2549
|
+
const timeoutSeconds = params.call.tool === "openclaw" ? void 0 : args?.timeoutSeconds;
|
|
2550
|
+
return normalizeQuestionTimeoutSeconds(timeoutSeconds) * 1e3 + CODEX_DYNAMIC_TOOL_TIMEOUT_SECONDS_GRACE_MS;
|
|
2560
2551
|
} catch {
|
|
2561
2552
|
return CODEX_DYNAMIC_TOOL_TIMEOUT_MS;
|
|
2562
2553
|
}
|
|
@@ -2763,6 +2754,18 @@ var definitions = {
|
|
|
2763
2754
|
],
|
|
2764
2755
|
"type": "string"
|
|
2765
2756
|
}] },
|
|
2757
|
+
"AsyncUserInputQuestion": {
|
|
2758
|
+
"additionalProperties": false,
|
|
2759
|
+
"properties": {
|
|
2760
|
+
"options": {
|
|
2761
|
+
"items": { "type": "string" },
|
|
2762
|
+
"type": ["array", "null"]
|
|
2763
|
+
},
|
|
2764
|
+
"title": { "type": "string" }
|
|
2765
|
+
},
|
|
2766
|
+
"required": ["title"],
|
|
2767
|
+
"type": "object"
|
|
2768
|
+
},
|
|
2766
2769
|
"ByteRange": {
|
|
2767
2770
|
"properties": {
|
|
2768
2771
|
"end": {
|
|
@@ -3716,6 +3719,10 @@ var definitions = {
|
|
|
3716
3719
|
"description": "Identifier for this thread. Codex-generated thread IDs are UUIDv7.",
|
|
3717
3720
|
"type": "string"
|
|
3718
3721
|
},
|
|
3722
|
+
"model": {
|
|
3723
|
+
"description": "Current configured model when loaded, otherwise the latest persisted model. Null when unavailable. This is not per-turn execution telemetry.",
|
|
3724
|
+
"type": ["string", "null"]
|
|
3725
|
+
},
|
|
3719
3726
|
"modelProvider": {
|
|
3720
3727
|
"description": "Model provider used for this thread (for example, 'openai').",
|
|
3721
3728
|
"type": "string"
|
|
@@ -3740,6 +3747,10 @@ var definitions = {
|
|
|
3740
3747
|
"description": "Canonical project assignment owned by app-server, if any.",
|
|
3741
3748
|
"type": ["string", "null"]
|
|
3742
3749
|
},
|
|
3750
|
+
"reasoningEffort": {
|
|
3751
|
+
"anyOf": [{ "$ref": "#/definitions/ReasoningEffort" }, { "type": "null" }],
|
|
3752
|
+
"description": "Current configured reasoning effort when loaded, otherwise the latest persisted effort. Null when unset or unavailable. This is not per-turn execution telemetry."
|
|
3753
|
+
},
|
|
3743
3754
|
"recencyAt": {
|
|
3744
3755
|
"description": "Unix timestamp (in seconds) used for thread recency ordering.",
|
|
3745
3756
|
"format": "int64",
|
|
@@ -3872,6 +3883,11 @@ var definitions = {
|
|
|
3872
3883
|
"anyOf": [{ "$ref": "#/definitions/MessagePhase" }, { "type": "null" }],
|
|
3873
3884
|
"default": null
|
|
3874
3885
|
},
|
|
3886
|
+
"questions": {
|
|
3887
|
+
"default": null,
|
|
3888
|
+
"items": { "$ref": "#/definitions/AsyncUserInputQuestion" },
|
|
3889
|
+
"type": ["array", "null"]
|
|
3890
|
+
},
|
|
3875
3891
|
"text": { "type": "string" },
|
|
3876
3892
|
"type": {
|
|
3877
3893
|
"enum": ["agentMessage"],
|
|
@@ -5074,6 +5090,22 @@ function assertCodexTurnStartResponse(value) {
|
|
|
5074
5090
|
const normalized = normalizeWithDefaults(turnStartResponseSchema, normalizeTurnStartResponse(value));
|
|
5075
5091
|
return assertCodexShape(validateTurnStartResponse, normalized, "turn/start response");
|
|
5076
5092
|
}
|
|
5093
|
+
/** Only the current text prompt may be echoed; capabilities and historical items are not passive. */
|
|
5094
|
+
function assertCodexPassiveTurnItems(items, prompt, taskLabel) {
|
|
5095
|
+
let promptEchoSeen = false;
|
|
5096
|
+
for (const item of items) {
|
|
5097
|
+
if (item.type === "agentMessage" || item.type === "reasoning") continue;
|
|
5098
|
+
if (item.type === "userMessage" && !promptEchoSeen) {
|
|
5099
|
+
const content = Array.isArray(item.content) ? item.content : [];
|
|
5100
|
+
const input = content[0];
|
|
5101
|
+
if (content.length === 1 && isJsonObject(input) && input.type === "text" && input.text === prompt) {
|
|
5102
|
+
promptEchoSeen = true;
|
|
5103
|
+
continue;
|
|
5104
|
+
}
|
|
5105
|
+
}
|
|
5106
|
+
throw new Error(`Codex ${taskLabel} returned unexpected native item: ${item.type}`);
|
|
5107
|
+
}
|
|
5108
|
+
}
|
|
5077
5109
|
/** Reads Codex dynamic-tool call params, returning undefined for invalid payloads. */
|
|
5078
5110
|
function readCodexDynamicToolCallParams(value) {
|
|
5079
5111
|
return readCodexShape(validateDynamicToolCallParams, normalizeWithDefaults(dynamicToolCallParamsSchema, value));
|
|
@@ -5176,6 +5208,9 @@ var CodexAppServerRpcError = class extends Error {
|
|
|
5176
5208
|
this.method = method;
|
|
5177
5209
|
}
|
|
5178
5210
|
};
|
|
5211
|
+
function isCodexThreadReadMissingError(error, threadId) {
|
|
5212
|
+
return error instanceof CodexAppServerRpcError && error.method === "thread/read" && error.code === -32600 && error.message === `thread not loaded: ${threadId}`;
|
|
5213
|
+
}
|
|
5179
5214
|
function formatCodexAppServerRpcErrorMessage(error, method) {
|
|
5180
5215
|
const message = error.message || `${method} failed`;
|
|
5181
5216
|
const detail = readCodexAppServerRpcReloginDetail(error.data);
|
|
@@ -5972,7 +6007,11 @@ var CodexAppServerClient = class CodexAppServerClient {
|
|
|
5972
6007
|
pending.reject(error);
|
|
5973
6008
|
}
|
|
5974
6009
|
this.pending.clear();
|
|
5975
|
-
for (const handler of this.closeHandlers)
|
|
6010
|
+
for (const handler of this.closeHandlers) try {
|
|
6011
|
+
handler(this);
|
|
6012
|
+
} catch (closeError) {
|
|
6013
|
+
embeddedAgentLog.warn("codex app-server close handler failed", { error: closeError });
|
|
6014
|
+
}
|
|
5976
6015
|
}
|
|
5977
6016
|
};
|
|
5978
6017
|
function defaultServerRequestResponse(request) {
|
|
@@ -6018,7 +6057,7 @@ function assertSupportedCodexAppServerVersion(response) {
|
|
|
6018
6057
|
if (!detectedVersion) throw new CodexAppServerVersionError(detectedVersion);
|
|
6019
6058
|
const detected = parse(detectedVersion);
|
|
6020
6059
|
if (!detected || detected.compare("0.149.0") < 0) throw new CodexAppServerVersionError(detectedVersion);
|
|
6021
|
-
if (detected.compare("0.
|
|
6060
|
+
if (detected.compare("0.153.4") > 0) embeddedAgentLog.warn("codex app-server is newer than OpenClaw's managed runtime; continuing with normal startup validation", {
|
|
6022
6061
|
detectedVersion,
|
|
6023
6062
|
validatedVersion: CODEX_APP_SERVER_VERSION
|
|
6024
6063
|
});
|
|
@@ -6597,7 +6636,10 @@ var shared_client_exports = /* @__PURE__ */ __exportAll({
|
|
|
6597
6636
|
const CODEX_APP_SERVER_INITIALIZE_TIMEOUT_MESSAGE = "codex app-server initialize timed out";
|
|
6598
6637
|
const SHARED_CODEX_APP_SERVER_CLIENT_STATE = Symbol.for("openclaw.codexAppServerClientState");
|
|
6599
6638
|
const SHARED_CODEX_APP_SERVER_CLIENT_DISPOSER = Symbol.for("openclaw.codexAppServerClientDisposer");
|
|
6600
|
-
const
|
|
6639
|
+
const createStartupLifetime = () => ({
|
|
6640
|
+
controller: new AbortController(),
|
|
6641
|
+
pending: /* @__PURE__ */ new Set()
|
|
6642
|
+
});
|
|
6601
6643
|
function getSharedCodexAppServerClientState() {
|
|
6602
6644
|
const globalState = globalThis;
|
|
6603
6645
|
globalState[SHARED_CODEX_APP_SERVER_CLIENT_STATE] ??= {
|
|
@@ -6605,19 +6647,37 @@ function getSharedCodexAppServerClientState() {
|
|
|
6605
6647
|
liveClients: /* @__PURE__ */ new Set(),
|
|
6606
6648
|
isolatedClients: /* @__PURE__ */ new Set(),
|
|
6607
6649
|
entriesByClient: /* @__PURE__ */ new WeakMap(),
|
|
6608
|
-
|
|
6609
|
-
|
|
6650
|
+
desktopGenerationDrainChecks: /* @__PURE__ */ new Set(),
|
|
6651
|
+
startup: createStartupLifetime(),
|
|
6652
|
+
startMetadata: /* @__PURE__ */ new WeakMap()
|
|
6610
6653
|
};
|
|
6611
6654
|
return globalState[SHARED_CODEX_APP_SERVER_CLIENT_STATE];
|
|
6612
6655
|
}
|
|
6613
|
-
function
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6656
|
+
function ownCodexStartup(lifetime, operation) {
|
|
6657
|
+
lifetime.pending.add(operation);
|
|
6658
|
+
const release = () => lifetime.pending.delete(operation);
|
|
6659
|
+
operation.then(release, release);
|
|
6660
|
+
return operation;
|
|
6661
|
+
}
|
|
6662
|
+
async function prepareCodexAppServerClient(options) {
|
|
6663
|
+
const lifetime = getSharedCodexAppServerClientState().startup;
|
|
6664
|
+
const abandonSignal = options?.abandonSignal ? AbortSignal.any([lifetime.controller.signal, options.abandonSignal]) : lifetime.controller.signal;
|
|
6665
|
+
const assertCurrent = () => {
|
|
6666
|
+
if (abandonSignal.aborted) throw new CodexAppServerStartupError("aborted", "codex app-server initialize aborted");
|
|
6667
|
+
};
|
|
6668
|
+
assertCurrent();
|
|
6669
|
+
const startedAt = Date.now();
|
|
6670
|
+
return {
|
|
6671
|
+
context: await withCodexAppServerAcquireDeadline(options?.timeoutMs ?? 0, ownCodexStartup(lifetime, resolveCodexAppServerClientStartContext(options)), abandonSignal),
|
|
6672
|
+
lifetime,
|
|
6673
|
+
abandonSignal,
|
|
6674
|
+
startedAt,
|
|
6675
|
+
assertCurrent
|
|
6676
|
+
};
|
|
6617
6677
|
}
|
|
6618
6678
|
/** Reads the exact successful spawn selection plus its initialized runtime identity. */
|
|
6619
6679
|
function readCodexAppServerClientProcessIdentity(client) {
|
|
6620
|
-
const metadata =
|
|
6680
|
+
const metadata = getSharedCodexAppServerClientState().startMetadata.get(client);
|
|
6621
6681
|
if (!metadata) return;
|
|
6622
6682
|
const runtimeIdentity = client.getRuntimeIdentity();
|
|
6623
6683
|
return {
|
|
@@ -6633,11 +6693,11 @@ function readCodexAppServerClientDesktopGenerationFingerprint(client) {
|
|
|
6633
6693
|
}
|
|
6634
6694
|
/** Returns the lifecycle generation that owns a managed desktop client. */
|
|
6635
6695
|
function readCodexAppServerClientDesktopGeneration(client) {
|
|
6636
|
-
return
|
|
6696
|
+
return getSharedCodexAppServerClientState().startMetadata.get(client)?.desktopGeneration;
|
|
6637
6697
|
}
|
|
6638
6698
|
/** Waits until older physical desktop clients for this client's Codex home exit. */
|
|
6639
6699
|
async function waitForCodexAppServerClientDesktopGenerationDrain(params) {
|
|
6640
|
-
const metadata =
|
|
6700
|
+
const metadata = getSharedCodexAppServerClientState().startMetadata.get(params.client);
|
|
6641
6701
|
if (!metadata?.desktopGeneration) return;
|
|
6642
6702
|
const drain = createOlderDesktopGenerationDrainWait({
|
|
6643
6703
|
generation: metadata.desktopGeneration,
|
|
@@ -6678,7 +6738,7 @@ function isCodexAppServerStartSelectionChangedError(error) {
|
|
|
6678
6738
|
* Use between the check and the JSON-RPC write on the same event loop turn.
|
|
6679
6739
|
*/
|
|
6680
6740
|
function assertCodexAppServerClientStartSelectionCurrent(params) {
|
|
6681
|
-
const metadata =
|
|
6741
|
+
const metadata = getSharedCodexAppServerClientState().startMetadata.get(params.client);
|
|
6682
6742
|
if (!metadata) return;
|
|
6683
6743
|
if (metadata.desktopGeneration && !isCodexDesktopGenerationCurrent(metadata.desktopGeneration)) throw new CodexAppServerStartSelectionChangedError();
|
|
6684
6744
|
const requestedStartOptions = params.startOptions ?? metadata.requestedStartOptions;
|
|
@@ -6691,7 +6751,7 @@ function assertCodexAppServerClientStartSelectionCurrent(params) {
|
|
|
6691
6751
|
}
|
|
6692
6752
|
/** Resolves the per-CODEX_HOME key used to serialize native config loading. */
|
|
6693
6753
|
function resolveCodexNativeConfigFenceKey(params) {
|
|
6694
|
-
const metadata = params.client ?
|
|
6754
|
+
const metadata = params.client ? getSharedCodexAppServerClientState().startMetadata.get(params.client) : void 0;
|
|
6695
6755
|
const startOptions = metadata?.startOptions ?? params.startOptions;
|
|
6696
6756
|
if (!startOptions || startOptions.transport !== "stdio") return;
|
|
6697
6757
|
const configuredHome = startOptions.env?.CODEX_HOME?.trim();
|
|
@@ -6779,27 +6839,19 @@ function shouldTrackDesktopGeneration(startOptions, pluginConfig) {
|
|
|
6779
6839
|
return startOptions.commandSource === "managed" && (startOptions.managedCommandOrder ?? "package-first") === "desktop-first";
|
|
6780
6840
|
}
|
|
6781
6841
|
/** Gets or starts a shared Codex app-server client without retaining a lease. */
|
|
6782
|
-
|
|
6783
|
-
return
|
|
6842
|
+
function getSharedCodexAppServerClient(options) {
|
|
6843
|
+
return acquireSharedCodexAppServerClient(options);
|
|
6784
6844
|
}
|
|
6785
6845
|
/** Gets or starts a shared Codex app-server client and records a release lease. */
|
|
6786
|
-
|
|
6787
|
-
|
|
6788
|
-
const state = getSharedCodexAppServerClientState();
|
|
6789
|
-
const releases = state.leasedReleases.get(acquired.client) ?? [];
|
|
6790
|
-
releases.push(acquired.release);
|
|
6791
|
-
state.leasedReleases.set(acquired.client, releases);
|
|
6792
|
-
return acquired.client;
|
|
6846
|
+
function getLeasedSharedCodexAppServerClient(options) {
|
|
6847
|
+
return acquireSharedCodexAppServerClient(options, true);
|
|
6793
6848
|
}
|
|
6794
6849
|
/** Releases one outstanding lease for a shared Codex app-server client. */
|
|
6795
6850
|
function releaseLeasedSharedCodexAppServerClient(client) {
|
|
6796
|
-
const
|
|
6797
|
-
|
|
6798
|
-
|
|
6799
|
-
|
|
6800
|
-
if (!release) return false;
|
|
6801
|
-
if (releases.length === 0) state.leasedReleases.delete(client);
|
|
6802
|
-
release();
|
|
6851
|
+
const entry = getSharedCodexAppServerClientState().entriesByClient.get(client);
|
|
6852
|
+
if (!entry || entry.anonymousLeases === 0) return false;
|
|
6853
|
+
entry.anonymousLeases -= 1;
|
|
6854
|
+
releaseSharedClientEntry(entry, "activeLeases");
|
|
6803
6855
|
return true;
|
|
6804
6856
|
}
|
|
6805
6857
|
/** Releases the currently owned client exactly once. */
|
|
@@ -6861,13 +6913,13 @@ async function withLeasedCodexAppServerClientStartSelectionRetry(params) {
|
|
|
6861
6913
|
}
|
|
6862
6914
|
throw new Error("Codex app-server selection retry loop exited unexpectedly");
|
|
6863
6915
|
}
|
|
6864
|
-
async function acquireSharedCodexAppServerClient(options,
|
|
6865
|
-
if (options?.abandonSignal?.aborted) throw new CodexAppServerStartupError("aborted", "codex app-server initialize aborted");
|
|
6866
|
-
const acquireStartedAt = Date.now();
|
|
6916
|
+
async function acquireSharedCodexAppServerClient(options, leased = false) {
|
|
6867
6917
|
const timeoutMs = options?.timeoutMs ?? 0;
|
|
6868
6918
|
const state = getSharedCodexAppServerClientState();
|
|
6869
|
-
const {
|
|
6870
|
-
|
|
6919
|
+
const { context, lifetime, abandonSignal, startedAt, assertCurrent } = await prepareCodexAppServerClient(options);
|
|
6920
|
+
assertCurrent();
|
|
6921
|
+
const { agentDir, usesNativeAuth, authProfileId, authProfileStore, preparedAuth, authRequirement, requestedStartOptions, startOptions, desktopGeneration, pluginConfig } = context;
|
|
6922
|
+
const remainingTimeoutMs = resolveRemainingAcquireTimeout(timeoutMs, startedAt);
|
|
6871
6923
|
const authIdentityCacheKey = preparedAuth?.kind === "api-key" ? resolveCodexAppServerPreparedApiKeyCacheKey(preparedAuth.apiKey) : preparedAuth?.snapshot.secretFreeCacheKey ?? (authRequirement === "api-key" && !authProfileId ? resolveCodexAppServerFallbackApiKeyCacheKey({ startOptions }) : void 0);
|
|
6872
6924
|
const baseKey = `${codexAppServerStartOptionsKey(startOptions, {
|
|
6873
6925
|
authProfileId,
|
|
@@ -6880,14 +6932,14 @@ async function acquireSharedCodexAppServerClient(options, leaseOptions) {
|
|
|
6880
6932
|
const key = runtimeArtifactMode ? `${baseKey}\0runtime-artifact:capture-v1:${expectedRuntimeArtifactKey}` : baseKey;
|
|
6881
6933
|
let entry = getOrCreateSharedClientEntry(state, key);
|
|
6882
6934
|
const existingClient = entry.client;
|
|
6883
|
-
const existingGeneration = existingClient ?
|
|
6935
|
+
const existingGeneration = existingClient ? state.startMetadata.get(existingClient)?.desktopGeneration : void 0;
|
|
6884
6936
|
if (existingClient && existingGeneration && !isCodexDesktopGenerationCurrent(existingGeneration)) {
|
|
6885
6937
|
retireSharedCodexAppServerClientIfCurrent(existingClient);
|
|
6886
6938
|
entry = getOrCreateSharedClientEntry(state, key);
|
|
6887
6939
|
}
|
|
6888
6940
|
entry.startupAbort ??= new AbortController();
|
|
6889
6941
|
entry.closeWhenIdle = false;
|
|
6890
|
-
const releasePendingAcquire =
|
|
6942
|
+
const releasePendingAcquire = retainSharedClientEntry(entry, "pendingAcquires");
|
|
6891
6943
|
const startedCallback = options?.onStartedClient;
|
|
6892
6944
|
if (startedCallback) {
|
|
6893
6945
|
entry.onStartedClientCallbacks.add(startedCallback);
|
|
@@ -6901,15 +6953,15 @@ async function acquireSharedCodexAppServerClient(options, leaseOptions) {
|
|
|
6901
6953
|
const abandon = () => {
|
|
6902
6954
|
stopStartedClientNotifications();
|
|
6903
6955
|
releasePendingAcquire();
|
|
6904
|
-
retirePendingSharedClientEntryIfUnclaimed(
|
|
6956
|
+
retirePendingSharedClientEntryIfUnclaimed(entry);
|
|
6905
6957
|
};
|
|
6906
6958
|
options.abandonSignal.addEventListener("abort", abandon, { once: true });
|
|
6907
6959
|
cleanupAbandonSignal = () => options.abandonSignal?.removeEventListener("abort", abandon);
|
|
6908
6960
|
if (options.abandonSignal.aborted) abandon();
|
|
6909
6961
|
}
|
|
6910
6962
|
const startup = entry.startup ?? (entry.startup = createSharedCodexAppServerClientStartup({
|
|
6963
|
+
lifetime,
|
|
6911
6964
|
entry,
|
|
6912
|
-
key,
|
|
6913
6965
|
requestedStartOptions,
|
|
6914
6966
|
startOptions,
|
|
6915
6967
|
desktopGeneration,
|
|
@@ -6921,13 +6973,12 @@ async function acquireSharedCodexAppServerClient(options, leaseOptions) {
|
|
|
6921
6973
|
authRequirement,
|
|
6922
6974
|
runtimeArtifactMode,
|
|
6923
6975
|
...options?.expectedRuntimeArtifact ? { expectedRuntimeArtifact: options.expectedRuntimeArtifact } : {},
|
|
6924
|
-
runtimeArtifactSignal: entry.startupAbort.signal,
|
|
6925
6976
|
abandonSignal: entry.startupAbort.signal,
|
|
6926
6977
|
config: options?.config
|
|
6927
6978
|
}));
|
|
6928
6979
|
try {
|
|
6929
|
-
await withCodexAppServerAcquireDeadline(remainingTimeoutMs, startup.initialized,
|
|
6930
|
-
const client = await withCodexAppServerAcquireDeadline(timeoutMs, startup.ready,
|
|
6980
|
+
await withCodexAppServerAcquireDeadline(remainingTimeoutMs, startup.initialized, abandonSignal, CODEX_APP_SERVER_INITIALIZE_TIMEOUT_MESSAGE, () => buildCodexAppServerInitializeTimeoutError(entry.client));
|
|
6981
|
+
const client = await withCodexAppServerAcquireDeadline(timeoutMs, startup.ready, abandonSignal, "codex app-server authentication timed out");
|
|
6931
6982
|
if (entry.closeError) throw entry.closeError;
|
|
6932
6983
|
ensureCodexAppServerClientRuntime(client, {
|
|
6933
6984
|
agentDir,
|
|
@@ -6936,14 +6987,14 @@ async function acquireSharedCodexAppServerClient(options, leaseOptions) {
|
|
|
6936
6987
|
authMode: preparedAuth?.kind === "api-key" ? "prepared-api-key" : "profile",
|
|
6937
6988
|
config: options?.config
|
|
6938
6989
|
});
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6990
|
+
if (leased) {
|
|
6991
|
+
entry.anonymousLeases += 1;
|
|
6992
|
+
entry.activeLeases += 1;
|
|
6993
|
+
}
|
|
6994
|
+
return client;
|
|
6944
6995
|
} catch (error) {
|
|
6945
6996
|
releasePendingAcquire();
|
|
6946
|
-
retirePendingSharedClientEntryIfUnclaimed(
|
|
6997
|
+
retirePendingSharedClientEntryIfUnclaimed(entry);
|
|
6947
6998
|
throw error;
|
|
6948
6999
|
} finally {
|
|
6949
7000
|
cleanupAbandonSignal?.();
|
|
@@ -6973,45 +7024,34 @@ function resolveRemainingAcquireTimeout(timeoutMs, startedAt) {
|
|
|
6973
7024
|
}
|
|
6974
7025
|
function createSharedCodexAppServerClientStartup(params) {
|
|
6975
7026
|
const initialized = createDeferred();
|
|
6976
|
-
const ready = startInitializedCodexAppServerClient({
|
|
6977
|
-
|
|
6978
|
-
startOptions: params.startOptions,
|
|
6979
|
-
...params.desktopGeneration ? { desktopGeneration: params.desktopGeneration } : {},
|
|
6980
|
-
...params.pluginConfig !== void 0 ? { pluginConfig: params.pluginConfig } : {},
|
|
6981
|
-
agentDir: params.agentDir,
|
|
6982
|
-
authProfileId: params.authProfileId,
|
|
6983
|
-
authProfileStore: params.authProfileStore,
|
|
6984
|
-
preparedAuth: params.preparedAuth,
|
|
6985
|
-
authRequirement: params.authRequirement,
|
|
6986
|
-
runtimeArtifactMode: params.runtimeArtifactMode,
|
|
6987
|
-
...params.expectedRuntimeArtifact ? { expectedRuntimeArtifact: params.expectedRuntimeArtifact } : {},
|
|
6988
|
-
runtimeArtifactSignal: params.runtimeArtifactSignal,
|
|
6989
|
-
abandonSignal: params.abandonSignal,
|
|
6990
|
-
config: params.config,
|
|
7027
|
+
const ready = ownCodexStartup(params.lifetime, startInitializedCodexAppServerClient({
|
|
7028
|
+
...params,
|
|
6991
7029
|
onStartedClient: (startedClient) => {
|
|
6992
7030
|
const state = getSharedCodexAppServerClientState();
|
|
7031
|
+
if (params.entry.client) state.entriesByClient.delete(params.entry.client);
|
|
6993
7032
|
params.entry.client = startedClient;
|
|
7033
|
+
state.entriesByClient.set(startedClient, params.entry);
|
|
6994
7034
|
state.liveClients.add(startedClient);
|
|
6995
7035
|
startedClient.addTransportExitHandler((exitedClient) => {
|
|
6996
7036
|
state.liveClients.delete(exitedClient);
|
|
6997
7037
|
notifyDesktopGenerationDrainChecks(state);
|
|
6998
7038
|
});
|
|
6999
|
-
startedClient.addCloseHandler((closedClient) => {
|
|
7000
|
-
if (state.entriesByClient.get(closedClient) === params.entry) clearSharedClientEntryIfCurrent(params.key, closedClient);
|
|
7001
|
-
});
|
|
7002
7039
|
for (const callback of params.entry.onStartedClientCallbacks) callback(startedClient);
|
|
7003
|
-
retirePendingSharedClientEntryIfUnclaimed(params.
|
|
7040
|
+
retirePendingSharedClientEntryIfUnclaimed(params.entry);
|
|
7004
7041
|
},
|
|
7005
7042
|
onInitializedClient: () => initialized.resolve()
|
|
7006
7043
|
}).then((client) => {
|
|
7007
7044
|
const state = getSharedCodexAppServerClientState();
|
|
7008
7045
|
params.entry.client = client;
|
|
7009
|
-
|
|
7046
|
+
client.addCloseHandler((closedClient) => {
|
|
7047
|
+
const entry = getCurrentSharedClientEntry(closedClient);
|
|
7048
|
+
if (entry) state.clients.delete(entry.key);
|
|
7049
|
+
});
|
|
7010
7050
|
return client;
|
|
7011
7051
|
}, (error) => {
|
|
7012
7052
|
initialized.reject(error);
|
|
7013
7053
|
throw error;
|
|
7014
|
-
});
|
|
7054
|
+
}));
|
|
7015
7055
|
initialized.promise.catch(() => void 0);
|
|
7016
7056
|
ready.catch(() => void 0);
|
|
7017
7057
|
return {
|
|
@@ -7019,13 +7059,15 @@ function createSharedCodexAppServerClientStartup(params) {
|
|
|
7019
7059
|
ready
|
|
7020
7060
|
};
|
|
7021
7061
|
}
|
|
7022
|
-
/** Starts a
|
|
7062
|
+
/** Starts a caller-owned client; its assertion never binds ordinary shared-client leases. */
|
|
7023
7063
|
async function createIsolatedCodexAppServerClient(options) {
|
|
7024
|
-
|
|
7025
|
-
const
|
|
7064
|
+
options?.assertCurrent?.();
|
|
7065
|
+
const { context, lifetime, abandonSignal, startedAt, assertCurrent } = await prepareCodexAppServerClient(options);
|
|
7066
|
+
assertCurrent();
|
|
7026
7067
|
const timeoutMs = options?.timeoutMs ?? 0;
|
|
7027
|
-
const { agentDir, usesNativeAuth, authProfileId, authProfileStore, preparedAuth, authRequirement, requestedStartOptions, startOptions, desktopGeneration, pluginConfig } =
|
|
7028
|
-
return await startInitializedCodexAppServerClient({
|
|
7068
|
+
const { agentDir, usesNativeAuth, authProfileId, authProfileStore, preparedAuth, authRequirement, requestedStartOptions, startOptions, desktopGeneration, pluginConfig } = context;
|
|
7069
|
+
return await ownCodexStartup(lifetime, startInitializedCodexAppServerClient({
|
|
7070
|
+
lifetime,
|
|
7029
7071
|
requestedStartOptions,
|
|
7030
7072
|
startOptions,
|
|
7031
7073
|
...desktopGeneration ? { desktopGeneration } : {},
|
|
@@ -7037,15 +7079,15 @@ async function createIsolatedCodexAppServerClient(options) {
|
|
|
7037
7079
|
authRequirement,
|
|
7038
7080
|
runtimeArtifactMode: options?.runtimeArtifactMode ?? (options?.expectedRuntimeArtifact ? "capture" : void 0),
|
|
7039
7081
|
...options?.expectedRuntimeArtifact ? { expectedRuntimeArtifact: options.expectedRuntimeArtifact } : {},
|
|
7040
|
-
runtimeArtifactSignal: options?.abandonSignal,
|
|
7041
7082
|
config: options?.config,
|
|
7042
|
-
timeoutMs: resolveRemainingAcquireTimeout(timeoutMs,
|
|
7043
|
-
abandonSignal
|
|
7083
|
+
timeoutMs: resolveRemainingAcquireTimeout(timeoutMs, startedAt),
|
|
7084
|
+
abandonSignal,
|
|
7085
|
+
assertCurrent: options?.assertCurrent,
|
|
7044
7086
|
onStartedClient: (client) => {
|
|
7045
7087
|
trackIsolatedCodexAppServerClient(client);
|
|
7046
7088
|
options?.onStartedClient?.(client);
|
|
7047
7089
|
}
|
|
7048
|
-
});
|
|
7090
|
+
}));
|
|
7049
7091
|
}
|
|
7050
7092
|
function trackIsolatedCodexAppServerClient(client) {
|
|
7051
7093
|
const state = getSharedCodexAppServerClientState();
|
|
@@ -7058,11 +7100,18 @@ function trackIsolatedCodexAppServerClient(client) {
|
|
|
7058
7100
|
async function startInitializedCodexAppServerClient(params) {
|
|
7059
7101
|
const acquireStartedAt = Date.now();
|
|
7060
7102
|
const timeoutMs = params.timeoutMs ?? 0;
|
|
7103
|
+
const abandonSignal = params.abandonSignal ? AbortSignal.any([params.lifetime.controller.signal, params.abandonSignal]) : params.lifetime.controller.signal;
|
|
7104
|
+
const waitForStartup = (operation, timeoutMessage = CODEX_APP_SERVER_INITIALIZE_TIMEOUT_MESSAGE, timeoutErrorFactory) => {
|
|
7105
|
+
if (abandonSignal.aborted) throw new CodexAppServerStartupError("aborted", "codex app-server initialize aborted");
|
|
7106
|
+
return withCodexAppServerAcquireDeadline(resolveRemainingAcquireTimeout(timeoutMs, acquireStartedAt), ownCodexStartup(params.lifetime, operation()), abandonSignal, timeoutMessage, timeoutErrorFactory);
|
|
7107
|
+
};
|
|
7061
7108
|
const startOptionsCandidates = resolveManagedFallbackStartOptions(params.startOptions);
|
|
7062
7109
|
for (const [index, startOptions] of startOptionsCandidates.entries()) {
|
|
7063
|
-
|
|
7064
|
-
const
|
|
7065
|
-
|
|
7110
|
+
params.assertCurrent?.();
|
|
7111
|
+
const desktopGeneration = params.desktopGeneration ?? (isManagedCodexDesktopCommand(startOptions.command) ? await waitForStartup(waitForCodexDesktopGeneration) : void 0);
|
|
7112
|
+
const assertStartupCurrent = () => {
|
|
7113
|
+
params.assertCurrent?.();
|
|
7114
|
+
if (abandonSignal.aborted) throw new CodexAppServerStartupError("aborted", "codex app-server initialize aborted");
|
|
7066
7115
|
if (desktopGeneration && !isCodexDesktopGenerationCurrent(desktopGeneration)) throw new CodexAppServerStartSelectionChangedError();
|
|
7067
7116
|
};
|
|
7068
7117
|
const computerUseConfig = resolveCodexComputerUseConfig({ pluginConfig: params.pluginConfig });
|
|
@@ -7073,13 +7122,13 @@ async function startInitializedCodexAppServerClient(params) {
|
|
|
7073
7122
|
agentDir: params.agentDir
|
|
7074
7123
|
}) : void 0;
|
|
7075
7124
|
try {
|
|
7076
|
-
if (artifactDrain) await
|
|
7125
|
+
if (artifactDrain) await waitForStartup(() => artifactDrain.promise);
|
|
7077
7126
|
await reconcileCodexComputerUseStartArtifacts({
|
|
7078
7127
|
startOptions,
|
|
7079
7128
|
agentDir: params.agentDir,
|
|
7080
7129
|
pluginConfig: params.pluginConfig,
|
|
7081
7130
|
...desktopGeneration ? { desktopGeneration } : {},
|
|
7082
|
-
assertCurrent:
|
|
7131
|
+
assertCurrent: assertStartupCurrent,
|
|
7083
7132
|
ownsIsolatedCodexHome
|
|
7084
7133
|
});
|
|
7085
7134
|
} catch (error) {
|
|
@@ -7094,80 +7143,69 @@ async function startInitializedCodexAppServerClient(params) {
|
|
|
7094
7143
|
} finally {
|
|
7095
7144
|
artifactDrain?.cancel();
|
|
7096
7145
|
}
|
|
7097
|
-
const runtimeArtifactModule = params.runtimeArtifactMode ? await import("./runtime-artifact-
|
|
7146
|
+
const runtimeArtifactModule = params.runtimeArtifactMode ? await import("./runtime-artifact-Bh_gf6-t.js") : void 0;
|
|
7098
7147
|
const runtimeArtifactBeforeStart = runtimeArtifactModule ? await runtimeArtifactModule.captureCodexAppServerRuntimeArtifactBeforeStart({
|
|
7099
7148
|
startOptions,
|
|
7100
7149
|
spawnIdentity: resolveCodexAppServerSpawnIdentity(startOptions),
|
|
7101
|
-
signal:
|
|
7150
|
+
signal: abandonSignal
|
|
7102
7151
|
}) : void 0;
|
|
7103
7152
|
if (runtimeArtifactModule && runtimeArtifactBeforeStart && params.expectedRuntimeArtifact && !runtimeArtifactModule.validateCodexAppServerRuntimeArtifactCapture(params.expectedRuntimeArtifact, runtimeArtifactBeforeStart)) {
|
|
7104
7153
|
if (index + 1 < startOptionsCandidates.length) continue;
|
|
7105
7154
|
throw new Error("Codex app-server runtime artifact does not match verified inference");
|
|
7106
7155
|
}
|
|
7107
|
-
|
|
7156
|
+
assertStartupCurrent();
|
|
7108
7157
|
let starting;
|
|
7109
7158
|
let client;
|
|
7110
7159
|
try {
|
|
7111
|
-
client = await
|
|
7112
|
-
|
|
7160
|
+
client = await waitForStartup(() => starting = CodexAppServerClient.start(startOptions, () => {
|
|
7161
|
+
assertStartupCurrent();
|
|
7113
7162
|
resolveRemainingAcquireTimeout(timeoutMs, acquireStartedAt);
|
|
7114
|
-
})
|
|
7115
|
-
} catch (error) {
|
|
7116
|
-
starting?.then((lateClient) => lateClient.close(), () => {});
|
|
7117
|
-
throw error;
|
|
7118
|
-
}
|
|
7119
|
-
const nativeCommandAtStart = startOptions.commandSource === "resolved-managed" ? resolveManagedCodexNativeCommand(startOptions.command) : void 0;
|
|
7120
|
-
getCodexAppServerClientStartMetadata().set(client, {
|
|
7121
|
-
requestedStartOptions: params.requestedStartOptions,
|
|
7122
|
-
startOptions,
|
|
7123
|
-
agentDir: params.agentDir,
|
|
7124
|
-
...nativeCommandAtStart ? { nativeCommand: nativeCommandAtStart } : {},
|
|
7125
|
-
...desktopGeneration ? { desktopGeneration } : {}
|
|
7126
|
-
});
|
|
7127
|
-
params.onStartedClient?.(client);
|
|
7128
|
-
let initialize;
|
|
7129
|
-
try {
|
|
7130
|
-
await withCodexAppServerAcquireDeadline(resolveRemainingAcquireTimeout(timeoutMs, acquireStartedAt), initialize = client.initialize(), params.abandonSignal, CODEX_APP_SERVER_INITIALIZE_TIMEOUT_MESSAGE, () => buildCodexAppServerInitializeTimeoutError(client));
|
|
7131
|
-
} catch (error) {
|
|
7132
|
-
client.close();
|
|
7133
|
-
initialize?.catch(() => void 0);
|
|
7134
|
-
if (shouldTryManagedFallbackStartOption(error, startOptions, index, startOptionsCandidates)) continue;
|
|
7135
|
-
throw error;
|
|
7136
|
-
}
|
|
7137
|
-
try {
|
|
7138
|
-
assertDesktopGenerationCurrent();
|
|
7163
|
+
}));
|
|
7139
7164
|
} catch (error) {
|
|
7140
|
-
|
|
7165
|
+
if (starting) ownCodexStartup(params.lifetime, starting.then((lateClient) => lateClient.closeAndWait(), () => {}));
|
|
7141
7166
|
throw error;
|
|
7142
7167
|
}
|
|
7143
|
-
|
|
7144
|
-
let runtimeArtifact;
|
|
7168
|
+
let ready = false;
|
|
7145
7169
|
try {
|
|
7170
|
+
const nativeCommandAtStart = startOptions.commandSource === "resolved-managed" ? resolveManagedCodexNativeCommand(startOptions.command) : void 0;
|
|
7171
|
+
getSharedCodexAppServerClientState().startMetadata.set(client, {
|
|
7172
|
+
requestedStartOptions: params.requestedStartOptions,
|
|
7173
|
+
startOptions,
|
|
7174
|
+
agentDir: params.agentDir,
|
|
7175
|
+
...nativeCommandAtStart ? { nativeCommand: nativeCommandAtStart } : {},
|
|
7176
|
+
...desktopGeneration ? { desktopGeneration } : {}
|
|
7177
|
+
});
|
|
7178
|
+
assertStartupCurrent();
|
|
7179
|
+
params.onStartedClient?.(client);
|
|
7180
|
+
try {
|
|
7181
|
+
await waitForStartup(() => client.initialize(), CODEX_APP_SERVER_INITIALIZE_TIMEOUT_MESSAGE, () => buildCodexAppServerInitializeTimeoutError(client));
|
|
7182
|
+
} catch (error) {
|
|
7183
|
+
if (shouldTryManagedFallbackStartOption(error, startOptions, index, startOptionsCandidates)) continue;
|
|
7184
|
+
throw error;
|
|
7185
|
+
}
|
|
7186
|
+
assertStartupCurrent();
|
|
7187
|
+
params.onInitializedClient?.();
|
|
7188
|
+
let runtimeArtifact;
|
|
7146
7189
|
if (runtimeArtifactModule && runtimeArtifactBeforeStart) {
|
|
7147
7190
|
runtimeArtifact = await runtimeArtifactModule.finalizeCodexAppServerRuntimeArtifact({
|
|
7148
7191
|
before: runtimeArtifactBeforeStart,
|
|
7149
7192
|
startOptions,
|
|
7150
7193
|
spawnIdentity: resolveCodexAppServerSpawnIdentity(startOptions),
|
|
7151
7194
|
runtimeIdentity: client.getRuntimeIdentity(),
|
|
7152
|
-
signal:
|
|
7195
|
+
signal: abandonSignal
|
|
7153
7196
|
});
|
|
7154
7197
|
if (params.expectedRuntimeArtifact && (runtimeArtifact.id !== params.expectedRuntimeArtifact.id || runtimeArtifact.fingerprint !== params.expectedRuntimeArtifact.fingerprint)) throw new Error("Codex app-server runtime artifact does not match verified inference");
|
|
7155
7198
|
}
|
|
7156
|
-
|
|
7157
|
-
|
|
7158
|
-
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
onAuthRefreshFailure: () => retireSharedCodexAppServerClientIfCurrent(client)
|
|
7167
|
-
});
|
|
7168
|
-
try {
|
|
7169
|
-
assertDesktopGenerationCurrent();
|
|
7170
|
-
await withCodexAppServerAcquireDeadline(resolveRemainingAcquireTimeout(timeoutMs, acquireStartedAt), applyCodexAppServerAuthProfile({
|
|
7199
|
+
ensureCodexAppServerClientRuntime(client, {
|
|
7200
|
+
agentDir: params.agentDir,
|
|
7201
|
+
authProfileId: params.authProfileId ?? void 0,
|
|
7202
|
+
authMode: params.preparedAuth?.kind === "api-key" ? "prepared-api-key" : "profile",
|
|
7203
|
+
...params.authProfileStore ? { authProfileStore: params.authProfileStore } : {},
|
|
7204
|
+
config: params.config,
|
|
7205
|
+
onAuthRefreshFailure: () => retireSharedCodexAppServerClientIfCurrent(client)
|
|
7206
|
+
});
|
|
7207
|
+
assertStartupCurrent();
|
|
7208
|
+
await waitForStartup(() => applyCodexAppServerAuthProfile({
|
|
7171
7209
|
client,
|
|
7172
7210
|
agentDir: params.agentDir,
|
|
7173
7211
|
authProfileId: params.authProfileId,
|
|
@@ -7175,10 +7213,11 @@ async function startInitializedCodexAppServerClient(params) {
|
|
|
7175
7213
|
authRequirement: params.authRequirement,
|
|
7176
7214
|
startOptions,
|
|
7177
7215
|
config: params.config,
|
|
7216
|
+
assertCurrent: assertStartupCurrent,
|
|
7178
7217
|
...params.authProfileStore ? { authProfileStore: params.authProfileStore } : {}
|
|
7179
|
-
})
|
|
7218
|
+
}));
|
|
7180
7219
|
if (runtimeArtifactModule && runtimeArtifact) runtimeArtifactModule.bindCodexAppServerRuntimeArtifact(client, runtimeArtifact);
|
|
7181
|
-
|
|
7220
|
+
assertStartupCurrent();
|
|
7182
7221
|
const fenceKey = resolveCodexNativeConfigFenceKey({ client });
|
|
7183
7222
|
if (fenceKey) client.setThreadSessionRequestGuard(async (options) => {
|
|
7184
7223
|
const release = await acquireCodexNativeConfigFence(fenceKey, options);
|
|
@@ -7190,10 +7229,10 @@ async function startInitializedCodexAppServerClient(params) {
|
|
|
7190
7229
|
throw error;
|
|
7191
7230
|
}
|
|
7192
7231
|
});
|
|
7232
|
+
ready = true;
|
|
7193
7233
|
return client;
|
|
7194
|
-
}
|
|
7195
|
-
client.
|
|
7196
|
-
throw error;
|
|
7234
|
+
} finally {
|
|
7235
|
+
if (!ready) ownCodexStartup(params.lifetime, client.closeAndWait());
|
|
7197
7236
|
}
|
|
7198
7237
|
}
|
|
7199
7238
|
throw new Error("Managed Codex app-server fallback candidates were exhausted.");
|
|
@@ -7223,12 +7262,11 @@ function shouldTryManagedFallbackStartOption(error, startOptions, index, startOp
|
|
|
7223
7262
|
function clearSharedCodexAppServerClientIfCurrent(client) {
|
|
7224
7263
|
if (!client) return false;
|
|
7225
7264
|
const state = getSharedCodexAppServerClientState();
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
|
|
7229
|
-
|
|
7230
|
-
|
|
7231
|
-
return false;
|
|
7265
|
+
const entry = getCurrentSharedClientEntry(client);
|
|
7266
|
+
if (!entry) return false;
|
|
7267
|
+
state.clients.delete(entry.key);
|
|
7268
|
+
client.close();
|
|
7269
|
+
return true;
|
|
7232
7270
|
}
|
|
7233
7271
|
/** Captures a revocable observation of the exact shared client and native account/config. */
|
|
7234
7272
|
function captureSharedCodexAppServerCatalogLifetime(client) {
|
|
@@ -7239,16 +7277,14 @@ function captureSharedCodexAppServerCatalogLifetime(client) {
|
|
|
7239
7277
|
/** Registration ends on retirement even when sibling leases keep the process alive. */
|
|
7240
7278
|
function captureSharedClientRegistration(client) {
|
|
7241
7279
|
const state = getSharedCodexAppServerClientState();
|
|
7242
|
-
const entry =
|
|
7243
|
-
const key = [...state.clients].find(([, candidate]) => candidate === entry)?.[0];
|
|
7280
|
+
const entry = getCurrentSharedClientEntry(client);
|
|
7244
7281
|
const generation = readCodexAppServerClientDesktopGeneration(client);
|
|
7245
|
-
return () =>
|
|
7282
|
+
return () => entry !== void 0 && state.clients.get(entry.key) === entry && entry.client === client && !entry.closeWhenIdle && !entry.closeError && !client.getCloseError() && (!generation || isCodexDesktopGenerationCurrent(generation));
|
|
7246
7283
|
}
|
|
7247
7284
|
/** Retains the matching shared client and returns a release callback. */
|
|
7248
7285
|
function retainSharedCodexAppServerClientIfCurrent(client) {
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
for (const entry of state.clients.values()) if (entry.client === client) return retainSharedClientEntry(entry);
|
|
7286
|
+
const entry = getCurrentSharedClientEntry(client);
|
|
7287
|
+
return entry ? retainSharedClientEntry(entry) : void 0;
|
|
7252
7288
|
}
|
|
7253
7289
|
/** Retains the live shared client whose initialized instance id matches a thread binding. */
|
|
7254
7290
|
function retainSharedCodexAppServerClientByInstanceId(clientId) {
|
|
@@ -7266,7 +7302,7 @@ function retainSharedCodexAppServerClientByInstanceId(clientId) {
|
|
|
7266
7302
|
/** Captures physical ownership, independently of unrelated thread and reader leases. */
|
|
7267
7303
|
function captureCodexAppServerClientLifetime(client, requiredOwnership) {
|
|
7268
7304
|
const state = getSharedCodexAppServerClientState();
|
|
7269
|
-
const start =
|
|
7305
|
+
const start = state.startMetadata.get(client)?.startOptions;
|
|
7270
7306
|
if (requiredOwnership === "native-process" && (start?.transport !== "stdio" || isCodexAppServerProxyLaunch(start.args))) throw new AgentHarnessPreflightError("Codex ordinary configuration refresh requires an OpenClaw-managed local stdio process, not an external socket or app-server proxy. No turn was sent; reconnect through managed local stdio before continuing.");
|
|
7271
7307
|
const isCurrent = requiredOwnership === "native-process" && state.isolatedClients.has(client) ? () => state.isolatedClients.has(client) && !client.getCloseError() : captureSharedClientRegistration(client);
|
|
7272
7308
|
const assertCurrent = () => {
|
|
@@ -7288,43 +7324,31 @@ function captureCodexAppServerClientLifetime(client, requiredOwnership) {
|
|
|
7288
7324
|
function retireSharedCodexAppServerClientIfCurrent(client, opts) {
|
|
7289
7325
|
if (!client) return;
|
|
7290
7326
|
const state = getSharedCodexAppServerClientState();
|
|
7291
|
-
|
|
7292
|
-
|
|
7327
|
+
const currentEntry = getCurrentSharedClientEntry(client);
|
|
7328
|
+
const entry = currentEntry ?? state.entriesByClient.get(client);
|
|
7329
|
+
if (!entry || entry.client !== client && !entry.closeError) return;
|
|
7330
|
+
if (currentEntry) {
|
|
7331
|
+
state.clients.delete(entry.key);
|
|
7293
7332
|
entry.closeWhenIdle = true;
|
|
7294
|
-
if (opts?.failActiveLeases) {
|
|
7295
|
-
entry.closeError = /* @__PURE__ */ new Error("codex app-server client is closed");
|
|
7296
|
-
return {
|
|
7297
|
-
activeLeases: entry.activeLeases,
|
|
7298
|
-
closed: closeRetiredSharedClientEntry(entry)
|
|
7299
|
-
};
|
|
7300
|
-
}
|
|
7301
|
-
const closed = closeRetiredSharedClientEntryIfIdle(entry);
|
|
7302
|
-
return {
|
|
7303
|
-
activeLeases: entry.activeLeases,
|
|
7304
|
-
closed
|
|
7305
|
-
};
|
|
7306
7333
|
}
|
|
7307
|
-
|
|
7308
|
-
|
|
7309
|
-
if (opts?.failActiveLeases && !detachedEntry.closeError) {
|
|
7310
|
-
detachedEntry.closeError = /* @__PURE__ */ new Error("codex app-server client is closed");
|
|
7311
|
-
return {
|
|
7312
|
-
activeLeases: detachedEntry.activeLeases,
|
|
7313
|
-
closed: closeRetiredSharedClientEntry(detachedEntry)
|
|
7314
|
-
};
|
|
7315
|
-
}
|
|
7334
|
+
if (opts?.failActiveLeases && (currentEntry || !entry.closeError)) {
|
|
7335
|
+
entry.closeError = /* @__PURE__ */ new Error("codex app-server client is closed");
|
|
7316
7336
|
return {
|
|
7317
|
-
activeLeases:
|
|
7318
|
-
closed:
|
|
7337
|
+
activeLeases: entry.activeLeases,
|
|
7338
|
+
closed: closeRetiredSharedClientEntry(entry)
|
|
7319
7339
|
};
|
|
7320
7340
|
}
|
|
7341
|
+
return {
|
|
7342
|
+
activeLeases: entry.activeLeases,
|
|
7343
|
+
closed: currentEntry ? closeRetiredSharedClientEntryIfIdle(entry) : false
|
|
7344
|
+
};
|
|
7321
7345
|
}
|
|
7322
7346
|
/** Gracefully retires exact clients attached to an older desktop generation. */
|
|
7323
7347
|
function retireSharedCodexAppServerClientsBeforeDesktopGeneration(generation) {
|
|
7324
7348
|
const state = getSharedCodexAppServerClientState();
|
|
7325
7349
|
for (const entry of state.clients.values()) {
|
|
7326
7350
|
const client = entry.client;
|
|
7327
|
-
const attached = client ?
|
|
7351
|
+
const attached = client ? state.startMetadata.get(client) : void 0;
|
|
7328
7352
|
if (client && attached?.desktopGeneration && attached.desktopGeneration.epoch < generation.epoch) retireSharedCodexAppServerClientIfCurrent(client);
|
|
7329
7353
|
}
|
|
7330
7354
|
}
|
|
@@ -7369,7 +7393,7 @@ function hasLiveOlderDesktopGenerationClient(params) {
|
|
|
7369
7393
|
return false;
|
|
7370
7394
|
}
|
|
7371
7395
|
function isOlderDesktopGenerationClientForHome(client, generation, targetHome) {
|
|
7372
|
-
const metadata =
|
|
7396
|
+
const metadata = getSharedCodexAppServerClientState().startMetadata.get(client);
|
|
7373
7397
|
return Boolean(metadata?.desktopGeneration && metadata.desktopGeneration.epoch < generation.epoch && resolveCodexNativeConfigFenceKey({ client }) === targetHome);
|
|
7374
7398
|
}
|
|
7375
7399
|
function notifyDesktopGenerationDrainChecks(state) {
|
|
@@ -7379,26 +7403,35 @@ function notifyDesktopGenerationDrainChecks(state) {
|
|
|
7379
7403
|
async function clearSharedCodexAppServerClientIfCurrentAndWait(client, options) {
|
|
7380
7404
|
if (!client) return false;
|
|
7381
7405
|
const state = getSharedCodexAppServerClientState();
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
return false;
|
|
7406
|
+
const entry = getCurrentSharedClientEntry(client);
|
|
7407
|
+
if (!entry) return false;
|
|
7408
|
+
state.clients.delete(entry.key);
|
|
7409
|
+
await client.closeAndWait(options);
|
|
7410
|
+
return true;
|
|
7388
7411
|
}
|
|
7389
7412
|
/** Clears all shared clients and waits for their processes to exit. */
|
|
7390
7413
|
async function clearSharedCodexAppServerClientAndWait(options) {
|
|
7391
7414
|
const state = getSharedCodexAppServerClientState();
|
|
7392
|
-
const
|
|
7415
|
+
const lifetime = state.startup;
|
|
7416
|
+
lifetime.controller.abort();
|
|
7393
7417
|
state.clients.clear();
|
|
7394
|
-
|
|
7418
|
+
const closing = Promise.all([...state.liveClients].map((client) => ownCodexStartup(lifetime, client.closeAndWait(options))));
|
|
7419
|
+
closing.catch(() => void 0);
|
|
7420
|
+
try {
|
|
7421
|
+
while (lifetime.pending.size > 0) await Promise.allSettled(lifetime.pending);
|
|
7422
|
+
await closing;
|
|
7423
|
+
} finally {
|
|
7424
|
+
if (state.startup === lifetime) state.startup = createStartupLifetime();
|
|
7425
|
+
}
|
|
7395
7426
|
}
|
|
7396
7427
|
globalThis[SHARED_CODEX_APP_SERVER_CLIENT_DISPOSER] = clearSharedCodexAppServerClientAndWait;
|
|
7397
7428
|
function getOrCreateSharedClientEntry(state, key) {
|
|
7398
7429
|
let entry = state.clients.get(key);
|
|
7399
7430
|
if (!entry) {
|
|
7400
7431
|
entry = {
|
|
7432
|
+
key,
|
|
7401
7433
|
activeLeases: 0,
|
|
7434
|
+
anonymousLeases: 0,
|
|
7402
7435
|
pendingAcquires: 0,
|
|
7403
7436
|
closeWhenIdle: false,
|
|
7404
7437
|
onStartedClientCallbacks: /* @__PURE__ */ new Set()
|
|
@@ -7407,53 +7440,34 @@ function getOrCreateSharedClientEntry(state, key) {
|
|
|
7407
7440
|
}
|
|
7408
7441
|
return entry;
|
|
7409
7442
|
}
|
|
7410
|
-
function
|
|
7443
|
+
function getCurrentSharedClientEntry(client) {
|
|
7411
7444
|
const state = getSharedCodexAppServerClientState();
|
|
7412
|
-
|
|
7445
|
+
const entry = client ? state.entriesByClient.get(client) : void 0;
|
|
7446
|
+
return entry && entry.client === client && state.clients.get(entry.key) === entry ? entry : void 0;
|
|
7413
7447
|
}
|
|
7414
7448
|
/** Clears a matching shared client only when no lease or acquire currently claims it. */
|
|
7415
7449
|
function clearSharedCodexAppServerClientIfCurrentAndUnclaimed(client) {
|
|
7416
|
-
|
|
7417
|
-
found: false,
|
|
7418
|
-
closed: false,
|
|
7419
|
-
activeLeases: 0,
|
|
7420
|
-
pendingAcquires: 0
|
|
7421
|
-
};
|
|
7422
|
-
const state = getSharedCodexAppServerClientState();
|
|
7423
|
-
for (const [key, entry] of state.clients) if (entry.client === client) return {
|
|
7424
|
-
found: true,
|
|
7425
|
-
closed: closeSharedClientEntryIfUnclaimed(key, entry),
|
|
7426
|
-
activeLeases: entry.activeLeases,
|
|
7427
|
-
pendingAcquires: entry.pendingAcquires
|
|
7428
|
-
};
|
|
7450
|
+
const entry = getCurrentSharedClientEntry(client);
|
|
7429
7451
|
return {
|
|
7430
|
-
found:
|
|
7431
|
-
closed: false,
|
|
7432
|
-
activeLeases: 0,
|
|
7433
|
-
pendingAcquires: 0
|
|
7452
|
+
found: entry !== void 0,
|
|
7453
|
+
closed: entry ? closeSharedClientEntryIfUnclaimed(entry) : false,
|
|
7454
|
+
activeLeases: entry?.activeLeases ?? 0,
|
|
7455
|
+
pendingAcquires: entry?.pendingAcquires ?? 0
|
|
7434
7456
|
};
|
|
7435
7457
|
}
|
|
7436
|
-
function
|
|
7458
|
+
function retainSharedClientEntry(entry, counter = "activeLeases") {
|
|
7437
7459
|
let released = false;
|
|
7438
|
-
entry
|
|
7460
|
+
entry[counter] += 1;
|
|
7439
7461
|
return () => {
|
|
7440
7462
|
if (released) return;
|
|
7441
7463
|
released = true;
|
|
7442
|
-
entry
|
|
7443
|
-
closeRetiredSharedClientEntryIfIdle(entry);
|
|
7444
|
-
notifyDesktopGenerationDrainChecks(getSharedCodexAppServerClientState());
|
|
7464
|
+
releaseSharedClientEntry(entry, counter);
|
|
7445
7465
|
};
|
|
7446
7466
|
}
|
|
7447
|
-
function
|
|
7448
|
-
|
|
7449
|
-
entry
|
|
7450
|
-
|
|
7451
|
-
if (released) return;
|
|
7452
|
-
released = true;
|
|
7453
|
-
entry.activeLeases = Math.max(0, entry.activeLeases - 1);
|
|
7454
|
-
closeRetiredSharedClientEntryIfIdle(entry);
|
|
7455
|
-
notifyDesktopGenerationDrainChecks(getSharedCodexAppServerClientState());
|
|
7456
|
-
};
|
|
7467
|
+
function releaseSharedClientEntry(entry, counter) {
|
|
7468
|
+
entry[counter] -= 1;
|
|
7469
|
+
closeRetiredSharedClientEntryIfIdle(entry);
|
|
7470
|
+
notifyDesktopGenerationDrainChecks(getSharedCodexAppServerClientState());
|
|
7457
7471
|
}
|
|
7458
7472
|
function closeRetiredSharedClientEntryIfIdle(entry) {
|
|
7459
7473
|
if (!entry.closeWhenIdle || entry.activeLeases > 0 || entry.pendingAcquires > 0 || !entry.client) return false;
|
|
@@ -7470,25 +7484,22 @@ function closeRetiredSharedClientEntry(entry) {
|
|
|
7470
7484
|
client.close();
|
|
7471
7485
|
return true;
|
|
7472
7486
|
}
|
|
7473
|
-
function closeSharedClientEntryIfUnclaimed(
|
|
7487
|
+
function closeSharedClientEntryIfUnclaimed(entry) {
|
|
7474
7488
|
if (entry.activeLeases > 0 || entry.pendingAcquires > 0) return false;
|
|
7475
7489
|
const state = getSharedCodexAppServerClientState();
|
|
7476
|
-
if (state.clients.get(key) !== entry) return false;
|
|
7477
|
-
state.clients.delete(key);
|
|
7490
|
+
if (state.clients.get(entry.key) !== entry) return false;
|
|
7491
|
+
state.clients.delete(entry.key);
|
|
7478
7492
|
entry.client?.close();
|
|
7479
7493
|
return Boolean(entry.client);
|
|
7480
7494
|
}
|
|
7481
|
-
function retirePendingSharedClientEntryIfUnclaimed(
|
|
7495
|
+
function retirePendingSharedClientEntryIfUnclaimed(entry) {
|
|
7482
7496
|
if (entry.activeLeases > 0 || entry.pendingAcquires > 0) return;
|
|
7483
7497
|
entry.startupAbort?.abort(/* @__PURE__ */ new Error("Codex app-server startup was abandoned"));
|
|
7484
7498
|
entry.closeWhenIdle = true;
|
|
7485
7499
|
const state = getSharedCodexAppServerClientState();
|
|
7486
|
-
if (state.clients.get(key) === entry) state.clients.delete(key);
|
|
7500
|
+
if (state.clients.get(entry.key) === entry) state.clients.delete(entry.key);
|
|
7487
7501
|
if (!entry.client) return;
|
|
7488
7502
|
closeRetiredSharedClientEntry(entry);
|
|
7489
7503
|
}
|
|
7490
|
-
function collectSharedClients(state) {
|
|
7491
|
-
return [...state.liveClients];
|
|
7492
|
-
}
|
|
7493
7504
|
//#endregion
|
|
7494
|
-
export {
|
|
7505
|
+
export { assertCodexThreadForkParams as $, TURN_FINALIZE_DRAIN_ABORT_GRACE_MS as A, readCodexClientSessionMeta as At, isCodexAppServerIndeterminateRequestCancellationError as B, resolveCodexAppServerAuthAccountCacheKey as Bt, withLeasedCodexAppServerClientStartSelectionRetry as C, claimCodexAppServerLiveThread as Ct, acquireCodexNativeConfigFence as D, isCodexAppServerClientRuntimeLive as Dt, CodexThreadStartRequestError as E, hasCodexAppServerLiveThread as Et, withCodexStartupTimeout as F, withTimeout$1 as Ft, isUnsupportedCodexAppServerVersionError as G, resolveCodexAppServerPreparedApiKeyCacheKey as Gt, isCodexAppServerOverloadError as H, resolveCodexAppServerAuthProfileIdForAgent as Ht, getCodexAppServerClientInstanceId as I, readCodexRateLimitsRevision as It, isCodexThreadReadMissingError as J, assertNotSymlink as Jt, resolveCodexAppServerClientInstanceId as K, resolveCodexAppServerPreparedAuthHandoff as Kt, isCodexAppServerApprovalRequest as L, readRecentCodexRateLimits as Lt, isCodexAppServerStartupError as M, retainCodexAppServerLiveThread as Mt, resolveCodexGatewayTimeoutWithGraceMs as N, unsubscribeCodexAppServerLiveThread as Nt, createCodexDesktopGenerationService as O, isCodexAppServerLiveThreadClaimed as Ot, resolveCodexStartupTimeoutMs as P, withAbortableTimeout as Pt, assertCodexThreadAcceptsDirectInput as Q, isCodexAppServerBrokenPipeError as R, rememberCodexRateLimitsRead as Rt, waitForCodexAppServerClientDesktopGenerationDrain as S, withDynamicToolTranscriptDetails as St, CodexThreadBindingConflictError as T, ensureCodexAppServerClientRuntime as Tt, isCodexAppServerPrewriteRequestCancellationError as U, resolveCodexAppServerAuthProfileStore as Ut, isCodexAppServerIndeterminateTransportError as V, resolveCodexAppServerAuthProfileId as Vt, isCodexAppServerRequestTimeoutError as W, resolveCodexAppServerFallbackApiKeyCacheKey as Wt, assertCodexModelListResponse as X, readCodexSessionMeta as Xt, CodexThreadDirectInputError as Y, isOpenClawManagedCodexThread as Yt, assertCodexPassiveTurnItems as Z, retainSharedCodexAppServerClientByInstanceId as _, toCodexDynamicToolProgressResponse as _t, clearSharedCodexAppServerClientIfCurrentAndUnclaimed as a, readCodexErrorNotification as at, retireSharedCodexAppServerClientsBeforeDesktopGeneration as b, createFailedDynamicToolResponse as bt, getLeasedSharedCodexAppServerClient as c, createCodexElicitationResponse as ct, readCodexAppServerClientDesktopGeneration as d, isDynamicToolTerminalDiagnosticEvent as dt, assertCodexThreadForkResponse as et, readCodexAppServerClientDesktopGenerationFingerprint as f, isMatchingDynamicToolTerminalDiagnostic as ft, resolveCodexNativeConfigFenceKey as g, shouldReleaseTurnAfterTerminalDynamicTool as gt, releaseLeasedSharedCodexAppServerClient as h, shouldBlockTerminalReleaseForNonTerminalDynamicToolResult as ht, clearSharedCodexAppServerClientIfCurrent as i, readCodexDynamicToolCallParams as it, TURN_TERMINAL_SETTLEMENT_TIMEOUT_MS as j, releaseCodexAppServerLiveThread as jt, CodexAppServerStartupError as k, protectCodexAppServerLiveThread as kt, getSharedCodexAppServerClient as l, handleDynamicToolCallWithTimeout as lt, releaseCodexAppServerClientLease as m, resolveTerminalDynamicToolBatchAction as mt, captureCodexAppServerClientLifetime as n, assertCodexThreadStartResponse as nt, clearSharedCodexAppServerClientIfCurrentAndWait as o, readCodexTurn as ot, readCodexAppServerClientProcessIdentity as p, resolveDynamicToolCallTimeoutMs as pt, CodexAppServerRpcError as q, resolveCodexManagedBundledMarketplacePath as qt, captureSharedCodexAppServerCatalogLifetime as r, assertCodexTurnStartResponse as rt, createIsolatedCodexAppServerClient as s, readCodexTurnCompletedNotification as st, assertCodexAppServerClientStartSelectionCurrent as t, assertCodexThreadResumeResponse as tt, isCodexAppServerStartSelectionChangedError as u, hasPendingDynamicToolTerminalDiagnostic as ut, retainSharedCodexAppServerClientIfCurrent as v, toCodexDynamicToolProtocolResponse as vt, CodexAdoptedThreadActiveError as w, consumeCodexAppServerLiveThread as wt, shared_client_exports as x, withDynamicToolExecutionState as xt, retireSharedCodexAppServerClientIfCurrent as y, resolveCodexToolAbortTerminalReason as yt, isCodexAppServerConnectionClosedError as z, reconcileCodexComputerUseStartArtifacts as zt };
|