@openclaw/codex 2026.8.2 → 2026.9.1
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 +3 -3
- package/dist/{attempt-client-cleanup-CpVfwctT.js → attempt-client-cleanup-DYHcRQAa.js} +6 -43
- package/dist/attempt-context-DmQUNWwT.js +634 -0
- package/dist/{binding-connection-CF7BmrDk.js → binding-connection-E6uDsPlx.js} +2 -2
- package/dist/{bounded-turn-DRC3hcjm.js → bounded-turn-wzJrwKKe.js} +8 -9
- package/dist/{capabilities-D6m_TdVy.js → capabilities-dIjNVCYH.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters--UToCokS.js → command-formatters-CLHhEB1Q.js} +3 -3
- package/dist/{command-handlers-CLFx2Ypa.js → command-handlers-CTGb2csu.js} +54 -55
- package/dist/{compact-5xqW1oCh.js → compact-_t0HQrUS.js} +33 -25
- package/dist/{config-CcYL77O6.js → config-BhmfC1s6.js} +12 -8
- package/dist/{context-compaction-activity-BOeJf7yo.js → context-compaction-activity-CMla5FPJ.js} +4 -1
- package/dist/doctor-contract-api.js +31 -4
- package/dist/{dynamic-tools-BmeXjwNZ.js → dynamic-tools-BU9tmlYm.js} +448 -457
- package/dist/{effective-mcp-catalog-XXQKgK1U.js → effective-mcp-catalog-DzYBW4h1.js} +2 -2
- package/dist/{event-projector-assistant-message-C5-Ds8mA.js → event-projector-assistant-message-DHRFXKbS.js} +4 -4
- package/dist/{event-projector-usage-B2r5vhWH.js → event-projector-usage-C5mcrGjp.js} +9 -137
- package/dist/{harness-BgeB7LnD.js → harness-DXVZ5II5.js} +13 -13
- package/dist/harness.js +1 -1
- package/dist/index.js +323 -313
- package/dist/{isolated-completion-CxTus3vZ.js → isolated-completion-kg9kv4iH.js} +4 -4
- package/dist/{launch-args-sXOAg0SX.js → launch-args-RXQwn8zV.js} +7 -1
- package/dist/{managed-binary-ZkGodW19.js → managed-binary-4-Vjz5GH.js} +14 -9
- package/dist/media-understanding-provider.js +1 -1
- package/dist/{model-catalog-DULBcniB.js → model-catalog-CUM68Hkl.js} +11 -11
- package/dist/{models-DaWfETQk.js → models-sYnEc0gd.js} +3 -3
- package/dist/{native-subagent-monitor-vXYUZH37.js → native-subagent-monitor-CnH147jH.js} +3 -3
- package/dist/{node-exec-server.runtime-DirKVZ5h.js → node-exec-server.runtime-CstNHCmC.js} +2 -2
- package/dist/{plugin-approval-roundtrip-CCWQGlAI.js → plugin-approval-roundtrip-CNe-Xrjx.js} +29 -3
- package/dist/{plugin-marketplace-discovery-BXjIFEiw.js → plugin-marketplace-discovery-CfFlKqDl.js} +6 -6
- package/dist/{plugin-metadata-cache-DQQm4gWT.js → plugin-metadata-cache-BFrPhb2c.js} +5 -5
- package/dist/provider-capabilities-DW5p4k9w.js +101 -0
- package/dist/{rate-limits-BqHEHXQJ.js → rate-limits-CawQJfUS.js} +1 -1
- package/dist/{request-BWxweEdK.js → request-DYAI5FQE.js} +18 -6
- package/dist/{run-attempt-BVLE4Gbi.js → run-attempt-D1hJO4fX.js} +483 -1865
- package/dist/{runtime-artifact-D9pYp4zL.js → runtime-artifact-C3jVimFn.js} +19 -12
- package/dist/{session-binding-D0zinCP1.js → session-binding-BHuTCRZQ.js} +8 -10
- package/dist/{session-catalog-eMhVm0Ql.js → session-catalog-yyvTWFOw.js} +138 -116
- package/dist/{session-cli-B2lyjJA0.js → session-cli-CmFEXMAM.js} +1 -1
- package/dist/session-initialization-BeWzjGiR.js +74 -0
- package/dist/{session-permission-policy-ScnAyG90.js → session-permission-policy-DeWVTCMj.js} +2 -2
- package/dist/{session-retirement-CtUtUTr9.js → session-retirement-BujDjXVF.js} +16 -9
- package/dist/{session-upstream-marker-gqrYIRHk.js → session-upstream-marker-C351-5Qw.js} +18 -2
- package/dist/{settled-turn-context-Bk3IUwod.js → settled-turn-context-D3SNWtUn.js} +6 -28
- package/dist/{settled-turn-finalizer-BXLN9PfJ.js → settled-turn-finalizer-BVJx4yoc.js} +5 -5
- package/dist/{shared-client-B1tT5U6r.js → shared-client-DxcfF9KX.js} +2748 -101
- package/dist/{side-question-CZ-mCw-t.js → side-question-BTZAII4l.js} +97 -63
- package/dist/{thread-lifecycle-CGGKP720.js → thread-lifecycle-DAcEJ_Om.js} +2039 -1487
- package/dist/{thread-ownership-RkaoZCmQ.js → thread-ownership-zGokd8i1.js} +10 -9
- package/dist/thread-policy-g4KbJPzp.js +54 -0
- package/dist/{thread-resume-BFt1-ZDa.js → thread-resume-C7pyVKeW.js} +15 -7
- package/dist/{transcript-mirror-1ep4XjzF.js → transcript-mirror-DTUxFWa_.js} +47 -10
- package/dist/{transport-stdio-NT_Dpd9V.js → transport-stdio-CyPldczm.js} +3 -1
- package/dist/upstream-session-fork-CYlBIGVt.js +966 -0
- package/dist/{usage-DUhd58gI.js → usage-Bj-rrzkR.js} +3 -3
- package/dist/{web-search-provider.runtime-BEmlE7ov.js → web-search-provider.runtime-D2FWSK4w.js} +3 -3
- package/openclaw.plugin.json +0 -30
- package/package.json +5 -5
- package/dist/protocol-validators-Bg5rpNxk.js +0 -2542
- package/dist/session-catalog-home-id-Dt2GiG5o.js +0 -112
- package/dist/upstream-session-fork-Dc8BFExw.js +0 -312
package/dist/index.js
CHANGED
|
@@ -1,27 +1,26 @@
|
|
|
1
1
|
import { registerCodexCliMetadata } from "./cli-metadata.js";
|
|
2
|
-
import { n as createCodexAppServerNativeCompaction, t as createCodexAppServerAgentHarness } from "./harness-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { n as createCodexAppServerNativeCompaction, t as createCodexAppServerAgentHarness } from "./harness-DXVZ5II5.js";
|
|
3
|
+
import { $t as isJsonObject, B as isCodexAppServerIndeterminateRequestCancellationError, Bt as resolveCodexAppServerAuthProfileIdForAgent, C as withLeasedCodexAppServerClientStartSelectionRetry, Et as isCodexAppServerLiveThreadClaimed, G as isUnsupportedCodexAppServerVersionError, H as isCodexAppServerOverloadError, Ht as resolveCodexAppServerFallbackApiKeyCacheKey, J as CodexThreadDirectInputError, O as createCodexDesktopGenerationService, Rt as resolveCodexAppServerAuthAccountCacheKey, St as consumeCodexAppServerLiveThread, Tt as isCodexAppServerClientRuntimeLive, X as assertCodexThreadAcceptsDirectInput, Xt as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS, _ as retainSharedCodexAppServerClientByInstanceId, b as retireSharedCodexAppServerClientsBeforeDesktopGeneration, c as getLeasedSharedCodexAppServerClient, et as assertCodexThreadStartResponse, h as releaseLeasedSharedCodexAppServerClient, kt as releaseCodexAppServerLiveThread, m as releaseCodexAppServerClientLease, o as clearSharedCodexAppServerClientIfCurrentAndWait, wt as hasCodexAppServerLiveThread } from "./shared-client-DxcfF9KX.js";
|
|
4
|
+
import { E as readCodexPluginConfig, M as CODEX_PLUGINS_MARKETPLACE_NAME, O as resolveOpenClawExecPolicyForCodexAppServer, c as assertCodexAppServerConnectionSecurity, i as resolveCodexAppServerRuntimeOptions, m as canUseCodexModelBackedApprovalsReviewerForModel, n as codexSandboxPolicyForTurn, s as resolveCodexSupervisionAppServerRuntimeOptions, t as codexAppServerStartOptionsKey, y as readCodexRequirementsToml } from "./config-BhmfC1s6.js";
|
|
5
|
+
import { a as setManagedCodexPluginRoot } from "./managed-binary-4-Vjz5GH.js";
|
|
6
6
|
import { n as CODEX_APP_SERVER_BINDING_NAMESPACE, t as CODEX_APP_SERVER_BINDING_MAX_ENTRIES } from "./session-binding-meta-B7aEMU7g.js";
|
|
7
|
-
import { d as sessionBindingIdentity, n as assertCodexBindingMayBeReplaced, o as isCodexAppServerNativeAuthProfile, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-
|
|
8
|
-
import { o as createCodexAppServerProcessReaperService } from "./transport-stdio-
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { s as
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import { c as resolveCodexNativeSandboxBlock, i as requestCodexAppServerJson, o as withCodexAppServerJsonClient, s as resolveCodexNativeExecutionBlock } from "./request-
|
|
16
|
-
import { p as projectBoundedCodexVisibleSessionHistory } from "./transcript-mirror-1ep4XjzF.js";
|
|
7
|
+
import { d as sessionBindingIdentity, n as assertCodexBindingMayBeReplaced, o as isCodexAppServerNativeAuthProfile, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-BHuTCRZQ.js";
|
|
8
|
+
import { o as createCodexAppServerProcessReaperService } from "./transport-stdio-CyPldczm.js";
|
|
9
|
+
import { a as closeCodexStartupClientBestEffort, c as isCodexAppServerUnsafeSubscriptionError, d as unsubscribeCodexThreadBestEffort, h as isCodexNotificationForTurn, l as retireUnsafeCodexTurnClientBestEffort, o as interruptCodexTurnAndWaitBestEffort, p as getCodexAppServerTurnRouter } from "./attempt-client-cleanup-DYHcRQAa.js";
|
|
10
|
+
import { o as isAssistantCommentaryCompletionNotification } from "./event-projector-usage-C5mcrGjp.js";
|
|
11
|
+
import { i as buildCodexPluginAppCacheKey, s as defaultCodexAppInventoryCache, t as resumeCodexAppServerThread } from "./thread-resume-C7pyVKeW.js";
|
|
12
|
+
import { Dt as mergeCodexThreadConfigs, E as resolveCodexAppServerRequestModelSelection, Et as buildDisabledAppsConfigPatch, J as createCodexManagedThreadStore, K as CODEX_MANAGED_THREAD_MAX_ENTRIES, Nt as pluginReadParams, jt as isOpenAiCuratedMarketplace, k as buildCodexProjectDocThreadConfig, kt as ensureCodexPluginActivation, q as CODEX_MANAGED_THREAD_NAMESPACE, w as CODEX_NATIVE_PERSONALITY_NONE } from "./thread-lifecycle-DAcEJ_Om.js";
|
|
13
|
+
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-zGokd8i1.js";
|
|
14
|
+
import { p as projectBoundedCodexVisibleSessionHistory } from "./transcript-mirror-DTUxFWa_.js";
|
|
15
|
+
import { c as resolveCodexNativeSandboxBlock, i as requestCodexAppServerJson, o as withCodexAppServerJsonClient, s as resolveCodexNativeExecutionBlock } from "./request-DYAI5FQE.js";
|
|
17
16
|
import { buildCodexMediaUnderstandingProvider } from "./media-understanding-provider.js";
|
|
18
|
-
import { n as describeControlFailure, t as CODEX_CONTROL_METHODS } from "./capabilities-
|
|
19
|
-
import {
|
|
20
|
-
import { a as resolveCodexAppServerForModelProvider, i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, t as CODEX_SESSION_PERMISSION_EXEC_MODES } from "./session-permission-policy-
|
|
21
|
-
import { f as trackCodexConversationActiveTurn, g as canMutateCodexHost, h as CODEX_NATIVE_EXECUTION_AUTH_ERROR, t as discoverCodexMarketplacePlugins } from "./plugin-marketplace-discovery-
|
|
17
|
+
import { n as describeControlFailure, t as CODEX_CONTROL_METHODS } from "./capabilities-dIjNVCYH.js";
|
|
18
|
+
import { a as formatCodexDisplayText } from "./command-formatters-CLHhEB1Q.js";
|
|
19
|
+
import { a as resolveCodexAppServerForModelProvider, i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, t as CODEX_SESSION_PERMISSION_EXEC_MODES } from "./session-permission-policy-DeWVTCMj.js";
|
|
20
|
+
import { f as trackCodexConversationActiveTurn, g as canMutateCodexHost, h as CODEX_NATIVE_EXECUTION_AUTH_ERROR, t as discoverCodexMarketplacePlugins } from "./plugin-marketplace-discovery-CfFlKqDl.js";
|
|
22
21
|
import { a as readCodexConversationBindingDataRecord, i as readCodexConversationBindingData, o as resolveCodexDefaultWorkspaceDir, r as createCodexConversationBindingData } from "./conversation-binding-data-BiodpIzq.js";
|
|
23
|
-
import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-
|
|
24
|
-
import { d as createCodexCliSessionNodeHostCommands, f as createCodexCliSessionNodeInvokePolicies, g as resumeCodexCliSessionOnNode, h as resolveCodexCliSessionForBindingOnNode, i as createCodexSessionCatalogNodeHostCommands, m as listCodexCliSessionsOnNode, n as createCodexSessionCatalogNodeInvokePolicies, o as assertCodexArchiveDescendantsUnowned, r as createCodexSessionCatalogControl, s as codexControlRequest, t as codexSessionCatalogRuntime } from "./session-catalog-
|
|
22
|
+
import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-E6uDsPlx.js";
|
|
23
|
+
import { d as createCodexCliSessionNodeHostCommands, f as createCodexCliSessionNodeInvokePolicies, g as resumeCodexCliSessionOnNode, h as resolveCodexCliSessionForBindingOnNode, i as createCodexSessionCatalogNodeHostCommands, m as listCodexCliSessionsOnNode, n as createCodexSessionCatalogNodeInvokePolicies, o as assertCodexArchiveDescendantsUnowned, r as createCodexSessionCatalogControl, s as codexControlRequest, t as codexSessionCatalogRuntime } from "./session-catalog-yyvTWFOw.js";
|
|
25
24
|
import { t as createCodexWebSearchProviderBase } from "./web-search-provider.shared-BrZmlqyR.js";
|
|
26
25
|
import { mutateConfigFile } from "openclaw/plugin-sdk/config-mutation";
|
|
27
26
|
import { normalizePluginsConfig, resolveEffectiveEnableState, resolveLivePluginConfigObject, resolvePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime";
|
|
@@ -31,6 +30,7 @@ import fs from "node:fs/promises";
|
|
|
31
30
|
import path from "node:path";
|
|
32
31
|
import { parseStrictNonNegativeInteger, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
33
32
|
import { embeddedAgentLog, formatErrorMessage, resolveActiveEmbeddedRunSessionId, resolveSandboxContext } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
33
|
+
import { canonicalPathFromExistingAncestor, isPathInside } from "openclaw/plugin-sdk/file-access-runtime";
|
|
34
34
|
import os from "node:os";
|
|
35
35
|
import { loadAuthProfileStoreWithoutExternalProfiles, resolveAgentConfig, resolveAgentWorkspaceDir, resolveDefaultAgentDir, resolveDefaultAgentId } from "openclaw/plugin-sdk/agent-runtime";
|
|
36
36
|
import { applyAuthProfileConfig, buildApiKeyCredential, buildOauthProviderAuthResult, buildOpenAICodexCredentialExtra, readCodexCliCredentialsCached, resolveOpenAICodexAuthIdentity, resolveOpenAICodexImportProfileName, updateAuthProfileStoreWithLock } from "openclaw/plugin-sdk/provider-auth";
|
|
@@ -41,7 +41,6 @@ import { getSessionEntry, resolveStorePath, resolveTranscriptSessionKeyBySession
|
|
|
41
41
|
import { coerceErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
42
42
|
import { fileURLToPath } from "node:url";
|
|
43
43
|
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
44
|
-
import { canonicalPathFromExistingAncestor, isPathInside } from "openclaw/plugin-sdk/file-access-runtime";
|
|
45
44
|
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
|
|
46
45
|
import { readVisibleSessionTranscriptMessageEntries } from "openclaw/plugin-sdk/session-transcript-runtime";
|
|
47
46
|
import { getSessionBindingService } from "openclaw/plugin-sdk/conversation-binding-runtime";
|
|
@@ -181,7 +180,7 @@ function waitForReconnect(delayMs, signal) {
|
|
|
181
180
|
/** Defers schema compilation and auth loading until the first binding operation. */
|
|
182
181
|
function createLazyCodexAppServerBindingStore(state, managedThreadState) {
|
|
183
182
|
let resolved;
|
|
184
|
-
const store = () => resolved ??= import("./session-binding-
|
|
183
|
+
const store = () => resolved ??= import("./session-binding-BHuTCRZQ.js").then((n) => n.f).then(({ createCodexAppServerBindingStore }) => createCodexAppServerBindingStore(state));
|
|
185
184
|
const managedThreads = managedThreadState ? createCodexManagedThreadStore(managedThreadState) : void 0;
|
|
186
185
|
return {
|
|
187
186
|
...managedThreads ? { managedThreads } : {},
|
|
@@ -212,7 +211,7 @@ async function handleCodexCommand(ctx, options) {
|
|
|
212
211
|
}
|
|
213
212
|
}
|
|
214
213
|
async function loadDefaultCodexSubcommandHandler() {
|
|
215
|
-
const { handleCodexSubcommand } = await import("./command-handlers-
|
|
214
|
+
const { handleCodexSubcommand } = await import("./command-handlers-CTGb2csu.js");
|
|
216
215
|
return handleCodexSubcommand;
|
|
217
216
|
}
|
|
218
217
|
//#endregion
|
|
@@ -525,11 +524,15 @@ async function startCodexConversationThread(params) {
|
|
|
525
524
|
agentId: params.agentId
|
|
526
525
|
};
|
|
527
526
|
const threadId = params.threadId?.trim();
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
527
|
+
const bind = () => params.bindingStore.withLease(identity, () => bindThread(bindingParams, threadId));
|
|
528
|
+
const ownedThreadId = threadId ?? existingBinding?.threadId;
|
|
529
|
+
if (ownedThreadId) await withExclusiveCodexAppServerThread({
|
|
530
|
+
bindingStore: params.bindingStore,
|
|
531
|
+
identity,
|
|
532
|
+
threadId: ownedThreadId,
|
|
533
|
+
run: bind
|
|
531
534
|
});
|
|
532
|
-
else await
|
|
535
|
+
else await bind();
|
|
533
536
|
const storedBinding = await params.bindingStore.read(identity);
|
|
534
537
|
if (!storedBinding) throw new Error("Codex session binding disappeared while starting its conversation thread.");
|
|
535
538
|
return createCodexConversationBindingData({
|
|
@@ -770,14 +773,6 @@ async function writeThreadBindingFromResponse(params, resolved, client, response
|
|
|
770
773
|
throw error;
|
|
771
774
|
}
|
|
772
775
|
}
|
|
773
|
-
async function attachExistingThread(params) {
|
|
774
|
-
await withExclusiveCodexAppServerThread({
|
|
775
|
-
bindingStore: params.bindingStore,
|
|
776
|
-
identity: params.identity,
|
|
777
|
-
threadId: params.threadId,
|
|
778
|
-
run: () => bindThread(params, params.threadId)
|
|
779
|
-
});
|
|
780
|
-
}
|
|
781
776
|
async function bindThread(params, threadId) {
|
|
782
777
|
const current = await params.bindingStore.read(params.identity);
|
|
783
778
|
assertCodexBindingMayBeReplaced(current, "binding a conversation-bound Codex thread");
|
|
@@ -830,277 +825,286 @@ async function runBoundTurn(params) {
|
|
|
830
825
|
const identity = conversationBindingIdentity(params.data);
|
|
831
826
|
const binding = await params.bindingStore.read(identity);
|
|
832
827
|
if (!binding?.threadId) throw new Error("bound Codex conversation has no thread binding");
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
if (!params.incognito && isCodexAppServerClientRuntimeLive(client)) {
|
|
905
|
-
const ownership = await consumeCodexAppServerLiveThread(client, threadId);
|
|
906
|
-
if (ownership) {
|
|
907
|
-
liveThreadOwnership = {
|
|
908
|
-
client,
|
|
828
|
+
return await withExclusiveCodexAppServerThread({
|
|
829
|
+
bindingStore: params.bindingStore,
|
|
830
|
+
identity,
|
|
831
|
+
threadId: binding.threadId,
|
|
832
|
+
run: async () => {
|
|
833
|
+
const current = await params.bindingStore.read(identity);
|
|
834
|
+
if (!isSameCodexAppServerThreadOwner(current, binding)) throw new Error("Codex conversation binding changed before its turn.");
|
|
835
|
+
assertCodexBindingMayBeReplaced(binding, "running a conversation-bound Codex thread");
|
|
836
|
+
let threadId = binding.threadId;
|
|
837
|
+
const requestedWorkspaceDir = binding.cwd || params.data.workspaceDir;
|
|
838
|
+
const reviewerModelProvider = resolveModelBackedReviewerPolicyProvider({
|
|
839
|
+
authProfileId: binding.authProfileId,
|
|
840
|
+
modelProvider: binding.modelProvider,
|
|
841
|
+
...agentLookup
|
|
842
|
+
});
|
|
843
|
+
const { runtime, workspaceDir } = await resolveConversationAppServerRuntime({
|
|
844
|
+
pluginConfig: params.pluginConfig,
|
|
845
|
+
config: params.config,
|
|
846
|
+
agentId: params.data.source?.agentId ?? params.data.agentId,
|
|
847
|
+
sessionKey: params.data.legacyBinding ? params.sessionKey : params.data.source?.sessionKey,
|
|
848
|
+
source: params.data.source,
|
|
849
|
+
workspaceDir: requestedWorkspaceDir,
|
|
850
|
+
modelProvider: reviewerModelProvider,
|
|
851
|
+
model: binding.model,
|
|
852
|
+
agentDir: params.data.agentDir
|
|
853
|
+
});
|
|
854
|
+
const modelScopedRuntime = resolveCodexAppServerForModelProvider({
|
|
855
|
+
appServer: runtime,
|
|
856
|
+
provider: reviewerModelProvider,
|
|
857
|
+
model: binding.model,
|
|
858
|
+
config: params.config,
|
|
859
|
+
env: process.env,
|
|
860
|
+
agentDir: params.data.agentDir
|
|
861
|
+
});
|
|
862
|
+
const sessionRoot = modelScopedRuntime.sessionRoot;
|
|
863
|
+
const approvalPolicy = modelScopedRuntime.approvalPolicy;
|
|
864
|
+
const sandbox = modelScopedRuntime.sandbox;
|
|
865
|
+
const permissionProfile = modelScopedRuntime.networkProxy?.profileName;
|
|
866
|
+
const networkProxyConfigFingerprint = modelScopedRuntime.networkProxy?.configFingerprint;
|
|
867
|
+
const networkProxyBindingChanged = binding.networkProxyProfileName !== permissionProfile || binding.networkProxyConfigFingerprint !== networkProxyConfigFingerprint;
|
|
868
|
+
const serviceTier = binding.serviceTier ?? runtime.serviceTier;
|
|
869
|
+
let useStickyNetworkProfile = permissionProfile !== void 0 && binding.networkProxyProfileName === permissionProfile && binding.networkProxyConfigFingerprint === networkProxyConfigFingerprint;
|
|
870
|
+
assertNativeConversationApprovalPolicySupported(modelScopedRuntime);
|
|
871
|
+
const modelSelection = binding.model ? resolveCodexAppServerRequestModelSelection({
|
|
872
|
+
model: binding.model,
|
|
873
|
+
modelProvider: binding.modelProvider,
|
|
874
|
+
authProfileId: binding.authProfileId,
|
|
875
|
+
...agentLookup
|
|
876
|
+
}) : void 0;
|
|
877
|
+
const threadRequestRuntime = {
|
|
878
|
+
runtime: modelScopedRuntime,
|
|
879
|
+
workspaceDir,
|
|
880
|
+
...modelSelection
|
|
881
|
+
};
|
|
882
|
+
const clientOptions = {
|
|
883
|
+
startOptions: runtime.start,
|
|
884
|
+
timeoutMs: runtime.requestTimeoutMs,
|
|
885
|
+
authProfileId: binding.authProfileId,
|
|
886
|
+
...agentLookup
|
|
887
|
+
};
|
|
888
|
+
let client = await getLeasedSharedCodexAppServerClient(clientOptions);
|
|
889
|
+
const clientLease = { client };
|
|
890
|
+
let activeTurnId;
|
|
891
|
+
let activeTurnCleanup = () => void 0;
|
|
892
|
+
let isolatedSubscriptionClient;
|
|
893
|
+
let turnRoute;
|
|
894
|
+
let liveThreadOwnership;
|
|
895
|
+
let ownsNativeSubscription = false;
|
|
896
|
+
let turnSucceeded = false;
|
|
897
|
+
const assertResumeInputAllowed = async () => {
|
|
898
|
+
const { thread } = await client.request("thread/read", {
|
|
909
899
|
threadId,
|
|
910
|
-
|
|
911
|
-
};
|
|
912
|
-
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
client = nextClient;
|
|
900
|
+
includeTurns: false
|
|
901
|
+
}, { timeoutMs: runtime.requestTimeoutMs });
|
|
902
|
+
assertCodexThreadAcceptsDirectInput(thread);
|
|
903
|
+
};
|
|
904
|
+
try {
|
|
905
|
+
if (!networkProxyBindingChanged && binding.clientId !== client.getInstanceId()) await assertResumeInputAllowed();
|
|
906
|
+
if (!params.incognito && isCodexAppServerClientRuntimeLive(client)) {
|
|
907
|
+
const ownership = await consumeCodexAppServerLiveThread(client, threadId);
|
|
908
|
+
if (ownership) {
|
|
909
|
+
liveThreadOwnership = {
|
|
910
|
+
client,
|
|
911
|
+
threadId,
|
|
912
|
+
ownership
|
|
913
|
+
};
|
|
914
|
+
ownsNativeSubscription = true;
|
|
915
|
+
}
|
|
927
916
|
}
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
917
|
+
if (networkProxyBindingChanged) {
|
|
918
|
+
const response = assertCodexThreadStartResponse(await withLeasedCodexAppServerClientStartSelectionRetry({
|
|
919
|
+
lease: clientLease,
|
|
920
|
+
options: clientOptions,
|
|
921
|
+
run: async (requestClient, requestOptions) => await requestClient.request("thread/start", {
|
|
922
|
+
...buildConversationThreadRequest(threadRequestRuntime, serviceTier),
|
|
923
|
+
developerInstructions: CODEX_CONVERSATION_THREAD_DEVELOPER_INSTRUCTIONS,
|
|
924
|
+
experimentalRawEvents: true,
|
|
925
|
+
...params.incognito ? { ephemeral: true } : {}
|
|
926
|
+
}, requestOptions()),
|
|
927
|
+
onClientChange: (nextClient) => {
|
|
928
|
+
client = nextClient;
|
|
929
|
+
}
|
|
930
|
+
}));
|
|
931
|
+
threadId = response.thread.id;
|
|
932
|
+
ownsNativeSubscription = true;
|
|
933
|
+
assertCodexThreadAcceptsDirectInput(response.thread);
|
|
934
|
+
if (liveThreadOwnership && (liveThreadOwnership.threadId !== threadId || liveThreadOwnership.client !== client)) {
|
|
935
|
+
const previousOwnership = liveThreadOwnership;
|
|
936
|
+
try {
|
|
937
|
+
await previousOwnership.ownership.release(previousOwnership.threadId);
|
|
938
|
+
} catch (error) {
|
|
939
|
+
if (!(isCodexAppServerClientRuntimeLive(previousOwnership.client) && await retainCodexAppServerBindingSubscription(previousOwnership.client, previousOwnership.threadId, previousOwnership.ownership).catch(() => false))) await closeCodexStartupClientBestEffort(previousOwnership.client);
|
|
940
|
+
liveThreadOwnership = void 0;
|
|
941
|
+
throw error;
|
|
942
|
+
}
|
|
943
|
+
liveThreadOwnership = void 0;
|
|
944
|
+
} else if (binding.threadId !== threadId) await releaseCodexAppServerBindingSubscription(binding);
|
|
945
|
+
if (!await params.bindingStore.mutate(identity, {
|
|
946
|
+
kind: "set",
|
|
947
|
+
binding: {
|
|
948
|
+
threadId,
|
|
949
|
+
clientId: client.getInstanceId(),
|
|
950
|
+
cwd: response.thread.cwd ?? workspaceDir,
|
|
951
|
+
authProfileId: binding.authProfileId,
|
|
952
|
+
model: response.model ?? modelSelection?.model ?? binding.model,
|
|
953
|
+
modelProvider: normalizeCodexAppServerBindingModelProvider({
|
|
954
|
+
authProfileId: binding.authProfileId,
|
|
955
|
+
modelProvider: response.modelProvider ?? modelSelection?.modelProvider ?? binding.modelProvider,
|
|
956
|
+
...agentLookup
|
|
957
|
+
}),
|
|
958
|
+
serviceTier: serviceTier ?? void 0,
|
|
959
|
+
networkProxyProfileName: modelScopedRuntime.networkProxy?.profileName,
|
|
960
|
+
networkProxyConfigFingerprint: modelScopedRuntime.networkProxy?.configFingerprint,
|
|
961
|
+
conversationStartId: binding.conversationStartId,
|
|
962
|
+
conversationSourceTransferComplete: binding.conversationSourceTransferComplete,
|
|
963
|
+
historyCoveredThrough: binding.historyCoveredThrough
|
|
964
|
+
}
|
|
965
|
+
})) throw new Error("Codex conversation binding changed while rotating its thread.");
|
|
966
|
+
useStickyNetworkProfile = modelScopedRuntime.networkProxy !== void 0;
|
|
967
|
+
} else if (binding.clientId !== client.getInstanceId() || isCodexAppServerClientRuntimeLive(client) && !params.incognito && !liveThreadOwnership) {
|
|
968
|
+
if (binding.clientId === client.getInstanceId()) await assertResumeInputAllowed();
|
|
969
|
+
const response = await withLeasedCodexAppServerClientStartSelectionRetry({
|
|
970
|
+
lease: clientLease,
|
|
971
|
+
options: clientOptions,
|
|
972
|
+
run: async (requestClient, requestOptions) => await resumeCodexAppServerThread({
|
|
973
|
+
client: requestClient,
|
|
974
|
+
onSubscriptionReleased: () => {
|
|
975
|
+
isolatedSubscriptionClient = requestClient;
|
|
976
|
+
},
|
|
977
|
+
abandonClient: async () => {
|
|
978
|
+
await closeCodexStartupClientBestEffort(requestClient);
|
|
979
|
+
isolatedSubscriptionClient = requestClient;
|
|
980
|
+
},
|
|
981
|
+
request: {
|
|
982
|
+
threadId,
|
|
983
|
+
...buildConversationThreadRequest(threadRequestRuntime, serviceTier)
|
|
984
|
+
},
|
|
985
|
+
requestResume: (request) => requestClient.request("thread/resume", request, requestOptions())
|
|
986
|
+
}),
|
|
987
|
+
onClientChange: (nextClient) => {
|
|
988
|
+
client = nextClient;
|
|
989
|
+
}
|
|
990
|
+
});
|
|
991
|
+
threadId = response.thread.id;
|
|
992
|
+
ownsNativeSubscription = true;
|
|
993
|
+
assertCodexThreadAcceptsDirectInput(response.thread);
|
|
994
|
+
if (!isSameCodexAppServerThreadOwner(binding, {
|
|
995
|
+
threadId,
|
|
996
|
+
clientId: client.getInstanceId()
|
|
997
|
+
})) await releaseCodexAppServerBindingSubscription(binding);
|
|
998
|
+
if (!await params.bindingStore.mutate(identity, {
|
|
999
|
+
kind: "patch",
|
|
1000
|
+
threadId: binding.threadId,
|
|
1001
|
+
patch: {
|
|
1002
|
+
clientId: client.getInstanceId(),
|
|
1003
|
+
cwd: response.thread.cwd ?? binding.cwd,
|
|
1004
|
+
model: response.model ?? modelSelection?.model ?? binding.model,
|
|
1005
|
+
modelProvider: normalizeCodexAppServerBindingModelProvider({
|
|
1006
|
+
authProfileId: binding.authProfileId,
|
|
1007
|
+
modelProvider: response.modelProvider ?? modelSelection?.modelProvider ?? binding.modelProvider,
|
|
1008
|
+
...agentLookup
|
|
1009
|
+
})
|
|
1010
|
+
}
|
|
1011
|
+
})) throw new Error("Codex conversation binding changed while resuming on a new client.");
|
|
940
1012
|
}
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
if (!await params.bindingStore.mutate(identity, {
|
|
944
|
-
kind: "set",
|
|
945
|
-
binding: {
|
|
1013
|
+
const turnCollector = createCodexConversationTurnCollector(threadId);
|
|
1014
|
+
turnRoute = getCodexAppServerTurnRouter(client).reserveThread({
|
|
946
1015
|
threadId,
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
1016
|
+
onNotification: turnCollector.handleNotification
|
|
1017
|
+
});
|
|
1018
|
+
turnRoute.armTurn();
|
|
1019
|
+
activeTurnId = (await client.request("turn/start", {
|
|
1020
|
+
threadId,
|
|
1021
|
+
input: buildCodexConversationTurnInput({
|
|
1022
|
+
prompt: params.prompt,
|
|
1023
|
+
event: params.event
|
|
955
1024
|
}),
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
1025
|
+
cwd: workspaceDir,
|
|
1026
|
+
...sessionRoot ? { runtimeWorkspaceRoots: [sessionRoot] } : {},
|
|
1027
|
+
approvalPolicy,
|
|
1028
|
+
approvalsReviewer: modelScopedRuntime.approvalsReviewer,
|
|
1029
|
+
...useStickyNetworkProfile ? {} : { sandboxPolicy: codexSandboxPolicyForTurn(sandbox, sessionRoot ?? workspaceDir) },
|
|
1030
|
+
...modelSelection?.model ? { model: modelSelection.model } : {},
|
|
1031
|
+
personality: CODEX_NATIVE_PERSONALITY_NONE,
|
|
1032
|
+
...serviceTier ? { serviceTier } : {}
|
|
1033
|
+
}, { timeoutMs: runtime.requestTimeoutMs })).turn.id;
|
|
1034
|
+
activeTurnCleanup = trackCodexConversationActiveTurn({
|
|
1035
|
+
identity,
|
|
1036
|
+
client,
|
|
1037
|
+
threadId,
|
|
1038
|
+
turnId: activeTurnId
|
|
1039
|
+
});
|
|
1040
|
+
turnCollector.setTurnId(activeTurnId);
|
|
1041
|
+
await turnRoute.bindTurn(activeTurnId);
|
|
1042
|
+
const replyText = (await turnCollector.wait({ timeoutMs: params.timeoutMs ?? DEFAULT_BOUND_TURN_TIMEOUT_MS })).replyText.trim();
|
|
1043
|
+
turnSucceeded = true;
|
|
1044
|
+
return { reply: { text: replyText || "Codex completed without a text reply." } };
|
|
1045
|
+
} catch (error) {
|
|
1046
|
+
if (isCodexAppServerOverloadError(error) && error.method === "thread/resume") throw error;
|
|
1047
|
+
if (error instanceof CodexThreadDirectInputError) {
|
|
1048
|
+
if (params.incognito && ownsNativeSubscription) {
|
|
1049
|
+
if (!await unsubscribeCodexThreadBestEffort(client, {
|
|
1050
|
+
threadId,
|
|
1051
|
+
timeoutMs: 5e3
|
|
1052
|
+
})) await retireUnsafeCodexTurnClientBestEffort(client, "parent-owned thread unsubscribe");
|
|
1053
|
+
}
|
|
1054
|
+
throw error;
|
|
962
1055
|
}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
} else if (binding.clientId !== client.getInstanceId() || isCodexAppServerClientRuntimeLive(client) && !params.incognito && !liveThreadOwnership) {
|
|
966
|
-
if (binding.clientId === client.getInstanceId()) await assertResumeInputAllowed();
|
|
967
|
-
const response = await withLeasedCodexAppServerClientStartSelectionRetry({
|
|
968
|
-
lease: clientLease,
|
|
969
|
-
options: clientOptions,
|
|
970
|
-
run: async (requestClient, requestOptions) => await resumeCodexAppServerThread({
|
|
971
|
-
client: requestClient,
|
|
972
|
-
onSubscriptionReleased: () => {
|
|
973
|
-
isolatedSubscriptionClient = requestClient;
|
|
974
|
-
},
|
|
975
|
-
abandonClient: async () => {
|
|
976
|
-
await closeCodexStartupClientBestEffort(requestClient);
|
|
977
|
-
isolatedSubscriptionClient = requestClient;
|
|
978
|
-
},
|
|
979
|
-
request: {
|
|
1056
|
+
if (error instanceof CodexConversationTurnTimeoutError && activeTurnId || turnRoute && isCodexAppServerIndeterminateRequestCancellationError(error)) {
|
|
1057
|
+
if (!await interruptCodexTurnAndWaitBestEffort(client, {
|
|
980
1058
|
threadId,
|
|
981
|
-
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
client = nextClient;
|
|
1059
|
+
turnId: activeTurnId ?? ""
|
|
1060
|
+
})) {
|
|
1061
|
+
await retireUnsafeCodexTurnClientBestEffort(client, "turn interrupt");
|
|
1062
|
+
isolatedSubscriptionClient = client;
|
|
1063
|
+
}
|
|
987
1064
|
}
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
threadId: binding.threadId,
|
|
999
|
-
patch: {
|
|
1000
|
-
clientId: client.getInstanceId(),
|
|
1001
|
-
cwd: response.thread.cwd ?? binding.cwd,
|
|
1002
|
-
model: response.model ?? modelSelection?.model ?? binding.model,
|
|
1003
|
-
modelProvider: normalizeCodexAppServerBindingModelProvider({
|
|
1004
|
-
authProfileId: binding.authProfileId,
|
|
1005
|
-
modelProvider: response.modelProvider ?? modelSelection?.modelProvider ?? binding.modelProvider,
|
|
1006
|
-
...agentLookup
|
|
1007
|
-
})
|
|
1065
|
+
if (params.incognito) {
|
|
1066
|
+
if (await params.bindingStore.mutate(identity, {
|
|
1067
|
+
kind: "clear",
|
|
1068
|
+
threadId
|
|
1069
|
+
}) && isolatedSubscriptionClient !== client) {
|
|
1070
|
+
if (!await unsubscribeCodexThreadBestEffort(client, {
|
|
1071
|
+
threadId,
|
|
1072
|
+
timeoutMs: 5e3
|
|
1073
|
+
})) await retireUnsafeCodexTurnClientBestEffort(client, "thread unsubscribe");
|
|
1074
|
+
}
|
|
1008
1075
|
}
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
}, { timeoutMs: runtime.requestTimeoutMs })).turn.id;
|
|
1032
|
-
activeTurnCleanup = trackCodexConversationActiveTurn({
|
|
1033
|
-
identity,
|
|
1034
|
-
client,
|
|
1035
|
-
threadId,
|
|
1036
|
-
turnId: activeTurnId
|
|
1037
|
-
});
|
|
1038
|
-
turnCollector.setTurnId(activeTurnId);
|
|
1039
|
-
await turnRoute.bindTurn(activeTurnId);
|
|
1040
|
-
const replyText = (await turnCollector.wait({ timeoutMs: params.timeoutMs ?? DEFAULT_BOUND_TURN_TIMEOUT_MS })).replyText.trim();
|
|
1041
|
-
turnSucceeded = true;
|
|
1042
|
-
return { reply: { text: replyText || "Codex completed without a text reply." } };
|
|
1043
|
-
} catch (error) {
|
|
1044
|
-
if (isCodexAppServerOverloadError(error) && error.method === "thread/resume") throw error;
|
|
1045
|
-
if (error instanceof CodexThreadDirectInputError) {
|
|
1046
|
-
if (params.incognito && ownsNativeSubscription) {
|
|
1047
|
-
if (!await unsubscribeCodexThreadBestEffort(client, {
|
|
1048
|
-
threadId,
|
|
1049
|
-
timeoutMs: 5e3
|
|
1050
|
-
})) await retireUnsafeCodexTurnClientBestEffort(client, "parent-owned thread unsubscribe");
|
|
1051
|
-
}
|
|
1052
|
-
throw error;
|
|
1053
|
-
}
|
|
1054
|
-
if (error instanceof CodexConversationTurnTimeoutError && activeTurnId || turnRoute && isCodexAppServerIndeterminateRequestCancellationError(error)) {
|
|
1055
|
-
if (!await interruptCodexTurnAndWaitBestEffort(client, {
|
|
1056
|
-
threadId,
|
|
1057
|
-
turnId: activeTurnId ?? ""
|
|
1058
|
-
})) {
|
|
1059
|
-
await retireUnsafeCodexTurnClientBestEffort(client, "turn interrupt");
|
|
1060
|
-
isolatedSubscriptionClient = client;
|
|
1061
|
-
}
|
|
1062
|
-
}
|
|
1063
|
-
if (params.incognito) {
|
|
1064
|
-
if (await params.bindingStore.mutate(identity, {
|
|
1065
|
-
kind: "clear",
|
|
1066
|
-
threadId
|
|
1067
|
-
}) && isolatedSubscriptionClient !== client) {
|
|
1068
|
-
if (!await unsubscribeCodexThreadBestEffort(client, {
|
|
1069
|
-
threadId,
|
|
1070
|
-
timeoutMs: 5e3
|
|
1071
|
-
})) await retireUnsafeCodexTurnClientBestEffort(client, "thread unsubscribe");
|
|
1072
|
-
}
|
|
1073
|
-
}
|
|
1074
|
-
throw error;
|
|
1075
|
-
} finally {
|
|
1076
|
-
activeTurnCleanup();
|
|
1077
|
-
turnRoute?.release();
|
|
1078
|
-
try {
|
|
1079
|
-
if (ownsNativeSubscription && isolatedSubscriptionClient !== client && !params.incognito && isCodexAppServerClientRuntimeLive(client)) {
|
|
1080
|
-
const currentLiveThreadOwnership = liveThreadOwnership?.client === client && liveThreadOwnership.threadId === threadId ? liveThreadOwnership.ownership : void 0;
|
|
1081
|
-
let retained = false;
|
|
1082
|
-
if (turnSucceeded) retained = await params.bindingStore.withLease(identity, async () => {
|
|
1083
|
-
const current = await params.bindingStore.read(identity);
|
|
1084
|
-
if (current?.threadId !== threadId || current.clientId !== client.getInstanceId()) return false;
|
|
1085
|
-
return await retainCodexAppServerBindingSubscription(client, threadId, currentLiveThreadOwnership);
|
|
1086
|
-
});
|
|
1087
|
-
if (!retained) {
|
|
1088
|
-
if (!(currentLiveThreadOwnership ? await currentLiveThreadOwnership.release(threadId).then(() => true) : await unsubscribeCodexThreadBestEffort(client, {
|
|
1076
|
+
throw error;
|
|
1077
|
+
} finally {
|
|
1078
|
+
activeTurnCleanup();
|
|
1079
|
+
turnRoute?.release();
|
|
1080
|
+
try {
|
|
1081
|
+
if (ownsNativeSubscription && isolatedSubscriptionClient !== client && !params.incognito && isCodexAppServerClientRuntimeLive(client)) {
|
|
1082
|
+
const currentLiveThreadOwnership = liveThreadOwnership?.client === client && liveThreadOwnership.threadId === threadId ? liveThreadOwnership.ownership : void 0;
|
|
1083
|
+
let retained = false;
|
|
1084
|
+
if (turnSucceeded) retained = await params.bindingStore.withLease(identity, async () => {
|
|
1085
|
+
const latest = await params.bindingStore.read(identity);
|
|
1086
|
+
if (latest?.threadId !== threadId || latest.clientId !== client.getInstanceId()) return false;
|
|
1087
|
+
return await retainCodexAppServerBindingSubscription(client, threadId, currentLiveThreadOwnership);
|
|
1088
|
+
});
|
|
1089
|
+
if (!retained) {
|
|
1090
|
+
if (!(currentLiveThreadOwnership ? await currentLiveThreadOwnership.release(threadId).then(() => true) : await unsubscribeCodexThreadBestEffort(client, {
|
|
1091
|
+
threadId,
|
|
1092
|
+
timeoutMs: 5e3
|
|
1093
|
+
}))) await closeCodexStartupClientBestEffort(client);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
} catch (error) {
|
|
1097
|
+
embeddedAgentLog.warn("codex conversation subscription cleanup failed", {
|
|
1089
1098
|
threadId,
|
|
1090
|
-
|
|
1091
|
-
})
|
|
1099
|
+
reason: formatErrorMessage(error)
|
|
1100
|
+
});
|
|
1101
|
+
await closeCodexStartupClientBestEffort(client);
|
|
1102
|
+
} finally {
|
|
1103
|
+
releaseCodexAppServerClientLease(clientLease);
|
|
1092
1104
|
}
|
|
1093
1105
|
}
|
|
1094
|
-
} catch (error) {
|
|
1095
|
-
embeddedAgentLog.warn("codex conversation subscription cleanup failed", {
|
|
1096
|
-
threadId,
|
|
1097
|
-
reason: formatErrorMessage(error)
|
|
1098
|
-
});
|
|
1099
|
-
await closeCodexStartupClientBestEffort(client);
|
|
1100
|
-
} finally {
|
|
1101
|
-
releaseCodexAppServerClientLease(clientLease);
|
|
1102
1106
|
}
|
|
1103
|
-
}
|
|
1107
|
+
});
|
|
1104
1108
|
}
|
|
1105
1109
|
function assertNativeConversationApprovalPolicySupported(runtime) {
|
|
1106
1110
|
if (runtime.approvalPolicy !== "never" && runtime.approvalsReviewer === "user") throw new Error(NATIVE_CONVERSATION_INTERACTIVE_APPROVALS_UNAVAILABLE);
|
|
@@ -1117,8 +1121,10 @@ async function runBoundTurnWithMissingThreadRecovery(params) {
|
|
|
1117
1121
|
}
|
|
1118
1122
|
async function prepareConversationBinding(params, options = {}) {
|
|
1119
1123
|
const identity = conversationBindingIdentity(params.data);
|
|
1120
|
-
await params.bindingStore.
|
|
1124
|
+
const snapshot = await params.bindingStore.read(identity);
|
|
1125
|
+
const run = () => params.bindingStore.withLease(identity, async () => {
|
|
1121
1126
|
const current = await params.bindingStore.read(identity);
|
|
1127
|
+
if (current?.threadId !== snapshot?.threadId || current?.clientId !== snapshot?.clientId) throw new Error("Codex conversation binding changed before preparation.");
|
|
1122
1128
|
const requested = params.data.start && current?.conversationStartId !== params.data.start.id ? params.data.start : void 0;
|
|
1123
1129
|
if (current && !requested && !options.forceNew) return;
|
|
1124
1130
|
const sourceIdentity = params.data.source ? sessionBindingIdentity({
|
|
@@ -1152,11 +1158,7 @@ async function prepareConversationBinding(params, options = {}) {
|
|
|
1152
1158
|
agentId: params.data.source?.agentId ?? params.data.agentId
|
|
1153
1159
|
};
|
|
1154
1160
|
const threadId = requested?.threadId;
|
|
1155
|
-
|
|
1156
|
-
...bindingParams,
|
|
1157
|
-
threadId
|
|
1158
|
-
});
|
|
1159
|
-
else await bindThread(bindingParams);
|
|
1161
|
+
await bindThread(bindingParams, options.forceNew ? void 0 : threadId);
|
|
1160
1162
|
const stored = await params.bindingStore.read(identity);
|
|
1161
1163
|
if (!stored) throw new Error("Codex conversation binding disappeared while initializing its thread.");
|
|
1162
1164
|
if (sourceIdentity && params.data.source && !current?.conversationSourceTransferComplete) await params.bindingStore.withLease(sourceIdentity, async () => {
|
|
@@ -1187,6 +1189,14 @@ async function prepareConversationBinding(params, options = {}) {
|
|
|
1187
1189
|
}
|
|
1188
1190
|
})) throw new Error("Codex conversation binding changed while initializing its thread.");
|
|
1189
1191
|
});
|
|
1192
|
+
const threadId = params.data.start?.threadId ?? snapshot?.threadId;
|
|
1193
|
+
if (threadId) await withExclusiveCodexAppServerThread({
|
|
1194
|
+
bindingStore: params.bindingStore,
|
|
1195
|
+
identity,
|
|
1196
|
+
threadId,
|
|
1197
|
+
run
|
|
1198
|
+
});
|
|
1199
|
+
else await run();
|
|
1190
1200
|
}
|
|
1191
1201
|
async function projectConversationSourceHistory(source, target, config) {
|
|
1192
1202
|
const storePath = resolveStorePath(config?.session?.store, { agentId: source.agentId });
|
|
@@ -3267,7 +3277,7 @@ function createCodexNodeExecServerCommand() {
|
|
|
3267
3277
|
try {
|
|
3268
3278
|
if (!context.prepareExecAuthorization) throw new Error("Codex node execution requires node-local exec policy support; update the node.");
|
|
3269
3279
|
const assertExecAuthorized = context.prepareExecAuthorization(request.authorization);
|
|
3270
|
-
const { runCodexNodeExecServer } = await import("./node-exec-server.runtime-
|
|
3280
|
+
const { runCodexNodeExecServer } = await import("./node-exec-server.runtime-CstNHCmC.js");
|
|
3271
3281
|
return await runCodexNodeExecServer({
|
|
3272
3282
|
workspaceDir: workspace.workspaceDir,
|
|
3273
3283
|
io,
|
|
@@ -3292,6 +3302,10 @@ function createCodexNodeExecServerInvokePolicy() {
|
|
|
3292
3302
|
return {
|
|
3293
3303
|
commands: [CODEX_NODE_EXEC_SERVER_COMMAND],
|
|
3294
3304
|
dangerous: true,
|
|
3305
|
+
standingApproval: {
|
|
3306
|
+
kind: "placement",
|
|
3307
|
+
scope: CODEX_NODE_EXEC_SERVER_CAPABILITY
|
|
3308
|
+
},
|
|
3295
3309
|
classifyRisk: () => ({
|
|
3296
3310
|
level: "high",
|
|
3297
3311
|
family: CODEX_NODE_EXEC_SERVER_CAPABILITY
|
|
@@ -3334,21 +3348,16 @@ function createCodexNodeExecServerInvokePolicy() {
|
|
|
3334
3348
|
};
|
|
3335
3349
|
const nodeName = context.node?.displayName ?? context.nodeId;
|
|
3336
3350
|
const approval = await context.approvals.request({
|
|
3337
|
-
title: "Run Codex
|
|
3338
|
-
description: `Allows arbitrary processes and filesystem access across the node account, not only this workspace. ${nodeName}: ${placement.cwd}`,
|
|
3351
|
+
title: "Run Codex on this node placement",
|
|
3352
|
+
description: `Allows arbitrary processes and filesystem access across the node account, not only this workspace. Allow always applies only while this exact placement remains active. ${nodeName}: ${placement.cwd}`,
|
|
3339
3353
|
severity: "critical",
|
|
3340
|
-
allowedDecisions: ["allow-once"]
|
|
3354
|
+
allowedDecisions: ["allow-once", "allow-always"]
|
|
3341
3355
|
});
|
|
3342
|
-
if (approval.decision !== "allow-once") {
|
|
3356
|
+
if (approval.decision !== "allow-once" && approval.decision !== "allow-always") {
|
|
3343
3357
|
if (approval.decision === "deny") return {
|
|
3344
3358
|
ok: false,
|
|
3345
3359
|
code: "CODEX_NODE_EXEC_APPROVAL_DENIED",
|
|
3346
|
-
message: "Codex node execution was denied. Retry the action and choose Allow once to continue."
|
|
3347
|
-
};
|
|
3348
|
-
if (approval.decision === "allow-always") return {
|
|
3349
|
-
ok: false,
|
|
3350
|
-
code: "CODEX_NODE_EXEC_APPROVAL_INVALID",
|
|
3351
|
-
message: "Codex node execution cannot use permanent approval. Retry the action and choose Allow once."
|
|
3360
|
+
message: "Codex node execution was denied. Retry the action and choose Allow once or Allow always to continue."
|
|
3352
3361
|
};
|
|
3353
3362
|
return {
|
|
3354
3363
|
ok: false,
|
|
@@ -4148,7 +4157,7 @@ function createCodexSupervisionTools(options) {
|
|
|
4148
4157
|
}
|
|
4149
4158
|
//#endregion
|
|
4150
4159
|
//#region extensions/codex/src/web-search-provider.ts
|
|
4151
|
-
const loadCodexWebSearchRuntime = createLazyRuntimeModule(() => import("./web-search-provider.runtime-
|
|
4160
|
+
const loadCodexWebSearchRuntime = createLazyRuntimeModule(() => import("./web-search-provider.runtime-D2FWSK4w.js"));
|
|
4152
4161
|
const CodexWebSearchSchema = {
|
|
4153
4162
|
type: "object",
|
|
4154
4163
|
properties: { query: {
|
|
@@ -4190,6 +4199,7 @@ var codex_default = definePluginEntry({
|
|
|
4190
4199
|
id: "codex",
|
|
4191
4200
|
name: "Codex",
|
|
4192
4201
|
description: "Codex app-server harness and native session supervision.",
|
|
4202
|
+
reload: { noopPrefixes: ["plugins.entries.codex.config.codexPlugins"] },
|
|
4193
4203
|
register(api) {
|
|
4194
4204
|
setManagedCodexPluginRoot(api.rootDir);
|
|
4195
4205
|
const resolveCurrentConfig = () => api.runtime.config?.current ? api.runtime.config.current() : void 0;
|
|
@@ -4383,7 +4393,7 @@ var codex_default = definePluginEntry({
|
|
|
4383
4393
|
if (!previousSessionId || !sessionId || previousSessionId === sessionId) return;
|
|
4384
4394
|
const config = resolveCurrentConfig();
|
|
4385
4395
|
const sessionKey = ctx.sessionKey?.trim();
|
|
4386
|
-
const { sessionBindingIdentity } = await import("./session-binding-
|
|
4396
|
+
const { sessionBindingIdentity } = await import("./session-binding-BHuTCRZQ.js").then((n) => n.f);
|
|
4387
4397
|
const identity = sessionBindingIdentity({
|
|
4388
4398
|
sessionId,
|
|
4389
4399
|
...sessionKey ? { sessionKey } : {},
|
|
@@ -4401,7 +4411,7 @@ var codex_default = definePluginEntry({
|
|
|
4401
4411
|
if (endedSessionKey && nextSessionKey && nextSessionKey !== endedSessionKey) return;
|
|
4402
4412
|
if (event.nextSessionId?.trim() === event.sessionId.trim()) return;
|
|
4403
4413
|
const config = resolveCurrentConfig();
|
|
4404
|
-
const [{ sessionBindingIdentity }, { retireCodexAppServerSessionGeneration }] = await Promise.all([import("./session-binding-
|
|
4414
|
+
const [{ sessionBindingIdentity }, { retireCodexAppServerSessionGeneration }] = await Promise.all([import("./session-binding-BHuTCRZQ.js").then((n) => n.f), import("./session-retirement-BujDjXVF.js")]);
|
|
4405
4415
|
await retireCodexAppServerSessionGeneration({
|
|
4406
4416
|
bindingStore,
|
|
4407
4417
|
identity: sessionBindingIdentity({
|