@openclaw/codex 2026.7.2-beta.3 → 2026.7.2-beta.4

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.
Files changed (38) hide show
  1. package/dist/{app-server-policy-DUMF2Xyr.js → app-server-policy-BO3jYBkv.js} +1 -1
  2. package/dist/{attempt-notifications-Ecjyzufe.js → attempt-notifications-DdmnBMUp.js} +1 -1
  3. package/dist/{media-understanding-provider-IPNNQre6.js → bounded-turn-CaQL96kg.js} +43 -183
  4. package/dist/capabilities-CLICvTxf.js +36 -0
  5. package/dist/cli-metadata.js +1 -1
  6. package/dist/{command-formatters-NCTL7A2q.js → command-formatters-DgADqnHa.js} +3 -37
  7. package/dist/{command-handlers-DtFbZiba.js → command-handlers-l_lVPNlB.js} +12 -11
  8. package/dist/{compact-Kgy26gIM.js → compact-CC5KhBzX.js} +5 -4
  9. package/dist/{computer-use-C7x4ZaqR.js → computer-use-Ip1-QGa-.js} +4 -4
  10. package/dist/{conversation-control-B0s3aIjT.js → conversation-control-sNPsbTCP.js} +6 -5
  11. package/dist/doctor-contract-api.js +1 -1
  12. package/dist/{dynamic-tools-D_vSVmv9.js → dynamic-tools-CQI3UwqY.js} +105 -2670
  13. package/dist/event-projector-assistant-message-DTgnPPVF.js +101 -0
  14. package/dist/event-projector-usage-D6tE7_qD.js +69 -0
  15. package/dist/harness.js +25 -6
  16. package/dist/incognito-session-ET_ufDH-.js +2 -0
  17. package/dist/index.js +60 -26
  18. package/dist/media-understanding-provider.js +168 -1
  19. package/dist/{models-DD5zBdX5.js → models-BNeMlHgg.js} +2 -2
  20. package/dist/{notification-correlation-C8DVQ_Bq.js → notification-correlation-BGLixv5_.js} +3 -3
  21. package/dist/{plugin-app-cache-key-DJbhLYSK.js → plugin-app-cache-key-CvzvmBRz.js} +2 -2
  22. package/dist/{rate-limits-CqhWQ2R9.js → rate-limits-D0IJT-a6.js} +1 -1
  23. package/dist/{request-9yf9pZjf.js → request-BTccUTD3.js} +1 -1
  24. package/dist/{run-attempt-BIoO8ISr.js → run-attempt--858NXDl.js} +2653 -109
  25. package/dist/{session-binding-Bmt20HfB.js → session-binding-ZSMX1omP.js} +7 -2
  26. package/dist/{session-catalog-CA7R-hX2.js → session-catalog-DsKaezgR.js} +82 -80
  27. package/dist/{session-cli-Bxk3-Wqz.js → session-cli-CYJTfRLG.js} +1 -1
  28. package/dist/session-upstream-marker-D7XlI9us.js +82 -0
  29. package/dist/settled-turn-finalizer-DHltNgtF.js +303 -0
  30. package/dist/{shared-client-CSXLtCLE.js → shared-client-wmgNFNYp.js} +33 -13
  31. package/dist/{side-question-DtzquMOb.js → side-question-BfFZCsJ-.js} +21 -15
  32. package/dist/{thread-lifecycle-CQ_9mAa1.js → thread-lifecycle-cqrOlJkq.js} +120 -26
  33. package/dist/{transcript-mirror-D9rTxx2P.js → transcript-mirror-2p7kl6e4.js} +433 -145
  34. package/dist/upstream-session-fork-vPjwkT1i.js +320 -0
  35. package/dist/{usage-CuPpFgTc.js → usage-DM_I3mPT.js} +3 -3
  36. package/dist/{web-search-provider.runtime-_x5XTeqh.js → web-search-provider.runtime-Bx6HAc_k.js} +3 -3
  37. package/npm-shrinkwrap.json +38 -38
  38. package/package.json +7 -7
