@openclaw/codex 2026.7.2-beta.3 → 2026.7.2-beta.5
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/{app-server-policy-DUMF2Xyr.js → app-server-policy-BmDgseo_.js} +1 -1
- package/dist/attempt-client-cleanup-Ia52yRWc.js +127 -0
- package/dist/{attempt-notifications-Ecjyzufe.js → attempt-notifications-CMR2_fmR.js} +1 -1
- package/dist/{media-understanding-provider-IPNNQre6.js → bounded-turn-FEbUXoYT.js} +71 -188
- package/dist/capabilities-BHRSI6Cn.js +36 -0
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-NCTL7A2q.js → command-formatters-ico4ZFnk.js} +3 -37
- package/dist/{command-handlers-DtFbZiba.js → command-handlers-CRmnwI2N.js} +1233 -1221
- package/dist/{compact-Kgy26gIM.js → compact-dEN49UH6.js} +8 -7
- package/dist/{computer-use-C7x4ZaqR.js → computer-use-BjGylO-E.js} +16 -6
- package/dist/{conversation-control-B0s3aIjT.js → conversation-control-DE7d9DOj.js} +6 -5
- package/dist/doctor-contract-api.js +24 -86
- package/dist/{dynamic-tools-D_vSVmv9.js → dynamic-tools-LIt9ojep.js} +135 -2696
- package/dist/event-projector-assistant-message-DTgnPPVF.js +101 -0
- package/dist/event-projector-usage-tvgb1NCX.js +69 -0
- package/dist/harness.js +31 -11
- package/dist/incognito-session-ET_ufDH-.js +2 -0
- package/dist/index.js +250 -275
- package/dist/media-understanding-provider.js +173 -1
- package/dist/{models-DD5zBdX5.js → models-BA01NEez.js} +2 -2
- package/dist/{notification-correlation-C8DVQ_Bq.js → notification-correlation-Bj_Ak_jI.js} +3 -3
- package/dist/{plugin-app-cache-key-DJbhLYSK.js → plugin-app-cache-key-DSXX-rXO.js} +5 -5
- package/dist/{transcript-mirror-D9rTxx2P.js → protocol-validators-Dm4eXZmt.js} +335 -595
- package/dist/{rate-limits-CqhWQ2R9.js → rate-limits-S_PXs0ul.js} +1 -1
- package/dist/realtime-voice-api-BPcA1uN9.js +494 -0
- package/dist/realtime-voice-api.js +2 -0
- package/dist/{request-9yf9pZjf.js → request-CXpPennK.js} +1 -1
- package/dist/{run-attempt-BIoO8ISr.js → run-attempt-C5GTPJOE.js} +3111 -387
- package/dist/{session-binding-Bmt20HfB.js → session-binding-DlVQ-Pxs.js} +957 -890
- package/dist/{session-catalog-CA7R-hX2.js → session-catalog-CP2oCcEb.js} +98 -87
- package/dist/{session-cli-Bxk3-Wqz.js → session-cli-CqZ0Fp2a.js} +2 -2
- package/dist/session-upstream-marker-QE-m5QFG.js +82 -0
- package/dist/settled-turn-finalizer-CA_2QXIE.js +303 -0
- package/dist/{shared-client-CSXLtCLE.js → shared-client-BVKE40c-.js} +1870 -1694
- package/dist/{side-question-DtzquMOb.js → side-question-CO12sHxo.js} +24 -16
- package/dist/{thread-lifecycle-CQ_9mAa1.js → thread-lifecycle-DRg_FdzC.js} +127 -153
- package/dist/transcript-mirror-uKA-A4tB.js +550 -0
- package/dist/upstream-session-fork-_Vrz4WJr.js +320 -0
- package/dist/{usage-CuPpFgTc.js → usage-UpVbdX5G.js} +3 -3
- package/dist/{web-search-provider.runtime-_x5XTeqh.js → web-search-provider.runtime-CaQMYDbp.js} +3 -3
- package/package.json +7 -8
- package/npm-shrinkwrap.json +0 -202
- package/dist/{auth-binding-C1czuHPA.js → auth-binding-B4FfbcCg.js} +1 -1
package/dist/index.js
CHANGED
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import { registerCodexCliMetadata } from "./cli-metadata.js";
|
|
2
2
|
import { createCodexAppServerAgentHarness } from "./harness.js";
|
|
3
|
-
import {
|
|
4
|
-
import { D as resolveOpenClawExecPolicyForCodexAppServer,
|
|
5
|
-
import { d as assertCodexThreadStartResponse } from "./transcript-mirror-D9rTxx2P.js";
|
|
6
|
-
import { i as defaultCodexAppInventoryCache, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-DJbhLYSK.js";
|
|
7
|
-
import { X as ensureCodexPluginActivation, Z as pluginReadParams, c as resumeCodexAppServerThread, h as resolveCodexAppServerRequestModelSelection, p as CODEX_NATIVE_PERSONALITY_NONE } from "./thread-lifecycle-CQ_9mAa1.js";
|
|
3
|
+
import { N as resolveCodexAppServerAuthProfileIdForAgent, P as resolveCodexAppServerFallbackApiKeyCacheKey, R as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS, V as isJsonObject, a as getLeasedSharedCodexAppServerClient, c as releaseCodexAppServerClientLease, j as resolveCodexAppServerAuthAccountCacheKey, l as releaseLeasedSharedCodexAppServerClient, m as withLeasedCodexAppServerClientStartSelectionRetry, r as clearSharedCodexAppServerClientIfCurrentAndWait } from "./shared-client-BVKE40c-.js";
|
|
4
|
+
import { D as resolveOpenClawExecPolicyForCodexAppServer, T as readCodexPluginConfig, _ as assertCodexAppServerConnectionSecurity, b as canUseCodexModelBackedApprovalsReviewerForModel, d as codexAppServerStartOptionsKey, f as codexSandboxPolicyForTurn, g as resolveCodexSupervisionAppServerRuntimeOptions, k as CODEX_PLUGINS_MARKETPLACE_NAME, l as sessionBindingIdentity, n as assertCodexBindingMayBeReplaced, o as isCodexAppServerNativeAuthProfile, p as resolveCodexAppServerRuntimeOptions, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-DlVQ-Pxs.js";
|
|
8
5
|
import { n as CODEX_APP_SERVER_BINDING_NAMESPACE, t as CODEX_APP_SERVER_BINDING_MAX_ENTRIES } from "./session-binding-meta-B7aEMU7g.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
6
|
+
import { n as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, u as unsubscribeCodexThreadBestEffort } from "./attempt-client-cleanup-Ia52yRWc.js";
|
|
7
|
+
import { J as pluginReadParams, _ as CODEX_NATIVE_PERSONALITY_NONE, c as resumeCodexAppServerThread, q as ensureCodexPluginActivation, y as resolveCodexAppServerRequestModelSelection } from "./thread-lifecycle-DRg_FdzC.js";
|
|
8
|
+
import { i as assertCodexThreadStartResponse } from "./protocol-validators-Dm4eXZmt.js";
|
|
9
|
+
import { i as defaultCodexAppInventoryCache, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-DSXX-rXO.js";
|
|
10
|
+
import { t as isIncognitoSessionKey } from "./incognito-session-ET_ufDH-.js";
|
|
11
|
+
import { buildCodexMediaUnderstandingProvider } from "./media-understanding-provider.js";
|
|
12
|
+
import { n as CODEX_REALTIME_OFFER_PATH, t as configureCodexRealtimeBrowserSession } from "./realtime-voice-api-BPcA1uN9.js";
|
|
13
|
+
import { n as describeControlFailure, t as CODEX_CONTROL_METHODS } from "./capabilities-BHRSI6Cn.js";
|
|
14
|
+
import { r as formatCodexDisplayText } from "./command-formatters-ico4ZFnk.js";
|
|
15
|
+
import { t as resolveCodexAppServerForModelProvider } from "./app-server-policy-BmDgseo_.js";
|
|
12
16
|
import { n as resolveCodexNativeExecutionBlock, r as resolveCodexNativeSandboxBlock } from "./sandbox-guard-D1Wky__S.js";
|
|
13
|
-
import { d as CODEX_NATIVE_EXECUTION_AUTH_ERROR, f as canMutateCodexHost, u as trackCodexConversationActiveTurn } from "./conversation-control-
|
|
17
|
+
import { d as CODEX_NATIVE_EXECUTION_AUTH_ERROR, f as canMutateCodexHost, u as trackCodexConversationActiveTurn } from "./conversation-control-DE7d9DOj.js";
|
|
14
18
|
import { a as readCodexConversationBindingDataRecord, i as readCodexConversationBindingData, o as resolveCodexDefaultWorkspaceDir, r as createCodexConversationBindingData } from "./conversation-binding-data-BHRpYbX3.js";
|
|
15
|
-
import { a as resolveCodexBindingAppServerConnection, n as readCodexNotificationThreadId, r as readCodexNotificationTurnId } from "./notification-correlation-
|
|
16
|
-
import { d as createCodexCliSessionNodeHostCommands, f as createCodexCliSessionNodeInvokePolicies, g as resumeCodexCliSessionOnNode, h as resolveCodexCliSessionForBindingOnNode, i as createCodexSessionCatalogNodeInvokePolicies, m as listCodexCliSessionsOnNode, n as createCodexSessionCatalogControl, o as codexControlRequest, r as createCodexSessionCatalogNodeHostCommands, t as codexSessionCatalogRuntime, u as assertCodexArchiveDescendantsUnowned } from "./session-catalog-
|
|
17
|
-
import { r as requestCodexAppServerJson } from "./request-
|
|
19
|
+
import { a as resolveCodexBindingAppServerConnection, n as readCodexNotificationThreadId, r as readCodexNotificationTurnId } from "./notification-correlation-Bj_Ak_jI.js";
|
|
20
|
+
import { d as createCodexCliSessionNodeHostCommands, f as createCodexCliSessionNodeInvokePolicies, g as resumeCodexCliSessionOnNode, h as resolveCodexCliSessionForBindingOnNode, i as createCodexSessionCatalogNodeInvokePolicies, m as listCodexCliSessionsOnNode, n as createCodexSessionCatalogControl, o as codexControlRequest, r as createCodexSessionCatalogNodeHostCommands, t as codexSessionCatalogRuntime, u as assertCodexArchiveDescendantsUnowned } from "./session-catalog-CP2oCcEb.js";
|
|
21
|
+
import { r as requestCodexAppServerJson } from "./request-CXpPennK.js";
|
|
18
22
|
import { t as createCodexWebSearchProviderBase } from "./web-search-provider.shared-BrZmlqyR.js";
|
|
19
23
|
import { mutateConfigFile } from "openclaw/plugin-sdk/config-mutation";
|
|
20
24
|
import { normalizePluginsConfig, resolveEffectiveEnableState, resolveLivePluginConfigObject, resolvePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
@@ -22,19 +26,19 @@ import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
|
22
26
|
import fs from "node:fs/promises";
|
|
23
27
|
import path from "node:path";
|
|
24
28
|
import { parseStrictNonNegativeInteger, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
29
|
+
import { formatErrorMessage, resolveSandboxContext } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
30
|
+
import { loadAuthProfileStoreWithoutExternalProfiles, resolveAgentConfig, resolveAgentWorkspaceDir, resolveDefaultAgentDir, resolveDefaultAgentId, resolveSessionAgentIds as resolveSessionAgentIds$1 } from "openclaw/plugin-sdk/agent-runtime";
|
|
25
31
|
import os from "node:os";
|
|
26
|
-
import {
|
|
32
|
+
import { applyAuthProfileConfig, buildApiKeyCredential, buildOauthProviderAuthResult, buildOpenAICodexCredentialExtra, readCodexCliCredentialsCached, resolveOpenAICodexAuthIdentity, resolveOpenAICodexImportProfileName, updateAuthProfileStoreWithLock } from "openclaw/plugin-sdk/provider-auth";
|
|
27
33
|
import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
|
|
28
34
|
import { asBoolean, asOptionalRecord, isRecord, normalizeOptionalString, normalizeSingleOrTrimmedStringList, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
29
|
-
import { formatErrorMessage, resolveSandboxContext } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
30
|
-
import { applyAuthProfileConfig, buildApiKeyCredential, buildOauthProviderAuthResult, buildOpenAICodexCredentialExtra, readCodexCliCredentialsCached, resolveOpenAICodexAuthIdentity, resolveOpenAICodexImportProfileName, updateAuthProfileStoreWithLock } from "openclaw/plugin-sdk/provider-auth";
|
|
31
35
|
import { getSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
32
36
|
import { fileURLToPath } from "node:url";
|
|
33
37
|
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
34
|
-
import { canonicalPathFromExistingAncestor, isPathInside, pathExists } from "openclaw/plugin-sdk/security-runtime";
|
|
38
|
+
import { canonicalPathFromExistingAncestor, extractErrorCode, isPathInside, pathExists } from "openclaw/plugin-sdk/security-runtime";
|
|
35
39
|
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
|
|
36
40
|
import { ModelSelectionLockedError, isModelSelectionLocked } from "openclaw/plugin-sdk/model-session-runtime";
|
|
37
|
-
import { MIGRATION_REASON_TARGET_EXISTS, applyMigrationManualItem, createMigrationItem, createMigrationManualItem, hasMigrationConfigPatchConflict, markMigrationItemConflict, markMigrationItemError, markMigrationItemSkipped, readMigrationConfigPath, summarizeMigrationItems, writeMigrationConfigPath } from "openclaw/plugin-sdk/migration";
|
|
41
|
+
import { MIGRATION_REASON_TARGET_EXISTS, applyMigrationManualItem, createMigrationItem, createMigrationManualItem, hasMigrationConfigPatchConflict, markMigrationItemConflict, markMigrationItemError, markMigrationItemSkipped, mergeMigrationConfigValue, readMigrationConfigPath, resolveMigrationConfigRuntime, summarizeMigrationItems, writeMigrationConfigPath } from "openclaw/plugin-sdk/migration";
|
|
38
42
|
import { archiveMigrationItem, copyMemoryMigrationFileItem, copyMigrationFileItem, withCachedMigrationConfigRuntime, writeMigrationReport } from "openclaw/plugin-sdk/migration-runtime";
|
|
39
43
|
import { sleep } from "openclaw/plugin-sdk/runtime-env";
|
|
40
44
|
import { readJsonFileWithFallback } from "openclaw/plugin-sdk/json-store";
|
|
@@ -45,13 +49,14 @@ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
|
45
49
|
/** Defers schema compilation and auth loading until the first binding operation. */
|
|
46
50
|
function createLazyCodexAppServerBindingStore(state) {
|
|
47
51
|
let resolved;
|
|
48
|
-
const store = () => resolved ??= import("./session-binding-
|
|
52
|
+
const store = () => resolved ??= import("./session-binding-DlVQ-Pxs.js").then((n) => n.u).then(({ createCodexAppServerBindingStore }) => createCodexAppServerBindingStore(state));
|
|
49
53
|
return {
|
|
50
54
|
read: async (identity) => (await store()).read(identity),
|
|
51
55
|
hasOtherThreadOwner: async (threadId, currentIdentity) => (await store()).hasOtherThreadOwner(threadId, currentIdentity),
|
|
52
56
|
mutate: async (identity, mutation) => (await store()).mutate(identity, mutation),
|
|
53
57
|
prepareSessionGenerationReclaim: async (identity) => (await store()).prepareSessionGenerationReclaim(identity),
|
|
54
58
|
adoptSessionGeneration: async (identity, previousSessionId) => (await store()).adoptSessionGeneration(identity, previousSessionId),
|
|
59
|
+
resetSessionGeneration: async (identity) => (await store()).resetSessionGeneration(identity),
|
|
55
60
|
retireSessionGeneration: async (identity) => (await store()).retireSessionGeneration(identity),
|
|
56
61
|
withThreadArchiveFence: async (run) => (await store()).withThreadArchiveFence(run),
|
|
57
62
|
withLease: async (identity, run) => (await store()).withLease(identity, run)
|
|
@@ -72,7 +77,7 @@ async function handleCodexCommand(ctx, options) {
|
|
|
72
77
|
}
|
|
73
78
|
}
|
|
74
79
|
async function loadDefaultCodexSubcommandHandler() {
|
|
75
|
-
const { handleCodexSubcommand } = await import("./command-handlers-
|
|
80
|
+
const { handleCodexSubcommand } = await import("./command-handlers-CRmnwI2N.js");
|
|
76
81
|
return handleCodexSubcommand;
|
|
77
82
|
}
|
|
78
83
|
//#endregion
|
|
@@ -569,7 +574,8 @@ async function requestNewConversationBindingThread(params, resolved) {
|
|
|
569
574
|
personality: CODEX_NATIVE_PERSONALITY_NONE,
|
|
570
575
|
...buildThreadRequestRuntimeOptions(params, resolved),
|
|
571
576
|
developerInstructions: CODEX_CONVERSATION_THREAD_DEVELOPER_INSTRUCTIONS,
|
|
572
|
-
experimentalRawEvents: true
|
|
577
|
+
experimentalRawEvents: true,
|
|
578
|
+
...isIncognitoSessionKey(params.sessionKey) ? { ephemeral: true } : {}
|
|
573
579
|
}, requestOptions),
|
|
574
580
|
onClientChange: (client) => {
|
|
575
581
|
resolved.client = client;
|
|
@@ -717,7 +723,8 @@ async function runBoundTurn(params) {
|
|
|
717
723
|
...modelScopedRuntime.networkProxy ? { config: modelScopedRuntime.networkProxy.configPatch } : { sandbox },
|
|
718
724
|
...serviceTier ? { serviceTier } : {},
|
|
719
725
|
developerInstructions: CODEX_CONVERSATION_THREAD_DEVELOPER_INSTRUCTIONS,
|
|
720
|
-
experimentalRawEvents: true
|
|
726
|
+
experimentalRawEvents: true,
|
|
727
|
+
...isIncognitoSessionKey(params.sessionKey) ? { ephemeral: true } : {}
|
|
721
728
|
}, requestOptions),
|
|
722
729
|
onClientChange: (nextClient) => {
|
|
723
730
|
client = nextClient;
|
|
@@ -834,6 +841,19 @@ async function runBoundTurn(params) {
|
|
|
834
841
|
});
|
|
835
842
|
collector.setTurnId(turnId);
|
|
836
843
|
return { reply: { text: (await collector.wait({ timeoutMs: params.timeoutMs ?? DEFAULT_BOUND_TURN_TIMEOUT_MS }).finally(activeCleanup)).replyText.trim() || "Codex completed without a text reply." } };
|
|
844
|
+
} catch (error) {
|
|
845
|
+
if (isIncognitoSessionKey(params.sessionKey)) {
|
|
846
|
+
const bindingReleased = await params.bindingStore.mutate(identity, {
|
|
847
|
+
kind: "clear",
|
|
848
|
+
threadId
|
|
849
|
+
});
|
|
850
|
+
const timedOut = error instanceof Error && error.message === "codex app-server bound turn timed out";
|
|
851
|
+
if (bindingReleased && !timedOut) await unsubscribeCodexThreadBestEffort(client, {
|
|
852
|
+
threadId,
|
|
853
|
+
timeoutMs: CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
throw error;
|
|
837
857
|
} finally {
|
|
838
858
|
notificationCleanup();
|
|
839
859
|
requestCleanup();
|
|
@@ -920,7 +940,7 @@ async function prepareConversationBinding(params, options = {}) {
|
|
|
920
940
|
});
|
|
921
941
|
}
|
|
922
942
|
function resolveConversationExecPolicy(params) {
|
|
923
|
-
const agentId = params.agentId ?? (params.config ? resolveSessionAgentIds({
|
|
943
|
+
const agentId = params.agentId ?? (params.config ? resolveSessionAgentIds$1({
|
|
924
944
|
sessionKey: params.sessionKey,
|
|
925
945
|
config: params.config
|
|
926
946
|
}).sessionAgentId : void 0);
|
|
@@ -1121,11 +1141,6 @@ async function readModelRefs(source) {
|
|
|
1121
1141
|
refs.add(OPENAI_CODEX_DEFAULT_MODEL);
|
|
1122
1142
|
return [...refs].toSorted();
|
|
1123
1143
|
}
|
|
1124
|
-
function readProviderAuthModelConfigs(result) {
|
|
1125
|
-
const models = result.configPatch?.agents?.defaults?.models;
|
|
1126
|
-
if (isRecord(models)) return { ...models };
|
|
1127
|
-
return { [normalizeOptionalString(result.defaultModel) ?? OPENAI_CODEX_DEFAULT_MODEL]: {} };
|
|
1128
|
-
}
|
|
1129
1144
|
async function buildCodexOAuthCredential(source) {
|
|
1130
1145
|
const credential = readCodexCliCredentialsCached({
|
|
1131
1146
|
codexHome: source.codexHome,
|
|
@@ -1160,8 +1175,7 @@ async function buildCodexOAuthCredential(source) {
|
|
|
1160
1175
|
kind: "oauth",
|
|
1161
1176
|
provider: OPENAI_PROVIDER_ID,
|
|
1162
1177
|
profileId: profile.profileId,
|
|
1163
|
-
result
|
|
1164
|
-
modelConfigs: readProviderAuthModelConfigs(result)
|
|
1178
|
+
result
|
|
1165
1179
|
} : null;
|
|
1166
1180
|
}
|
|
1167
1181
|
async function buildCodexApiKeyCredential(source) {
|
|
@@ -1219,7 +1233,7 @@ function hasAuthProfileConfigConflict(config, profile, overwrite) {
|
|
|
1219
1233
|
function hasCurrentAuthProfileConfigConflict(ctx, profile) {
|
|
1220
1234
|
let config = ctx.config;
|
|
1221
1235
|
try {
|
|
1222
|
-
config = ctx
|
|
1236
|
+
config = resolveMigrationConfigRuntime(ctx)?.current?.() ?? config;
|
|
1223
1237
|
} catch {}
|
|
1224
1238
|
return hasAuthProfileConfigConflict(config, profile, Boolean(ctx.overwrite));
|
|
1225
1239
|
}
|
|
@@ -1240,30 +1254,8 @@ function applyDefaultModelIfMissing(cfg) {
|
|
|
1240
1254
|
}
|
|
1241
1255
|
};
|
|
1242
1256
|
}
|
|
1243
|
-
function mergeModelConfigEntry(existing, patch) {
|
|
1244
|
-
if (existing && isRecord(existing) && isRecord(patch)) return {
|
|
1245
|
-
...existing,
|
|
1246
|
-
...patch
|
|
1247
|
-
};
|
|
1248
|
-
return existing ?? patch;
|
|
1249
|
-
}
|
|
1250
|
-
function applyOAuthModelConfigsToConfig(cfg, credential) {
|
|
1251
|
-
const existingModels = cfg.agents?.defaults?.models ?? {};
|
|
1252
|
-
const models = credential.result.replaceDefaultModels ? { ...credential.modelConfigs } : { ...existingModels };
|
|
1253
|
-
if (!credential.result.replaceDefaultModels) for (const [modelRef, modelConfig] of Object.entries(credential.modelConfigs)) models[modelRef] = mergeModelConfigEntry(models[modelRef], modelConfig);
|
|
1254
|
-
return {
|
|
1255
|
-
...cfg,
|
|
1256
|
-
agents: {
|
|
1257
|
-
...cfg.agents,
|
|
1258
|
-
defaults: {
|
|
1259
|
-
...cfg.agents?.defaults,
|
|
1260
|
-
models
|
|
1261
|
-
}
|
|
1262
|
-
}
|
|
1263
|
-
};
|
|
1264
|
-
}
|
|
1265
1257
|
function applyOAuthConfigToConfig(cfg, credential, profileId) {
|
|
1266
|
-
let next =
|
|
1258
|
+
let next = mergeMigrationConfigValue(cfg, credential.result.configPatch);
|
|
1267
1259
|
const profile = credential.result.profiles[0];
|
|
1268
1260
|
if (profile) next = applyAuthProfileConfig(next, {
|
|
1269
1261
|
profileId,
|
|
@@ -1287,30 +1279,25 @@ function applyApiKeyConfigToConfig(cfg, credential, profileId) {
|
|
|
1287
1279
|
function shouldReturnAuthConfigPatch(ctx) {
|
|
1288
1280
|
return ctx.providerOptions?.configPatchMode === CODEX_CONFIG_PATCH_MODE_RETURN$1;
|
|
1289
1281
|
}
|
|
1290
|
-
function
|
|
1282
|
+
function authProfileConfigForCredential(credential, profileId) {
|
|
1283
|
+
if (credential.kind === "api_key") return {
|
|
1284
|
+
profileId,
|
|
1285
|
+
provider: credential.provider,
|
|
1286
|
+
mode: "api_key",
|
|
1287
|
+
displayName: CODEX_IMPORT_DISPLAY_NAME
|
|
1288
|
+
};
|
|
1291
1289
|
const profile = credential.result.profiles[0];
|
|
1292
1290
|
if (!profile || profile.credential.type !== "oauth") return null;
|
|
1293
1291
|
return {
|
|
1294
1292
|
profileId,
|
|
1295
1293
|
provider: profile.credential.provider,
|
|
1296
1294
|
mode: "oauth",
|
|
1297
|
-
...
|
|
1298
|
-
...
|
|
1299
|
-
};
|
|
1300
|
-
}
|
|
1301
|
-
function apiKeyAuthProfileConfig(credential, profileId) {
|
|
1302
|
-
return {
|
|
1303
|
-
profileId,
|
|
1304
|
-
provider: credential.provider,
|
|
1305
|
-
mode: "api_key",
|
|
1306
|
-
displayName: CODEX_IMPORT_DISPLAY_NAME
|
|
1295
|
+
...profile.credential.email ? { email: profile.credential.email } : {},
|
|
1296
|
+
...profile.credential.displayName ? { displayName: profile.credential.displayName } : {}
|
|
1307
1297
|
};
|
|
1308
1298
|
}
|
|
1309
|
-
function authProfileConfigForCredential(credential, profileId) {
|
|
1310
|
-
return credential.kind === "oauth" ? oauthAuthProfileConfig(credential, profileId) : apiKeyAuthProfileConfig(credential, profileId);
|
|
1311
|
-
}
|
|
1312
1299
|
async function applyCodexAuthProfileConfig(ctx, profile, applyConfig) {
|
|
1313
|
-
const configApi = ctx
|
|
1300
|
+
const configApi = resolveMigrationConfigRuntime(ctx);
|
|
1314
1301
|
if (!configApi?.current || !configApi.mutateConfigFile) return "unavailable";
|
|
1315
1302
|
try {
|
|
1316
1303
|
await configApi.mutateConfigFile({
|
|
@@ -1327,13 +1314,13 @@ async function applyCodexAuthProfileConfig(ctx, profile, applyConfig) {
|
|
|
1327
1314
|
return error instanceof CodexAuthConfigConflict ? "conflict" : "unavailable";
|
|
1328
1315
|
}
|
|
1329
1316
|
}
|
|
1330
|
-
async function
|
|
1331
|
-
const profile =
|
|
1317
|
+
async function applyCodexAuthConfig(ctx, credential, profileId) {
|
|
1318
|
+
const profile = authProfileConfigForCredential(credential, profileId);
|
|
1332
1319
|
if (!profile) return "unavailable";
|
|
1333
|
-
return applyCodexAuthProfileConfig(ctx, profile, (config) =>
|
|
1320
|
+
return applyCodexAuthProfileConfig(ctx, profile, (config) => applyCredentialConfig(config, credential, profileId));
|
|
1334
1321
|
}
|
|
1335
|
-
|
|
1336
|
-
return
|
|
1322
|
+
function applyCredentialConfig(config, credential, profileId) {
|
|
1323
|
+
return credential.kind === "oauth" ? applyOAuthConfigToConfig(config, credential, profileId) : applyApiKeyConfigToConfig(config, credential, profileId);
|
|
1337
1324
|
}
|
|
1338
1325
|
async function buildCodexAuthItems(params) {
|
|
1339
1326
|
const credentials = await readCodexAuthCredentials(params.source);
|
|
@@ -1366,26 +1353,27 @@ async function buildCodexAuthItems(params) {
|
|
|
1366
1353
|
});
|
|
1367
1354
|
});
|
|
1368
1355
|
}
|
|
1369
|
-
async function
|
|
1356
|
+
async function applyCodexAuthItems(params) {
|
|
1370
1357
|
const { ctx, item, source, targets } = params;
|
|
1371
|
-
if (item.status !== "planned") return item;
|
|
1358
|
+
if (item.status !== "planned") return [item];
|
|
1372
1359
|
const profileId = typeof item.details?.profileId === "string" ? item.details.profileId : "";
|
|
1373
1360
|
const provider = typeof item.details?.provider === "string" ? item.details.provider : "";
|
|
1374
1361
|
const sourceProfileId = typeof item.details?.sourceProfileId === "string" ? item.details.sourceProfileId : void 0;
|
|
1375
|
-
if (!profileId || !provider) return markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA);
|
|
1362
|
+
if (!profileId || !provider) return [markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA)];
|
|
1376
1363
|
const credential = (await readCodexAuthCredentials(source)).find((candidate) => candidate.provider === provider);
|
|
1377
|
-
if (!credential) return markMigrationItemSkipped(item, CODEX_REASON_AUTH_NO_LONGER_PRESENT);
|
|
1378
|
-
if (credential.kind === "oauth" && sourceProfileId && credential.profileId !== sourceProfileId) return markMigrationItemSkipped(item, CODEX_REASON_AUTH_NO_LONGER_PRESENT);
|
|
1364
|
+
if (!credential) return [markMigrationItemSkipped(item, CODEX_REASON_AUTH_NO_LONGER_PRESENT)];
|
|
1365
|
+
if (credential.kind === "oauth" && sourceProfileId && credential.profileId !== sourceProfileId) return [markMigrationItemSkipped(item, CODEX_REASON_AUTH_NO_LONGER_PRESENT)];
|
|
1379
1366
|
const oauthProfile = credential.kind === "oauth" ? credential.result.profiles[0] : void 0;
|
|
1380
1367
|
const oauthCredential = oauthProfile?.credential.type === "oauth" ? oauthProfile.credential : void 0;
|
|
1381
|
-
if (credential.kind === "oauth" && !oauthCredential) return markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA);
|
|
1368
|
+
if (credential.kind === "oauth" && !oauthCredential) return [markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA)];
|
|
1382
1369
|
const configProfile = authProfileConfigForCredential(credential, profileId);
|
|
1383
|
-
if (!configProfile) return markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA);
|
|
1384
|
-
if (hasCurrentAuthProfileConfigConflict(ctx, configProfile)) return markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS);
|
|
1370
|
+
if (!configProfile) return [markMigrationItemError(item, CODEX_REASON_MISSING_AUTH_METADATA)];
|
|
1371
|
+
if (hasCurrentAuthProfileConfigConflict(ctx, configProfile)) return [markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS)];
|
|
1385
1372
|
let conflicted = false;
|
|
1386
1373
|
let wrote = false;
|
|
1387
1374
|
const store = await updateAuthProfileStoreWithLock({
|
|
1388
1375
|
agentDir: targets.agentDir,
|
|
1376
|
+
stateDir: ctx.stateDir,
|
|
1389
1377
|
updater: (freshStore) => {
|
|
1390
1378
|
const existing = freshStore.profiles[profileId];
|
|
1391
1379
|
if (!ctx.overwrite && existing) {
|
|
@@ -1404,11 +1392,11 @@ async function applyCodexAuthItem(params) {
|
|
|
1404
1392
|
return true;
|
|
1405
1393
|
}
|
|
1406
1394
|
});
|
|
1407
|
-
if (conflicted) return markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS);
|
|
1408
|
-
if (!store?.profiles[profileId]) return markMigrationItemError(item, CODEX_REASON_AUTH_PROFILE_WRITE_FAILED);
|
|
1409
|
-
const configResult = shouldReturnAuthConfigPatch(ctx) ? "unavailable" :
|
|
1410
|
-
if (configResult === "conflict") return markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS);
|
|
1411
|
-
|
|
1395
|
+
if (conflicted) return [markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS)];
|
|
1396
|
+
if (!store?.profiles[profileId]) return [markMigrationItemError(item, CODEX_REASON_AUTH_PROFILE_WRITE_FAILED)];
|
|
1397
|
+
const configResult = shouldReturnAuthConfigPatch(ctx) ? "unavailable" : await applyCodexAuthConfig(ctx, credential, profileId);
|
|
1398
|
+
if (configResult === "conflict") return [markMigrationItemConflict(item, CODEX_REASON_AUTH_PROFILE_EXISTS)];
|
|
1399
|
+
const migratedItem = {
|
|
1412
1400
|
...item,
|
|
1413
1401
|
status: "migrated",
|
|
1414
1402
|
details: {
|
|
@@ -1418,18 +1406,10 @@ async function applyCodexAuthItem(params) {
|
|
|
1418
1406
|
...shouldReturnAuthConfigPatch(ctx) ? { configPatchReturned: true } : {}
|
|
1419
1407
|
}
|
|
1420
1408
|
};
|
|
1409
|
+
return [migratedItem, ...shouldReturnAuthConfigPatch(ctx) ? buildCodexAuthConfigPatchItems(ctx, migratedItem, credential, profileId) : []];
|
|
1421
1410
|
}
|
|
1422
|
-
|
|
1423
|
-
const
|
|
1424
|
-
if (item.status !== "migrated" || !shouldReturnAuthConfigPatch(ctx)) return [];
|
|
1425
|
-
const profileId = typeof item.details?.profileId === "string" ? item.details.profileId : "";
|
|
1426
|
-
const provider = typeof item.details?.provider === "string" ? item.details.provider : "";
|
|
1427
|
-
const sourceProfileId = typeof item.details?.sourceProfileId === "string" ? item.details.sourceProfileId : void 0;
|
|
1428
|
-
if (!profileId || !provider) return [];
|
|
1429
|
-
const credential = (await readCodexAuthCredentials(source)).find((candidate) => candidate.provider === provider);
|
|
1430
|
-
if (!credential) return [];
|
|
1431
|
-
if (credential.kind === "oauth" && sourceProfileId && credential.profileId !== sourceProfileId) return [];
|
|
1432
|
-
const next = credential.kind === "oauth" ? applyOAuthConfigToConfig(ctx.config, credential, profileId) : applyApiKeyConfigToConfig(ctx.config, credential, profileId);
|
|
1411
|
+
function buildCodexAuthConfigPatchItems(ctx, item, credential, profileId) {
|
|
1412
|
+
const next = applyCredentialConfig(ctx.config, credential, profileId);
|
|
1433
1413
|
const items = [];
|
|
1434
1414
|
if (next.auth) items.push(createMigrationItem({
|
|
1435
1415
|
id: `${item.id}:config:auth`,
|
|
@@ -1458,108 +1438,6 @@ async function buildCodexAuthConfigPatchItems(params) {
|
|
|
1458
1438
|
return items;
|
|
1459
1439
|
}
|
|
1460
1440
|
//#endregion
|
|
1461
|
-
//#region extensions/codex/src/migration/memory-plan.ts
|
|
1462
|
-
const MIGRATION_REASON_TARGET_NOT_REGULAR = "target is not a regular file";
|
|
1463
|
-
async function lstatIfExists(filePath) {
|
|
1464
|
-
try {
|
|
1465
|
-
return await fs.lstat(filePath);
|
|
1466
|
-
} catch (error) {
|
|
1467
|
-
const code = error && typeof error === "object" && "code" in error ? String(error.code) : void 0;
|
|
1468
|
-
if (code === "ENOENT" || code === "ENOTDIR") return;
|
|
1469
|
-
throw error;
|
|
1470
|
-
}
|
|
1471
|
-
}
|
|
1472
|
-
async function assertSafeMemoryDestination(params) {
|
|
1473
|
-
const [canonicalSource, canonicalWorkspace, canonicalTarget] = await Promise.all([
|
|
1474
|
-
fs.realpath(path.dirname(params.source)),
|
|
1475
|
-
canonicalPathFromExistingAncestor(params.workspaceDir),
|
|
1476
|
-
canonicalPathFromExistingAncestor(params.target)
|
|
1477
|
-
]);
|
|
1478
|
-
if (!isPathInside(canonicalWorkspace, canonicalTarget)) throw new Error("Codex memory import destination must stay in the selected workspace.");
|
|
1479
|
-
if (isPathInside(canonicalSource, canonicalTarget) || isPathInside(canonicalTarget, canonicalSource)) throw new Error("Codex memory source and OpenClaw import destination must be separate paths.");
|
|
1480
|
-
}
|
|
1481
|
-
async function buildCodexMemoryItems(params) {
|
|
1482
|
-
const items = [];
|
|
1483
|
-
for (const memory of params.memoryFiles) {
|
|
1484
|
-
const target = path.join(params.workspaceDir, "memory", "imports", "codex", path.basename(memory.path));
|
|
1485
|
-
const targetStat = await lstatIfExists(target);
|
|
1486
|
-
const targetExists = targetStat !== void 0;
|
|
1487
|
-
const targetNotRegular = targetExists && !targetStat.isFile();
|
|
1488
|
-
if (!targetNotRegular) await assertSafeMemoryDestination({
|
|
1489
|
-
source: memory.path,
|
|
1490
|
-
workspaceDir: params.workspaceDir,
|
|
1491
|
-
target
|
|
1492
|
-
});
|
|
1493
|
-
const targetConflict = targetNotRegular || targetExists && !params.overwrite;
|
|
1494
|
-
items.push(createMigrationItem({
|
|
1495
|
-
id: memory.id,
|
|
1496
|
-
kind: "memory",
|
|
1497
|
-
action: "copy",
|
|
1498
|
-
source: memory.path,
|
|
1499
|
-
target,
|
|
1500
|
-
status: targetConflict ? "conflict" : "planned",
|
|
1501
|
-
reason: targetNotRegular ? MIGRATION_REASON_TARGET_NOT_REGULAR : targetConflict ? MIGRATION_REASON_TARGET_EXISTS : void 0,
|
|
1502
|
-
message: "Copy consolidated Codex memory into the OpenClaw memory index.",
|
|
1503
|
-
details: {
|
|
1504
|
-
sourceType: "codex-memory",
|
|
1505
|
-
sourceLabel: memory.label,
|
|
1506
|
-
collectionId: "codex",
|
|
1507
|
-
collectionLabel: "Codex",
|
|
1508
|
-
relativePath: path.basename(memory.path)
|
|
1509
|
-
}
|
|
1510
|
-
}));
|
|
1511
|
-
}
|
|
1512
|
-
return items;
|
|
1513
|
-
}
|
|
1514
|
-
//#endregion
|
|
1515
|
-
//#region extensions/codex/src/migration/skill-plan.ts
|
|
1516
|
-
function uniqueSkillName(skill, counts) {
|
|
1517
|
-
const base = sanitizeName(skill.name) || "codex-skill";
|
|
1518
|
-
if ((counts.get(base) ?? 0) <= 1) return base;
|
|
1519
|
-
return sanitizeName([
|
|
1520
|
-
"codex",
|
|
1521
|
-
sanitizeName(path.basename(path.dirname(skill.source))),
|
|
1522
|
-
base
|
|
1523
|
-
].filter(Boolean).join("-")) || base;
|
|
1524
|
-
}
|
|
1525
|
-
async function buildCodexSkillItems(params) {
|
|
1526
|
-
const baseCounts = /* @__PURE__ */ new Map();
|
|
1527
|
-
for (const skill of params.skills) {
|
|
1528
|
-
const base = sanitizeName(skill.name) || "codex-skill";
|
|
1529
|
-
baseCounts.set(base, (baseCounts.get(base) ?? 0) + 1);
|
|
1530
|
-
}
|
|
1531
|
-
const resolvedCounts = /* @__PURE__ */ new Map();
|
|
1532
|
-
const planned = params.skills.map((skill) => {
|
|
1533
|
-
const name = uniqueSkillName(skill, baseCounts);
|
|
1534
|
-
resolvedCounts.set(name, (resolvedCounts.get(name) ?? 0) + 1);
|
|
1535
|
-
return {
|
|
1536
|
-
skill,
|
|
1537
|
-
name,
|
|
1538
|
-
target: path.join(params.workspaceDir, "skills", name)
|
|
1539
|
-
};
|
|
1540
|
-
});
|
|
1541
|
-
const items = [];
|
|
1542
|
-
for (const item of planned) {
|
|
1543
|
-
const collides = (resolvedCounts.get(item.name) ?? 0) > 1;
|
|
1544
|
-
const targetExists = await exists(item.target);
|
|
1545
|
-
items.push(createMigrationItem({
|
|
1546
|
-
id: `skill:${item.name}`,
|
|
1547
|
-
kind: "skill",
|
|
1548
|
-
action: "copy",
|
|
1549
|
-
source: item.skill.source,
|
|
1550
|
-
target: item.target,
|
|
1551
|
-
status: collides ? "conflict" : targetExists && !params.overwrite ? "conflict" : "planned",
|
|
1552
|
-
reason: collides ? `multiple Codex skills normalize to "${item.name}"` : targetExists && !params.overwrite ? MIGRATION_REASON_TARGET_EXISTS : void 0,
|
|
1553
|
-
message: `Copy ${item.skill.sourceLabel} into this OpenClaw agent workspace.`,
|
|
1554
|
-
details: {
|
|
1555
|
-
skillName: item.name,
|
|
1556
|
-
sourceLabel: item.skill.sourceLabel
|
|
1557
|
-
}
|
|
1558
|
-
}));
|
|
1559
|
-
}
|
|
1560
|
-
return items;
|
|
1561
|
-
}
|
|
1562
|
-
//#endregion
|
|
1563
1441
|
//#region extensions/codex/src/migration/source-files.ts
|
|
1564
1442
|
const SKILL_FILENAME = "SKILL.md";
|
|
1565
1443
|
const MAX_SCAN_DEPTH = 6;
|
|
@@ -1600,8 +1478,6 @@ async function discoverPluginDirs(codexHome) {
|
|
|
1600
1478
|
discovered.set(dir, {
|
|
1601
1479
|
name: manifestName || path.basename(dir),
|
|
1602
1480
|
source: dir,
|
|
1603
|
-
manifestPath,
|
|
1604
|
-
sourceKind: "cache",
|
|
1605
1481
|
migratable: false,
|
|
1606
1482
|
message: "Cached Codex plugin bundle found. Review manually unless the plugin is also installed in the source Codex app-server inventory"
|
|
1607
1483
|
});
|
|
@@ -1625,7 +1501,7 @@ async function discoverCodexMemoryFile(candidate) {
|
|
|
1625
1501
|
}
|
|
1626
1502
|
async function discoverCodexMemorySources(codexHome) {
|
|
1627
1503
|
const memoriesDir = path.join(codexHome, "memories");
|
|
1628
|
-
|
|
1504
|
+
return (await Promise.all([{
|
|
1629
1505
|
id: "memory:codex:MEMORY.md",
|
|
1630
1506
|
label: "Codex consolidated memory",
|
|
1631
1507
|
name: "MEMORY.md"
|
|
@@ -1638,10 +1514,6 @@ async function discoverCodexMemorySources(codexHome) {
|
|
|
1638
1514
|
label: candidate.label,
|
|
1639
1515
|
path: path.join(memoriesDir, candidate.name)
|
|
1640
1516
|
})))).filter((entry) => entry !== void 0);
|
|
1641
|
-
return {
|
|
1642
|
-
...await isDirectory(memoriesDir) ? { memoriesDir } : {},
|
|
1643
|
-
memoryFiles
|
|
1644
|
-
};
|
|
1645
1517
|
}
|
|
1646
1518
|
//#endregion
|
|
1647
1519
|
//#region extensions/codex/src/migration/source.ts
|
|
@@ -1713,7 +1585,6 @@ function buildInstalledPluginSource(plugin) {
|
|
|
1713
1585
|
pluginName,
|
|
1714
1586
|
marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
|
|
1715
1587
|
source: `${CODEX_PLUGINS_MARKETPLACE_NAME}/${pluginName}`,
|
|
1716
|
-
sourceKind: "app-server",
|
|
1717
1588
|
migratable: true,
|
|
1718
1589
|
installed: plugin.installed,
|
|
1719
1590
|
enabled: plugin.enabled
|
|
@@ -1920,8 +1791,7 @@ function pluginNameFromSummary(summary) {
|
|
|
1920
1791
|
if (normalized) return normalized;
|
|
1921
1792
|
}
|
|
1922
1793
|
}
|
|
1923
|
-
async function discoverCodexSource(
|
|
1924
|
-
const options = typeof inputOrOptions === "string" || inputOrOptions === void 0 ? { input: inputOrOptions } : inputOrOptions;
|
|
1794
|
+
async function discoverCodexSource(options = {}) {
|
|
1925
1795
|
const codexHome = resolveHomePath(options.input?.trim() || defaultCodexHome());
|
|
1926
1796
|
const codexSkillsDir = path.join(codexHome, "skills");
|
|
1927
1797
|
const agentsSkillsDir = personalAgentsSkillsDir();
|
|
@@ -1929,7 +1799,7 @@ async function discoverCodexSource(inputOrOptions) {
|
|
|
1929
1799
|
const authPath = path.join(codexHome, "auth.json");
|
|
1930
1800
|
const modelsCachePath = path.join(codexHome, "models_cache.json");
|
|
1931
1801
|
const hooksPath = path.join(codexHome, "hooks", "hooks.json");
|
|
1932
|
-
const
|
|
1802
|
+
const memoryFiles = await discoverCodexMemorySources(codexHome);
|
|
1933
1803
|
const codexSkills = options.memoryOnly ? [] : await discoverSkillDirs({
|
|
1934
1804
|
root: codexSkillsDir,
|
|
1935
1805
|
sourceLabel: "Codex skill",
|
|
@@ -1969,11 +1839,8 @@ async function discoverCodexSource(inputOrOptions) {
|
|
|
1969
1839
|
codexHome,
|
|
1970
1840
|
...await isDirectory(codexSkillsDir) ? { codexSkillsDir } : {},
|
|
1971
1841
|
...await isDirectory(agentsSkillsDir) ? { personalAgentsSkillsDir: agentsSkillsDir } : {},
|
|
1972
|
-
...await exists(configPath) ? { configPath } : {},
|
|
1973
1842
|
...hasAuth ? { authPath } : {},
|
|
1974
1843
|
...await exists(modelsCachePath) ? { modelsCachePath } : {},
|
|
1975
|
-
...await exists(hooksPath) ? { hooksPath } : {},
|
|
1976
|
-
...memoriesDir ? { memoriesDir } : {},
|
|
1977
1844
|
memoryFiles,
|
|
1978
1845
|
skills,
|
|
1979
1846
|
plugins,
|
|
@@ -2022,12 +1889,98 @@ const CODEX_PLUGIN_NATIVE_CONFIG_PATH = [
|
|
|
2022
1889
|
];
|
|
2023
1890
|
const MIGRATION_REASON_PLUGIN_EXISTS = "plugin exists";
|
|
2024
1891
|
const CODEX_PLUGIN_SOURCE_APP_VERIFICATION_UNVERIFIED = "not_run";
|
|
2025
|
-
|
|
2026
|
-
|
|
1892
|
+
const MIGRATION_REASON_TARGET_NOT_REGULAR = "target is not a regular file";
|
|
1893
|
+
async function lstatIfExists(filePath) {
|
|
1894
|
+
try {
|
|
1895
|
+
return await fs.lstat(filePath);
|
|
1896
|
+
} catch (error) {
|
|
1897
|
+
const code = extractErrorCode(error);
|
|
1898
|
+
if (code === "ENOENT" || code === "ENOTDIR") return;
|
|
1899
|
+
throw error;
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
async function buildCodexMemoryItems(params) {
|
|
1903
|
+
const items = [];
|
|
1904
|
+
for (const memory of params.memoryFiles) {
|
|
1905
|
+
const target = path.join(params.workspaceDir, "memory", "imports", "codex", path.basename(memory.path));
|
|
1906
|
+
const targetStat = await lstatIfExists(target);
|
|
1907
|
+
const targetNotRegular = targetStat !== void 0 && !targetStat.isFile();
|
|
1908
|
+
if (!targetNotRegular) {
|
|
1909
|
+
const [source, workspace, destination] = await Promise.all([
|
|
1910
|
+
fs.realpath(path.dirname(memory.path)),
|
|
1911
|
+
canonicalPathFromExistingAncestor(params.workspaceDir),
|
|
1912
|
+
canonicalPathFromExistingAncestor(target)
|
|
1913
|
+
]);
|
|
1914
|
+
if (!isPathInside(workspace, destination)) throw new Error("Codex memory import destination must stay in the selected workspace.");
|
|
1915
|
+
if (isPathInside(source, destination) || isPathInside(destination, source)) throw new Error("Codex memory source and OpenClaw import destination must be separate paths.");
|
|
1916
|
+
}
|
|
1917
|
+
const targetConflict = targetStat !== void 0 && !params.overwrite;
|
|
1918
|
+
items.push(createMigrationItem({
|
|
1919
|
+
id: memory.id,
|
|
1920
|
+
kind: "memory",
|
|
1921
|
+
action: "copy",
|
|
1922
|
+
source: memory.path,
|
|
1923
|
+
target,
|
|
1924
|
+
status: targetNotRegular || targetConflict ? "conflict" : "planned",
|
|
1925
|
+
reason: targetNotRegular ? MIGRATION_REASON_TARGET_NOT_REGULAR : targetConflict ? MIGRATION_REASON_TARGET_EXISTS : void 0,
|
|
1926
|
+
message: "Copy consolidated Codex memory into the OpenClaw memory index.",
|
|
1927
|
+
details: {
|
|
1928
|
+
sourceType: "codex-memory",
|
|
1929
|
+
sourceLabel: memory.label,
|
|
1930
|
+
collectionId: "codex",
|
|
1931
|
+
collectionLabel: "Codex",
|
|
1932
|
+
relativePath: path.basename(memory.path)
|
|
1933
|
+
}
|
|
1934
|
+
}));
|
|
1935
|
+
}
|
|
1936
|
+
return items;
|
|
1937
|
+
}
|
|
1938
|
+
function uniqueSkillName(skill, counts) {
|
|
1939
|
+
const base = sanitizeName(skill.name) || "codex-skill";
|
|
2027
1940
|
if ((counts.get(base) ?? 0) <= 1) return base;
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
1941
|
+
return sanitizeName([
|
|
1942
|
+
"codex",
|
|
1943
|
+
sanitizeName(path.basename(path.dirname(skill.source))),
|
|
1944
|
+
base
|
|
1945
|
+
].filter(Boolean).join("-")) || base;
|
|
1946
|
+
}
|
|
1947
|
+
async function buildCodexSkillItems(params) {
|
|
1948
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1949
|
+
for (const skill of params.skills) {
|
|
1950
|
+
const base = sanitizeName(skill.name) || "codex-skill";
|
|
1951
|
+
counts.set(base, (counts.get(base) ?? 0) + 1);
|
|
1952
|
+
}
|
|
1953
|
+
const planned = params.skills.map((skill) => {
|
|
1954
|
+
const name = uniqueSkillName(skill, counts);
|
|
1955
|
+
return {
|
|
1956
|
+
skill,
|
|
1957
|
+
name,
|
|
1958
|
+
target: path.join(params.workspaceDir, "skills", name)
|
|
1959
|
+
};
|
|
1960
|
+
});
|
|
1961
|
+
const resolvedCounts = planned.reduce((resolved, item) => {
|
|
1962
|
+
resolved.set(item.name, (resolved.get(item.name) ?? 0) + 1);
|
|
1963
|
+
return resolved;
|
|
1964
|
+
}, /* @__PURE__ */ new Map());
|
|
1965
|
+
return await Promise.all(planned.map(async (item) => {
|
|
1966
|
+
const collision = (resolvedCounts.get(item.name) ?? 0) > 1;
|
|
1967
|
+
const targetExists = await exists(item.target);
|
|
1968
|
+
const conflict = collision || targetExists && !params.overwrite;
|
|
1969
|
+
return createMigrationItem({
|
|
1970
|
+
id: `skill:${item.name}`,
|
|
1971
|
+
kind: "skill",
|
|
1972
|
+
action: "copy",
|
|
1973
|
+
source: item.skill.source,
|
|
1974
|
+
target: item.target,
|
|
1975
|
+
status: conflict ? "conflict" : "planned",
|
|
1976
|
+
reason: collision ? `multiple Codex skills normalize to "${item.name}"` : conflict ? MIGRATION_REASON_TARGET_EXISTS : void 0,
|
|
1977
|
+
message: `Copy ${item.skill.sourceLabel} into this OpenClaw agent workspace.`,
|
|
1978
|
+
details: {
|
|
1979
|
+
skillName: item.name,
|
|
1980
|
+
sourceLabel: item.skill.sourceLabel
|
|
1981
|
+
}
|
|
1982
|
+
});
|
|
1983
|
+
}));
|
|
2031
1984
|
}
|
|
2032
1985
|
function readExistingCodexPluginEntries(config) {
|
|
2033
1986
|
const entries = readMigrationConfigPath(config, [...CODEX_PLUGIN_NATIVE_CONFIG_PATH, "plugins"]);
|
|
@@ -2058,18 +2011,12 @@ function readExistingPluginAllowDestructiveActions(existing, pluginName) {
|
|
|
2058
2011
|
return normalized === "auto" || normalized === "ask" ? normalized : void 0;
|
|
2059
2012
|
}
|
|
2060
2013
|
function buildPluginItems(ctx, plugins) {
|
|
2061
|
-
const baseCounts = /* @__PURE__ */ new Map();
|
|
2062
|
-
for (const plugin of plugins.filter((entry) => entry.migratable)) {
|
|
2063
|
-
const base = sanitizeName(plugin.pluginName ?? plugin.name) || "codex-plugin";
|
|
2064
|
-
baseCounts.set(base, (baseCounts.get(base) ?? 0) + 1);
|
|
2065
|
-
}
|
|
2066
2014
|
const existingPluginEntries = readExistingCodexPluginEntries(ctx.config);
|
|
2067
|
-
const usedCounts = /* @__PURE__ */ new Map();
|
|
2068
2015
|
let manualIndex = 0;
|
|
2069
2016
|
const items = [];
|
|
2070
2017
|
for (const plugin of plugins) {
|
|
2071
2018
|
if (plugin.migratable && plugin.marketplaceName === "openai-curated" && plugin.pluginName) {
|
|
2072
|
-
const configKey =
|
|
2019
|
+
const configKey = plugin.pluginName;
|
|
2073
2020
|
const plannedEntry = {
|
|
2074
2021
|
enabled: true,
|
|
2075
2022
|
marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
|
|
@@ -2086,6 +2033,7 @@ function buildPluginItems(ctx, plugins) {
|
|
|
2086
2033
|
action: "install",
|
|
2087
2034
|
status: conflict ? "conflict" : "planned",
|
|
2088
2035
|
reason: conflict ? MIGRATION_REASON_PLUGIN_EXISTS : void 0,
|
|
2036
|
+
applyPhase: "after-promotion",
|
|
2089
2037
|
source: plugin.source,
|
|
2090
2038
|
target: `plugins.entries.codex.config.codexPlugins.plugins.${configKey}`,
|
|
2091
2039
|
message: `Install Codex plugin "${plugin.pluginName}" in the OpenClaw-managed Codex app-server runtime.`,
|
|
@@ -2103,12 +2051,6 @@ function buildPluginItems(ctx, plugins) {
|
|
|
2103
2051
|
}
|
|
2104
2052
|
manualIndex += 1;
|
|
2105
2053
|
if (plugin.migrationBlock && plugin.pluginName) {
|
|
2106
|
-
const details = {
|
|
2107
|
-
pluginName: plugin.pluginName,
|
|
2108
|
-
marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
|
|
2109
|
-
...plugin.migrationBlock.apps ? { apps: plugin.migrationBlock.apps } : {},
|
|
2110
|
-
...plugin.migrationBlock.error ? { error: plugin.migrationBlock.error } : {}
|
|
2111
|
-
};
|
|
2112
2054
|
items.push(createMigrationItem({
|
|
2113
2055
|
id: `plugin:${sanitizeName(plugin.name) || sanitizeName(path.basename(plugin.source))}:${manualIndex}`,
|
|
2114
2056
|
kind: "manual",
|
|
@@ -2117,7 +2059,12 @@ function buildPluginItems(ctx, plugins) {
|
|
|
2117
2059
|
status: "skipped",
|
|
2118
2060
|
reason: plugin.migrationBlock.code,
|
|
2119
2061
|
message: plugin.message ?? `Codex native plugin "${plugin.name}" was found but not activated automatically.`,
|
|
2120
|
-
details: {
|
|
2062
|
+
details: {
|
|
2063
|
+
pluginName: plugin.pluginName,
|
|
2064
|
+
marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
|
|
2065
|
+
...plugin.migrationBlock.apps ? { apps: plugin.migrationBlock.apps } : {},
|
|
2066
|
+
...plugin.migrationBlock.error ? { error: plugin.migrationBlock.error } : {}
|
|
2067
|
+
}
|
|
2121
2068
|
}));
|
|
2122
2069
|
continue;
|
|
2123
2070
|
}
|
|
@@ -2155,7 +2102,6 @@ function normalizeExistingAllowDestructiveActions(value) {
|
|
|
2155
2102
|
return asBoolean(value);
|
|
2156
2103
|
}
|
|
2157
2104
|
function readExistingPluginPolicyRepairs(config) {
|
|
2158
|
-
if (config === void 0) return {};
|
|
2159
2105
|
return Object.fromEntries(Object.entries(readExistingCodexPluginEntries(config)).flatMap(([configKey, entry]) => {
|
|
2160
2106
|
const pluginEntry = isRecord(entry) ? entry : void 0;
|
|
2161
2107
|
if (pluginEntry?.allow_destructive_actions !== "on-request") return [];
|
|
@@ -2165,9 +2111,9 @@ function readExistingPluginPolicyRepairs(config) {
|
|
|
2165
2111
|
}]];
|
|
2166
2112
|
}));
|
|
2167
2113
|
}
|
|
2168
|
-
function buildCodexPluginsConfigValue(entries,
|
|
2114
|
+
function buildCodexPluginsConfigValue(entries, config) {
|
|
2169
2115
|
const plugins = {
|
|
2170
|
-
...readExistingPluginPolicyRepairs(
|
|
2116
|
+
...readExistingPluginPolicyRepairs(config),
|
|
2171
2117
|
...Object.fromEntries(entries.toSorted((a, b) => a.configKey.localeCompare(b.configKey)).map((entry) => [entry.configKey, {
|
|
2172
2118
|
enabled: entry.enabled,
|
|
2173
2119
|
marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
|
|
@@ -2179,7 +2125,7 @@ function buildCodexPluginsConfigValue(entries, params = {}) {
|
|
|
2179
2125
|
enabled: true,
|
|
2180
2126
|
config: { codexPlugins: {
|
|
2181
2127
|
enabled: true,
|
|
2182
|
-
allow_destructive_actions:
|
|
2128
|
+
allow_destructive_actions: readExistingAllowDestructiveActions(config) ?? true,
|
|
2183
2129
|
plugins
|
|
2184
2130
|
} }
|
|
2185
2131
|
};
|
|
@@ -2206,7 +2152,7 @@ function hasCodexPluginConfigConflict(config, value) {
|
|
|
2206
2152
|
function buildPluginConfigItem(ctx, pluginItems) {
|
|
2207
2153
|
const entries = pluginItems.filter((item) => item.status === "planned").map((item) => readCodexPluginMigrationConfigEntry(item, true)).filter((entry) => entry !== void 0);
|
|
2208
2154
|
if (entries.length === 0) return;
|
|
2209
|
-
const value = buildCodexPluginsConfigValue(entries,
|
|
2155
|
+
const value = buildCodexPluginsConfigValue(entries, ctx.config);
|
|
2210
2156
|
const conflict = !ctx.overwrite && hasCodexPluginConfigConflict(ctx.config, value);
|
|
2211
2157
|
return createMigrationItem({
|
|
2212
2158
|
id: CODEX_PLUGIN_CONFIG_ITEM_ID,
|
|
@@ -2215,6 +2161,7 @@ function buildPluginConfigItem(ctx, pluginItems) {
|
|
|
2215
2161
|
target: "plugins.entries.codex.config.codexPlugins",
|
|
2216
2162
|
status: conflict ? "conflict" : "planned",
|
|
2217
2163
|
reason: conflict ? MIGRATION_REASON_TARGET_EXISTS : void 0,
|
|
2164
|
+
applyPhase: "after-promotion",
|
|
2218
2165
|
message: "Enable OpenClaw's Codex plugin integration and record migrated source-installed curated plugins.",
|
|
2219
2166
|
details: {
|
|
2220
2167
|
path: [...CODEX_PLUGIN_CONFIG_PATH],
|
|
@@ -2331,15 +2278,9 @@ async function applyCodexMigrationPlan(params) {
|
|
|
2331
2278
|
const targets = resolveCodexMigrationTargets(params.ctx);
|
|
2332
2279
|
const codexHome = typeof plan.metadata?.codexHome === "string" && plan.metadata.codexHome.trim() ? plan.metadata.codexHome : plan.source;
|
|
2333
2280
|
const authSource = {
|
|
2334
|
-
root: plan.source,
|
|
2335
|
-
confidence: "high",
|
|
2336
2281
|
codexHome,
|
|
2337
2282
|
authPath: path.join(codexHome, "auth.json"),
|
|
2338
|
-
modelsCachePath: path.join(codexHome, "models_cache.json")
|
|
2339
|
-
memoryFiles: [],
|
|
2340
|
-
skills: [],
|
|
2341
|
-
plugins: [],
|
|
2342
|
-
archivePaths: []
|
|
2283
|
+
modelsCachePath: path.join(codexHome, "models_cache.json")
|
|
2343
2284
|
};
|
|
2344
2285
|
const runtime = withCachedMigrationConfigRuntime(params.ctx.runtime ?? params.runtime, params.ctx.config);
|
|
2345
2286
|
const applyCtx = {
|
|
@@ -2352,20 +2293,13 @@ async function applyCodexMigrationPlan(params) {
|
|
|
2352
2293
|
continue;
|
|
2353
2294
|
}
|
|
2354
2295
|
if (item.id === "config:codex-plugins") items.push(await applyCodexPluginConfigItem(applyCtx, item, items));
|
|
2355
|
-
else if (item.kind === "auth") {
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
items.push(authItem);
|
|
2363
|
-
items.push(...await buildCodexAuthConfigPatchItems({
|
|
2364
|
-
ctx: applyCtx,
|
|
2365
|
-
item: authItem,
|
|
2366
|
-
source: authSource
|
|
2367
|
-
}));
|
|
2368
|
-
} else if (item.kind === "plugin" && item.action === "install") items.push(await applyCodexPluginInstallItem(applyCtx, item));
|
|
2296
|
+
else if (item.kind === "auth") items.push(...await applyCodexAuthItems({
|
|
2297
|
+
ctx: applyCtx,
|
|
2298
|
+
item,
|
|
2299
|
+
source: authSource,
|
|
2300
|
+
targets
|
|
2301
|
+
}));
|
|
2302
|
+
else if (item.kind === "plugin" && item.action === "install") items.push(await applyCodexPluginInstallItem(applyCtx, item));
|
|
2369
2303
|
else if (item.kind === "manual") items.push(applyMigrationManualItem(item));
|
|
2370
2304
|
else if (item.action === "archive") items.push(await archiveMigrationItem(item, reportDir));
|
|
2371
2305
|
else if (item.kind === "memory") items.push(await copyMemoryMigrationFileItem(item, reportDir, {
|
|
@@ -2542,13 +2476,21 @@ async function buildTargetCodexPluginAppCacheKey(ctx) {
|
|
|
2542
2476
|
});
|
|
2543
2477
|
}
|
|
2544
2478
|
async function applyCodexPluginConfigItem(ctx, item, appliedItems) {
|
|
2479
|
+
if (appliedItems.filter((candidate) => candidate.kind === "plugin" && candidate.action === "install" && readCodexPluginPolicy(candidate) !== void 0 && !isCodexPluginConfigTerminal(candidate)).length > 0) return {
|
|
2480
|
+
...item,
|
|
2481
|
+
status: "warning",
|
|
2482
|
+
reason: "selected Codex plugin activation is incomplete"
|
|
2483
|
+
};
|
|
2545
2484
|
const entries = appliedItems.map(readAppliedPluginConfigEntry).filter((entry) => entry !== void 0);
|
|
2546
|
-
if (entries.length === 0) return
|
|
2485
|
+
if (entries.length === 0) return {
|
|
2486
|
+
...markMigrationItemSkipped(item, "no selected Codex plugins"),
|
|
2487
|
+
deferredCompletion: true
|
|
2488
|
+
};
|
|
2547
2489
|
const returnPatch = shouldReturnCodexPluginConfigPatch(ctx);
|
|
2548
|
-
const configApi = ctx
|
|
2490
|
+
const configApi = resolveMigrationConfigRuntime(ctx);
|
|
2549
2491
|
const currentConfig = returnPatch ? ctx.config : configApi?.current?.();
|
|
2550
2492
|
if (!currentConfig) return markMigrationItemError(item, "config runtime unavailable");
|
|
2551
|
-
const value = buildCodexPluginsConfigValue(entries,
|
|
2493
|
+
const value = buildCodexPluginsConfigValue(entries, currentConfig);
|
|
2552
2494
|
if (!ctx.overwrite && hasCodexPluginConfigConflict(currentConfig, value)) return markMigrationItemConflict(item, MIGRATION_REASON_TARGET_EXISTS);
|
|
2553
2495
|
const migratedItem = {
|
|
2554
2496
|
...item,
|
|
@@ -2576,19 +2518,20 @@ async function applyCodexPluginConfigItem(ctx, item, appliedItems) {
|
|
|
2576
2518
|
return markMigrationItemError(item, error instanceof Error ? error.message : String(error));
|
|
2577
2519
|
}
|
|
2578
2520
|
}
|
|
2521
|
+
function isCodexPluginConfigTerminal(item) {
|
|
2522
|
+
return item.status === "migrated" || item.status === "skipped" && (item.deferredCompletion === true || item.reason === CODEX_PLUGIN_NOT_SELECTED_REASON || item.reason === CODEX_PLUGIN_AUTH_REQUIRED_REASON);
|
|
2523
|
+
}
|
|
2579
2524
|
function readAppliedPluginConfigEntry(item) {
|
|
2580
|
-
if (item.status === "migrated") return readCodexPluginMigrationConfigEntry(item, true);
|
|
2581
|
-
if (item.status === "skipped" && item.reason
|
|
2525
|
+
if (item.status === "migrated" || item.deferredCompletion === true) return readCodexPluginMigrationConfigEntry(item, true);
|
|
2526
|
+
if (item.status === "skipped" && item.reason === CODEX_PLUGIN_AUTH_REQUIRED_REASON) return readCodexPluginMigrationConfigEntry(item, false);
|
|
2582
2527
|
}
|
|
2583
2528
|
function readCodexPluginPolicy(item) {
|
|
2584
|
-
const
|
|
2585
|
-
|
|
2586
|
-
const pluginName = item.details?.pluginName;
|
|
2587
|
-
if (typeof configKey !== "string" || marketplaceName !== "openai-curated" || typeof pluginName !== "string") return;
|
|
2529
|
+
const entry = readCodexPluginMigrationConfigEntry(item, true);
|
|
2530
|
+
if (!entry) return;
|
|
2588
2531
|
return {
|
|
2589
|
-
configKey,
|
|
2532
|
+
configKey: entry.configKey,
|
|
2590
2533
|
marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME,
|
|
2591
|
-
pluginName,
|
|
2534
|
+
pluginName: entry.pluginName,
|
|
2592
2535
|
enabled: true,
|
|
2593
2536
|
allowDestructiveActions: true,
|
|
2594
2537
|
destructiveApprovalMode: "allow"
|
|
@@ -2620,6 +2563,7 @@ function buildCodexMigrationProvider(params = {}) {
|
|
|
2620
2563
|
};
|
|
2621
2564
|
},
|
|
2622
2565
|
plan: buildCodexMigrationPlan,
|
|
2566
|
+
deferredApply: { retrySafe: true },
|
|
2623
2567
|
prepareApply(ctx) {
|
|
2624
2568
|
if (isMemoryOnlyMigration(ctx)) return;
|
|
2625
2569
|
return prepareTargetCodexAppServer(ctx);
|
|
@@ -2801,7 +2745,7 @@ function createCodexThreadsTool(options) {
|
|
|
2801
2745
|
return {
|
|
2802
2746
|
name: "codex_threads",
|
|
2803
2747
|
label: "Codex Threads",
|
|
2804
|
-
description: "
|
|
2748
|
+
description: "Manage native Codex threads: list, read, fork, rename, archive (confirm:true), unarchive. When supervision is enabled, raw transcript reads and every mutation require their matching supervision policy option.",
|
|
2805
2749
|
parameters: CodexThreadsParamsSchema,
|
|
2806
2750
|
async execute(_toolCallId, rawParams) {
|
|
2807
2751
|
const params = asRecord$1(rawParams);
|
|
@@ -3726,7 +3670,7 @@ function createCodexSupervisionTools(options) {
|
|
|
3726
3670
|
}
|
|
3727
3671
|
//#endregion
|
|
3728
3672
|
//#region extensions/codex/src/web-search-provider.ts
|
|
3729
|
-
const loadCodexWebSearchRuntime = createLazyRuntimeModule(() => import("./web-search-provider.runtime-
|
|
3673
|
+
const loadCodexWebSearchRuntime = createLazyRuntimeModule(() => import("./web-search-provider.runtime-CaQMYDbp.js"));
|
|
3730
3674
|
const CodexWebSearchSchema = {
|
|
3731
3675
|
type: "object",
|
|
3732
3676
|
properties: { query: {
|
|
@@ -3780,11 +3724,39 @@ var codex_default = definePluginEntry({
|
|
|
3780
3724
|
origin: "bundled",
|
|
3781
3725
|
config: normalizePluginsConfig(liveConfig.plugins),
|
|
3782
3726
|
rootConfig: liveConfig,
|
|
3783
|
-
enabledByDefault:
|
|
3727
|
+
enabledByDefault: livePluginConfig !== void 0
|
|
3784
3728
|
}).enabled) return;
|
|
3785
3729
|
return livePluginConfig;
|
|
3786
3730
|
};
|
|
3787
3731
|
const resolveCurrentPluginConfig = () => resolvePluginConfig(resolveCurrentConfig);
|
|
3732
|
+
if (api.registrationMode === "full") {
|
|
3733
|
+
const realtimeBrowserSession = configureCodexRealtimeBrowserSession({
|
|
3734
|
+
getConfig: resolveCurrentConfig,
|
|
3735
|
+
getPluginConfig: resolveCurrentPluginConfig
|
|
3736
|
+
});
|
|
3737
|
+
api.registerHttpRoute({
|
|
3738
|
+
path: CODEX_REALTIME_OFFER_PATH,
|
|
3739
|
+
auth: "plugin",
|
|
3740
|
+
match: "exact",
|
|
3741
|
+
handler: realtimeBrowserSession.handler
|
|
3742
|
+
});
|
|
3743
|
+
api.registerService({
|
|
3744
|
+
id: "codex-oauth-realtime-browser-session-warmup",
|
|
3745
|
+
start: () => {
|
|
3746
|
+
realtimeBrowserSession.warmup().catch((error) => {
|
|
3747
|
+
api.logger.debug?.(`Codex OAuth realtime warmup unavailable: ${error instanceof Error ? error.message : String(error)}`);
|
|
3748
|
+
});
|
|
3749
|
+
}
|
|
3750
|
+
});
|
|
3751
|
+
api.lifecycle.registerRuntimeLifecycle({
|
|
3752
|
+
id: "codex-oauth-realtime-browser-session",
|
|
3753
|
+
description: "Release Codex OAuth realtime browser sessions when the plugin stops",
|
|
3754
|
+
cleanup: async ({ reason }) => {
|
|
3755
|
+
if (reason === "reset" || reason === "delete") return;
|
|
3756
|
+
await realtimeBrowserSession.cleanup();
|
|
3757
|
+
}
|
|
3758
|
+
});
|
|
3759
|
+
}
|
|
3788
3760
|
let bindingStateStore;
|
|
3789
3761
|
const openBindingStateStore = () => bindingStateStore ??= api.runtime.state.openSyncKeyedStore({
|
|
3790
3762
|
namespace: CODEX_APP_SERVER_BINDING_NAMESPACE,
|
|
@@ -3825,8 +3797,10 @@ var codex_default = definePluginEntry({
|
|
|
3825
3797
|
}, { names: [...CODEX_SUPERVISION_COMPAT_TOOL_NAMES] });
|
|
3826
3798
|
api.registerAgentHarness(createCodexAppServerAgentHarness({
|
|
3827
3799
|
bindingStore,
|
|
3800
|
+
sessionCatalogControl,
|
|
3828
3801
|
resolveConfig: resolveCurrentConfig,
|
|
3829
|
-
resolvePluginConfig: resolveCurrentPluginConfig
|
|
3802
|
+
resolvePluginConfig: resolveCurrentPluginConfig,
|
|
3803
|
+
runtime: api.runtime
|
|
3830
3804
|
}));
|
|
3831
3805
|
api.registerMediaUnderstandingProvider(buildCodexMediaUnderstandingProvider({ pluginConfig: api.pluginConfig }));
|
|
3832
3806
|
api.registerWebSearchProvider(createCodexWebSearchProvider({ resolvePluginConfig: resolveCurrentPluginConfig }));
|
|
@@ -3914,7 +3888,7 @@ var codex_default = definePluginEntry({
|
|
|
3914
3888
|
if (!previousSessionId || !sessionId || previousSessionId === sessionId) return;
|
|
3915
3889
|
const config = resolveCurrentConfig();
|
|
3916
3890
|
const sessionKey = ctx.sessionKey?.trim();
|
|
3917
|
-
const { sessionBindingIdentity } = await import("./session-binding-
|
|
3891
|
+
const { sessionBindingIdentity } = await import("./session-binding-DlVQ-Pxs.js").then((n) => n.u);
|
|
3918
3892
|
const identity = sessionBindingIdentity({
|
|
3919
3893
|
sessionId,
|
|
3920
3894
|
...sessionKey ? { sessionKey } : {},
|
|
@@ -3930,8 +3904,9 @@ var codex_default = definePluginEntry({
|
|
|
3930
3904
|
const endedSessionKey = sessionKey?.trim();
|
|
3931
3905
|
const nextSessionKey = event.nextSessionKey?.trim();
|
|
3932
3906
|
if (endedSessionKey && nextSessionKey && nextSessionKey !== endedSessionKey) return;
|
|
3907
|
+
if (event.nextSessionId?.trim() === event.sessionId.trim()) return;
|
|
3933
3908
|
const config = resolveCurrentConfig();
|
|
3934
|
-
const { sessionBindingIdentity } = await import("./session-binding-
|
|
3909
|
+
const { sessionBindingIdentity } = await import("./session-binding-DlVQ-Pxs.js").then((n) => n.u);
|
|
3935
3910
|
await bindingStore.retireSessionGeneration(sessionBindingIdentity({
|
|
3936
3911
|
sessionId: event.sessionId,
|
|
3937
3912
|
...sessionKey ? { sessionKey } : {},
|