@jingyi0605/codingns 0.5.5 → 0.6.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/bin/codingns.mjs +15 -2
- package/dist/public/assets/{AdaptiveButlerPage-CUyNL98E.js → AdaptiveButlerPage-Dw72U3hG.js} +3 -3
- package/dist/public/assets/App-CcDXqFl1.css +1 -0
- package/dist/public/assets/{App-BFP7LCSC.js → App-Dsf3ooXU.js} +3 -3
- package/dist/public/assets/{BootstrapPage-G74dX2Us.js → BootstrapPage-CE0m1qSR.js} +1 -1
- package/dist/public/assets/ConversationPage-8wOY7SX-.js +4 -0
- package/dist/public/assets/{DesktopDetachPreviewPage-IV7oEdOX.js → DesktopDetachPreviewPage-Dxarr_Wf.js} +1 -1
- package/dist/public/assets/DesktopWindowPage-VytPwJ4c.js +2 -0
- package/dist/public/assets/FileContextPanel-DwFzLsOp.js +1 -0
- package/dist/public/assets/GitSidebar-CH6WqTrM.js +6 -0
- package/dist/public/assets/MobileCreateSessionSheet-DcxKM00P.js +1 -0
- package/dist/public/assets/{MobileTopHeaderFrame-COTc7cRr.js → MobileTopHeaderFrame-C5rIKQT6.js} +1 -1
- package/dist/public/assets/MobileWorkspaceSwitcherHeader-CfUnHgv_.js +1 -0
- package/dist/public/assets/RelayConnectEntryPage-CgMvVZwa.js +1 -0
- package/dist/public/assets/ServerSettingsModal-CFul__z1.js +1 -0
- package/dist/public/assets/SessionIndexPage-B-tRhBXC.js +1 -0
- package/dist/public/assets/SettingsPage-C9LGxSQZ.js +1 -0
- package/dist/public/assets/TerminalManagerPanel-BbORd-ee.js +1 -0
- package/dist/public/assets/{TerminalPage-DpsvQQVR.js → TerminalPage-DWHv6mlu.js} +19 -19
- package/dist/public/assets/TerminalRuntimeFallbackModal-B29YxbQe.js +1 -0
- package/dist/public/assets/ToolFilesPage-Dx9cv9hu.js +1 -0
- package/dist/public/assets/ToolGitPage-D7H3vAia.js +1 -0
- package/dist/public/assets/ToolProcessesPage-PqQWxsy-.js +1 -0
- package/dist/public/assets/ToolsHomePage-CX05Pe_4.js +1 -0
- package/dist/public/assets/WorkbenchLandingPage-CchkAC75.js +1 -0
- package/dist/public/assets/WorkbenchLayout-pOZvEqp7.js +3 -0
- package/dist/public/assets/{WorkbenchModal-CbDxaCOR.js → WorkbenchModal-ColqvV6a.js} +1 -1
- package/dist/public/assets/WorkbenchShellRoute-C0_h4lP6.js +1 -0
- package/dist/public/assets/WorkbenchShellRoute-RGZpA0_J.css +1 -0
- package/dist/public/assets/WorkspaceDebugDetailPage-Deqy2_pO.js +1 -0
- package/dist/public/assets/WorkspaceDetailPage-Cvf-ZdlB.js +1 -0
- package/dist/public/assets/WorkspaceHomePage-Dsyvqyk1.js +1 -0
- package/dist/public/assets/client-runtime-manager-DROQJ9v3.js +1 -0
- package/dist/public/assets/{file-tree-icon-BMKuc5pw.js → file-tree-icon-Bp3Ntt7u.js} +7 -7
- package/dist/public/assets/index-B84Po2NA.css +1 -0
- package/dist/public/assets/index-C-0oeG_5.js +42 -0
- package/dist/public/assets/legna-code-6TqgZ4Ls.png +0 -0
- package/dist/public/assets/login-direct-candidate-resolver-DotM530R.js +1 -0
- package/dist/public/assets/model-switch-api-Bh9nYslz.js +1 -0
- package/dist/public/assets/{preferences-service-gv_9vGKz.js → preferences-service-BG6GKG29.js} +1 -1
- package/dist/public/assets/relay-entry-pmr-c42O.js +1 -0
- package/dist/public/assets/session-runtime-machine-YN84QBlr.js +21 -0
- package/dist/public/assets/{styles-BWPBZvze.css → styles-CsEMfdaS.css} +1 -1
- package/dist/public/assets/{terminal-runtime-meta-B9xJGY__.js → terminal-runtime-meta-8_uRZf7h.js} +1 -1
- package/dist/public/assets/useRegisteredDebugTemplates-DWX7LXQu.js +1 -0
- package/dist/public/assets/window-BVUB8gMK.js +1 -0
- package/dist/public/index.html +2 -2
- package/dist/server/config/env.d.ts +3 -0
- package/dist/server/config/env.js +10 -0
- package/dist/server/config/env.js.map +1 -1
- package/dist/server/modules/client/npm-global-package-service.d.ts +7 -1
- package/dist/server/modules/client/npm-global-package-service.js +149 -43
- package/dist/server/modules/client/npm-global-package-service.js.map +1 -1
- package/dist/server/modules/client/service-update-task-service.js +6 -2
- package/dist/server/modules/client/service-update-task-service.js.map +1 -1
- package/dist/server/modules/client/service-update-types.d.ts +2 -0
- package/dist/server/modules/git/git-controller.d.ts +3 -0
- package/dist/server/modules/git/git-controller.js +3 -0
- package/dist/server/modules/git/git-controller.js.map +1 -1
- package/dist/server/modules/git/git-read-service.js +47 -1
- package/dist/server/modules/git/git-read-service.js.map +1 -1
- package/dist/server/modules/git/git-write-service.d.ts +4 -0
- package/dist/server/modules/git/git-write-service.js +24 -0
- package/dist/server/modules/git/git-write-service.js.map +1 -1
- package/dist/server/modules/git/types.d.ts +1 -0
- package/dist/server/modules/git/workspace-repo-guard.d.ts +2 -0
- package/dist/server/modules/git/workspace-repo-guard.js +24 -10
- package/dist/server/modules/git/workspace-repo-guard.js.map +1 -1
- package/dist/server/modules/model-switch/cc-switch-adapter.d.ts +7 -0
- package/dist/server/modules/model-switch/cc-switch-adapter.js +17 -0
- package/dist/server/modules/model-switch/cc-switch-adapter.js.map +1 -1
- package/dist/server/modules/parallel-sessions/parallel-session-controller.d.ts +57 -0
- package/dist/server/modules/parallel-sessions/parallel-session-controller.js +77 -0
- package/dist/server/modules/parallel-sessions/parallel-session-controller.js.map +1 -0
- package/dist/server/modules/parallel-sessions/parallel-session-group-service.d.ts +88 -0
- package/dist/server/modules/parallel-sessions/parallel-session-group-service.js +625 -0
- package/dist/server/modules/parallel-sessions/parallel-session-group-service.js.map +1 -0
- package/dist/server/modules/parallel-sessions/session-isolated-workspace-service.d.ts +56 -0
- package/dist/server/modules/parallel-sessions/session-isolated-workspace-service.js +483 -0
- package/dist/server/modules/parallel-sessions/session-isolated-workspace-service.js.map +1 -0
- package/dist/server/modules/provider/opencode-model-options.d.ts +1 -0
- package/dist/server/modules/provider/opencode-model-options.js +54 -12
- package/dist/server/modules/provider/opencode-model-options.js.map +1 -1
- package/dist/server/modules/provider/provider-controller.d.ts +6 -1
- package/dist/server/modules/provider/provider-controller.js +24 -2
- package/dist/server/modules/provider/provider-controller.js.map +1 -1
- package/dist/server/modules/provider/provider-discovery-helper-client.d.ts +2 -0
- package/dist/server/modules/provider/provider-discovery-helper-client.js.map +1 -1
- package/dist/server/modules/provider/provider-discovery-helper-process.js +1 -1
- package/dist/server/modules/provider/provider-discovery-helper-process.js.map +1 -1
- package/dist/server/modules/provider/provider-discovery-runtime.js +5 -1
- package/dist/server/modules/provider/provider-discovery-runtime.js.map +1 -1
- package/dist/server/modules/relay-tunnel/relay-tunnel-candidate-endpoints.d.ts +2 -0
- package/dist/server/modules/relay-tunnel/relay-tunnel-candidate-endpoints.js +129 -0
- package/dist/server/modules/relay-tunnel/relay-tunnel-candidate-endpoints.js.map +1 -0
- package/dist/server/modules/relay-tunnel/relay-tunnel-runtime-adapter.js +12 -9
- package/dist/server/modules/relay-tunnel/relay-tunnel-runtime-adapter.js.map +1 -1
- package/dist/server/modules/relay-tunnel/relay-tunnel-service.js +1 -128
- package/dist/server/modules/relay-tunnel/relay-tunnel-service.js.map +1 -1
- package/dist/server/modules/sessions/claude-runtime-helper-client.d.ts +1 -0
- package/dist/server/modules/sessions/claude-runtime-helper-client.js +14 -0
- package/dist/server/modules/sessions/claude-runtime-helper-client.js.map +1 -1
- package/dist/server/modules/sessions/codex-app-server-helper-client.d.ts +4 -0
- package/dist/server/modules/sessions/codex-app-server-helper-client.js +66 -45
- package/dist/server/modules/sessions/codex-app-server-helper-client.js.map +1 -1
- package/dist/server/modules/sessions/codex-app-server-helper-process.js +21 -2
- package/dist/server/modules/sessions/codex-app-server-helper-process.js.map +1 -1
- package/dist/server/modules/sessions/provider-session-delete-cli.js +2 -0
- package/dist/server/modules/sessions/provider-session-delete-cli.js.map +1 -1
- package/dist/server/modules/sessions/session-controller.d.ts +7 -0
- package/dist/server/modules/sessions/session-controller.js +22 -0
- package/dist/server/modules/sessions/session-controller.js.map +1 -1
- package/dist/server/modules/sessions/session-history-service.d.ts +21 -2
- package/dist/server/modules/sessions/session-history-service.js +425 -29
- package/dist/server/modules/sessions/session-history-service.js.map +1 -1
- package/dist/server/modules/sessions/session-live-runtime-service.d.ts +23 -2
- package/dist/server/modules/sessions/session-live-runtime-service.js +472 -74
- package/dist/server/modules/sessions/session-live-runtime-service.js.map +1 -1
- package/dist/server/modules/sessions/session-message-attachment-service.js +2 -2
- package/dist/server/modules/sessions/session-message-attachment-service.js.map +1 -1
- package/dist/server/modules/sessions/session-provider-config-service.d.ts +66 -0
- package/dist/server/modules/sessions/session-provider-config-service.js +821 -0
- package/dist/server/modules/sessions/session-provider-config-service.js.map +1 -0
- package/dist/server/modules/sessions/session-provider-error-mapper.d.ts +2 -0
- package/dist/server/modules/sessions/session-provider-error-mapper.js +42 -0
- package/dist/server/modules/sessions/session-provider-error-mapper.js.map +1 -1
- package/dist/server/modules/workbench/codex-archive-watcher.d.ts +16 -0
- package/dist/server/modules/workbench/codex-archive-watcher.js +50 -0
- package/dist/server/modules/workbench/codex-archive-watcher.js.map +1 -0
- package/dist/server/modules/workbench/workbench-service.d.ts +11 -2
- package/dist/server/modules/workbench/workbench-service.js +37 -8
- package/dist/server/modules/workbench/workbench-service.js.map +1 -1
- package/dist/server/modules/workbench/workspace-panel-snapshot-service.d.ts +1 -1
- package/dist/server/modules/workbench/workspace-panel-snapshot-service.js +26 -3
- package/dist/server/modules/workbench/workspace-panel-snapshot-service.js.map +1 -1
- package/dist/server/modules/workspace/workspace-service.d.ts +3 -1
- package/dist/server/modules/workspace/workspace-service.js +10 -2
- package/dist/server/modules/workspace/workspace-service.js.map +1 -1
- package/dist/server/modules/worktree/worktree-base-ref-resolver.d.ts +20 -0
- package/dist/server/modules/worktree/worktree-base-ref-resolver.js +111 -0
- package/dist/server/modules/worktree/worktree-base-ref-resolver.js.map +1 -0
- package/dist/server/modules/worktree/worktree-cleanup-service.js +9 -3
- package/dist/server/modules/worktree/worktree-cleanup-service.js.map +1 -1
- package/dist/server/modules/worktree/worktree-manager.d.ts +0 -1
- package/dist/server/modules/worktree/worktree-manager.js +14 -20
- package/dist/server/modules/worktree/worktree-manager.js.map +1 -1
- package/dist/server/routes/git.js +1 -0
- package/dist/server/routes/git.js.map +1 -1
- package/dist/server/routes/parallel-groups.d.ts +3 -0
- package/dist/server/routes/parallel-groups.js +9 -0
- package/dist/server/routes/parallel-groups.js.map +1 -0
- package/dist/server/server/create-server.d.ts +8 -0
- package/dist/server/server/create-server.js +48 -11
- package/dist/server/server/create-server.js.map +1 -1
- package/dist/server/server/workbench-runtime-terminal-sync.d.ts +14 -0
- package/dist/server/server/workbench-runtime-terminal-sync.js +17 -0
- package/dist/server/server/workbench-runtime-terminal-sync.js.map +1 -0
- package/dist/server/storage/repositories/parallel-session-group-repository.d.ts +11 -0
- package/dist/server/storage/repositories/parallel-session-group-repository.js +131 -0
- package/dist/server/storage/repositories/parallel-session-group-repository.js.map +1 -0
- package/dist/server/storage/repositories/parallel-session-member-repository.d.ts +12 -0
- package/dist/server/storage/repositories/parallel-session-member-repository.js +150 -0
- package/dist/server/storage/repositories/parallel-session-member-repository.js.map +1 -0
- package/dist/server/storage/repositories/session-binding-repository.js +44 -5
- package/dist/server/storage/repositories/session-binding-repository.js.map +1 -1
- package/dist/server/storage/repositories/session-index-repository.js +6 -0
- package/dist/server/storage/repositories/session-index-repository.js.map +1 -1
- package/dist/server/storage/repositories/session-isolated-workspace-repository.d.ts +15 -0
- package/dist/server/storage/repositories/session-isolated-workspace-repository.js +230 -0
- package/dist/server/storage/repositories/session-isolated-workspace-repository.js.map +1 -0
- package/dist/server/storage/sqlite/client.js +19 -0
- package/dist/server/storage/sqlite/client.js.map +1 -1
- package/dist/server/storage/sqlite/schema.sql +78 -0
- package/dist/server/types/domain.d.ts +78 -0
- package/dist/server/ws/workbench-ws-hub.d.ts +3 -1
- package/dist/server/ws/workbench-ws-hub.js +23 -4
- package/dist/server/ws/workbench-ws-hub.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.d.ts +5 -2
- package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js +40 -8
- package/node_modules/@codingns/session-sync-core/dist/claude-message-utils.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/index.d.ts +2 -0
- package/node_modules/@codingns/session-sync-core/dist/index.js +2 -0
- package/node_modules/@codingns/session-sync-core/dist/index.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.d.ts +10 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js +110 -35
- package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/claude-session-store.d.ts +11 -0
- package/node_modules/@codingns/session-sync-core/dist/providers/claude-session-store.js +105 -0
- package/node_modules/@codingns/session-sync-core/dist/providers/claude-session-store.js.map +1 -0
- package/node_modules/@codingns/session-sync-core/dist/providers/codex.d.ts +1 -0
- package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +34 -0
- package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/gemini.js +131 -39
- package/node_modules/@codingns/session-sync-core/dist/providers/gemini.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/legna-code.d.ts +9 -0
- package/node_modules/@codingns/session-sync-core/dist/providers/legna-code.js +17 -0
- package/node_modules/@codingns/session-sync-core/dist/providers/legna-code.js.map +1 -0
- package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.d.ts +8 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.js +19 -6
- package/node_modules/@codingns/session-sync-core/dist/providers/opencode-shared.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/providers/opencode.d.ts +1 -0
- package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js +13 -8
- package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.d.ts +3 -0
- package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js +46 -22
- package/node_modules/@codingns/session-sync-core/dist/runtime/active-run-registry.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.d.ts +5 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js +103 -51
- package/node_modules/@codingns/session-sync-core/dist/runtime/claude-runtime.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.d.ts +2 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js +528 -301
- package/node_modules/@codingns/session-sync-core/dist/runtime/codex-runtime.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/gemini-runtime.js +32 -8
- package/node_modules/@codingns/session-sync-core/dist/runtime/gemini-runtime.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/legna-runtime.d.ts +10 -0
- package/node_modules/@codingns/session-sync-core/dist/runtime/legna-runtime.js +16 -0
- package/node_modules/@codingns/session-sync-core/dist/runtime/legna-runtime.js.map +1 -0
- package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js +196 -15
- package/node_modules/@codingns/session-sync-core/dist/runtime/opencode-runtime.js.map +1 -1
- package/node_modules/@codingns/session-sync-core/dist/runtime/types.d.ts +2 -0
- package/node_modules/@codingns/session-sync-core/dist/types.d.ts +1 -1
- package/node_modules/@codingns/session-sync-core/dist/types.js +1 -1
- package/node_modules/@codingns/session-sync-core/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/dist/public/assets/App-DUAg5urj.css +0 -1
- package/dist/public/assets/ConversationPage-Bz0_tvvM.js +0 -2
- package/dist/public/assets/DesktopWindowPage-BBmHyRg5.js +0 -2
- package/dist/public/assets/FileContextPanel--FVTxDrq.js +0 -1
- package/dist/public/assets/GitSidebar-DAiSi9oc.js +0 -6
- package/dist/public/assets/MobileCreateSessionSheet-DqVwz_Hp.js +0 -1
- package/dist/public/assets/MobileSheet-D1lMrcvD.js +0 -1
- package/dist/public/assets/MobileWorkspaceSwitcherHeader-DJPV9ym2.js +0 -1
- package/dist/public/assets/RelayConnectEntryPage-dSwU8VzK.js +0 -1
- package/dist/public/assets/ServerSettingsModal-B34ms3ze.js +0 -1
- package/dist/public/assets/SessionIndexPage-D3tG1gmM.js +0 -1
- package/dist/public/assets/SettingsPage-B3-6-5GL.js +0 -1
- package/dist/public/assets/TerminalManagerPanel-DhuTEdzV.js +0 -1
- package/dist/public/assets/TerminalRuntimeFallbackModal-CNzOt5v5.js +0 -1
- package/dist/public/assets/ToolFilesPage-BX9QDi9Y.js +0 -1
- package/dist/public/assets/ToolGitPage-4VtFox3p.js +0 -1
- package/dist/public/assets/ToolProcessesPage-DZJC6Qnt.js +0 -1
- package/dist/public/assets/ToolsHomePage-D7JbrAWv.js +0 -1
- package/dist/public/assets/WorkbenchLandingPage-C0yqnzqh.js +0 -1
- package/dist/public/assets/WorkbenchLayout-Brlj8K3i.js +0 -3
- package/dist/public/assets/WorkbenchShellRoute-BMcnFadA.css +0 -1
- package/dist/public/assets/WorkbenchShellRoute-puGpdDFY.js +0 -1
- package/dist/public/assets/WorkspaceDebugDetailPage-fTGweC9N.js +0 -1
- package/dist/public/assets/WorkspaceDetailPage-BtaIzSDB.js +0 -1
- package/dist/public/assets/WorkspaceHomePage-CUmmYDrM.js +0 -1
- package/dist/public/assets/client-runtime-manager-RHFa_iWo.js +0 -1
- package/dist/public/assets/default-session-permission-mode-Cu5SreTG.js +0 -1
- package/dist/public/assets/index-Cq3ue0za.css +0 -1
- package/dist/public/assets/index-DEbFT-Aq.js +0 -42
- package/dist/public/assets/session-runtime-machine-Bfnxkk9B.js +0 -17
- package/dist/public/assets/useRegisteredDebugTemplates-CDfl54Wt.js +0 -1
- package/dist/public/assets/window-BWqRixxq.js +0 -1
- /package/dist/public/assets/{styles-CSUx5LGe.js → styles-DRVvx_kv.js} +0 -0
|
@@ -12,6 +12,7 @@ import { buildApplyPatchFromFileChangeList, extractApplyPatchTargetPathsFromTool
|
|
|
12
12
|
import { loadDatabaseSync } from "../sqlite/node-sqlite.js";
|
|
13
13
|
import { createCodexThreadPermissionOptions } from "./codex-permissions.js";
|
|
14
14
|
const CODEX_RUNTIME_DEBUG_ENABLED = /^(1|true|yes)$/i.test(process.env.CODINGNS_PERF_DEBUG?.trim() ?? "");
|
|
15
|
+
const CODEX_APP_SERVER_REQUEST_TIMEOUT_MS = 20_000;
|
|
15
16
|
function logCodexRuntimeStep(scope, startedAtMs, detail = {}) {
|
|
16
17
|
if (!CODEX_RUNTIME_DEBUG_ENABLED) {
|
|
17
18
|
return;
|
|
@@ -59,110 +60,121 @@ export class CodexRuntimeAdapter {
|
|
|
59
60
|
const launchedAtMs = Date.now();
|
|
60
61
|
const launchPerfStartedAtMs = performance.now();
|
|
61
62
|
const transport = this.options.transportFactory
|
|
62
|
-
? this.options.transportFactory()
|
|
63
|
-
: createCodexAppServerTransport(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
providerSessionId,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
63
|
+
? this.options.transportFactory(request)
|
|
64
|
+
: createCodexAppServerTransport({
|
|
65
|
+
...this.options,
|
|
66
|
+
homeDir: request.runtimeHomeDir?.trim() || this.options.homeDir,
|
|
67
|
+
runtimeEnv: request.runtimeEnv ?? this.options.runtimeEnv ?? null
|
|
68
|
+
});
|
|
69
|
+
try {
|
|
70
|
+
const initializeStartedAtMs = performance.now();
|
|
71
|
+
await transport.initialize();
|
|
72
|
+
logCodexRuntimeStep("start_session.initialize", initializeStartedAtMs, {
|
|
73
|
+
sessionId: request.sessionId,
|
|
74
|
+
workspacePath: request.workspacePath
|
|
75
|
+
});
|
|
76
|
+
const abortController = new AbortController();
|
|
77
|
+
const eventQueue = createAsyncEventQueue();
|
|
78
|
+
const translateNotification = createCodexAppServerNotificationTranslator();
|
|
79
|
+
const forwardTranslatedNotification = createCodexTranslatedNotificationForwarder(eventQueue);
|
|
80
|
+
const resumedSyntheticSession = await this.resumeSyntheticThreadFromHistory(transport, request);
|
|
81
|
+
const startedSession = resumedSyntheticSession ??
|
|
82
|
+
await (async () => {
|
|
83
|
+
const startThreadStartedAtMs = performance.now();
|
|
84
|
+
const started = await transport.startThread(request);
|
|
85
|
+
logCodexRuntimeStep("start_session.thread_start", startThreadStartedAtMs, {
|
|
86
|
+
sessionId: request.sessionId,
|
|
87
|
+
providerSessionId: started.providerSessionId
|
|
88
|
+
});
|
|
89
|
+
return started;
|
|
90
|
+
})();
|
|
91
|
+
const providerSessionId = startedSession.providerSessionId;
|
|
92
|
+
const syntheticRawStoreRef = buildRuntimeRawStoreRef(resolveRuntimeStoreKey(providerSessionId, request.sessionId));
|
|
93
|
+
const rawStoreRef = pickAvailableCodexRawStoreRef(providerSessionId, resumedSyntheticSession
|
|
94
|
+
? [resumedSyntheticSession.rawStoreRef]
|
|
95
|
+
: [startedSession.rawStoreRef, request.rawStoreRef], syntheticRawStoreRef);
|
|
96
|
+
logCodexRuntimeStep("start_session.raw_store_ref_ready", launchPerfStartedAtMs, {
|
|
97
|
+
sessionId: request.sessionId,
|
|
98
|
+
providerSessionId,
|
|
99
|
+
synthetic: isSyntheticRawStoreRef(rawStoreRef),
|
|
100
|
+
hasProviderRawStoreRef: Boolean(startedSession.rawStoreRef),
|
|
101
|
+
providerRawStoreRefExists: Boolean(startedSession.rawStoreRef && existsSync(startedSession.rawStoreRef))
|
|
102
|
+
});
|
|
103
|
+
sink.updateSessionBinding({
|
|
104
|
+
providerSessionId,
|
|
105
|
+
rawStoreRef
|
|
106
|
+
});
|
|
107
|
+
let firstNotificationLogged = false;
|
|
108
|
+
transport.setNotificationHandler(async (notification) => {
|
|
109
|
+
if (!firstNotificationLogged) {
|
|
110
|
+
firstNotificationLogged = true;
|
|
111
|
+
logCodexRuntimeStep("start_session.first_notification", launchPerfStartedAtMs, {
|
|
112
|
+
sessionId: request.sessionId,
|
|
113
|
+
providerSessionId,
|
|
114
|
+
method: ensureText(notification.method).trim() || null
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
const translated = translateNotification(notification);
|
|
118
|
+
forwardTranslatedNotification(translated);
|
|
119
|
+
});
|
|
120
|
+
transport.setServerRequestHandler(async (serverRequest) => {
|
|
121
|
+
if (!this.options.handleServerRequest) {
|
|
122
|
+
throw new Error("CODEX_APP_SERVER_REQUEST_NOT_SUPPORTED");
|
|
123
|
+
}
|
|
124
|
+
return this.options.handleServerRequest({
|
|
105
125
|
sessionId: request.sessionId,
|
|
106
126
|
providerSessionId,
|
|
107
|
-
|
|
127
|
+
request: serverRequest
|
|
108
128
|
});
|
|
129
|
+
});
|
|
130
|
+
transport.setOnClose((error) => {
|
|
131
|
+
if (error) {
|
|
132
|
+
eventQueue.push({
|
|
133
|
+
type: "turn.failed",
|
|
134
|
+
timestamp: nextTimestamp(),
|
|
135
|
+
error: error.message
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
eventQueue.close();
|
|
139
|
+
});
|
|
140
|
+
const startTurnStartedAtMs = performance.now();
|
|
141
|
+
const startTurnResult = await transport.startTurn(request, providerSessionId);
|
|
142
|
+
const startTurnNotification = startTurnResult?.notification ?? null;
|
|
143
|
+
if (startTurnNotification) {
|
|
144
|
+
const translated = translateNotification(startTurnNotification);
|
|
145
|
+
forwardTranslatedNotification(translated);
|
|
109
146
|
}
|
|
110
|
-
|
|
111
|
-
forwardTranslatedNotification(translated);
|
|
112
|
-
});
|
|
113
|
-
transport.setServerRequestHandler(async (serverRequest) => {
|
|
114
|
-
if (!this.options.handleServerRequest) {
|
|
115
|
-
throw new Error("CODEX_APP_SERVER_REQUEST_NOT_SUPPORTED");
|
|
116
|
-
}
|
|
117
|
-
return this.options.handleServerRequest({
|
|
147
|
+
logCodexRuntimeStep("start_session.turn_start", startTurnStartedAtMs, {
|
|
118
148
|
sessionId: request.sessionId,
|
|
119
|
-
providerSessionId
|
|
120
|
-
request: serverRequest
|
|
149
|
+
providerSessionId
|
|
121
150
|
});
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
providerSessionId,
|
|
150
|
-
rawStoreRef,
|
|
151
|
-
submitDuringRun: async (options) => {
|
|
152
|
-
await transport.steerTurn(options);
|
|
153
|
-
},
|
|
154
|
-
interrupt: async () => {
|
|
155
|
-
abortController.abort();
|
|
156
|
-
await transport.interruptTurn().catch(() => {
|
|
157
|
-
return;
|
|
158
|
-
});
|
|
159
|
-
transport.close();
|
|
160
|
-
},
|
|
161
|
-
isAlive: () => transport.isClosed() === false,
|
|
162
|
-
completed: this.runTurn(null, request, sink, providerSessionId, rawStoreRef, abortController, eventQueue.iterator, [], launchedAtMs, launchPerfStartedAtMs).finally(() => {
|
|
163
|
-
transport.close();
|
|
164
|
-
})
|
|
165
|
-
};
|
|
151
|
+
logCodexRuntimeStep("start_session.ready", launchPerfStartedAtMs, {
|
|
152
|
+
sessionId: request.sessionId,
|
|
153
|
+
providerSessionId
|
|
154
|
+
});
|
|
155
|
+
return {
|
|
156
|
+
providerSessionId,
|
|
157
|
+
rawStoreRef,
|
|
158
|
+
submitDuringRun: async (options) => {
|
|
159
|
+
await transport.steerTurn(options);
|
|
160
|
+
},
|
|
161
|
+
interrupt: async () => {
|
|
162
|
+
abortController.abort();
|
|
163
|
+
await transport.interruptTurn().catch(() => {
|
|
164
|
+
return;
|
|
165
|
+
});
|
|
166
|
+
transport.close();
|
|
167
|
+
},
|
|
168
|
+
isAlive: () => transport.isClosed() === false,
|
|
169
|
+
completed: this.runTurn(null, request, sink, providerSessionId, rawStoreRef, abortController, eventQueue.iterator, [], launchedAtMs, launchPerfStartedAtMs).finally(() => {
|
|
170
|
+
transport.close();
|
|
171
|
+
})
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
transport.close();
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
166
178
|
}
|
|
167
179
|
async resumeSyntheticThreadFromHistory(transport, request) {
|
|
168
180
|
const history = buildSyntheticResumeHistory(request.rawStoreRef);
|
|
@@ -189,139 +201,151 @@ export class CodexRuntimeAdapter {
|
|
|
189
201
|
throw new Error("PROVIDER_SESSION_ID_REQUIRED");
|
|
190
202
|
}
|
|
191
203
|
const transport = this.options.transportFactory
|
|
192
|
-
? this.options.transportFactory()
|
|
193
|
-
: createCodexAppServerTransport(
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
logCodexRuntimeStep("continue_session.initialize", initializeStartedAtMs, {
|
|
198
|
-
sessionId: request.sessionId,
|
|
199
|
-
providerSessionId
|
|
200
|
-
});
|
|
201
|
-
const syntheticRawStoreRef = buildRuntimeRawStoreRef(providerSessionId);
|
|
202
|
-
let resolvedSessionId = providerSessionId;
|
|
203
|
-
let resolvedFallbackHistoryRawStoreRef = null;
|
|
204
|
-
const resumeThreadStartedAtMs = performance.now();
|
|
205
|
-
let resumed;
|
|
206
|
-
try {
|
|
207
|
-
resumed = await transport.resumeThread(request, resolvedSessionId);
|
|
208
|
-
logCodexRuntimeStep("continue_session.thread_resume", resumeThreadStartedAtMs, {
|
|
209
|
-
sessionId: request.sessionId,
|
|
210
|
-
providerSessionId: resolvedSessionId,
|
|
211
|
-
fallback: false
|
|
204
|
+
? this.options.transportFactory(request)
|
|
205
|
+
: createCodexAppServerTransport({
|
|
206
|
+
...this.options,
|
|
207
|
+
homeDir: request.runtimeHomeDir?.trim() || this.options.homeDir,
|
|
208
|
+
runtimeEnv: request.runtimeEnv ?? this.options.runtimeEnv ?? null
|
|
212
209
|
});
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
workspacePath: request.workspacePath
|
|
219
|
-
});
|
|
220
|
-
const resumeHistory = fallbackHistorySource?.history ?? [];
|
|
221
|
-
if (!shouldFallbackCodexContinueFromHistory(error, resumeHistory)) {
|
|
222
|
-
throw error;
|
|
223
|
-
}
|
|
224
|
-
resolvedFallbackHistoryRawStoreRef = fallbackHistorySource?.rawStoreRef ?? null;
|
|
225
|
-
const resumeFallbackStartedAtMs = performance.now();
|
|
226
|
-
resumed = await transport.resumeThreadFromHistory({
|
|
227
|
-
providerSessionId: null,
|
|
228
|
-
workspacePath: request.workspacePath,
|
|
229
|
-
history: resumeHistory,
|
|
230
|
-
model: request.options.model
|
|
231
|
-
});
|
|
232
|
-
resolvedSessionId = resumed.providerSessionId;
|
|
233
|
-
logCodexRuntimeStep("continue_session.thread_resume_from_history_fallback", resumeFallbackStartedAtMs, {
|
|
210
|
+
try {
|
|
211
|
+
const runtimeStartedAtMs = performance.now();
|
|
212
|
+
const initializeStartedAtMs = performance.now();
|
|
213
|
+
await transport.initialize();
|
|
214
|
+
logCodexRuntimeStep("continue_session.initialize", initializeStartedAtMs, {
|
|
234
215
|
sessionId: request.sessionId,
|
|
235
|
-
|
|
236
|
-
providerSessionId: resolvedSessionId,
|
|
237
|
-
historyLength: resumeHistory.length
|
|
216
|
+
providerSessionId
|
|
238
217
|
});
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
logCodexRuntimeStep("continue_session.raw_store_ref_ready", runtimeStartedAtMs, {
|
|
248
|
-
sessionId: request.sessionId,
|
|
249
|
-
providerSessionId: resolvedSessionId,
|
|
250
|
-
synthetic: isSyntheticRawStoreRef(rawStoreRef),
|
|
251
|
-
hasResumedRawStoreRef: Boolean(resumed.rawStoreRef),
|
|
252
|
-
hasRequestRawStoreRef: Boolean(request.rawStoreRef),
|
|
253
|
-
resumedRawStoreRefExists: Boolean(resumed.rawStoreRef && existsSync(resumed.rawStoreRef))
|
|
254
|
-
});
|
|
255
|
-
sink.updateSessionBinding({
|
|
256
|
-
providerSessionId: resolvedSessionId,
|
|
257
|
-
rawStoreRef
|
|
258
|
-
});
|
|
259
|
-
let firstNotificationLogged = false;
|
|
260
|
-
transport.setNotificationHandler(async (notification) => {
|
|
261
|
-
if (!firstNotificationLogged) {
|
|
262
|
-
firstNotificationLogged = true;
|
|
263
|
-
logCodexRuntimeStep("continue_session.first_notification", runtimeStartedAtMs, {
|
|
218
|
+
const syntheticRawStoreRef = buildRuntimeRawStoreRef(providerSessionId);
|
|
219
|
+
let resolvedSessionId = providerSessionId;
|
|
220
|
+
let resolvedFallbackHistoryRawStoreRef = null;
|
|
221
|
+
const resumeThreadStartedAtMs = performance.now();
|
|
222
|
+
let resumed;
|
|
223
|
+
try {
|
|
224
|
+
resumed = await transport.resumeThread(request, resolvedSessionId);
|
|
225
|
+
logCodexRuntimeStep("continue_session.thread_resume", resumeThreadStartedAtMs, {
|
|
264
226
|
sessionId: request.sessionId,
|
|
265
227
|
providerSessionId: resolvedSessionId,
|
|
266
|
-
|
|
228
|
+
fallback: false
|
|
267
229
|
});
|
|
268
230
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
231
|
+
catch (error) {
|
|
232
|
+
const fallbackHistorySource = await this.resolveContinueFallbackHistorySource({
|
|
233
|
+
providerSessionId,
|
|
234
|
+
rawStoreRef: request.rawStoreRef,
|
|
235
|
+
workspacePath: request.workspacePath,
|
|
236
|
+
homeDir: request.runtimeHomeDir?.trim() || this.options.homeDir?.trim() || null
|
|
237
|
+
});
|
|
238
|
+
const resumeHistory = fallbackHistorySource?.history ?? [];
|
|
239
|
+
if (!shouldFallbackCodexContinueFromHistory(error, resumeHistory)) {
|
|
240
|
+
throw error;
|
|
241
|
+
}
|
|
242
|
+
resolvedFallbackHistoryRawStoreRef = fallbackHistorySource?.rawStoreRef ?? null;
|
|
243
|
+
const resumeFallbackStartedAtMs = performance.now();
|
|
244
|
+
resumed = await transport.resumeThreadFromHistory({
|
|
245
|
+
providerSessionId: null,
|
|
246
|
+
workspacePath: request.workspacePath,
|
|
247
|
+
history: resumeHistory,
|
|
248
|
+
model: request.options.model
|
|
249
|
+
});
|
|
250
|
+
resolvedSessionId = resumed.providerSessionId;
|
|
251
|
+
logCodexRuntimeStep("continue_session.thread_resume_from_history_fallback", resumeFallbackStartedAtMs, {
|
|
252
|
+
sessionId: request.sessionId,
|
|
253
|
+
requestedProviderSessionId: providerSessionId,
|
|
254
|
+
providerSessionId: resolvedSessionId,
|
|
255
|
+
historyLength: resumeHistory.length
|
|
256
|
+
});
|
|
275
257
|
}
|
|
276
|
-
|
|
258
|
+
const pickedRawStoreRef = pickAvailableCodexRawStoreRef(resolvedSessionId, [resolvedFallbackHistoryRawStoreRef, request.rawStoreRef, resumed.rawStoreRef], syntheticRawStoreRef);
|
|
259
|
+
const rawStoreRef = !resumed.rawStoreRef?.trim() && resolvedFallbackHistoryRawStoreRef
|
|
260
|
+
? resolvedFallbackHistoryRawStoreRef
|
|
261
|
+
: pickedRawStoreRef;
|
|
262
|
+
const abortController = new AbortController();
|
|
263
|
+
const eventQueue = createAsyncEventQueue();
|
|
264
|
+
const translateNotification = createCodexAppServerNotificationTranslator();
|
|
265
|
+
const forwardTranslatedNotification = createCodexTranslatedNotificationForwarder(eventQueue);
|
|
266
|
+
logCodexRuntimeStep("continue_session.raw_store_ref_ready", runtimeStartedAtMs, {
|
|
277
267
|
sessionId: request.sessionId,
|
|
278
268
|
providerSessionId: resolvedSessionId,
|
|
279
|
-
|
|
269
|
+
synthetic: isSyntheticRawStoreRef(rawStoreRef),
|
|
270
|
+
hasResumedRawStoreRef: Boolean(resumed.rawStoreRef),
|
|
271
|
+
hasRequestRawStoreRef: Boolean(request.rawStoreRef),
|
|
272
|
+
resumedRawStoreRefExists: Boolean(resumed.rawStoreRef && existsSync(resumed.rawStoreRef))
|
|
280
273
|
});
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
274
|
+
sink.updateSessionBinding({
|
|
275
|
+
providerSessionId: resolvedSessionId,
|
|
276
|
+
rawStoreRef
|
|
277
|
+
});
|
|
278
|
+
let firstNotificationLogged = false;
|
|
279
|
+
transport.setNotificationHandler(async (notification) => {
|
|
280
|
+
if (!firstNotificationLogged) {
|
|
281
|
+
firstNotificationLogged = true;
|
|
282
|
+
logCodexRuntimeStep("continue_session.first_notification", runtimeStartedAtMs, {
|
|
283
|
+
sessionId: request.sessionId,
|
|
284
|
+
providerSessionId: resolvedSessionId,
|
|
285
|
+
method: ensureText(notification.method).trim() || null
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
const translated = translateNotification(notification);
|
|
289
|
+
forwardTranslatedNotification(translated);
|
|
290
|
+
});
|
|
291
|
+
transport.setServerRequestHandler(async (serverRequest) => {
|
|
292
|
+
if (!this.options.handleServerRequest) {
|
|
293
|
+
throw new Error("CODEX_APP_SERVER_REQUEST_NOT_SUPPORTED");
|
|
294
|
+
}
|
|
295
|
+
return this.options.handleServerRequest({
|
|
296
|
+
sessionId: request.sessionId,
|
|
297
|
+
providerSessionId: resolvedSessionId,
|
|
298
|
+
request: serverRequest
|
|
288
299
|
});
|
|
300
|
+
});
|
|
301
|
+
transport.setOnClose((error) => {
|
|
302
|
+
if (error) {
|
|
303
|
+
eventQueue.push({
|
|
304
|
+
type: "turn.failed",
|
|
305
|
+
timestamp: nextTimestamp(),
|
|
306
|
+
error: error.message
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
eventQueue.close();
|
|
310
|
+
});
|
|
311
|
+
const startTurnStartedAtMs = performance.now();
|
|
312
|
+
const startTurnResult = await transport.startTurn(request, resolvedSessionId);
|
|
313
|
+
const startTurnNotification = startTurnResult?.notification ?? null;
|
|
314
|
+
if (startTurnNotification) {
|
|
315
|
+
const translated = translateNotification(startTurnNotification);
|
|
316
|
+
forwardTranslatedNotification(translated);
|
|
289
317
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
completed: this.runTurn(null, request, sink, resolvedSessionId, rawStoreRef, abortController, eventQueue.iterator, [], Date.now()).finally(() => {
|
|
322
|
-
transport.close();
|
|
323
|
-
})
|
|
324
|
-
};
|
|
318
|
+
logCodexRuntimeStep("continue_session.turn_start", startTurnStartedAtMs, {
|
|
319
|
+
sessionId: request.sessionId,
|
|
320
|
+
providerSessionId: resolvedSessionId
|
|
321
|
+
});
|
|
322
|
+
logCodexRuntimeStep("continue_session.ready", runtimeStartedAtMs, {
|
|
323
|
+
sessionId: request.sessionId,
|
|
324
|
+
providerSessionId: resolvedSessionId
|
|
325
|
+
});
|
|
326
|
+
return {
|
|
327
|
+
providerSessionId: resolvedSessionId,
|
|
328
|
+
rawStoreRef,
|
|
329
|
+
submitDuringRun: async (options) => {
|
|
330
|
+
await transport.steerTurn(options);
|
|
331
|
+
},
|
|
332
|
+
interrupt: async () => {
|
|
333
|
+
abortController.abort();
|
|
334
|
+
await transport.interruptTurn().catch(() => {
|
|
335
|
+
return;
|
|
336
|
+
});
|
|
337
|
+
transport.close();
|
|
338
|
+
},
|
|
339
|
+
isAlive: () => transport.isClosed() === false,
|
|
340
|
+
completed: this.runTurn(null, request, sink, resolvedSessionId, rawStoreRef, abortController, eventQueue.iterator, [], Date.now()).finally(() => {
|
|
341
|
+
transport.close();
|
|
342
|
+
})
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
transport.close();
|
|
347
|
+
throw error;
|
|
348
|
+
}
|
|
325
349
|
}
|
|
326
350
|
async resolveContinueFallbackHistorySource(input) {
|
|
327
351
|
const candidates = [];
|
|
@@ -337,7 +361,7 @@ export class CodexRuntimeAdapter {
|
|
|
337
361
|
pushCandidate(input.rawStoreRef);
|
|
338
362
|
// 旧会话的 binding 可能只剩 synthetic stream,或者已经指到了父线程 transcript。
|
|
339
363
|
// 继续会话失败时,额外按真实 thread id 扫一次本地 transcript,尽量把历史恢复链路救回来。
|
|
340
|
-
pushCandidate(await this.resolveRealRawStoreRef(input.providerSessionId.trim(), input.workspacePath));
|
|
364
|
+
pushCandidate(await this.resolveRealRawStoreRef(input.providerSessionId.trim(), input.workspacePath, input.homeDir));
|
|
341
365
|
let fallbackMatch = null;
|
|
342
366
|
for (const candidate of candidates) {
|
|
343
367
|
const history = buildCodexResumeHistoryFromRawStore(candidate);
|
|
@@ -371,6 +395,7 @@ export class CodexRuntimeAdapter {
|
|
|
371
395
|
sink,
|
|
372
396
|
workspacePath: request.workspacePath,
|
|
373
397
|
firstUserMessage: request.options.content,
|
|
398
|
+
homeDir: request.runtimeHomeDir?.trim() || this.options.homeDir?.trim() || null,
|
|
374
399
|
launchedAtMs,
|
|
375
400
|
launchPerfStartedAtMs
|
|
376
401
|
};
|
|
@@ -613,8 +638,8 @@ export class CodexRuntimeAdapter {
|
|
|
613
638
|
if (!isSyntheticRawStoreRef(context.rawStoreRef)) {
|
|
614
639
|
return;
|
|
615
640
|
}
|
|
616
|
-
const resolved = await this.resolveLaunchedSessionBinding(context.workspacePath, context.firstUserMessage, context.launchedAtMs) ??
|
|
617
|
-
await this.resolveExistingSessionBinding(context.providerSessionId, context.rawStoreRef, context.workspacePath);
|
|
641
|
+
const resolved = await this.resolveLaunchedSessionBinding(context.workspacePath, context.firstUserMessage, context.launchedAtMs, context.homeDir) ??
|
|
642
|
+
await this.resolveExistingSessionBinding(context.providerSessionId, context.rawStoreRef, context.workspacePath, context.homeDir);
|
|
618
643
|
if (!resolved ||
|
|
619
644
|
(resolved.providerSessionId === context.providerSessionId &&
|
|
620
645
|
resolved.rawStoreRef === context.rawStoreRef)) {
|
|
@@ -627,7 +652,7 @@ export class CodexRuntimeAdapter {
|
|
|
627
652
|
rawStoreRef: resolved.rawStoreRef
|
|
628
653
|
});
|
|
629
654
|
}
|
|
630
|
-
async resolveExistingSessionBinding(providerSessionId, rawStoreRef, workspacePath) {
|
|
655
|
+
async resolveExistingSessionBinding(providerSessionId, rawStoreRef, workspacePath, homeDirOverride = null) {
|
|
631
656
|
const normalizedProviderSessionId = providerSessionId.trim();
|
|
632
657
|
const meta = readSessionMeta(rawStoreRef);
|
|
633
658
|
if (meta && meta.threadId === normalizedProviderSessionId && existsSync(rawStoreRef)) {
|
|
@@ -639,7 +664,7 @@ export class CodexRuntimeAdapter {
|
|
|
639
664
|
if (!normalizedProviderSessionId) {
|
|
640
665
|
return null;
|
|
641
666
|
}
|
|
642
|
-
const resolvedRawStoreRef = await this.resolveRealRawStoreRef(normalizedProviderSessionId, workspacePath);
|
|
667
|
+
const resolvedRawStoreRef = await this.resolveRealRawStoreRef(normalizedProviderSessionId, workspacePath, homeDirOverride);
|
|
643
668
|
if (!resolvedRawStoreRef) {
|
|
644
669
|
return null;
|
|
645
670
|
}
|
|
@@ -648,9 +673,9 @@ export class CodexRuntimeAdapter {
|
|
|
648
673
|
rawStoreRef: resolvedRawStoreRef
|
|
649
674
|
};
|
|
650
675
|
}
|
|
651
|
-
async resolveLaunchedSessionBinding(workspacePath, firstUserMessage, launchedAtMs) {
|
|
676
|
+
async resolveLaunchedSessionBinding(workspacePath, firstUserMessage, launchedAtMs, homeDirOverride = null) {
|
|
652
677
|
for (let attempt = 0; attempt < 20; attempt += 1) {
|
|
653
|
-
const matched = this.findLaunchedSessionBindingOnce(workspacePath, firstUserMessage, launchedAtMs);
|
|
678
|
+
const matched = this.findLaunchedSessionBindingOnce(workspacePath, firstUserMessage, launchedAtMs, homeDirOverride);
|
|
654
679
|
if (matched) {
|
|
655
680
|
return matched;
|
|
656
681
|
}
|
|
@@ -660,9 +685,9 @@ export class CodexRuntimeAdapter {
|
|
|
660
685
|
}
|
|
661
686
|
return null;
|
|
662
687
|
}
|
|
663
|
-
async resolveRealRawStoreRef(providerSessionId, workspacePath) {
|
|
688
|
+
async resolveRealRawStoreRef(providerSessionId, workspacePath, homeDirOverride = null) {
|
|
664
689
|
for (let attempt = 0; attempt < 10; attempt += 1) {
|
|
665
|
-
const matched = this.findRawStoreRefOnce(providerSessionId, workspacePath);
|
|
690
|
+
const matched = this.findRawStoreRefOnce(providerSessionId, workspacePath, homeDirOverride);
|
|
666
691
|
if (matched) {
|
|
667
692
|
return matched;
|
|
668
693
|
}
|
|
@@ -672,8 +697,11 @@ export class CodexRuntimeAdapter {
|
|
|
672
697
|
}
|
|
673
698
|
return null;
|
|
674
699
|
}
|
|
675
|
-
findRawStoreRefOnce(providerSessionId, workspacePath) {
|
|
676
|
-
const homeDir =
|
|
700
|
+
findRawStoreRefOnce(providerSessionId, workspacePath, homeDirOverride = null) {
|
|
701
|
+
const homeDir = homeDirOverride?.trim()
|
|
702
|
+
|| this.options.homeDir?.trim()
|
|
703
|
+
|| process.env.CODINGNS_CODEX_HOME
|
|
704
|
+
|| join(homedir(), ".codex");
|
|
677
705
|
const candidates = this.listSessionFiles(homeDir);
|
|
678
706
|
const normalizedWorkspace = normalizeWorkspacePath(workspacePath);
|
|
679
707
|
for (const filePath of candidates) {
|
|
@@ -714,8 +742,8 @@ export class CodexRuntimeAdapter {
|
|
|
714
742
|
}
|
|
715
743
|
return files;
|
|
716
744
|
}
|
|
717
|
-
findLaunchedSessionBindingOnce(workspacePath, firstUserMessage, launchedAtMs) {
|
|
718
|
-
const dbPath = findLatestCodexStateDatabase(this.getCodexHomeDir());
|
|
745
|
+
findLaunchedSessionBindingOnce(workspacePath, firstUserMessage, launchedAtMs, homeDirOverride = null) {
|
|
746
|
+
const dbPath = findLatestCodexStateDatabase(this.getCodexHomeDir(homeDirOverride));
|
|
719
747
|
if (!dbPath) {
|
|
720
748
|
return null;
|
|
721
749
|
}
|
|
@@ -751,8 +779,11 @@ export class CodexRuntimeAdapter {
|
|
|
751
779
|
}
|
|
752
780
|
return null;
|
|
753
781
|
}
|
|
754
|
-
getCodexHomeDir() {
|
|
755
|
-
return
|
|
782
|
+
getCodexHomeDir(homeDirOverride = null) {
|
|
783
|
+
return (homeDirOverride?.trim()
|
|
784
|
+
|| this.options.homeDir?.trim()
|
|
785
|
+
|| process.env.CODINGNS_CODEX_HOME
|
|
786
|
+
|| join(homedir(), ".codex"));
|
|
756
787
|
}
|
|
757
788
|
buildMessage(context, input) {
|
|
758
789
|
const stableRef = this.resolveStableMessageRef(context, input.stableIdentity ?? null);
|
|
@@ -830,8 +861,12 @@ export class CodexRuntimeAdapter {
|
|
|
830
861
|
function createCodexAppServerTransport(options) {
|
|
831
862
|
const commandPath = resolveCodexCommand(options.commandPath);
|
|
832
863
|
const launch = resolveCodexCommandLaunch(commandPath, ["app-server"]);
|
|
864
|
+
const runtimeEnv = options.runtimeEnv ?? null;
|
|
833
865
|
const child = spawn(launch.command, launch.args, {
|
|
834
|
-
env:
|
|
866
|
+
env: {
|
|
867
|
+
...process.env,
|
|
868
|
+
...(runtimeEnv ?? {})
|
|
869
|
+
},
|
|
835
870
|
stdio: ["pipe", "pipe", "pipe"],
|
|
836
871
|
shell: launch.shell,
|
|
837
872
|
windowsHide: true
|
|
@@ -1230,110 +1265,285 @@ function normalizeReplayKeyText(value) {
|
|
|
1230
1265
|
}
|
|
1231
1266
|
return ensureText(value).trim();
|
|
1232
1267
|
}
|
|
1233
|
-
function
|
|
1234
|
-
const
|
|
1235
|
-
const
|
|
1236
|
-
|
|
1268
|
+
function createCodexAppServerNotificationTranslator() {
|
|
1269
|
+
const agentMessageTextById = new Map();
|
|
1270
|
+
const reasoningSummaryPartsById = new Map();
|
|
1271
|
+
const reasoningContentPartsById = new Map();
|
|
1272
|
+
const resetStreamState = () => {
|
|
1273
|
+
agentMessageTextById.clear();
|
|
1274
|
+
reasoningSummaryPartsById.clear();
|
|
1275
|
+
reasoningContentPartsById.clear();
|
|
1276
|
+
};
|
|
1277
|
+
const ensureIndexedTextPart = (store, itemId, index) => {
|
|
1278
|
+
if (!itemId || !Number.isInteger(index) || index < 0) {
|
|
1279
|
+
return null;
|
|
1280
|
+
}
|
|
1281
|
+
const existing = store.get(itemId) ?? [];
|
|
1282
|
+
while (existing.length <= index) {
|
|
1283
|
+
existing.push("");
|
|
1284
|
+
}
|
|
1285
|
+
store.set(itemId, existing);
|
|
1286
|
+
return existing;
|
|
1287
|
+
};
|
|
1288
|
+
const buildReasoningSyntheticItem = (itemId) => {
|
|
1289
|
+
// 这里必须复制一份快照,不能把可变数组引用直接塞进事件队列。
|
|
1290
|
+
// 否则后续 delta 继续追加时,前一帧事件里的 summary/content 也会被同步改掉,
|
|
1291
|
+
// 最终所有帧都会看起来像“最后一帧”,下游稳定消息去重就会把中间增量吃掉。
|
|
1292
|
+
const summary = [...(reasoningSummaryPartsById.get(itemId) ?? [])];
|
|
1293
|
+
const content = [...(reasoningContentPartsById.get(itemId) ?? [])];
|
|
1237
1294
|
return {
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1295
|
+
type: "reasoning",
|
|
1296
|
+
id: itemId,
|
|
1297
|
+
summary,
|
|
1298
|
+
content
|
|
1241
1299
|
};
|
|
1242
|
-
}
|
|
1243
|
-
|
|
1244
|
-
const
|
|
1245
|
-
const
|
|
1246
|
-
|
|
1247
|
-
if (status === "failed") {
|
|
1248
|
-
return {
|
|
1249
|
-
events: [
|
|
1250
|
-
...itemEvents,
|
|
1251
|
-
{
|
|
1252
|
-
type: "turn.failed",
|
|
1253
|
-
timestamp: nextTimestamp(),
|
|
1254
|
-
error: ensureText(readProp(turn?.error, "message")).trim() || "codex turn failed"
|
|
1255
|
-
}
|
|
1256
|
-
],
|
|
1257
|
-
terminal: true,
|
|
1258
|
-
turnId: ensureText(turn?.id).trim() || null
|
|
1259
|
-
};
|
|
1260
|
-
}
|
|
1261
|
-
if (status === "interrupted") {
|
|
1300
|
+
};
|
|
1301
|
+
const translateAgentMessageDelta = (params) => {
|
|
1302
|
+
const itemId = ensureText(params.itemId).trim();
|
|
1303
|
+
const delta = ensureText(params.delta);
|
|
1304
|
+
if (!itemId || delta.length === 0) {
|
|
1262
1305
|
return {
|
|
1263
|
-
events: [
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
type: "turn.interrupted",
|
|
1267
|
-
timestamp: nextTimestamp()
|
|
1268
|
-
}
|
|
1269
|
-
],
|
|
1270
|
-
terminal: true,
|
|
1271
|
-
turnId: ensureText(turn?.id).trim() || null
|
|
1306
|
+
events: [],
|
|
1307
|
+
terminal: false,
|
|
1308
|
+
turnId: ensureText(params.turnId).trim() || null
|
|
1272
1309
|
};
|
|
1273
1310
|
}
|
|
1311
|
+
const nextText = `${agentMessageTextById.get(itemId) ?? ""}${delta}`;
|
|
1312
|
+
agentMessageTextById.set(itemId, nextText);
|
|
1274
1313
|
return {
|
|
1275
1314
|
events: [
|
|
1276
|
-
...itemEvents,
|
|
1277
1315
|
{
|
|
1278
|
-
type: "
|
|
1316
|
+
type: "item.updated",
|
|
1317
|
+
item: {
|
|
1318
|
+
type: "agent_message",
|
|
1319
|
+
id: itemId,
|
|
1320
|
+
text: nextText
|
|
1321
|
+
},
|
|
1279
1322
|
timestamp: nextTimestamp()
|
|
1280
1323
|
}
|
|
1281
1324
|
],
|
|
1282
|
-
terminal:
|
|
1283
|
-
turnId: ensureText(
|
|
1325
|
+
terminal: false,
|
|
1326
|
+
turnId: ensureText(params.turnId).trim() || null
|
|
1284
1327
|
};
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
|
-
const
|
|
1288
|
-
const
|
|
1289
|
-
|
|
1328
|
+
};
|
|
1329
|
+
const translateReasoningSummaryPartAdded = (params) => {
|
|
1330
|
+
const itemId = ensureText(params.itemId).trim();
|
|
1331
|
+
const summaryIndex = Math.trunc(Number(params.summaryIndex));
|
|
1332
|
+
ensureIndexedTextPart(reasoningSummaryPartsById, itemId, summaryIndex);
|
|
1333
|
+
return {
|
|
1334
|
+
events: [],
|
|
1335
|
+
terminal: false,
|
|
1336
|
+
turnId: ensureText(params.turnId).trim() || null
|
|
1337
|
+
};
|
|
1338
|
+
};
|
|
1339
|
+
const translateReasoningSummaryTextDelta = (params) => {
|
|
1340
|
+
const itemId = ensureText(params.itemId).trim();
|
|
1341
|
+
const summaryIndex = Math.trunc(Number(params.summaryIndex));
|
|
1342
|
+
const delta = ensureText(params.delta);
|
|
1343
|
+
const parts = ensureIndexedTextPart(reasoningSummaryPartsById, itemId, summaryIndex);
|
|
1344
|
+
if (!parts || delta.length === 0) {
|
|
1290
1345
|
return {
|
|
1291
1346
|
events: [],
|
|
1292
1347
|
terminal: false,
|
|
1293
1348
|
turnId: ensureText(params.turnId).trim() || null
|
|
1294
1349
|
};
|
|
1295
1350
|
}
|
|
1351
|
+
parts[summaryIndex] = `${parts[summaryIndex] ?? ""}${delta}`;
|
|
1296
1352
|
return {
|
|
1297
1353
|
events: [
|
|
1298
1354
|
{
|
|
1299
|
-
type: "
|
|
1300
|
-
|
|
1301
|
-
|
|
1355
|
+
type: "item.updated",
|
|
1356
|
+
item: buildReasoningSyntheticItem(itemId),
|
|
1357
|
+
timestamp: nextTimestamp()
|
|
1302
1358
|
}
|
|
1303
1359
|
],
|
|
1304
|
-
terminal:
|
|
1360
|
+
terminal: false,
|
|
1305
1361
|
turnId: ensureText(params.turnId).trim() || null
|
|
1306
1362
|
};
|
|
1307
|
-
}
|
|
1308
|
-
|
|
1309
|
-
const
|
|
1310
|
-
|
|
1363
|
+
};
|
|
1364
|
+
const translateReasoningTextDelta = (params) => {
|
|
1365
|
+
const itemId = ensureText(params.itemId).trim();
|
|
1366
|
+
const contentIndex = Math.trunc(Number(params.contentIndex));
|
|
1367
|
+
const delta = ensureText(params.delta);
|
|
1368
|
+
const parts = ensureIndexedTextPart(reasoningContentPartsById, itemId, contentIndex);
|
|
1369
|
+
if (!parts || delta.length === 0) {
|
|
1311
1370
|
return {
|
|
1312
1371
|
events: [],
|
|
1313
1372
|
terminal: false,
|
|
1314
|
-
turnId: null
|
|
1373
|
+
turnId: ensureText(params.turnId).trim() || null
|
|
1315
1374
|
};
|
|
1316
1375
|
}
|
|
1376
|
+
parts[contentIndex] = `${parts[contentIndex] ?? ""}${delta}`;
|
|
1317
1377
|
return {
|
|
1318
1378
|
events: [
|
|
1319
1379
|
{
|
|
1320
|
-
type:
|
|
1321
|
-
|
|
1322
|
-
: method === "item/updated"
|
|
1323
|
-
? "item.updated"
|
|
1324
|
-
: "item.completed",
|
|
1325
|
-
item,
|
|
1380
|
+
type: "item.updated",
|
|
1381
|
+
item: buildReasoningSyntheticItem(itemId),
|
|
1326
1382
|
timestamp: nextTimestamp()
|
|
1327
1383
|
}
|
|
1328
1384
|
],
|
|
1329
1385
|
terminal: false,
|
|
1386
|
+
turnId: ensureText(params.turnId).trim() || null
|
|
1387
|
+
};
|
|
1388
|
+
};
|
|
1389
|
+
return (notification) => {
|
|
1390
|
+
const method = ensureText(notification.method).trim();
|
|
1391
|
+
const params = toRecord(notification.params) ?? {};
|
|
1392
|
+
if (method === "turn/started") {
|
|
1393
|
+
return {
|
|
1394
|
+
events: [],
|
|
1395
|
+
terminal: false,
|
|
1396
|
+
turnId: ensureText(readProp(readProp(params, "turn"), "id")).trim() || null
|
|
1397
|
+
};
|
|
1398
|
+
}
|
|
1399
|
+
if (method === "turn/completed") {
|
|
1400
|
+
const turn = toRecord(params.turn);
|
|
1401
|
+
const status = ensureText(turn?.status).trim();
|
|
1402
|
+
const itemEvents = translateCodexAppServerTurnItems(turn, "item.completed");
|
|
1403
|
+
resetStreamState();
|
|
1404
|
+
if (status === "failed") {
|
|
1405
|
+
return {
|
|
1406
|
+
events: [
|
|
1407
|
+
...itemEvents,
|
|
1408
|
+
{
|
|
1409
|
+
type: "turn.failed",
|
|
1410
|
+
timestamp: nextTimestamp(),
|
|
1411
|
+
error: ensureText(readProp(turn?.error, "message")).trim() || "codex turn failed"
|
|
1412
|
+
}
|
|
1413
|
+
],
|
|
1414
|
+
terminal: true,
|
|
1415
|
+
turnId: ensureText(turn?.id).trim() || null
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1418
|
+
if (status === "interrupted") {
|
|
1419
|
+
return {
|
|
1420
|
+
events: [
|
|
1421
|
+
...itemEvents,
|
|
1422
|
+
{
|
|
1423
|
+
type: "turn.interrupted",
|
|
1424
|
+
timestamp: nextTimestamp()
|
|
1425
|
+
}
|
|
1426
|
+
],
|
|
1427
|
+
terminal: true,
|
|
1428
|
+
turnId: ensureText(turn?.id).trim() || null
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
return {
|
|
1432
|
+
events: [
|
|
1433
|
+
...itemEvents,
|
|
1434
|
+
{
|
|
1435
|
+
type: "turn.completed",
|
|
1436
|
+
timestamp: nextTimestamp()
|
|
1437
|
+
}
|
|
1438
|
+
],
|
|
1439
|
+
terminal: true,
|
|
1440
|
+
turnId: ensureText(turn?.id).trim() || null
|
|
1441
|
+
};
|
|
1442
|
+
}
|
|
1443
|
+
if (method === "error") {
|
|
1444
|
+
const error = toRecord(params.error);
|
|
1445
|
+
const detail = buildCodexAppServerErrorDetail(error);
|
|
1446
|
+
if (params.willRetry === true) {
|
|
1447
|
+
return {
|
|
1448
|
+
events: [],
|
|
1449
|
+
terminal: false,
|
|
1450
|
+
turnId: ensureText(params.turnId).trim() || null
|
|
1451
|
+
};
|
|
1452
|
+
}
|
|
1453
|
+
resetStreamState();
|
|
1454
|
+
return {
|
|
1455
|
+
events: [
|
|
1456
|
+
{
|
|
1457
|
+
type: "turn.failed",
|
|
1458
|
+
timestamp: nextTimestamp(),
|
|
1459
|
+
error: detail
|
|
1460
|
+
}
|
|
1461
|
+
],
|
|
1462
|
+
terminal: true,
|
|
1463
|
+
turnId: ensureText(params.turnId).trim() || null
|
|
1464
|
+
};
|
|
1465
|
+
}
|
|
1466
|
+
if (method === "item/agentMessage/delta") {
|
|
1467
|
+
return translateAgentMessageDelta(params);
|
|
1468
|
+
}
|
|
1469
|
+
if (method === "item/reasoning/summaryPartAdded") {
|
|
1470
|
+
return translateReasoningSummaryPartAdded(params);
|
|
1471
|
+
}
|
|
1472
|
+
if (method === "item/reasoning/summaryTextDelta") {
|
|
1473
|
+
return translateReasoningSummaryTextDelta(params);
|
|
1474
|
+
}
|
|
1475
|
+
if (method === "item/reasoning/textDelta") {
|
|
1476
|
+
return translateReasoningTextDelta(params);
|
|
1477
|
+
}
|
|
1478
|
+
if (method === "item/started" || method === "item/updated" || method === "item/completed") {
|
|
1479
|
+
const item = translateCodexAppServerItem(toRecord(params.item));
|
|
1480
|
+
if (!item) {
|
|
1481
|
+
return {
|
|
1482
|
+
events: [],
|
|
1483
|
+
terminal: false,
|
|
1484
|
+
turnId: null
|
|
1485
|
+
};
|
|
1486
|
+
}
|
|
1487
|
+
if (ensureText(item.type).trim() === "agent_message") {
|
|
1488
|
+
const itemId = ensureText(item.id).trim();
|
|
1489
|
+
const itemText = ensureText(item.text);
|
|
1490
|
+
if (itemId) {
|
|
1491
|
+
if (itemText.length > 0) {
|
|
1492
|
+
agentMessageTextById.set(itemId, itemText);
|
|
1493
|
+
}
|
|
1494
|
+
else if (method === "item/completed") {
|
|
1495
|
+
agentMessageTextById.delete(itemId);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
if (ensureText(item.type).trim() === "reasoning") {
|
|
1500
|
+
const itemId = ensureText(item.id).trim();
|
|
1501
|
+
if (itemId) {
|
|
1502
|
+
const summary = Array.isArray(item.summary)
|
|
1503
|
+
? item.summary.map((entry) => ensureText(entry))
|
|
1504
|
+
: ensureText(item.summary).trim()
|
|
1505
|
+
? [ensureText(item.summary)]
|
|
1506
|
+
: [];
|
|
1507
|
+
const content = Array.isArray(item.content)
|
|
1508
|
+
? item.content.map((entry) => ensureText(entry))
|
|
1509
|
+
: ensureText(item.text).trim()
|
|
1510
|
+
? [ensureText(item.text)]
|
|
1511
|
+
: [];
|
|
1512
|
+
if (summary.length > 0) {
|
|
1513
|
+
reasoningSummaryPartsById.set(itemId, summary);
|
|
1514
|
+
}
|
|
1515
|
+
else if (method === "item/completed") {
|
|
1516
|
+
reasoningSummaryPartsById.delete(itemId);
|
|
1517
|
+
}
|
|
1518
|
+
if (content.length > 0) {
|
|
1519
|
+
reasoningContentPartsById.set(itemId, content);
|
|
1520
|
+
}
|
|
1521
|
+
else if (method === "item/completed") {
|
|
1522
|
+
reasoningContentPartsById.delete(itemId);
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
return {
|
|
1527
|
+
events: [
|
|
1528
|
+
{
|
|
1529
|
+
type: method === "item/started"
|
|
1530
|
+
? "item.started"
|
|
1531
|
+
: method === "item/updated"
|
|
1532
|
+
? "item.updated"
|
|
1533
|
+
: "item.completed",
|
|
1534
|
+
item,
|
|
1535
|
+
timestamp: nextTimestamp()
|
|
1536
|
+
}
|
|
1537
|
+
],
|
|
1538
|
+
terminal: false,
|
|
1539
|
+
turnId: null
|
|
1540
|
+
};
|
|
1541
|
+
}
|
|
1542
|
+
return {
|
|
1543
|
+
events: [],
|
|
1544
|
+
terminal: false,
|
|
1330
1545
|
turnId: null
|
|
1331
1546
|
};
|
|
1332
|
-
}
|
|
1333
|
-
return {
|
|
1334
|
-
events: [],
|
|
1335
|
-
terminal: false,
|
|
1336
|
-
turnId: null
|
|
1337
1547
|
};
|
|
1338
1548
|
}
|
|
1339
1549
|
function translateCodexAppServerTurnItems(turn, eventType) {
|
|
@@ -1796,7 +2006,20 @@ function writeJsonRpcMessage(child, payload) {
|
|
|
1796
2006
|
function sendJsonRpcRequest(child, pendingResponses, createRequestId, input) {
|
|
1797
2007
|
const id = createRequestId();
|
|
1798
2008
|
return new Promise((resolve, reject) => {
|
|
1799
|
-
|
|
2009
|
+
const timeout = setTimeout(() => {
|
|
2010
|
+
pendingResponses.delete(id);
|
|
2011
|
+
reject(new Error("SERVER_TIMEOUT"));
|
|
2012
|
+
}, CODEX_APP_SERVER_REQUEST_TIMEOUT_MS);
|
|
2013
|
+
pendingResponses.set(id, {
|
|
2014
|
+
resolve: (value) => {
|
|
2015
|
+
clearTimeout(timeout);
|
|
2016
|
+
resolve(value);
|
|
2017
|
+
},
|
|
2018
|
+
reject: (error) => {
|
|
2019
|
+
clearTimeout(timeout);
|
|
2020
|
+
reject(error);
|
|
2021
|
+
}
|
|
2022
|
+
});
|
|
1800
2023
|
try {
|
|
1801
2024
|
writeJsonRpcMessage(child, {
|
|
1802
2025
|
jsonrpc: "2.0",
|
|
@@ -1806,6 +2029,7 @@ function sendJsonRpcRequest(child, pendingResponses, createRequestId, input) {
|
|
|
1806
2029
|
});
|
|
1807
2030
|
}
|
|
1808
2031
|
catch (error) {
|
|
2032
|
+
clearTimeout(timeout);
|
|
1809
2033
|
pendingResponses.delete(id);
|
|
1810
2034
|
reject(error instanceof Error ? error : new Error("CODEX_APP_SERVER_REQUEST_WRITE_FAILED"));
|
|
1811
2035
|
}
|
|
@@ -1843,7 +2067,7 @@ function shouldFallbackCodexContinueFromHistory(error, history) {
|
|
|
1843
2067
|
if (history.length === 0) {
|
|
1844
2068
|
return false;
|
|
1845
2069
|
}
|
|
1846
|
-
return isCodexThreadLoadError(error);
|
|
2070
|
+
return isCodexThreadLoadError(error) || isCodexRequestTimeoutError(error);
|
|
1847
2071
|
}
|
|
1848
2072
|
function isCodexThreadLoadError(error) {
|
|
1849
2073
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1851,6 +2075,9 @@ function isCodexThreadLoadError(error) {
|
|
|
1851
2075
|
return (normalized.includes("thread not loaded") ||
|
|
1852
2076
|
normalized.includes("no rollout found for thread id"));
|
|
1853
2077
|
}
|
|
2078
|
+
function isCodexRequestTimeoutError(error) {
|
|
2079
|
+
return error instanceof Error && error.message === "SERVER_TIMEOUT";
|
|
2080
|
+
}
|
|
1854
2081
|
function readProp(value, key) {
|
|
1855
2082
|
if (!value || typeof value !== "object") {
|
|
1856
2083
|
return null;
|