@@ -0,0 +1,101 @@
1
+ import { formatErrorMessage } from "openclaw/plugin-sdk/agent-harness-runtime";
2
+ //#region extensions/codex/src/app-server/local-runtime-attribution.ts
3
+ const OPENAI_PROVIDER_ID = "openai";
4
+ const OPENAI_RESPONSES_API = "openai-responses";
5
+ const OPENAI_CODEX_RESPONSES_API = "openai-chatgpt-responses";
6
+ function normalizeRuntimeId(value) {
7
+ return value?.trim().toLowerCase() ?? "";
8
+ }
9
+ /** Maps local Codex runtime plans onto the provider/api pair exposed to event projection. */
10
+ function resolveCodexLocalRuntimeAttribution(params) {
11
+ const authProfileProvider = normalizeRuntimeId(params.runtimePlan?.auth?.authProfileProviderForAuth);
12
+ if (normalizeRuntimeId(params.runtimePlan?.observability.harnessId) === "codex" && authProfileProvider !== OPENAI_PROVIDER_ID && normalizeRuntimeId(params.model.provider) === OPENAI_PROVIDER_ID && normalizeRuntimeId(params.model.api) === OPENAI_RESPONSES_API) return {
13
+ provider: OPENAI_PROVIDER_ID,
14
+ api: OPENAI_CODEX_RESPONSES_API
15
+ };
16
+ return {
17
+ provider: params.provider,
18
+ api: params.model.api
19
+ };
20
+ }
21
+ //#endregion
22
+ //#region extensions/codex/src/app-server/event-projector-assistant-message.ts
23
+ const ZERO_USAGE = {
24
+ input: 0,
25
+ output: 0,
26
+ cacheRead: 0,
27
+ cacheWrite: 0,
28
+ totalTokens: 0,
29
+ cost: {
30
+ input: 0,
31
+ output: 0,
32
+ cacheRead: 0,
33
+ cacheWrite: 0,
34
+ total: 0
35
+ }
36
+ };
37
+ function createAssistantMessage(params, text, options) {
38
+ const attribution = resolveCodexLocalRuntimeAttribution(params);
39
+ const usage = options.tokenUsage ? {
40
+ input: options.tokenUsage.input ?? 0,
41
+ output: options.tokenUsage.output ?? 0,
42
+ cacheRead: options.tokenUsage.cacheRead ?? 0,
43
+ cacheWrite: options.tokenUsage.cacheWrite ?? 0,
44
+ ...options.tokenUsage.contextUsage ? { contextUsage: options.tokenUsage.contextUsage } : {},
45
+ totalTokens: options.tokenUsage.total ?? (options.tokenUsage.input ?? 0) + (options.tokenUsage.output ?? 0) + (options.tokenUsage.cacheRead ?? 0) + (options.tokenUsage.cacheWrite ?? 0),
46
+ cost: ZERO_USAGE.cost
47
+ } : ZERO_USAGE;
48
+ return {
49
+ role: "assistant",
50
+ content: [{
51
+ type: "text",
52
+ text
53
+ }],
54
+ api: attribution.api ?? "openai-chatgpt-responses",
55
+ provider: attribution.provider,
56
+ model: params.modelId,
57
+ usage,
58
+ stopReason: options.aborted ? "aborted" : options.promptError ? "error" : "stop",
59
+ errorMessage: options.promptError ? formatErrorMessage(options.promptError) : void 0,
60
+ timestamp: Date.now()
61
+ };
62
+ }
63
+ function createAssistantCommentaryMessage(params, text, itemId, timestamp) {
64
+ const attribution = resolveCodexLocalRuntimeAttribution(params);
65
+ return {
66
+ role: "assistant",
67
+ content: [{
68
+ type: "text",
69
+ text
70
+ }],
71
+ api: attribution.api ?? "openai-chatgpt-responses",
72
+ provider: attribution.provider,
73
+ model: params.modelId,
74
+ usage: ZERO_USAGE,
75
+ stopReason: "stop",
76
+ timestamp,
77
+ openclawStreamFallback: {
78
+ replacementText: text,
79
+ source: "segment",
80
+ itemId
81
+ }
82
+ };
83
+ }
84
+ function createAssistantMirrorMessage(params, title, text) {
85
+ const attribution = resolveCodexLocalRuntimeAttribution(params);
86
+ return {
87
+ role: "assistant",
88
+ content: [{
89
+ type: "text",
90
+ text: `${title}:\n${text}`
91
+ }],
92
+ api: attribution.api ?? "openai-chatgpt-responses",
93
+ provider: attribution.provider,
94
+ model: params.modelId,
95
+ usage: ZERO_USAGE,
96
+ stopReason: "stop",
97
+ timestamp: Date.now()
98
+ };
99
+ }
100
+ //#endregion
101
+ export { resolveCodexLocalRuntimeAttribution as i, createAssistantMessage as n, createAssistantMirrorMessage as r, createAssistantCommentaryMessage as t };
@@ -0,0 +1,69 @@
1
+ import { Q as isJsonObject } from "./shared-client-wmgNFNYp.js";
2
+ import { dt as readNonNegativeInteger, pt as readNumber } from "./thread-lifecycle-cqrOlJkq.js";
3
+ import { normalizeUsage } from "openclaw/plugin-sdk/agent-harness-runtime";
4
+ //#region extensions/codex/src/app-server/event-projector-usage.ts
5
+ function readTokenCount(record, key) {
6
+ const value = readNonNegativeInteger(record, key);
7
+ return value !== void 0 && Number.isSafeInteger(value) ? value : void 0;
8
+ }
9
+ function readCodexThreadTokenUsage(params) {
10
+ const tokenUsage = isJsonObject(params.tokenUsage) ? params.tokenUsage : void 0;
11
+ const last = tokenUsage && isJsonObject(tokenUsage.last) ? tokenUsage.last : void 0;
12
+ return last ? normalizeCodexThreadTokenUsage(last) : void 0;
13
+ }
14
+ function readCodexThreadContextSnapshot(params) {
15
+ const tokenUsage = isJsonObject(params.tokenUsage) ? params.tokenUsage : void 0;
16
+ const last = tokenUsage && isJsonObject(tokenUsage.last) ? tokenUsage.last : void 0;
17
+ const modelContextWindow = tokenUsage ? readTokenCount(tokenUsage, "modelContextWindow") : void 0;
18
+ const promptTokens = last ? readTokenCount(last, "inputTokens") : void 0;
19
+ return {
20
+ ...modelContextWindow && modelContextWindow > 0 ? { modelContextWindow } : {},
21
+ ...promptTokens !== void 0 ? { promptTokens } : {}
22
+ };
23
+ }
24
+ function projectCodexThreadUsageUpdate(params, currentUsage, applyUsage, emitContext) {
25
+ applyUsage(readCodexThreadTokenUsage(params) ?? currentUsage);
26
+ const context = readCodexThreadContextSnapshot(params);
27
+ if (context.modelContextWindow !== void 0 || context.promptTokens !== void 0) emitContext(context);
28
+ }
29
+ function normalizeCodexThreadTokenUsage(record) {
30
+ const inputTokens = readNumber(record, "inputTokens");
31
+ const cacheRead = readNumber(record, "cachedInputTokens");
32
+ const usage = normalizeUsage({
33
+ input: inputTokens !== void 0 && cacheRead !== void 0 ? Math.max(0, inputTokens - cacheRead) : inputTokens,
34
+ output: readNumber(record, "outputTokens"),
35
+ cacheRead,
36
+ total: readNumber(record, "totalTokens")
37
+ });
38
+ return usage ? {
39
+ ...usage,
40
+ contextUsage: { state: "unavailable" }
41
+ } : void 0;
42
+ }
43
+ function normalizeCodexResponseTokenUsage(record) {
44
+ const totalTokens = readTokenCount(record, "totalTokens");
45
+ const inputTokens = readTokenCount(record, "inputTokens");
46
+ const cacheRead = readTokenCount(record, "cachedInputTokens");
47
+ const output = readTokenCount(record, "outputTokens");
48
+ const reasoningOutput = readTokenCount(record, "reasoningOutputTokens");
49
+ const cacheWrite = record.cacheWriteInputTokens === void 0 ? 0 : readTokenCount(record, "cacheWriteInputTokens");
50
+ if (totalTokens === void 0 || inputTokens === void 0 || cacheRead === void 0 || cacheWrite === void 0 || output === void 0 || reasoningOutput === void 0 || cacheRead + cacheWrite > inputTokens || totalTokens !== inputTokens + output) return;
51
+ const usage = normalizeUsage({
52
+ input: inputTokens - cacheRead - cacheWrite,
53
+ output,
54
+ cacheRead,
55
+ cacheWrite,
56
+ total: totalTokens
57
+ });
58
+ if (!usage) return;
59
+ return {
60
+ ...usage,
61
+ contextUsage: {
62
+ state: "available",
63
+ promptTokens: inputTokens,
64
+ totalTokens
65
+ }
66
+ };
67
+ }
68
+ //#endregion
69
+ export { projectCodexThreadUsageUpdate as n, normalizeCodexResponseTokenUsage as t };
package/dist/harness.js CHANGED
@@ -22,6 +22,8 @@ function createCodexAppServerAgentHarness(options) {
22
22
  const harnessRuntimeId = options?.id ?? "codex";
23
23
  const normalizedHarnessRuntimeId = harnessRuntimeId.trim().toLowerCase();
24
24
  const providerIds = new Set([...options?.providerIds ?? DEFAULT_CODEX_HARNESS_PROVIDER_IDS].map((id) => id.trim().toLowerCase()));
25
+ const sessionCatalogControl = options.sessionCatalogControl;
26
+ const sessionRuntime = options.runtime;
25
27
  return {
26
28
  id: harnessRuntimeId,
27
29
  label: options?.label ?? "Codex agent harness",
@@ -30,6 +32,19 @@ function createCodexAppServerAgentHarness(options) {
30
32
  contextEngineHostCapabilities: CODEX_APP_SERVER_CONTEXT_ENGINE_HOST_CAPABILITIES,
31
33
  deliveryDefaults: { visibleReplies: "message_tool" },
32
34
  authBootstrap: "harness",
35
+ ...sessionCatalogControl && sessionRuntime ? { sessionFork: {
36
+ upstreamKinds: ["codex-app-server"],
37
+ fork: async (params) => {
38
+ const { forkCodexUpstreamSession } = await import("./upstream-session-fork-vPjwkT1i.js");
39
+ return await forkCodexUpstreamSession(params, {
40
+ bindingStore: options.bindingStore,
41
+ control: sessionCatalogControl,
42
+ harnessRuntimeId,
43
+ resolveConfig: options.resolveConfig,
44
+ runtime: sessionRuntime
45
+ });
46
+ }
47
+ } } : {},
33
48
  authBinding: { fingerprint: async (params) => {
34
49
  const { fingerprintCodexAppServerAuthBinding } = await import("./auth-binding-C1czuHPA.js").then((n) => n.t);
35
50
  return fingerprintCodexAppServerAuthBinding(params);
@@ -39,7 +54,7 @@ function createCodexAppServerAgentHarness(options) {
39
54
  return validateCodexAppServerRuntimeArtifact(binding);
40
55
  } },
41
56
  fetchUsageSnapshot: async (ctx) => {
42
- const { fetchCodexAppServerUsageSnapshot } = await import("./usage-CuPpFgTc.js");
57
+ const { fetchCodexAppServerUsageSnapshot } = await import("./usage-DM_I3mPT.js");
43
58
  return await fetchCodexAppServerUsageSnapshot(ctx, { pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig });
44
59
  },
45
60
  supports: (ctx) => {
@@ -80,15 +95,19 @@ function createCodexAppServerAgentHarness(options) {
80
95
  };
81
96
  },
82
97
  runAttempt: async (params) => {
83
- const { runCodexAppServerAttempt } = await import("./run-attempt-BIoO8ISr.js");
98
+ const { runCodexAppServerAttempt } = await import("./run-attempt--858NXDl.js");
84
99
  return runCodexAppServerAttempt(params, {
85
100
  bindingStore: options.bindingStore,
86
101
  pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig,
87
102
  nativeHookRelay: { enabled: true }
88
103
  });
89
104
  },
105
+ finalizeSettledTurn: async (params) => {
106
+ const { runCodexSettledTurnFinalization } = await import("./settled-turn-finalizer-DHltNgtF.js");
107
+ return runCodexSettledTurnFinalization(params, { pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig });
108
+ },
90
109
  runSideQuestion: async (params) => {
91
- const { runCodexAppServerSideQuestion } = await import("./side-question-DtzquMOb.js");
110
+ const { runCodexAppServerSideQuestion } = await import("./side-question-BfFZCsJ-.js");
92
111
  return runCodexAppServerSideQuestion(params, {
93
112
  bindingStore: options.bindingStore,
94
113
  pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig,
@@ -96,14 +115,14 @@ function createCodexAppServerAgentHarness(options) {
96
115
  });
97
116
  },
98
117
  compact: async (params) => {
99
- const { maybeCompactCodexAppServerSession } = await import("./compact-Kgy26gIM.js");
118
+ const { maybeCompactCodexAppServerSession } = await import("./compact-CC5KhBzX.js");
100
119
  return maybeCompactCodexAppServerSession(params, {
101
120
  bindingStore: options.bindingStore,
102
121
  pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig
103
122
  });
104
123
  },
105
124
  compactAfterContextEngine: async (params) => {
106
- const { maybeCompactCodexAppServerSession } = await import("./compact-Kgy26gIM.js");
125
+ const { maybeCompactCodexAppServerSession } = await import("./compact-CC5KhBzX.js");
107
126
  return maybeCompactCodexAppServerSession(params, {
108
127
  bindingStore: options.bindingStore,
109
128
  pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig,
@@ -112,7 +131,7 @@ function createCodexAppServerAgentHarness(options) {
112
131
  },
113
132
  reset: async (params) => {
114
133
  if (params.sessionId) {
115
- const { reclaimCurrentCodexSessionGeneration, sessionBindingIdentity } = await import("./session-binding-Bmt20HfB.js").then((n) => n.l);
134
+ const { reclaimCurrentCodexSessionGeneration, sessionBindingIdentity } = await import("./session-binding-ZSMX1omP.js").then((n) => n.u);
116
135
  const identity = sessionBindingIdentity({
117
136
  agentId: params.agentId,
118
137
  sessionId: params.sessionId,
@@ -0,0 +1,2 @@
1
+ import { isIncognitoSessionKey } from "openclaw/plugin-sdk/routing";
2
+ export { isIncognitoSessionKey as t };
package/dist/index.js CHANGED
@@ -1,20 +1,22 @@
1
1
  import { registerCodexCliMetadata } from "./cli-metadata.js";
2
2
  import { createCodexAppServerAgentHarness } from "./harness.js";
3
- import { C as resolveCodexAppServerFallbackApiKeyCacheKey, J as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS, S as resolveCodexAppServerAuthProfileIdForAgent, Z as isJsonObject, a as getLeasedSharedCodexAppServerClient, b as resolveCodexAppServerAuthAccountCacheKey, c as releaseLeasedSharedCodexAppServerClient, p as withLeasedCodexAppServerClientStartSelectionRetry, r as clearSharedCodexAppServerClientIfCurrentAndWait, s as releaseCodexAppServerClientLease } from "./shared-client-CSXLtCLE.js";
4
- import { D as resolveOpenClawExecPolicyForCodexAppServer, E as resolveCodexSupervisionAppServerRuntimeOptions, a as isCodexAppServerNativeAuthProfile, b as resolveCodexAppServerRuntimeOptions, c as sessionBindingIdentity, f as assertCodexAppServerConnectionSecurity, h as codexSandboxPolicyForTurn, m as codexAppServerStartOptionsKey, n as assertCodexBindingMayBeReplaced, o as normalizeCodexAppServerBindingModelProvider, p as canUseCodexModelBackedApprovalsReviewerForModel, u as CODEX_PLUGINS_MARKETPLACE_NAME, y as readCodexPluginConfig } from "./session-binding-Bmt20HfB.js";
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 { C as resolveCodexAppServerFallbackApiKeyCacheKey, Q as isJsonObject, S as resolveCodexAppServerAuthProfileIdForAgent, Y as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS, a as getLeasedSharedCodexAppServerClient, b as resolveCodexAppServerAuthAccountCacheKey, c as releaseLeasedSharedCodexAppServerClient, p as withLeasedCodexAppServerClientStartSelectionRetry, r as clearSharedCodexAppServerClientIfCurrentAndWait, s as releaseCodexAppServerClientLease } from "./shared-client-wmgNFNYp.js";
4
+ import { D as resolveCodexSupervisionAppServerRuntimeOptions, O as resolveOpenClawExecPolicyForCodexAppServer, b as readCodexPluginConfig, d as CODEX_PLUGINS_MARKETPLACE_NAME, g as codexSandboxPolicyForTurn, h as codexAppServerStartOptionsKey, l as sessionBindingIdentity, m as canUseCodexModelBackedApprovalsReviewerForModel, n as assertCodexBindingMayBeReplaced, o as isCodexAppServerNativeAuthProfile, p as assertCodexAppServerConnectionSecurity, s as normalizeCodexAppServerBindingModelProvider, x as resolveCodexAppServerRuntimeOptions } from "./session-binding-ZSMX1omP.js";
5
+ import { N as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, R as unsubscribeCodexThreadBestEffort, _ as CODEX_NATIVE_PERSONALITY_NONE, c as resumeCodexAppServerThread, et as ensureCodexPluginActivation, tt as pluginReadParams, y as resolveCodexAppServerRequestModelSelection } from "./thread-lifecycle-cqrOlJkq.js";
6
+ import { _ as assertCodexThreadStartResponse } from "./transcript-mirror-2p7kl6e4.js";
7
+ import { i as defaultCodexAppInventoryCache, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-CvzvmBRz.js";
8
8
  import { n as CODEX_APP_SERVER_BINDING_NAMESPACE, t as CODEX_APP_SERVER_BINDING_MAX_ENTRIES } from "./session-binding-meta-B7aEMU7g.js";
9
- import { t as buildCodexMediaUnderstandingProvider } from "./media-understanding-provider-IPNNQre6.js";
10
- import { d as CODEX_CONTROL_METHODS, f as describeControlFailure, r as formatCodexDisplayText } from "./command-formatters-NCTL7A2q.js";
11
- import { t as resolveCodexAppServerForModelProvider } from "./app-server-policy-DUMF2Xyr.js";
9
+ import { t as isIncognitoSessionKey } from "./incognito-session-ET_ufDH-.js";
10
+ import { buildCodexMediaUnderstandingProvider } from "./media-understanding-provider.js";
11
+ import { n as describeControlFailure, t as CODEX_CONTROL_METHODS } from "./capabilities-CLICvTxf.js";
12
+ import { r as formatCodexDisplayText } from "./command-formatters-DgADqnHa.js";
13
+ import { t as resolveCodexAppServerForModelProvider } from "./app-server-policy-BO3jYBkv.js";
12
14
  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-B0s3aIjT.js";
15
+ import { d as CODEX_NATIVE_EXECUTION_AUTH_ERROR, f as canMutateCodexHost, u as trackCodexConversationActiveTurn } from "./conversation-control-sNPsbTCP.js";
14
16
  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-C8DVQ_Bq.js";
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-CA7R-hX2.js";
17
- import { r as requestCodexAppServerJson } from "./request-9yf9pZjf.js";
17
+ import { a as resolveCodexBindingAppServerConnection, n as readCodexNotificationThreadId, r as readCodexNotificationTurnId } from "./notification-correlation-BGLixv5_.js";
18
+ 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-DsKaezgR.js";
19
+ import { r as requestCodexAppServerJson } from "./request-BTccUTD3.js";
18
20
  import { t as createCodexWebSearchProviderBase } from "./web-search-provider.shared-BrZmlqyR.js";
19
21
  import { mutateConfigFile } from "openclaw/plugin-sdk/config-mutation";
20
22
  import { normalizePluginsConfig, resolveEffectiveEnableState, resolveLivePluginConfigObject, resolvePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime";
@@ -34,7 +36,7 @@ import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
34
36
  import { canonicalPathFromExistingAncestor, isPathInside, pathExists } from "openclaw/plugin-sdk/security-runtime";
35
37
  import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
36
38
  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";
39
+ import { MIGRATION_REASON_TARGET_EXISTS, applyMigrationManualItem, createMigrationItem, createMigrationManualItem, hasMigrationConfigPatchConflict, markMigrationItemConflict, markMigrationItemError, markMigrationItemSkipped, readMigrationConfigPath, resolveMigrationConfigRuntime, summarizeMigrationItems, writeMigrationConfigPath } from "openclaw/plugin-sdk/migration";
38
40
  import { archiveMigrationItem, copyMemoryMigrationFileItem, copyMigrationFileItem, withCachedMigrationConfigRuntime, writeMigrationReport } from "openclaw/plugin-sdk/migration-runtime";
39
41
  import { sleep } from "openclaw/plugin-sdk/runtime-env";
40
42
  import { readJsonFileWithFallback } from "openclaw/plugin-sdk/json-store";
@@ -45,7 +47,7 @@ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
45
47
  /** Defers schema compilation and auth loading until the first binding operation. */
46
48
  function createLazyCodexAppServerBindingStore(state) {
47
49
  let resolved;
48
- const store = () => resolved ??= import("./session-binding-Bmt20HfB.js").then((n) => n.l).then(({ createCodexAppServerBindingStore }) => createCodexAppServerBindingStore(state));
50
+ const store = () => resolved ??= import("./session-binding-ZSMX1omP.js").then((n) => n.u).then(({ createCodexAppServerBindingStore }) => createCodexAppServerBindingStore(state));
49
51
  return {
50
52
  read: async (identity) => (await store()).read(identity),
51
53
  hasOtherThreadOwner: async (threadId, currentIdentity) => (await store()).hasOtherThreadOwner(threadId, currentIdentity),
@@ -72,7 +74,7 @@ async function handleCodexCommand(ctx, options) {
72
74
  }
73
75
  }
74
76
  async function loadDefaultCodexSubcommandHandler() {
75
- const { handleCodexSubcommand } = await import("./command-handlers-DtFbZiba.js");
77
+ const { handleCodexSubcommand } = await import("./command-handlers-l_lVPNlB.js");
76
78
  return handleCodexSubcommand;
77
79
  }
78
80
  //#endregion
@@ -569,7 +571,8 @@ async function requestNewConversationBindingThread(params, resolved) {
569
571
  personality: CODEX_NATIVE_PERSONALITY_NONE,
570
572
  ...buildThreadRequestRuntimeOptions(params, resolved),
571
573
  developerInstructions: CODEX_CONVERSATION_THREAD_DEVELOPER_INSTRUCTIONS,
572
- experimentalRawEvents: true
574
+ experimentalRawEvents: true,
575
+ ...isIncognitoSessionKey(params.sessionKey) ? { ephemeral: true } : {}
573
576
  }, requestOptions),
574
577
  onClientChange: (client) => {
575
578
  resolved.client = client;
@@ -717,7 +720,8 @@ async function runBoundTurn(params) {
717
720
  ...modelScopedRuntime.networkProxy ? { config: modelScopedRuntime.networkProxy.configPatch } : { sandbox },
718
721
  ...serviceTier ? { serviceTier } : {},
719
722
  developerInstructions: CODEX_CONVERSATION_THREAD_DEVELOPER_INSTRUCTIONS,
720
- experimentalRawEvents: true
723
+ experimentalRawEvents: true,
724
+ ...isIncognitoSessionKey(params.sessionKey) ? { ephemeral: true } : {}
721
725
  }, requestOptions),
722
726
  onClientChange: (nextClient) => {
723
727
  client = nextClient;
@@ -834,6 +838,19 @@ async function runBoundTurn(params) {
834
838
  });
835
839
  collector.setTurnId(turnId);
836
840
  return { reply: { text: (await collector.wait({ timeoutMs: params.timeoutMs ?? DEFAULT_BOUND_TURN_TIMEOUT_MS }).finally(activeCleanup)).replyText.trim() || "Codex completed without a text reply." } };
841
+ } catch (error) {
842
+ if (isIncognitoSessionKey(params.sessionKey)) {
843
+ const bindingReleased = await params.bindingStore.mutate(identity, {
844
+ kind: "clear",
845
+ threadId
846
+ });
847
+ const timedOut = error instanceof Error && error.message === "codex app-server bound turn timed out";
848
+ if (bindingReleased && !timedOut) await unsubscribeCodexThreadBestEffort(client, {
849
+ threadId,
850
+ timeoutMs: CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS
851
+ });
852
+ }
853
+ throw error;
837
854
  } finally {
838
855
  notificationCleanup();
839
856
  requestCleanup();
@@ -1219,7 +1236,7 @@ function hasAuthProfileConfigConflict(config, profile, overwrite) {
1219
1236
  function hasCurrentAuthProfileConfigConflict(ctx, profile) {
1220
1237
  let config = ctx.config;
1221
1238
  try {
1222
- config = ctx.runtime?.config?.current?.() ?? config;
1239
+ config = resolveMigrationConfigRuntime(ctx)?.current?.() ?? config;
1223
1240
  } catch {}
1224
1241
  return hasAuthProfileConfigConflict(config, profile, Boolean(ctx.overwrite));
1225
1242
  }
@@ -1310,7 +1327,7 @@ function authProfileConfigForCredential(credential, profileId) {
1310
1327
  return credential.kind === "oauth" ? oauthAuthProfileConfig(credential, profileId) : apiKeyAuthProfileConfig(credential, profileId);
1311
1328
  }
1312
1329
  async function applyCodexAuthProfileConfig(ctx, profile, applyConfig) {
1313
- const configApi = ctx.runtime?.config;
1330
+ const configApi = resolveMigrationConfigRuntime(ctx);
1314
1331
  if (!configApi?.current || !configApi.mutateConfigFile) return "unavailable";
1315
1332
  try {
1316
1333
  await configApi.mutateConfigFile({
@@ -1386,6 +1403,7 @@ async function applyCodexAuthItem(params) {
1386
1403
  let wrote = false;
1387
1404
  const store = await updateAuthProfileStoreWithLock({
1388
1405
  agentDir: targets.agentDir,
1406
+ stateDir: ctx.stateDir,
1389
1407
  updater: (freshStore) => {
1390
1408
  const existing = freshStore.profiles[profileId];
1391
1409
  if (!ctx.overwrite && existing) {
@@ -2086,6 +2104,7 @@ function buildPluginItems(ctx, plugins) {
2086
2104
  action: "install",
2087
2105
  status: conflict ? "conflict" : "planned",
2088
2106
  reason: conflict ? MIGRATION_REASON_PLUGIN_EXISTS : void 0,
2107
+ applyPhase: "after-promotion",
2089
2108
  source: plugin.source,
2090
2109
  target: `plugins.entries.codex.config.codexPlugins.plugins.${configKey}`,
2091
2110
  message: `Install Codex plugin "${plugin.pluginName}" in the OpenClaw-managed Codex app-server runtime.`,
@@ -2215,6 +2234,7 @@ function buildPluginConfigItem(ctx, pluginItems) {
2215
2234
  target: "plugins.entries.codex.config.codexPlugins",
2216
2235
  status: conflict ? "conflict" : "planned",
2217
2236
  reason: conflict ? MIGRATION_REASON_TARGET_EXISTS : void 0,
2237
+ applyPhase: "after-promotion",
2218
2238
  message: "Enable OpenClaw's Codex plugin integration and record migrated source-installed curated plugins.",
2219
2239
  details: {
2220
2240
  path: [...CODEX_PLUGIN_CONFIG_PATH],
@@ -2542,10 +2562,18 @@ async function buildTargetCodexPluginAppCacheKey(ctx) {
2542
2562
  });
2543
2563
  }
2544
2564
  async function applyCodexPluginConfigItem(ctx, item, appliedItems) {
2565
+ if (appliedItems.filter((candidate) => candidate.kind === "plugin" && candidate.action === "install" && readCodexPluginPolicy(candidate) !== void 0 && !isCodexPluginConfigTerminal(candidate)).length > 0) return {
2566
+ ...item,
2567
+ status: "warning",
2568
+ reason: "selected Codex plugin activation is incomplete"
2569
+ };
2545
2570
  const entries = appliedItems.map(readAppliedPluginConfigEntry).filter((entry) => entry !== void 0);
2546
- if (entries.length === 0) return markMigrationItemSkipped(item, "no selected Codex plugins");
2571
+ if (entries.length === 0) return {
2572
+ ...markMigrationItemSkipped(item, "no selected Codex plugins"),
2573
+ deferredCompletion: true
2574
+ };
2547
2575
  const returnPatch = shouldReturnCodexPluginConfigPatch(ctx);
2548
- const configApi = ctx.runtime?.config;
2576
+ const configApi = resolveMigrationConfigRuntime(ctx);
2549
2577
  const currentConfig = returnPatch ? ctx.config : configApi?.current?.();
2550
2578
  if (!currentConfig) return markMigrationItemError(item, "config runtime unavailable");
2551
2579
  const value = buildCodexPluginsConfigValue(entries, { config: currentConfig });
@@ -2576,8 +2604,11 @@ async function applyCodexPluginConfigItem(ctx, item, appliedItems) {
2576
2604
  return markMigrationItemError(item, error instanceof Error ? error.message : String(error));
2577
2605
  }
2578
2606
  }
2607
+ function isCodexPluginConfigTerminal(item) {
2608
+ return item.status === "migrated" || item.status === "skipped" && (item.deferredCompletion === true || item.reason === CODEX_PLUGIN_NOT_SELECTED_REASON || item.reason === CODEX_PLUGIN_AUTH_REQUIRED_REASON);
2609
+ }
2579
2610
  function readAppliedPluginConfigEntry(item) {
2580
- if (item.status === "migrated") return readCodexPluginMigrationConfigEntry(item, true);
2611
+ if (item.status === "migrated" || item.deferredCompletion === true) return readCodexPluginMigrationConfigEntry(item, true);
2581
2612
  if (item.status === "skipped" && item.reason !== CODEX_PLUGIN_NOT_SELECTED_REASON && item.reason === CODEX_PLUGIN_AUTH_REQUIRED_REASON) return readCodexPluginMigrationConfigEntry(item, false);
2582
2613
  }
2583
2614
  function readCodexPluginPolicy(item) {
@@ -2620,6 +2651,7 @@ function buildCodexMigrationProvider(params = {}) {
2620
2651
  };
2621
2652
  },
2622
2653
  plan: buildCodexMigrationPlan,
2654
+ deferredApply: { retrySafe: true },
2623
2655
  prepareApply(ctx) {
2624
2656
  if (isMemoryOnlyMigration(ctx)) return;
2625
2657
  return prepareTargetCodexAppServer(ctx);
@@ -3726,7 +3758,7 @@ function createCodexSupervisionTools(options) {
3726
3758
  }
3727
3759
  //#endregion
3728
3760
  //#region extensions/codex/src/web-search-provider.ts
3729
- const loadCodexWebSearchRuntime = createLazyRuntimeModule(() => import("./web-search-provider.runtime-_x5XTeqh.js"));
3761
+ const loadCodexWebSearchRuntime = createLazyRuntimeModule(() => import("./web-search-provider.runtime-Bx6HAc_k.js"));
3730
3762
  const CodexWebSearchSchema = {
3731
3763
  type: "object",
3732
3764
  properties: { query: {
@@ -3825,8 +3857,10 @@ var codex_default = definePluginEntry({
3825
3857
  }, { names: [...CODEX_SUPERVISION_COMPAT_TOOL_NAMES] });
3826
3858
  api.registerAgentHarness(createCodexAppServerAgentHarness({
3827
3859
  bindingStore,
3860
+ sessionCatalogControl,
3828
3861
  resolveConfig: resolveCurrentConfig,
3829
- resolvePluginConfig: resolveCurrentPluginConfig
3862
+ resolvePluginConfig: resolveCurrentPluginConfig,
3863
+ runtime: api.runtime
3830
3864
  }));
3831
3865
  api.registerMediaUnderstandingProvider(buildCodexMediaUnderstandingProvider({ pluginConfig: api.pluginConfig }));
3832
3866
  api.registerWebSearchProvider(createCodexWebSearchProvider({ resolvePluginConfig: resolveCurrentPluginConfig }));
@@ -3914,7 +3948,7 @@ var codex_default = definePluginEntry({
3914
3948
  if (!previousSessionId || !sessionId || previousSessionId === sessionId) return;
3915
3949
  const config = resolveCurrentConfig();
3916
3950
  const sessionKey = ctx.sessionKey?.trim();
3917
- const { sessionBindingIdentity } = await import("./session-binding-Bmt20HfB.js").then((n) => n.l);
3951
+ const { sessionBindingIdentity } = await import("./session-binding-ZSMX1omP.js").then((n) => n.u);
3918
3952
  const identity = sessionBindingIdentity({
3919
3953
  sessionId,
3920
3954
  ...sessionKey ? { sessionKey } : {},
@@ -3931,7 +3965,7 @@ var codex_default = definePluginEntry({
3931
3965
  const nextSessionKey = event.nextSessionKey?.trim();
3932
3966
  if (endedSessionKey && nextSessionKey && nextSessionKey !== endedSessionKey) return;
3933
3967
  const config = resolveCurrentConfig();
3934
- const { sessionBindingIdentity } = await import("./session-binding-Bmt20HfB.js").then((n) => n.l);
3968
+ const { sessionBindingIdentity } = await import("./session-binding-ZSMX1omP.js").then((n) => n.u);
3935
3969
  await bindingStore.retireSessionGeneration(sessionBindingIdentity({
3936
3970
  sessionId: event.sessionId,
3937
3971
  ...sessionKey ? { sessionKey } : {},
@@ -1,2 +1,169 @@
1
- import { t as buildCodexMediaUnderstandingProvider } from "./media-understanding-provider-IPNNQre6.js";
1
+ import { t as runBoundedCodexAppServerTurn } from "./bounded-turn-CaQL96kg.js";
2
+ import { validateJsonSchemaValue } from "openclaw/plugin-sdk/json-schema-runtime";
3
+ //#region extensions/codex/media-understanding-provider.ts
4
+ /**
5
+ * Codex-backed media understanding provider for bounded image description and
6
+ * structured extraction turns.
7
+ */
8
+ const CODEX_MEDIA_PROVIDER_ID = "codex";
9
+ const DEFAULT_CODEX_IMAGE_MODEL = "gpt-5.6-sol";
10
+ const DEFAULT_CODEX_IMAGE_PROMPT = "Describe the image.";
11
+ /**
12
+ * Builds the media-understanding provider that delegates image tasks to an
13
+ * isolated Codex app-server session.
14
+ */
15
+ function buildCodexMediaUnderstandingProvider(options = {}) {
16
+ return {
17
+ id: CODEX_MEDIA_PROVIDER_ID,
18
+ capabilities: ["image"],
19
+ defaultModels: { image: DEFAULT_CODEX_IMAGE_MODEL },
20
+ describeImage: async (req) => describeCodexImages({
21
+ images: [{
22
+ buffer: req.buffer,
23
+ fileName: req.fileName,
24
+ mime: req.mime
25
+ }],
26
+ provider: req.provider,
27
+ model: req.model,
28
+ prompt: req.prompt,
29
+ maxTokens: req.maxTokens,
30
+ timeoutMs: req.timeoutMs,
31
+ profile: req.profile,
32
+ preferredProfile: req.preferredProfile,
33
+ authStore: req.authStore,
34
+ agentDir: req.agentDir,
35
+ cfg: req.cfg
36
+ }, options),
37
+ describeImages: async (req) => describeCodexImages(req, options),
38
+ extractStructured: async (req) => extractCodexStructured(req, options)
39
+ };
40
+ }
41
+ async function describeCodexImages(req, options) {
42
+ const model = req.model.trim();
43
+ if (!model) throw new Error("Codex image understanding requires model id.");
44
+ const { text } = await runBoundedCodexAppServerTurn({
45
+ config: req.cfg,
46
+ model: {
47
+ mode: "required",
48
+ id: model
49
+ },
50
+ profile: req.profile,
51
+ timeoutMs: req.timeoutMs,
52
+ agentDir: req.agentDir,
53
+ authProfileStore: req.authStore,
54
+ options,
55
+ taskLabel: "image understanding",
56
+ developerInstructions: "You are OpenClaw's bounded image-understanding worker. Describe only the provided image content. Do not call tools, edit files, or ask follow-up questions.",
57
+ input: [{
58
+ type: "text",
59
+ text: buildCodexImagePrompt(req),
60
+ text_elements: []
61
+ }, ...req.images.map((image) => ({
62
+ type: "image",
63
+ url: `data:${image.mime ?? "image/png"};base64,${image.buffer.toString("base64")}`
64
+ }))],
65
+ requiredModalities: ["text", "image"],
66
+ isolation: "configured-transport"
67
+ });
68
+ return {
69
+ text,
70
+ model
71
+ };
72
+ }
73
+ async function extractCodexStructured(req, options) {
74
+ const model = req.model.trim();
75
+ if (!model) throw new Error("Codex structured extraction requires model id.");
76
+ if (!req.instructions.trim()) throw new Error("Codex structured extraction requires instructions.");
77
+ if (req.input.length === 0) throw new Error("Codex structured extraction requires at least one input.");
78
+ if (!req.input.some((entry) => entry.type === "image")) throw new Error("Codex structured extraction requires at least one image input.");
79
+ const { text } = await runBoundedCodexAppServerTurn({
80
+ config: req.cfg,
81
+ model: {
82
+ mode: "required",
83
+ id: model
84
+ },
85
+ profile: req.profile,
86
+ timeoutMs: req.timeoutMs,
87
+ agentDir: req.agentDir,
88
+ authProfileStore: req.authStore,
89
+ options,
90
+ taskLabel: "structured extraction",
91
+ developerInstructions: "You are OpenClaw's bounded structured-extraction worker. Return only the requested extraction. Do not call tools, edit files, ask follow-up questions, or include secrets.",
92
+ input: buildCodexStructuredInput(req),
93
+ requiredModalities: requiredStructuredModalities(),
94
+ isolation: "configured-transport"
95
+ });
96
+ return normalizeStructuredExtractionResult({
97
+ text,
98
+ model,
99
+ provider: req.provider,
100
+ req
101
+ });
102
+ }
103
+ function buildCodexImagePrompt(req) {
104
+ const prompt = req.prompt?.trim() || DEFAULT_CODEX_IMAGE_PROMPT;
105
+ if (req.images.length <= 1) return prompt;
106
+ return `${prompt}\n\nAnalyze all ${req.images.length} images together.`;
107
+ }
108
+ function requiredStructuredModalities() {
109
+ return ["text", "image"];
110
+ }
111
+ function buildCodexStructuredInput(req) {
112
+ return [{
113
+ type: "text",
114
+ text: buildStructuredExtractionPrompt(req),
115
+ text_elements: []
116
+ }, ...req.input.map((entry) => {
117
+ if (entry.type === "text") return {
118
+ type: "text",
119
+ text: entry.text,
120
+ text_elements: []
121
+ };
122
+ return {
123
+ type: "image",
124
+ url: `data:${entry.mime ?? "image/png"};base64,${entry.buffer.toString("base64")}`
125
+ };
126
+ })];
127
+ }
128
+ function buildStructuredExtractionPrompt(req) {
129
+ return [
130
+ req.instructions.trim(),
131
+ req.schemaName ? `Schema name: ${req.schemaName}` : void 0,
132
+ req.jsonSchema ? `JSON schema:\n${JSON.stringify(req.jsonSchema)}` : void 0,
133
+ req.jsonMode === false ? "Return the extraction as concise text." : "Return valid JSON only. Do not wrap the JSON in Markdown fences."
134
+ ].filter((part) => Boolean(part)).join("\n\n");
135
+ }
136
+ function isJsonSchemaObject(value) {
137
+ return typeof value === "object" && value !== null && !Array.isArray(value);
138
+ }
139
+ function normalizeStructuredExtractionResult(params) {
140
+ const result = {
141
+ text: params.text,
142
+ model: params.model,
143
+ provider: params.provider,
144
+ contentType: params.req.jsonMode === false ? "text" : "json"
145
+ };
146
+ if (params.req.jsonMode !== false) {
147
+ try {
148
+ result.parsed = JSON.parse(params.text);
149
+ } catch {
150
+ throw new Error("Codex structured extraction returned invalid JSON.");
151
+ }
152
+ if (isJsonSchemaObject(params.req.jsonSchema)) {
153
+ const validation = validateJsonSchemaValue({
154
+ schema: params.req.jsonSchema,
155
+ cacheKey: "codex.media-understanding.extractStructured",
156
+ value: result.parsed,
157
+ cache: false
158
+ });
159
+ if (!validation.ok) {
160
+ const message = validation.errors.map((error) => error.text).join("; ") || "invalid";
161
+ throw new Error(`Codex structured extraction JSON did not match schema: ${message}`);
162
+ }
163
+ result.parsed = validation.value;
164
+ }
165
+ }
166
+ return result;
167
+ }
168
+ //#endregion
2
169
  export { buildCodexMediaUnderstandingProvider };