@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,29 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { r as
|
|
11
|
-
import {
|
|
12
|
-
import { s as
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
1
|
+
import { m as CODEX_PLUGINS_MARKETPLACE_NAME, n as isCodexFastServiceTier } from "./config-utils-C57JiJrU.js";
|
|
2
|
+
import { l as sessionBindingIdentity, t as bindingStoreKey } from "./session-binding-record-CyaXZvTe.js";
|
|
3
|
+
import { B as isJsonObject, i as resolveCodexAppServerRuntimeOptions } from "./config-CyapYSji.js";
|
|
4
|
+
import { Bt as resolveCodexAppServerAuthAccountCacheKey, Et as hasCodexAppServerLiveThread, Ht as resolveCodexAppServerAuthProfileIdForAgent, Q as assertCodexThreadAcceptsDirectInput, Wt as resolveCodexAppServerFallbackApiKeyCacheKey, c as getLeasedSharedCodexAppServerClient, h as releaseLeasedSharedCodexAppServerClient, tt as assertCodexThreadResumeResponse, wt as consumeCodexAppServerLiveThread } from "./shared-client-CKhX2kFt.js";
|
|
5
|
+
import { l as resolveCodexSessionBinding, n as assertCodexBindingMayBeReplaced, o as normalizeCodexAppServerBindingModelProvider, r as createCodexSessionGenerationSupersededError } from "./session-binding-4Ki04sW-.js";
|
|
6
|
+
import { a as closeCodexStartupClientBestEffort } from "./attempt-client-cleanup-Bp1ZOnk2.js";
|
|
7
|
+
import { t as listAllCodexAppServerModels } from "./models-CcrgSMQR.js";
|
|
8
|
+
import { c as defaultCodexAppInventoryCache, i as buildCodexPluginAppCacheKey } from "./thread-resume-BLgqkUc1.js";
|
|
9
|
+
import { At as refreshCodexPluginRuntimeState, Mt as isOpenAiCuratedMarketplaceName } from "./thread-lifecycle-DPK30jad.js";
|
|
10
|
+
import { a as rollbackCodexAppServerBindingSubscription, c as withExclusiveCodexAppServerThread, i as retireCodexConversationThreadBinding, l as isIncognitoSessionKey, n as releaseCodexAppServerBindingSubscription, r as retainCodexAppServerBindingSubscription, s as withCodexConversationThreadActivity, t as isSameCodexAppServerThreadOwner } from "./thread-ownership-CbucAmmp.js";
|
|
11
|
+
import { r as assertCodexSupervisionThreadLineage, s as resolveCodexBindingAppServerConnection } from "./thread-policy-CTalhWFy.js";
|
|
12
|
+
import { c as resolveCodexNativeSandboxBlock, s as resolveCodexNativeExecutionBlock } from "./request-C8H22rPi.js";
|
|
13
|
+
import { t as CODEX_CONTROL_METHODS } from "./capabilities-B1mgvpP8.js";
|
|
14
|
+
import { s as summarizeCodexAccountUsage } from "./rate-limits-Fx_l4eNa.js";
|
|
15
|
+
import { a as formatCodexDisplayText, c as formatComputerUseStatus, d as formatSkills, f as formatThreads, i as formatAccount, l as formatList, n as buildHelp, o as formatCodexStatus, r as escapeCodexChatText, s as formatCodexTextForDisplay, t as CODEX_RESUME_SAFE_THREAD_ID_PATTERN, u as formatModels } from "./command-formatters-DSbGMXA0.js";
|
|
16
|
+
import { _ as hasCodexAdminScope, a as parseCodexPermissionsModeArg, c as setCodexConversationModel, d as stopCodexConversationTurn, g as canMutateCodexHost, h as CODEX_NATIVE_EXECUTION_AUTH_ERROR, i as parseCodexFastModeArg, l as setCodexConversationPermissions, m as CODEX_HOST_INSPECTION_AUTH_ERROR, n as parseCodexPluginMarketplaceId, o as readCodexConversationActiveTurn, p as CODEX_FULL_PERMISSIONS_AUTH_ERROR, r as formatPermissionsMode, s as setCodexConversationFastMode, t as discoverCodexMarketplacePlugins, u as steerCodexConversationTurn } from "./plugin-marketplace-discovery-B7gHXJ3d.js";
|
|
15
17
|
import { i as readCodexConversationBindingData, n as createCodexCliNodeConversationBindingData, o as resolveCodexDefaultWorkspaceDir, r as createCodexConversationBindingData } from "./conversation-binding-data-BiodpIzq.js";
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import { i as readCodexComputerUseStatus, r as installCodexComputerUse, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-BFrPhb2c.js";
|
|
18
|
+
import { c as readCodexStatusProbes, l as requestOptions, p as formatCodexCliSessions, s as codexControlRequest, u as safeCodexControlRequest } from "./session-catalog-B47uwekb.js";
|
|
19
|
+
import { i as readCodexComputerUseStatus, r as installCodexComputerUse, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-BwCLTY_U.js";
|
|
19
20
|
import { normalizeOptionalString, normalizeUniqueStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
20
|
-
import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
21
21
|
import crypto from "node:crypto";
|
|
22
|
-
import { isDeepStrictEqual } from "node:util";
|
|
23
|
-
import { ensureAuthProfileStore, resolveAgentDir, resolveAuthProfileEligibility, resolveProfileUnusableUntilForDisplay } from "openclaw/plugin-sdk/agent-runtime";
|
|
24
|
-
import { findNormalizedProviderValue, resolveAuthProfileOrder } from "openclaw/plugin-sdk/provider-auth";
|
|
25
22
|
import { resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
|
|
26
23
|
import { getSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
24
|
+
import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
25
|
+
import { isDeepStrictEqual } from "node:util";
|
|
26
|
+
import { ensureAuthProfileStore, resolveAgentDir as resolveAgentDir$1, resolveAuthProfileEligibility, resolveProfileUnusableUntilForDisplay } from "openclaw/plugin-sdk/agent-runtime";
|
|
27
|
+
import { findNormalizedProviderValue, resolveAuthProfileOrder } from "openclaw/plugin-sdk/provider-auth";
|
|
27
28
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
28
29
|
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
29
30
|
import { parseAgentSessionKey } from "openclaw/plugin-sdk/routing";
|
|
@@ -1065,11 +1066,56 @@ async function resolveControlTarget(ctx) {
|
|
|
1065
1066
|
agentDir: scope.agentDir
|
|
1066
1067
|
} : void 0;
|
|
1067
1068
|
}
|
|
1068
|
-
async function
|
|
1069
|
+
async function resolvePreparedCodexCommandAuthority(deps, ctx) {
|
|
1069
1070
|
const target = await resolveControlTarget(ctx);
|
|
1070
1071
|
const fallback = resolveCodexConversationControlScope(ctx);
|
|
1072
|
+
const sessionId = ctx.sessionId;
|
|
1073
|
+
const sessionKey = ctx.sessionKey;
|
|
1074
|
+
const sessionAgentId = ctx.sessionTarget?.agentId ?? fallback.agentId;
|
|
1075
|
+
const storePath = ctx.sessionTarget?.storePath ?? (sessionKey ? resolveStorePath(ctx.config.session?.store, { agentId: sessionAgentId }) : void 0);
|
|
1076
|
+
const sessionIdentity = sessionId ? sessionBindingIdentity({
|
|
1077
|
+
sessionId,
|
|
1078
|
+
sessionKey,
|
|
1079
|
+
agentId: sessionAgentId,
|
|
1080
|
+
config: ctx.config
|
|
1081
|
+
}) : void 0;
|
|
1082
|
+
const currentSession = sessionIdentity ? await resolveCodexSessionBinding({
|
|
1083
|
+
reclaimStale: true,
|
|
1084
|
+
bindingStore: deps.bindingStore,
|
|
1085
|
+
identity: sessionIdentity,
|
|
1086
|
+
config: ctx.config,
|
|
1087
|
+
storePath
|
|
1088
|
+
}) : void 0;
|
|
1089
|
+
const assertHostCurrent = currentSession?.assertCurrent ?? (() => {});
|
|
1090
|
+
const binding = (target && (!sessionIdentity || !isDeepStrictEqual(target.identity, sessionIdentity)) ? await resolveCodexSessionBinding({
|
|
1091
|
+
bindingStore: deps.bindingStore,
|
|
1092
|
+
identity: target.identity,
|
|
1093
|
+
config: ctx.config,
|
|
1094
|
+
storePath,
|
|
1095
|
+
assertCurrent: assertHostCurrent
|
|
1096
|
+
}) : currentSession)?.binding;
|
|
1097
|
+
const assertCurrent = () => {
|
|
1098
|
+
assertHostCurrent();
|
|
1099
|
+
if (target && !isDeepStrictEqual(deps.bindingStore.read(target.identity), binding)) throw new Error("Codex command binding changed before dispatch");
|
|
1100
|
+
assertHostCurrent();
|
|
1101
|
+
};
|
|
1102
|
+
assertCurrent();
|
|
1103
|
+
return {
|
|
1104
|
+
target,
|
|
1105
|
+
binding,
|
|
1106
|
+
currentSessionBinding: currentSession?.binding,
|
|
1107
|
+
sessionId,
|
|
1108
|
+
sessionKey,
|
|
1109
|
+
storePath,
|
|
1110
|
+
assertHostCurrent,
|
|
1111
|
+
assertCurrent
|
|
1112
|
+
};
|
|
1113
|
+
}
|
|
1114
|
+
async function resolveCommandAppServerScope(deps, ctx, pluginConfig) {
|
|
1115
|
+
const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
|
|
1116
|
+
const { target, binding } = authority;
|
|
1117
|
+
const fallback = resolveCodexConversationControlScope(ctx);
|
|
1071
1118
|
const agentDir = target?.agentDir ?? fallback.agentDir;
|
|
1072
|
-
const binding = target ? await deps.bindingStore.read(target.identity) : void 0;
|
|
1073
1119
|
const authProfileId = binding?.connectionScope === "supervision" ? void 0 : resolveCodexAppServerAuthProfileIdForAgent({
|
|
1074
1120
|
authProfileId: binding?.authProfileId ?? target?.requestedAuthProfileId,
|
|
1075
1121
|
agentDir,
|
|
@@ -1085,8 +1131,10 @@ async function resolveCommandAppServerScope(deps, ctx, pluginConfig) {
|
|
|
1085
1131
|
agentDir,
|
|
1086
1132
|
...connection.clientAuthProfileId !== void 0 ? { authProfileId: connection.clientAuthProfileId } : {},
|
|
1087
1133
|
...connection.usesSupervisionConnection ? { startOptions: connection.appServer.start } : {},
|
|
1088
|
-
...
|
|
1089
|
-
...
|
|
1134
|
+
...authority.sessionKey ? { sessionKey: authority.sessionKey } : {},
|
|
1135
|
+
...authority.sessionId ? { sessionId: authority.sessionId } : {},
|
|
1136
|
+
...authority.storePath ? { storePath: authority.storePath } : {},
|
|
1137
|
+
assertCurrent: authority.assertCurrent
|
|
1090
1138
|
};
|
|
1091
1139
|
}
|
|
1092
1140
|
function conversationBindingIdentity(bindingId) {
|
|
@@ -1103,7 +1151,7 @@ function resolveCodexConversationControlScope(ctx) {
|
|
|
1103
1151
|
});
|
|
1104
1152
|
return {
|
|
1105
1153
|
agentId: sessionAgentId,
|
|
1106
|
-
agentDir: resolveAgentDir(ctx.config, sessionAgentId)
|
|
1154
|
+
agentDir: resolveAgentDir$1(ctx.config, sessionAgentId)
|
|
1107
1155
|
};
|
|
1108
1156
|
}
|
|
1109
1157
|
//#endregion
|
|
@@ -1200,7 +1248,7 @@ async function confirmCodexDiagnosticsFeedback(deps, ctx, pluginConfig, token) {
|
|
|
1200
1248
|
if (scopeMismatch) return scopeMismatch.confirmMessage;
|
|
1201
1249
|
deletePendingCodexDiagnosticsConfirmation(token);
|
|
1202
1250
|
if (!pending.privateRouted && !await hasAnyCodexDiagnosticsIdentity(ctx)) return "Cannot send Codex diagnostics because this command did not include a stable session identity.";
|
|
1203
|
-
const currentTargets = pending.privateRouted ?
|
|
1251
|
+
const currentTargets = pending.privateRouted ? resolvePendingCodexDiagnosticsTargets(deps, pending.targets, ctx.config) : await resolveCodexDiagnosticsTargets(deps, ctx);
|
|
1204
1252
|
if (!codexDiagnosticsTargetsMatch(pending.targets, currentTargets)) return "The Codex diagnostics sessions changed before confirmation. Run /diagnostics again for the current threads.";
|
|
1205
1253
|
return await sendCodexDiagnosticsFeedbackForTargets(deps, ctx, pluginConfig, pending.note ?? "", currentTargets, { cooldownScope: pending.scopeKey });
|
|
1206
1254
|
}
|
|
@@ -1307,7 +1355,7 @@ async function resolveCodexDiagnosticsTargets(deps, ctx) {
|
|
|
1307
1355
|
});
|
|
1308
1356
|
candidates.push({
|
|
1309
1357
|
identity,
|
|
1310
|
-
agentDir: resolveAgentDir(ctx.config, identity.agentId),
|
|
1358
|
+
agentDir: resolveAgentDir$1(ctx.config, identity.agentId),
|
|
1311
1359
|
sessionKey: session.sessionKey,
|
|
1312
1360
|
sessionId: session.sessionId,
|
|
1313
1361
|
channel: session.channel,
|
|
@@ -1324,17 +1372,17 @@ async function resolveCodexDiagnosticsTargets(deps, ctx) {
|
|
|
1324
1372
|
const key = bindingStoreKey(candidate.identity);
|
|
1325
1373
|
if (seenBindingKeys.has(key)) continue;
|
|
1326
1374
|
seenBindingKeys.add(key);
|
|
1327
|
-
const binding =
|
|
1375
|
+
const binding = deps.bindingStore.read(candidate.identity);
|
|
1328
1376
|
if (!binding?.threadId || seenThreadIds.has(binding.threadId)) continue;
|
|
1329
1377
|
seenThreadIds.add(binding.threadId);
|
|
1330
1378
|
targets.push(resolveCodexDiagnosticsTarget(candidate, binding, ctx.config));
|
|
1331
1379
|
}
|
|
1332
1380
|
return targets;
|
|
1333
1381
|
}
|
|
1334
|
-
|
|
1382
|
+
function resolvePendingCodexDiagnosticsTargets(deps, targets, config) {
|
|
1335
1383
|
const resolved = [];
|
|
1336
1384
|
for (const target of targets) {
|
|
1337
|
-
const binding =
|
|
1385
|
+
const binding = deps.bindingStore.read(target.identity);
|
|
1338
1386
|
if (!binding?.threadId) continue;
|
|
1339
1387
|
resolved.push(resolveCodexDiagnosticsTarget(target, binding, config));
|
|
1340
1388
|
}
|
|
@@ -1376,7 +1424,7 @@ function isCurrentSessionModelSelectionLocked(ctx) {
|
|
|
1376
1424
|
const sessionKey = ctx.sessionKey?.trim();
|
|
1377
1425
|
if (!sessionKey) return false;
|
|
1378
1426
|
const { agentId } = resolveCodexConversationControlScope(ctx);
|
|
1379
|
-
const storePath = resolveStorePath(ctx.config.session?.store, { agentId });
|
|
1427
|
+
const storePath = ctx.sessionTarget?.storePath ?? resolveStorePath(ctx.config.session?.store, { agentId });
|
|
1380
1428
|
return isModelSelectionLocked(getSessionEntry({
|
|
1381
1429
|
storePath,
|
|
1382
1430
|
sessionKey,
|
|
@@ -1400,7 +1448,7 @@ async function bindConversation(deps, ctx, pluginConfig, args) {
|
|
|
1400
1448
|
config: ctx.config
|
|
1401
1449
|
}) : void 0;
|
|
1402
1450
|
const currentOwner = currentConversationData?.kind === "codex-app-server-session" ? conversationBindingIdentity(currentConversationData.bindingId) : sessionOwner;
|
|
1403
|
-
const existingBinding = currentOwner ?
|
|
1451
|
+
const existingBinding = currentOwner ? deps.bindingStore.read(currentOwner) : void 0;
|
|
1404
1452
|
assertCodexBindingMayBeReplaced(existingBinding, "binding this conversation to another thread");
|
|
1405
1453
|
const sessionSource = sessionOwner && existingBinding ? {
|
|
1406
1454
|
agentId: sessionOwner.agentId,
|
|
@@ -1442,7 +1490,7 @@ async function detachConversation(deps, ctx) {
|
|
|
1442
1490
|
let expectedThreadId;
|
|
1443
1491
|
let expectedStartId;
|
|
1444
1492
|
if (data?.kind === "codex-app-server-session") {
|
|
1445
|
-
const binding =
|
|
1493
|
+
const binding = deps.bindingStore.read(identity);
|
|
1446
1494
|
assertCodexBindingMayBeReplaced(binding, "detaching its conversation binding");
|
|
1447
1495
|
if (deps.readCodexConversationActiveTurn(identity)) return "This Codex conversation has an active run; use /codex stop before detaching it.";
|
|
1448
1496
|
expectedThreadId = binding?.threadId;
|
|
@@ -1480,13 +1528,13 @@ async function describeConversationBinding(deps, ctx) {
|
|
|
1480
1528
|
"- Active run: not tracked"
|
|
1481
1529
|
].join("\n");
|
|
1482
1530
|
const identity = conversationBindingIdentity(data.bindingId);
|
|
1483
|
-
const threadBinding =
|
|
1531
|
+
const threadBinding = deps.bindingStore.read(identity);
|
|
1484
1532
|
const active = deps.readCodexConversationActiveTurn(identity);
|
|
1485
1533
|
const sessionKey = ctx.sessionKey?.trim();
|
|
1486
1534
|
const { agentId } = resolveCodexConversationControlScope(ctx);
|
|
1487
1535
|
const sessionEntry = sessionKey ? getSessionEntry({
|
|
1488
1536
|
agentId,
|
|
1489
|
-
storePath: resolveStorePath(ctx.config.session?.store, { agentId }),
|
|
1537
|
+
storePath: ctx.sessionTarget?.storePath ?? resolveStorePath(ctx.config.session?.store, { agentId }),
|
|
1490
1538
|
sessionKey,
|
|
1491
1539
|
hydrateSkillPromptRefs: false,
|
|
1492
1540
|
readConsistency: "latest"
|
|
@@ -1538,17 +1586,22 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
|
|
|
1538
1586
|
agentId: scope.agentId,
|
|
1539
1587
|
config: ctx.config
|
|
1540
1588
|
});
|
|
1589
|
+
const { assertCurrent: assertHostGeneration } = await resolveCodexSessionBinding({
|
|
1590
|
+
reclaimStale: true,
|
|
1591
|
+
bindingStore: deps.bindingStore,
|
|
1592
|
+
identity,
|
|
1593
|
+
config: ctx.config,
|
|
1594
|
+
storePath: ctx.sessionTarget?.storePath
|
|
1595
|
+
});
|
|
1541
1596
|
return await withExclusiveCodexAppServerThread({
|
|
1542
1597
|
bindingStore: deps.bindingStore,
|
|
1543
1598
|
identity,
|
|
1544
1599
|
threadId: normalizedThreadId,
|
|
1545
1600
|
run: async () => await deps.bindingStore.withLease(identity, async () => {
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
})) throw createCodexSessionGenerationSupersededError(identity.sessionId);
|
|
1551
|
-
const currentBinding = await deps.bindingStore.read(identity);
|
|
1601
|
+
const generation = await deps.bindingStore.prepareSessionGenerationReclaim(identity);
|
|
1602
|
+
assertHostGeneration();
|
|
1603
|
+
if (generation.kind !== "resolved" || !generation.result) throw createCodexSessionGenerationSupersededError(identity.sessionId);
|
|
1604
|
+
const currentBinding = deps.bindingStore.read(identity);
|
|
1552
1605
|
assertCodexBindingMayBeReplaced(currentBinding, "attaching a different resumed thread");
|
|
1553
1606
|
let pendingResumeConfiguration = false;
|
|
1554
1607
|
const commitResumedThread = async (value, client, { authProfileId, assertCurrent }) => {
|
|
@@ -1568,7 +1621,7 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
|
|
|
1568
1621
|
let sameOwner = false;
|
|
1569
1622
|
let knownOwnership;
|
|
1570
1623
|
try {
|
|
1571
|
-
const bindingBeforeCommit =
|
|
1624
|
+
const bindingBeforeCommit = deps.bindingStore.read(identity);
|
|
1572
1625
|
assertCodexBindingMayBeReplaced(bindingBeforeCommit, "committing a different resumed thread");
|
|
1573
1626
|
sameOwner = isSameCodexAppServerThreadOwner(bindingBeforeCommit, {
|
|
1574
1627
|
threadId: effectiveThreadId,
|
|
@@ -1583,7 +1636,7 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
|
|
|
1583
1636
|
retained = await retainCodexAppServerBindingSubscription(client, effectiveThreadId, knownOwnership);
|
|
1584
1637
|
assertCurrent();
|
|
1585
1638
|
if (!retained) throw new Error("Codex resumed thread lost its native subscription owner.");
|
|
1586
|
-
if (bindingBeforeCommit && !sameOwner) await releaseCodexAppServerBindingSubscription(bindingBeforeCommit);
|
|
1639
|
+
if (bindingBeforeCommit && !sameOwner) await releaseCodexAppServerBindingSubscription(bindingBeforeCommit, { assertCurrent });
|
|
1587
1640
|
assertCurrent();
|
|
1588
1641
|
if (!await deps.bindingStore.mutate(identity, {
|
|
1589
1642
|
kind: "set",
|
|
@@ -1617,6 +1670,8 @@ async function resumeThread(deps, ctx, pluginConfig, args) {
|
|
|
1617
1670
|
authProfileId: currentBinding?.authProfileId,
|
|
1618
1671
|
sessionKey: ctx.sessionKey,
|
|
1619
1672
|
sessionId: ctx.sessionId,
|
|
1673
|
+
storePath: ctx.sessionTarget?.storePath,
|
|
1674
|
+
assertCurrent: assertHostGeneration,
|
|
1620
1675
|
beforeRequest: async (request) => {
|
|
1621
1676
|
const { thread } = await request({
|
|
1622
1677
|
method: "thread/read",
|
|
@@ -1638,7 +1693,7 @@ async function bindCodexCliNodeSession(deps, ctx, parsed) {
|
|
|
1638
1693
|
if (isCurrentSessionModelSelectionLocked(ctx)) return MODEL_SELECTION_LOCKED_MESSAGE;
|
|
1639
1694
|
if (ctx.sessionId) {
|
|
1640
1695
|
const scope = resolveCodexConversationControlScope(ctx);
|
|
1641
|
-
const binding =
|
|
1696
|
+
const binding = deps.bindingStore.read(sessionBindingIdentity({
|
|
1642
1697
|
sessionId: ctx.sessionId,
|
|
1643
1698
|
sessionKey: ctx.sessionKey,
|
|
1644
1699
|
agentId: scope.agentId,
|
|
@@ -1759,9 +1814,9 @@ async function handleComputerUseCommand(deps, ctx, pluginConfig, args) {
|
|
|
1759
1814
|
async function handleNativeGoal(deps, ctx, pluginConfig, args) {
|
|
1760
1815
|
const action = (args[0] ?? "status").toLowerCase();
|
|
1761
1816
|
const objective = args.slice(1).join(" ").trim();
|
|
1762
|
-
const
|
|
1817
|
+
const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
|
|
1818
|
+
const { target, binding } = authority;
|
|
1763
1819
|
if (!target) return "Cannot manage the Codex goal because this command has no stable binding identity.";
|
|
1764
|
-
const binding = await deps.bindingStore.read(target.identity);
|
|
1765
1820
|
if (!binding?.threadId) return "No Codex thread is attached to this OpenClaw session yet.";
|
|
1766
1821
|
const connection = resolveCodexBindingAppServerConnection({
|
|
1767
1822
|
binding,
|
|
@@ -1772,6 +1827,10 @@ async function handleNativeGoal(deps, ctx, pluginConfig, args) {
|
|
|
1772
1827
|
agentDir: target.agentDir,
|
|
1773
1828
|
authProfileId: connection.clientAuthProfileId,
|
|
1774
1829
|
config: ctx.config,
|
|
1830
|
+
sessionId: authority.sessionId,
|
|
1831
|
+
sessionKey: authority.sessionKey,
|
|
1832
|
+
storePath: authority.storePath,
|
|
1833
|
+
assertCurrent: authority.assertCurrent,
|
|
1775
1834
|
...connection.usesSupervisionConnection ? { startOptions: connection.appServer.start } : {}
|
|
1776
1835
|
};
|
|
1777
1836
|
if (action === "status" || action === "get") {
|
|
@@ -1810,26 +1869,30 @@ function formatNativeGoal(response) {
|
|
|
1810
1869
|
].join("\n");
|
|
1811
1870
|
}
|
|
1812
1871
|
async function stopConversationTurn(deps, ctx, pluginConfig) {
|
|
1813
|
-
const
|
|
1872
|
+
const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
|
|
1873
|
+
const { target, binding } = authority;
|
|
1814
1874
|
if (!target) return "Cannot stop Codex because this command did not include a stable binding identity.";
|
|
1815
1875
|
return (await deps.stopCodexConversationTurn({
|
|
1816
1876
|
identity: target.identity,
|
|
1817
|
-
|
|
1877
|
+
binding,
|
|
1818
1878
|
pluginConfig,
|
|
1819
1879
|
agentDir: target.agentDir,
|
|
1820
|
-
config: ctx.config
|
|
1880
|
+
config: ctx.config,
|
|
1881
|
+
assertCurrent: authority.assertCurrent
|
|
1821
1882
|
})).message;
|
|
1822
1883
|
}
|
|
1823
1884
|
async function steerConversationTurn(deps, ctx, pluginConfig, message) {
|
|
1824
|
-
const
|
|
1885
|
+
const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
|
|
1886
|
+
const { target, binding } = authority;
|
|
1825
1887
|
if (!target) return "Cannot steer Codex because this command did not include a stable binding identity.";
|
|
1826
1888
|
return (await deps.steerCodexConversationTurn({
|
|
1827
1889
|
identity: target.identity,
|
|
1828
|
-
|
|
1890
|
+
binding,
|
|
1829
1891
|
message,
|
|
1830
1892
|
pluginConfig,
|
|
1831
1893
|
agentDir: target.agentDir,
|
|
1832
|
-
config: ctx.config
|
|
1894
|
+
config: ctx.config,
|
|
1895
|
+
assertCurrent: authority.assertCurrent
|
|
1833
1896
|
})).message;
|
|
1834
1897
|
}
|
|
1835
1898
|
async function setConversationModel(deps, ctx, pluginConfig, args) {
|
|
@@ -1837,17 +1900,18 @@ async function setConversationModel(deps, ctx, pluginConfig, args) {
|
|
|
1837
1900
|
const [model = ""] = args;
|
|
1838
1901
|
const normalized = model.trim();
|
|
1839
1902
|
if (normalized && isCurrentSessionModelSelectionLocked(ctx)) return MODEL_SELECTION_LOCKED_MESSAGE;
|
|
1840
|
-
const
|
|
1903
|
+
const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
|
|
1904
|
+
const { target, binding } = authority;
|
|
1841
1905
|
if (!target) return "Cannot set Codex model because this command did not include a stable binding identity.";
|
|
1842
1906
|
if (!normalized) {
|
|
1843
|
-
const currentSession =
|
|
1844
|
-
storePath:
|
|
1845
|
-
sessionKey:
|
|
1907
|
+
const currentSession = authority.sessionId && authority.sessionKey && authority.storePath ? getSessionEntry({
|
|
1908
|
+
storePath: authority.storePath,
|
|
1909
|
+
sessionKey: authority.sessionKey,
|
|
1846
1910
|
hydrateSkillPromptRefs: false,
|
|
1847
1911
|
readConsistency: "latest"
|
|
1848
1912
|
}) : void 0;
|
|
1849
|
-
const selectedModel = currentSession && currentSession.sessionId ===
|
|
1850
|
-
|
|
1913
|
+
const selectedModel = currentSession && currentSession.sessionId === authority.sessionId ? currentSession.modelOverride ?? currentSession.model : void 0;
|
|
1914
|
+
authority.assertCurrent();
|
|
1851
1915
|
const activeModel = target.identity.kind === "conversation" ? binding?.model : selectedModel ?? binding?.model;
|
|
1852
1916
|
return activeModel ? `Codex model: ${formatCodexDisplayText(activeModel)}` : "Usage: /codex model <model>";
|
|
1853
1917
|
}
|
|
@@ -1857,12 +1921,16 @@ async function setConversationModel(deps, ctx, pluginConfig, args) {
|
|
|
1857
1921
|
pluginConfig,
|
|
1858
1922
|
model: normalized,
|
|
1859
1923
|
agentDir: target.agentDir,
|
|
1860
|
-
config: ctx.config
|
|
1924
|
+
config: ctx.config,
|
|
1925
|
+
binding,
|
|
1926
|
+
storePath: authority.storePath,
|
|
1927
|
+
assertCurrent: authority.assertCurrent
|
|
1861
1928
|
});
|
|
1862
1929
|
}
|
|
1863
1930
|
async function setConversationFastMode(deps, ctx, args) {
|
|
1864
1931
|
if (args.length > 1) return "Usage: /codex fast [on|off|status]";
|
|
1865
|
-
const
|
|
1932
|
+
const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
|
|
1933
|
+
const { target, binding } = authority;
|
|
1866
1934
|
if (!target) return "Cannot set Codex fast mode because this command did not include a stable binding identity.";
|
|
1867
1935
|
const value = args[0];
|
|
1868
1936
|
const parsed = parseCodexFastModeArg(value);
|
|
@@ -1870,12 +1938,15 @@ async function setConversationFastMode(deps, ctx, args) {
|
|
|
1870
1938
|
return await deps.setCodexConversationFastMode({
|
|
1871
1939
|
identity: target.identity,
|
|
1872
1940
|
bindingStore: deps.bindingStore,
|
|
1873
|
-
|
|
1941
|
+
binding,
|
|
1942
|
+
enabled: parsed,
|
|
1943
|
+
assertCurrent: authority.assertCurrent
|
|
1874
1944
|
});
|
|
1875
1945
|
}
|
|
1876
1946
|
async function setConversationPermissions(deps, ctx, args) {
|
|
1877
1947
|
if (args.length > 1) return "Usage: /codex permissions [default|yolo|status]";
|
|
1878
|
-
const
|
|
1948
|
+
const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
|
|
1949
|
+
const { target } = authority;
|
|
1879
1950
|
if (!target || !ctx.sessionId || !ctx.sessionKey) return "Cannot set Codex permissions because this command did not include a complete session identity.";
|
|
1880
1951
|
const value = args[0];
|
|
1881
1952
|
const parsed = parseCodexPermissionsModeArg(value);
|
|
@@ -1884,6 +1955,8 @@ async function setConversationPermissions(deps, ctx, args) {
|
|
|
1884
1955
|
return await deps.setCodexConversationPermissions({
|
|
1885
1956
|
mode: parsed,
|
|
1886
1957
|
config: ctx.config,
|
|
1958
|
+
storePath: authority.storePath,
|
|
1959
|
+
assertCurrent: authority.assertHostCurrent,
|
|
1887
1960
|
session: {
|
|
1888
1961
|
agentId: target.agentId,
|
|
1889
1962
|
sessionId: ctx.sessionId,
|
|
@@ -1893,31 +1966,26 @@ async function setConversationPermissions(deps, ctx, args) {
|
|
|
1893
1966
|
}
|
|
1894
1967
|
async function startThreadAction(deps, ctx, pluginConfig, kind, args) {
|
|
1895
1968
|
if (args.length > 0) return `Usage: /codex ${kind}`;
|
|
1896
|
-
const
|
|
1969
|
+
const authority = await resolvePreparedCodexCommandAuthority(deps, ctx);
|
|
1970
|
+
const { target, binding } = authority;
|
|
1897
1971
|
if (!target) return `Cannot start Codex ${kind === "compact" ? "compaction" : "review"} because this command did not include a stable binding identity.`;
|
|
1898
|
-
const binding = await deps.bindingStore.read(target.identity);
|
|
1899
1972
|
if (!binding?.threadId) return `No Codex thread is attached to this OpenClaw session yet.`;
|
|
1900
1973
|
if (kind === "compact") {
|
|
1901
1974
|
const sessionTarget = ctx.sessionTarget;
|
|
1902
1975
|
if (!ctx.sessionId || !ctx.sessionKey || !sessionTarget || sessionTarget.sessionId !== ctx.sessionId || sessionTarget.sessionKey !== ctx.sessionKey) return "Codex compaction is unavailable because this command is not bound to a complete session identity.";
|
|
1903
1976
|
const currentSession = getSessionEntry({
|
|
1904
|
-
storePath: sessionTarget.storePath,
|
|
1977
|
+
storePath: authority.storePath ?? sessionTarget.storePath,
|
|
1905
1978
|
sessionKey: ctx.sessionKey,
|
|
1906
1979
|
hydrateSkillPromptRefs: false,
|
|
1907
1980
|
readConsistency: "latest"
|
|
1908
1981
|
});
|
|
1909
1982
|
if (currentSession?.sessionId !== ctx.sessionId || resolvePersistedSessionRuntimeId(currentSession) !== "codex") return "Codex compaction is unavailable because the current OpenClaw session is not using the Codex runtime.";
|
|
1910
1983
|
if (target.identity.kind === "conversation") {
|
|
1911
|
-
|
|
1912
|
-
sessionId: ctx.sessionId,
|
|
1913
|
-
sessionKey: ctx.sessionKey,
|
|
1914
|
-
agentId: sessionTarget.agentId,
|
|
1915
|
-
config: ctx.config
|
|
1916
|
-
})) : void 0;
|
|
1917
|
-
if (!isSameCodexAppServerThreadOwner(binding, sessionBinding)) return "Codex compaction is unavailable because the conversation-bound thread differs from the current session binding. Resume that thread into the session first.";
|
|
1984
|
+
if (!isSameCodexAppServerThreadOwner(binding, authority.currentSessionBinding)) return "Codex compaction is unavailable because the conversation-bound thread differs from the current session binding. Resume that thread into the session first.";
|
|
1918
1985
|
}
|
|
1919
1986
|
const compactCurrent = ctx.runtimeContext?.compactCurrent;
|
|
1920
1987
|
if (!compactCurrent) return "Codex compaction is unavailable because this command is not bound to a session.";
|
|
1988
|
+
authority.assertCurrent();
|
|
1921
1989
|
const result = await compactCurrent();
|
|
1922
1990
|
return result.compacted ? `Compacted Codex session (${result.tokensAfter ?? "unknown"} tokens after).` : `Codex compaction did not complete: ${formatCodexDisplayText(result.reason ?? "no reason returned")}.`;
|
|
1923
1991
|
}
|
|
@@ -1933,6 +2001,10 @@ async function startThreadAction(deps, ctx, pluginConfig, kind, args) {
|
|
|
1933
2001
|
agentDir: target.agentDir,
|
|
1934
2002
|
authProfileId: connection.clientAuthProfileId,
|
|
1935
2003
|
config: ctx.config,
|
|
2004
|
+
sessionId: authority.sessionId,
|
|
2005
|
+
sessionKey: authority.sessionKey,
|
|
2006
|
+
storePath: authority.storePath,
|
|
2007
|
+
assertCurrent: authority.assertCurrent,
|
|
1936
2008
|
...connection.usesSupervisionConnection ? {
|
|
1937
2009
|
startOptions: connection.appServer.start,
|
|
1938
2010
|
beforeRequest: supervisedCommandGuard(deps, target.identity, binding)
|
|
@@ -1947,7 +2019,7 @@ function supervisedCommandGuard(deps, identity, binding) {
|
|
|
1947
2019
|
includeTurns: false
|
|
1948
2020
|
});
|
|
1949
2021
|
scope.assertCurrent();
|
|
1950
|
-
if (!isDeepStrictEqual(
|
|
2022
|
+
if (!isDeepStrictEqual(deps.bindingStore.read(identity), binding)) throw new Error("Codex command binding changed before model execution");
|
|
1951
2023
|
scope.assertCurrent();
|
|
1952
2024
|
assertCodexSupervisionThreadLineage(binding, thread);
|
|
1953
2025
|
};
|