@jingyi0605/codingns 0.6.0 → 0.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/codingns.mjs +240 -2
- package/dist/public/assets/AdaptiveButlerPage-CfsUVZKl.js +3 -0
- package/dist/public/assets/{App-BZvapsi8.js → App-B9HcTkMT.js} +3 -3
- package/dist/public/assets/{BootstrapPage-gHSoa4JN.js → BootstrapPage-BgLdZEKQ.js} +1 -1
- package/dist/public/assets/ConversationPage-Cj8go7L0.js +4 -0
- package/dist/public/assets/{DesktopDetachPreviewPage-4eMRxiBW.js → DesktopDetachPreviewPage-YCBnyC58.js} +1 -1
- package/dist/public/assets/DesktopWindowPage-CrvndE23.js +2 -0
- package/dist/public/assets/FileContextPanel-CdC7GGw5.js +1 -0
- package/dist/public/assets/GitSidebar-z2SBinQh.js +6 -0
- package/dist/public/assets/MobileCreateSessionSheet-Cb2HM-y3.js +1 -0
- package/dist/public/assets/{MobileTopHeaderFrame-Bwv8Ovm_.js → MobileTopHeaderFrame-etF2HKlm.js} +1 -1
- package/dist/public/assets/MobileWorkspaceSwitcherHeader-CuGJ31kb.js +1 -0
- package/dist/public/assets/{RelayConnectEntryPage-D_4YL-YH.js → RelayConnectEntryPage-BB6DbGtP.js} +1 -1
- package/dist/public/assets/{ServerSettingsModal-CMSm3BZU.js → ServerSettingsModal-Bl1sacZg.js} +1 -1
- package/dist/public/assets/SessionIndexPage-NbF9gJnp.js +1 -0
- package/dist/public/assets/SettingsPage-DGsmQpLv.js +1 -0
- package/dist/public/assets/TerminalManagerPanel-BOm8Hi_v.js +1 -0
- package/dist/public/assets/{TerminalPage-DaooFaJ4.js → TerminalPage-B5JNFU6w.js} +19 -19
- package/dist/public/assets/TerminalRuntimeFallbackModal-CM3LRKOJ.js +1 -0
- package/dist/public/assets/{ToolFilesPage-CGxBvYG0.js → ToolFilesPage-GSqKQsj_.js} +1 -1
- package/dist/public/assets/ToolGitPage-BVFWMMQp.js +1 -0
- package/dist/public/assets/ToolProcessesPage-DZ456fYz.js +1 -0
- package/dist/public/assets/ToolsHomePage-DsJp0y8A.js +1 -0
- package/dist/public/assets/WorkbenchLandingPage-DyPei0e-.js +1 -0
- package/dist/public/assets/WorkbenchLayout-DlbgBT3n.js +4 -0
- package/dist/public/assets/WorkbenchModal-LNfB69qx.js +1 -0
- package/dist/public/assets/WorkbenchShellRoute-BsxumYx5.js +1 -0
- package/dist/public/assets/WorkbenchShellRoute-DhQo_0vu.css +1 -0
- package/dist/public/assets/WorkspaceDebugDetailPage-CaXj5zVI.js +1 -0
- package/dist/public/assets/WorkspaceDetailPage-DOexuuaw.js +1 -0
- package/dist/public/assets/WorkspaceHomePage-DkCHNjKD.js +1 -0
- package/dist/public/assets/{client-runtime-manager-BZpL17fc.js → client-runtime-manager-6OoYHXGd.js} +1 -1
- package/dist/public/assets/{file-tree-icon-Db5LXC8h.js → file-tree-icon-9pt1OStn.js} +1 -1
- package/dist/public/assets/index-BwlbvwaA.css +1 -0
- package/dist/public/assets/index-DSw-TkQL.js +42 -0
- package/dist/public/assets/legna-code-6TqgZ4Ls.png +0 -0
- package/dist/public/assets/{login-direct-candidate-resolver-1mxe_Oh8.js → login-direct-candidate-resolver-CLlYtBRq.js} +1 -1
- package/dist/public/assets/model-switch-api-C-l8-E1S.js +1 -0
- package/dist/public/assets/{preferences-service-DWnzl5a0.js → preferences-service-BCcfYP_d.js} +1 -1
- package/dist/public/assets/{relay-entry-C5_Iay0I.js → relay-entry-BmLkMKuq.js} +1 -1
- package/dist/public/assets/session-runtime-machine-DgtvREca.js +21 -0
- package/dist/public/assets/{terminal-runtime-meta-cdtWVfCm.js → terminal-runtime-meta-0h-75uRy.js} +1 -1
- package/dist/public/assets/useRegisteredDebugTemplates-rBVmAqh3.js +1 -0
- package/dist/public/index.html +2 -2
- package/dist/server/config/env.d.ts +2 -0
- package/dist/server/config/env.js +7 -0
- package/dist/server/config/env.js.map +1 -1
- package/dist/server/modules/assistant-capability/assistant-capability-service.d.ts +4 -1
- package/dist/server/modules/assistant-capability/assistant-capability-service.js +12 -1
- package/dist/server/modules/assistant-capability/assistant-capability-service.js.map +1 -1
- package/dist/server/modules/butler/butler-control-session-service.d.ts +4 -1
- package/dist/server/modules/butler/butler-control-session-service.js +17 -1
- package/dist/server/modules/butler/butler-control-session-service.js.map +1 -1
- package/dist/server/modules/butler/butler-profile-service.d.ts +3 -1
- package/dist/server/modules/butler/butler-profile-service.js +16 -4
- package/dist/server/modules/butler/butler-profile-service.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/opencli/opencli-bridge-skill-service.d.ts +12 -0
- package/dist/server/modules/opencli/opencli-bridge-skill-service.js +124 -0
- package/dist/server/modules/opencli/opencli-bridge-skill-service.js.map +1 -0
- package/dist/server/modules/opencli/opencli-catalog-service.d.ts +50 -0
- package/dist/server/modules/opencli/opencli-catalog-service.js +345 -0
- package/dist/server/modules/opencli/opencli-catalog-service.js.map +1 -0
- package/dist/server/modules/opencli/opencli-controller.d.ts +13 -0
- package/dist/server/modules/opencli/opencli-controller.js +30 -0
- package/dist/server/modules/opencli/opencli-controller.js.map +1 -0
- package/dist/server/modules/opencli/opencli-health-service.d.ts +28 -0
- package/dist/server/modules/opencli/opencli-health-service.js +106 -0
- package/dist/server/modules/opencli/opencli-health-service.js.map +1 -0
- package/dist/server/modules/opencli/opencli-install-discovery.d.ts +23 -0
- package/dist/server/modules/opencli/opencli-install-discovery.js +130 -0
- package/dist/server/modules/opencli/opencli-install-discovery.js.map +1 -0
- package/dist/server/modules/opencli/opencli-management-service.d.ts +59 -0
- package/dist/server/modules/opencli/opencli-management-service.js +152 -0
- package/dist/server/modules/opencli/opencli-management-service.js.map +1 -0
- package/dist/server/modules/opencli/opencli-runtime-builder.d.ts +11 -0
- package/dist/server/modules/opencli/opencli-runtime-builder.js +214 -0
- package/dist/server/modules/opencli/opencli-runtime-builder.js.map +1 -0
- package/dist/server/modules/opencli/opencli-runtime-layout.d.ts +3 -0
- package/dist/server/modules/opencli/opencli-runtime-layout.js +11 -0
- package/dist/server/modules/opencli/opencli-runtime-layout.js.map +1 -0
- package/dist/server/modules/opencli/opencli-runtime-profile-service.d.ts +29 -0
- package/dist/server/modules/opencli/opencli-runtime-profile-service.js +104 -0
- package/dist/server/modules/opencli/opencli-runtime-profile-service.js.map +1 -0
- package/dist/server/modules/opencli/opencli-runtime-resolver.d.ts +29 -0
- package/dist/server/modules/opencli/opencli-runtime-resolver.js +110 -0
- package/dist/server/modules/opencli/opencli-runtime-resolver.js.map +1 -0
- package/dist/server/modules/opencli/opencli-session-prompt-service.d.ts +11 -0
- package/dist/server/modules/opencli/opencli-session-prompt-service.js +66 -0
- package/dist/server/modules/opencli/opencli-session-prompt-service.js.map +1 -0
- package/dist/server/modules/parallel-sessions/parallel-session-controller.d.ts +4 -0
- package/dist/server/modules/parallel-sessions/parallel-session-controller.js +7 -0
- package/dist/server/modules/parallel-sessions/parallel-session-controller.js.map +1 -1
- package/dist/server/modules/parallel-sessions/parallel-session-group-service.d.ts +6 -1
- package/dist/server/modules/parallel-sessions/parallel-session-group-service.js +36 -2
- package/dist/server/modules/parallel-sessions/parallel-session-group-service.js.map +1 -1
- 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-catalog-service.d.ts +46 -0
- package/dist/server/modules/provider/provider-catalog-service.js +249 -0
- package/dist/server/modules/provider/provider-catalog-service.js.map +1 -0
- package/dist/server/modules/provider/provider-controller.d.ts +20 -2
- package/dist/server/modules/provider/provider-controller.js +65 -5
- package/dist/server/modules/provider/provider-controller.js.map +1 -1
- package/dist/server/modules/provider/provider-disabled.d.ts +8 -0
- package/dist/server/modules/provider/provider-disabled.js +45 -0
- package/dist/server/modules/provider/provider-disabled.js.map +1 -0
- package/dist/server/modules/provider/provider-discovery-helper-client.d.ts +3 -0
- package/dist/server/modules/provider/provider-discovery-helper-client.js.map +1 -1
- package/dist/server/modules/provider/provider-discovery-helper-process.js +4 -4
- package/dist/server/modules/provider/provider-discovery-helper-process.js.map +1 -1
- package/dist/server/modules/provider/provider-discovery-runtime.d.ts +1 -1
- package/dist/server/modules/provider/provider-discovery-runtime.js +17 -9
- package/dist/server/modules/provider/provider-discovery-runtime.js.map +1 -1
- package/dist/server/modules/sessions/claude-compatible-provider-registry.d.ts +16 -0
- package/dist/server/modules/sessions/claude-compatible-provider-registry.js +91 -0
- package/dist/server/modules/sessions/claude-compatible-provider-registry.js.map +1 -0
- 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 +1 -0
- package/dist/server/modules/sessions/codex-app-server-helper-client.js +10 -0
- package/dist/server/modules/sessions/codex-app-server-helper-client.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 +18 -2
- package/dist/server/modules/sessions/session-history-service.js +330 -29
- package/dist/server/modules/sessions/session-history-service.js.map +1 -1
- package/dist/server/modules/sessions/session-live-runtime-router-service.js +9 -4
- package/dist/server/modules/sessions/session-live-runtime-router-service.js.map +1 -1
- package/dist/server/modules/sessions/session-live-runtime-service.d.ts +22 -5
- package/dist/server/modules/sessions/session-live-runtime-service.js +350 -122
- 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-permission-request-service.d.ts +5 -2
- package/dist/server/modules/sessions/session-permission-request-service.js +26 -27
- package/dist/server/modules/sessions/session-permission-request-service.js.map +1 -1
- package/dist/server/modules/sessions/session-provider-config-service.d.ts +82 -0
- package/dist/server/modules/sessions/session-provider-config-service.js +925 -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/skills/skill-manager-service.d.ts +5 -0
- package/dist/server/modules/skills/skill-manager-service.js +26 -0
- package/dist/server/modules/skills/skill-manager-service.js.map +1 -1
- package/dist/server/modules/tasks/task-helper-process-handlers.d.ts +1 -0
- package/dist/server/modules/tasks/task-helper-process-handlers.js +1 -1
- package/dist/server/modules/tasks/task-helper-process-handlers.js.map +1 -1
- package/dist/server/routes/opencli.d.ts +3 -0
- package/dist/server/routes/opencli.js +7 -0
- package/dist/server/routes/opencli.js.map +1 -0
- package/dist/server/routes/providers.js +4 -2
- package/dist/server/routes/providers.js.map +1 -1
- package/dist/server/server/create-server.d.ts +8 -0
- package/dist/server/server/create-server.js +48 -12
- package/dist/server/server/create-server.js.map +1 -1
- package/dist/server/storage/repositories/opencli-catalog-entry-repository.d.ts +9 -0
- package/dist/server/storage/repositories/opencli-catalog-entry-repository.js +85 -0
- package/dist/server/storage/repositories/opencli-catalog-entry-repository.js.map +1 -0
- package/dist/server/storage/repositories/opencli-provider-repository.d.ts +8 -0
- package/dist/server/storage/repositories/opencli-provider-repository.js +88 -0
- package/dist/server/storage/repositories/opencli-provider-repository.js.map +1 -0
- package/dist/server/storage/repositories/opencli-runtime-profile-repository.d.ts +11 -0
- package/dist/server/storage/repositories/opencli-runtime-profile-repository.js +127 -0
- package/dist/server/storage/repositories/opencli-runtime-profile-repository.js.map +1 -0
- package/dist/server/storage/repositories/provider-control-repository.d.ts +9 -0
- package/dist/server/storage/repositories/provider-control-repository.js +51 -0
- package/dist/server/storage/repositories/provider-control-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/sqlite/client.js +72 -0
- package/dist/server/storage/sqlite/client.js.map +1 -1
- package/dist/server/storage/sqlite/schema.sql +71 -0
- package/dist/server/types/domain.d.ts +56 -0
- 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/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/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 +41 -21
- 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 +15 -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 +167 -10
- 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/AdaptiveButlerPage-uFwDdN-F.js +0 -3
- package/dist/public/assets/ConversationPage-z3sXtKZ7.js +0 -4
- package/dist/public/assets/DesktopWindowPage-CZcoGApB.js +0 -2
- package/dist/public/assets/FileContextPanel-C3qex8bb.js +0 -1
- package/dist/public/assets/GitSidebar-BK6H16XU.js +0 -6
- package/dist/public/assets/MobileCreateSessionSheet-BYfbvK8o.js +0 -1
- package/dist/public/assets/MobileSheet-Ckug8hTb.js +0 -1
- package/dist/public/assets/MobileWorkspaceSwitcherHeader-RqWrBdn2.js +0 -1
- package/dist/public/assets/SessionIndexPage-DuK10DL5.js +0 -1
- package/dist/public/assets/SettingsPage-fyD-xaHL.js +0 -1
- package/dist/public/assets/TerminalManagerPanel-CCLr1Ypk.js +0 -1
- package/dist/public/assets/TerminalRuntimeFallbackModal-aUzjEBwP.js +0 -1
- package/dist/public/assets/ToolGitPage-C264yjS9.js +0 -1
- package/dist/public/assets/ToolProcessesPage-BOP4A1cb.js +0 -1
- package/dist/public/assets/ToolsHomePage-CQxGiKQA.js +0 -1
- package/dist/public/assets/WorkbenchLandingPage-CvAY68ca.js +0 -1
- package/dist/public/assets/WorkbenchLayout-DGm8Tc5M.js +0 -3
- package/dist/public/assets/WorkbenchModal-0tPIIhca.js +0 -1
- package/dist/public/assets/WorkbenchShellRoute-BF0nHWOk.css +0 -1
- package/dist/public/assets/WorkbenchShellRoute-DBBOsJo9.js +0 -1
- package/dist/public/assets/WorkspaceDebugDetailPage-CDerFYd2.js +0 -1
- package/dist/public/assets/WorkspaceDetailPage-BlJc1CHE.js +0 -1
- package/dist/public/assets/WorkspaceHomePage-BUsKJ3lv.js +0 -1
- package/dist/public/assets/default-session-permission-mode-DT4SGiwp.js +0 -1
- package/dist/public/assets/index-BZLcEHW3.js +0 -42
- package/dist/public/assets/index-BbspQPC2.css +0 -1
- package/dist/public/assets/session-runtime-machine-DdLeDqQr.js +0 -17
- package/dist/public/assets/useRegisteredDebugTemplates-oFAQNIqh.js +0 -1
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import { existsSync,
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { performance } from "node:perf_hooks";
|
|
4
|
-
import { ClaudeRuntimeAdapter, CodexRuntimeAdapter, GeminiRuntimeAdapter, KimiRuntimeAdapter, OpenCodeRuntimeAdapter, ProviderRuntimeService } from "@codingns/session-sync-core";
|
|
4
|
+
import { ClaudeRuntimeAdapter, CodexRuntimeAdapter, GeminiRuntimeAdapter, KimiRuntimeAdapter, LegnaRuntimeAdapter, OpenCodeRuntimeAdapter, ProviderRuntimeService } from "@codingns/session-sync-core";
|
|
5
5
|
import { AppError, isAppError } from "../../shared/errors/app-error.js";
|
|
6
6
|
import { createId } from "../../shared/utils/id.js";
|
|
7
7
|
import { isPerfDebugEnabled, logPerformance } from "../../shared/utils/perf-log.js";
|
|
8
8
|
import { logPermissionDebug } from "../../shared/utils/permission-debug-log.js";
|
|
9
9
|
import { nowIso } from "../../shared/utils/time.js";
|
|
10
10
|
import { SessionActivityAuthorityService } from "./session-activity-authority-service.js";
|
|
11
|
+
import { createProviderCapabilityBlockedError } from "../provider/provider-disabled.js";
|
|
11
12
|
import { SessionPermissionRequestService } from "./session-permission-request-service.js";
|
|
12
|
-
import { mapSessionProviderError } from "./session-provider-error-mapper.js";
|
|
13
|
+
import { appendSessionProviderErrorContext, mapSessionProviderError } from "./session-provider-error-mapper.js";
|
|
14
|
+
import { buildClaudeCompatibleHookBridgeUrl, buildClaudeCompatibleRawStoreRef, buildClaudeCompatibleSessionTitle, findClaudeCompatibleSessionFile, isClaudeCompatibleProvider } from "./claude-compatible-provider-registry.js";
|
|
13
15
|
import { ClaudeRuntimeHelperAdapter } from "./claude-runtime-helper-client.js";
|
|
14
16
|
import { CodexAppServerHelperClient } from "./codex-app-server-helper-client.js";
|
|
17
|
+
const OPENCODE_ORDER_DEBUG_ENABLED = /^(1|true|yes)$/i.test(process.env.CODINGNS_OPENCODE_ORDER_DEBUG?.trim() ?? "");
|
|
15
18
|
const RUNTIME_START_BINDING_WAIT_TIMEOUT_MS = 10_000;
|
|
16
19
|
const START_BINDING_POLL_INTERVAL_MS = 50;
|
|
17
20
|
const EXTERNAL_RUNTIME_INTERRUPT_SUPPRESSION_MS = 30_000;
|
|
@@ -27,7 +30,9 @@ export class SessionLiveRuntimeService {
|
|
|
27
30
|
sessionIndexRepository;
|
|
28
31
|
sessionStateRepository;
|
|
29
32
|
sessionStatusSnapshotRepository;
|
|
33
|
+
sessionProviderConfigService;
|
|
30
34
|
config;
|
|
35
|
+
openCliSessionPromptService;
|
|
31
36
|
providerRuntimeService;
|
|
32
37
|
sessionActivityAuthorityService;
|
|
33
38
|
sessionPermissionRequestService;
|
|
@@ -42,7 +47,7 @@ export class SessionLiveRuntimeService {
|
|
|
42
47
|
queueDispatchSessions = new Set();
|
|
43
48
|
queueRetryTimers = new Map();
|
|
44
49
|
pendingSendDebugTracesBySessionId = new Map();
|
|
45
|
-
constructor(sessionHistoryService, sessionMessageAttachmentService, workspaceService, sessionChangedFileService, sessionBindingRepository, authUserRepository, sessionSendQueueRepository, sessionIndexRepository, sessionStateRepository, sessionStatusSnapshotRepository, config, sessionActivityAuthorityService = new SessionActivityAuthorityService()) {
|
|
50
|
+
constructor(sessionHistoryService, sessionMessageAttachmentService, workspaceService, sessionChangedFileService, sessionBindingRepository, authUserRepository, sessionSendQueueRepository, sessionIndexRepository, sessionStateRepository, sessionStatusSnapshotRepository, sessionProviderConfigService, config, sessionActivityAuthorityService = new SessionActivityAuthorityService(), openCliSessionPromptService = null) {
|
|
46
51
|
this.sessionHistoryService = sessionHistoryService;
|
|
47
52
|
this.sessionMessageAttachmentService = sessionMessageAttachmentService;
|
|
48
53
|
this.workspaceService = workspaceService;
|
|
@@ -53,7 +58,9 @@ export class SessionLiveRuntimeService {
|
|
|
53
58
|
this.sessionIndexRepository = sessionIndexRepository;
|
|
54
59
|
this.sessionStateRepository = sessionStateRepository;
|
|
55
60
|
this.sessionStatusSnapshotRepository = sessionStatusSnapshotRepository;
|
|
61
|
+
this.sessionProviderConfigService = sessionProviderConfigService;
|
|
56
62
|
this.config = config;
|
|
63
|
+
this.openCliSessionPromptService = openCliSessionPromptService;
|
|
57
64
|
this.sessionActivityAuthorityService = sessionActivityAuthorityService;
|
|
58
65
|
this.sessionPermissionRequestService = new SessionPermissionRequestService(sessionHistoryService, sessionBindingRepository, authUserRepository, workspaceService, config, async (envelope) => {
|
|
59
66
|
await this.emitExternalRuntimeEnvelope(envelope);
|
|
@@ -79,12 +86,25 @@ export class SessionLiveRuntimeService {
|
|
|
79
86
|
});
|
|
80
87
|
try {
|
|
81
88
|
const capabilities = this.sessionHistoryService.getProviderCapabilitiesSnapshot(input.provider);
|
|
82
|
-
this.
|
|
89
|
+
const providerBinding = this.sessionProviderConfigService.prepareSessionBinding({
|
|
90
|
+
sessionId,
|
|
91
|
+
provider: input.provider,
|
|
92
|
+
providerConfigMode: input.providerConfigMode,
|
|
93
|
+
providerPresetId: input.providerPresetId ?? null
|
|
94
|
+
});
|
|
95
|
+
const providerLaunchContext = this.sessionProviderConfigService.resolveLaunchContext({
|
|
96
|
+
provider: input.provider,
|
|
97
|
+
providerConfigMode: providerBinding.providerConfigMode,
|
|
98
|
+
providerPresetId: providerBinding.providerPresetId,
|
|
99
|
+
runtimeHomeDir: providerBinding.runtimeHomeDir
|
|
100
|
+
});
|
|
101
|
+
this.ensurePendingSessionBinding(sessionId, workspace.id, input.provider, providerBinding);
|
|
83
102
|
const persistedAttachments = this.persistMessageAttachments(sessionId, input.clientRequestId, input.runtimeOptions?.attachments ?? []);
|
|
84
103
|
const providerPrompt = this.sessionMessageAttachmentService.buildProviderPrompt(input.provider, input.content, persistedAttachments.runtimeAttachments);
|
|
104
|
+
const resolvedProviderPrompt = this.composeProviderPrompt(input.provider, providerPrompt, providerLaunchContext.runtimeEnv);
|
|
85
105
|
const providerInstructionFilePath = resolveRuntimeInstructionFilePath(input.provider, workspace.path, input.runtimeOptions?.providerInstructionFilePath ?? null);
|
|
86
|
-
this.ensureCapability(capabilities
|
|
87
|
-
this.ensureCapability(capabilities
|
|
106
|
+
this.ensureCapability(capabilities, "provider", "canStartSession", "provider 不支持 start-live");
|
|
107
|
+
this.ensureCapability(capabilities, "provider", "canSendMessage", "provider 不支持实时对话");
|
|
88
108
|
const launchRuntimeStartedAtMs = performance.now();
|
|
89
109
|
const handle = await this.launchRuntimeRun({
|
|
90
110
|
sessionId,
|
|
@@ -93,6 +113,8 @@ export class SessionLiveRuntimeService {
|
|
|
93
113
|
provider: input.provider,
|
|
94
114
|
providerSessionId: null,
|
|
95
115
|
rawStoreRef: null,
|
|
116
|
+
runtimeHomeDir: providerLaunchContext.runtimeHomeDir,
|
|
117
|
+
runtimeEnv: providerLaunchContext.runtimeEnv,
|
|
96
118
|
sequenceBase: 1,
|
|
97
119
|
options: {
|
|
98
120
|
content: input.content,
|
|
@@ -100,11 +122,16 @@ export class SessionLiveRuntimeService {
|
|
|
100
122
|
model: input.runtimeOptions?.model ?? null,
|
|
101
123
|
reasoningLevel: input.runtimeOptions?.reasoningLevel ?? null,
|
|
102
124
|
permissionMode: input.runtimeOptions?.permissionMode ?? null,
|
|
103
|
-
providerPrompt,
|
|
125
|
+
providerPrompt: resolvedProviderPrompt,
|
|
104
126
|
providerInstructionFilePath,
|
|
105
127
|
attachments: persistedAttachments.runtimeAttachments
|
|
106
128
|
}
|
|
107
|
-
}, "start"
|
|
129
|
+
}, "start", {
|
|
130
|
+
provider: input.provider,
|
|
131
|
+
providerConfigMode: providerBinding.providerConfigMode,
|
|
132
|
+
providerPresetId: providerBinding.providerPresetId,
|
|
133
|
+
runtimeHomeDir: providerBinding.runtimeHomeDir
|
|
134
|
+
});
|
|
108
135
|
this.logSendDebugStep(debugTrace, "launch_runtime", launchRuntimeStartedAtMs, {
|
|
109
136
|
userId: input.userId
|
|
110
137
|
});
|
|
@@ -149,7 +176,7 @@ export class SessionLiveRuntimeService {
|
|
|
149
176
|
if (!shouldAwaitStartBindingBeforeAcceptedUserLookup(input.provider)) {
|
|
150
177
|
void startBindingTask;
|
|
151
178
|
}
|
|
152
|
-
const acceptedAt = acceptedMessage?.timestamp ??
|
|
179
|
+
const acceptedAt = acceptedMessage?.timestamp ?? requestStartedAt;
|
|
153
180
|
const boundAttachments = this.sessionMessageAttachmentService.bindClientRequestToMessage(sessionId, input.clientRequestId, acceptedMessage?.messageId ?? null);
|
|
154
181
|
const session = this.resolveStartedSession({
|
|
155
182
|
sessionId,
|
|
@@ -203,6 +230,7 @@ export class SessionLiveRuntimeService {
|
|
|
203
230
|
}
|
|
204
231
|
async enqueueLiveMessage(input) {
|
|
205
232
|
const session = await this.resolveQueueDispatchSession(input.sessionId, input.userId);
|
|
233
|
+
this.resolveEffectiveSessionProviderBinding(session, input);
|
|
206
234
|
this.persistMessageAttachments(input.sessionId, input.clientRequestId, input.runtimeOptions?.attachments ?? []);
|
|
207
235
|
const timestamp = nowIso();
|
|
208
236
|
const queueItem = {
|
|
@@ -330,16 +358,25 @@ export class SessionLiveRuntimeService {
|
|
|
330
358
|
deleted: true
|
|
331
359
|
};
|
|
332
360
|
}
|
|
333
|
-
getClaudeHookBridgeConfig() {
|
|
334
|
-
return buildClaudeHookBridgeConfig(this.config);
|
|
335
|
-
}
|
|
336
|
-
async ingestClaudeHookEvent(payload) {
|
|
337
|
-
const
|
|
361
|
+
getClaudeHookBridgeConfig(provider = "claude-code") {
|
|
362
|
+
return buildClaudeHookBridgeConfig(this.config, provider);
|
|
363
|
+
}
|
|
364
|
+
async ingestClaudeHookEvent(providerOrPayload, payload) {
|
|
365
|
+
const hasExplicitProvider = typeof providerOrPayload === "string"
|
|
366
|
+
&& isClaudeCompatibleProvider(providerOrPayload);
|
|
367
|
+
const provider = hasExplicitProvider
|
|
368
|
+
? providerOrPayload
|
|
369
|
+
: "claude-code";
|
|
370
|
+
const resolvedPayload = hasExplicitProvider
|
|
371
|
+
? (payload ?? {})
|
|
372
|
+
: providerOrPayload;
|
|
373
|
+
const hookEventName = normalizeClaudeHookEventName(resolvedPayload.hook_event_name);
|
|
338
374
|
logPermissionDebug("claude_hook_event.ingest.begin", {
|
|
375
|
+
provider,
|
|
339
376
|
hookEventName,
|
|
340
|
-
sessionId:
|
|
341
|
-
cwd:
|
|
342
|
-
transcriptPath:
|
|
377
|
+
sessionId: resolvedPayload.session_id ?? null,
|
|
378
|
+
cwd: resolvedPayload.cwd ?? null,
|
|
379
|
+
transcriptPath: resolvedPayload.transcript_path ?? null
|
|
343
380
|
});
|
|
344
381
|
if (!hookEventName) {
|
|
345
382
|
throw new AppError({
|
|
@@ -365,23 +402,23 @@ export class SessionLiveRuntimeService {
|
|
|
365
402
|
hookEventName,
|
|
366
403
|
route: "handleClaudePreToolUse"
|
|
367
404
|
});
|
|
368
|
-
return this.sessionPermissionRequestService.handleClaudePreToolUse(
|
|
405
|
+
return this.sessionPermissionRequestService.handleClaudePreToolUse(resolvedPayload, provider);
|
|
369
406
|
}
|
|
370
407
|
if (hookEventName === "PermissionRequest") {
|
|
371
408
|
logPermissionDebug("claude_hook_event.route", {
|
|
372
409
|
hookEventName,
|
|
373
410
|
route: "handleClaudePermissionRequest"
|
|
374
411
|
});
|
|
375
|
-
return this.sessionPermissionRequestService.handleClaudePermissionRequest(
|
|
412
|
+
return this.sessionPermissionRequestService.handleClaudePermissionRequest(resolvedPayload, provider);
|
|
376
413
|
}
|
|
377
|
-
const providerSessionId = normalizeRequiredText(
|
|
378
|
-
const workspacePath = normalizeRequiredText(
|
|
414
|
+
const providerSessionId = normalizeRequiredText(resolvedPayload.session_id, "session_id");
|
|
415
|
+
const workspacePath = normalizeRequiredText(resolvedPayload.cwd, "cwd");
|
|
379
416
|
const workspace = this.workspaceService.findWorkspaceByPath(workspacePath);
|
|
380
417
|
if (!workspace) {
|
|
381
418
|
logPermissionDebug("claude_hook_event.workspace_not_found", {
|
|
382
419
|
hookEventName,
|
|
383
|
-
sessionId:
|
|
384
|
-
cwd:
|
|
420
|
+
sessionId: resolvedPayload.session_id ?? null,
|
|
421
|
+
cwd: resolvedPayload.cwd ?? null
|
|
385
422
|
});
|
|
386
423
|
return {
|
|
387
424
|
accepted: true,
|
|
@@ -391,13 +428,14 @@ export class SessionLiveRuntimeService {
|
|
|
391
428
|
};
|
|
392
429
|
}
|
|
393
430
|
const binding = await this.resolveClaudeExternalBinding({
|
|
431
|
+
provider,
|
|
394
432
|
providerSessionId,
|
|
395
433
|
workspaceId: workspace.id,
|
|
396
434
|
workspacePath: workspace.path,
|
|
397
|
-
transcriptPath: normalizeOptionalText(
|
|
435
|
+
transcriptPath: normalizeOptionalText(resolvedPayload.transcript_path)
|
|
398
436
|
});
|
|
399
437
|
const timestamp = nowIso();
|
|
400
|
-
const runtimeUpdate = mapClaudeHookToRuntimeUpdate(hookEventName,
|
|
438
|
+
const runtimeUpdate = mapClaudeHookToRuntimeUpdate(hookEventName, resolvedPayload, timestamp);
|
|
401
439
|
logPermissionDebug("claude_hook_event.runtime_update", {
|
|
402
440
|
hookEventName,
|
|
403
441
|
sessionId: binding.sessionId,
|
|
@@ -422,6 +460,7 @@ export class SessionLiveRuntimeService {
|
|
|
422
460
|
};
|
|
423
461
|
}
|
|
424
462
|
await this.applyExternalRuntimeUpdate({
|
|
463
|
+
provider,
|
|
425
464
|
sessionId: binding.sessionId,
|
|
426
465
|
workspaceId: workspace.id,
|
|
427
466
|
providerSessionId,
|
|
@@ -483,7 +522,7 @@ export class SessionLiveRuntimeService {
|
|
|
483
522
|
if (externalRuntimeSnapshot) {
|
|
484
523
|
return {
|
|
485
524
|
sessionId,
|
|
486
|
-
provider:
|
|
525
|
+
provider: externalRuntimeSnapshot.provider,
|
|
487
526
|
providerSessionId: externalRuntimeSnapshot.providerSessionId,
|
|
488
527
|
runningState: resolution.runningState,
|
|
489
528
|
hasActiveRun: externalHasActiveRun,
|
|
@@ -649,6 +688,16 @@ export class SessionLiveRuntimeService {
|
|
|
649
688
|
if (!envelope) {
|
|
650
689
|
return;
|
|
651
690
|
}
|
|
691
|
+
logOpenCodeOrderEnvelopeDebug("runtime.envelope.forward", {
|
|
692
|
+
sessionId,
|
|
693
|
+
runtimeSessionId,
|
|
694
|
+
provider: event.provider ?? null,
|
|
695
|
+
eventType: event.type ?? null,
|
|
696
|
+
envelopeType: envelope.type,
|
|
697
|
+
message: "message" in envelope && envelope.message
|
|
698
|
+
? summarizeOpenCodeOrderMessage(envelope.message)
|
|
699
|
+
: null
|
|
700
|
+
});
|
|
652
701
|
await onEnvelope(envelope);
|
|
653
702
|
});
|
|
654
703
|
const externalSubscription = this.subscribeExternalRuntime(runtimeSessionId, async (envelope) => {
|
|
@@ -867,10 +916,10 @@ export class SessionLiveRuntimeService {
|
|
|
867
916
|
}
|
|
868
917
|
async resolveClaudeExternalBinding(input) {
|
|
869
918
|
const rawStoreRef = input.transcriptPath ??
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
let binding = this.sessionBindingRepository.findByProviderSession(
|
|
873
|
-
this.sessionBindingRepository.findByRawStoreRef(
|
|
919
|
+
findClaudeCompatibleSessionFile(this.config, input.provider, input.workspacePath, input.providerSessionId) ??
|
|
920
|
+
buildClaudeCompatibleRawStoreRef(this.config, input.provider, input.workspacePath, input.providerSessionId);
|
|
921
|
+
let binding = this.sessionBindingRepository.findByProviderSession(input.provider, input.providerSessionId) ??
|
|
922
|
+
this.sessionBindingRepository.findByRawStoreRef(input.provider, rawStoreRef);
|
|
874
923
|
if (!binding) {
|
|
875
924
|
const userIds = this.authUserRepository.listIds();
|
|
876
925
|
const bootstrapUserId = userIds[0] ?? null;
|
|
@@ -883,8 +932,8 @@ export class SessionLiveRuntimeService {
|
|
|
883
932
|
});
|
|
884
933
|
}
|
|
885
934
|
binding =
|
|
886
|
-
this.sessionBindingRepository.findByProviderSession(
|
|
887
|
-
this.sessionBindingRepository.findByRawStoreRef(
|
|
935
|
+
this.sessionBindingRepository.findByProviderSession(input.provider, input.providerSessionId) ??
|
|
936
|
+
this.sessionBindingRepository.findByRawStoreRef(input.provider, rawStoreRef);
|
|
888
937
|
}
|
|
889
938
|
if (binding) {
|
|
890
939
|
return {
|
|
@@ -895,19 +944,19 @@ export class SessionLiveRuntimeService {
|
|
|
895
944
|
const sessionId = createId();
|
|
896
945
|
const timestamp = nowIso();
|
|
897
946
|
this.sessionHistoryService.persistSessionBinding(sessionId, input.workspaceId, {
|
|
898
|
-
provider:
|
|
947
|
+
provider: input.provider,
|
|
899
948
|
providerSessionId: input.providerSessionId,
|
|
900
949
|
rawStoreRef
|
|
901
950
|
});
|
|
902
951
|
this.sessionIndexRepository.upsert({
|
|
903
952
|
sessionId,
|
|
904
953
|
workspaceId: input.workspaceId,
|
|
905
|
-
provider:
|
|
954
|
+
provider: input.provider,
|
|
906
955
|
parentSessionId: null,
|
|
907
956
|
sessionKind: "default",
|
|
908
957
|
isSubagent: false,
|
|
909
958
|
subagentLabel: null,
|
|
910
|
-
title:
|
|
959
|
+
title: buildClaudeCompatibleSessionTitle(input.provider, input.providerSessionId),
|
|
911
960
|
messageCount: 0,
|
|
912
961
|
isArchived: false,
|
|
913
962
|
lastMessageAt: null,
|
|
@@ -988,7 +1037,7 @@ export class SessionLiveRuntimeService {
|
|
|
988
1037
|
if (input.runningState === "running") {
|
|
989
1038
|
this.externalRuntimeSnapshots.set(input.sessionId, {
|
|
990
1039
|
sessionId: input.sessionId,
|
|
991
|
-
provider:
|
|
1040
|
+
provider: input.provider,
|
|
992
1041
|
providerSessionId: input.providerSessionId,
|
|
993
1042
|
rawStoreRef: input.rawStoreRef,
|
|
994
1043
|
runningState: input.runningState,
|
|
@@ -1027,14 +1076,14 @@ export class SessionLiveRuntimeService {
|
|
|
1027
1076
|
void this.dispatchNextQueuedMessage(input.sessionId);
|
|
1028
1077
|
}
|
|
1029
1078
|
}
|
|
1030
|
-
async startRuntimeRun(request, userId, mode) {
|
|
1079
|
+
async startRuntimeRun(request, userId, mode, providerBinding) {
|
|
1031
1080
|
this.runtimeMessageSeenSessions.delete(request.sessionId);
|
|
1032
1081
|
this.runtimeHistoryFallbackSentSessions.delete(request.sessionId);
|
|
1033
1082
|
this.clearExternalRuntimeInterruptSuppression(request.sessionId);
|
|
1034
|
-
if (request.provider
|
|
1083
|
+
if (isClaudeCompatibleProvider(request.provider)) {
|
|
1035
1084
|
this.clearExternalRuntimeSnapshot(request.sessionId);
|
|
1036
1085
|
}
|
|
1037
|
-
const handle = await this.launchRuntimeRun(request, mode);
|
|
1086
|
+
const handle = await this.launchRuntimeRun(request, mode, providerBinding);
|
|
1038
1087
|
const snapshot = handle.getSnapshot();
|
|
1039
1088
|
const currentState = this.sessionStateRepository.findBySessionAndUser(request.sessionId, userId);
|
|
1040
1089
|
this.attachRuntimePersistence(handle, request.sessionId, request.workspaceId, userId);
|
|
@@ -1066,24 +1115,61 @@ export class SessionLiveRuntimeService {
|
|
|
1066
1115
|
const capabilities = await this.sessionHistoryService.getSessionCapabilities(input.sessionId);
|
|
1067
1116
|
const workspace = this.workspaceService.getWorkspaceOrThrow(session.workspaceId);
|
|
1068
1117
|
const runtimeMode = shouldStartNativeSessionOnFirstMessage(session);
|
|
1118
|
+
const existingBinding = this.getSessionBindingOrThrow(session.sessionId);
|
|
1119
|
+
const resolvedProviderBinding = this.resolveRequestedSessionProviderBinding(session, input, existingBinding);
|
|
1120
|
+
const runtimeSessionId = this.resolveRuntimeSessionId(input.sessionId);
|
|
1121
|
+
const activeRun = this.getLiveRuntimeSnapshot(runtimeSessionId);
|
|
1122
|
+
const externalRuntimeSnapshot = this.getFreshExternalRuntimeSnapshot(runtimeSessionId);
|
|
1123
|
+
const hasActiveRun = Boolean(activeRun && isActiveRuntimeState(activeRun.runningState));
|
|
1124
|
+
if (hasActiveRun && isClaudeCompatibleProvider(activeRun?.provider)) {
|
|
1125
|
+
this.clearExternalRuntimeSnapshot(runtimeSessionId);
|
|
1126
|
+
}
|
|
1127
|
+
if (hasActiveRun
|
|
1128
|
+
|| (!activeRun &&
|
|
1129
|
+
isClaudeCompatibleProvider(session.provider) &&
|
|
1130
|
+
externalRuntimeSnapshot &&
|
|
1131
|
+
isActiveRuntimeState(externalRuntimeSnapshot.runningState))) {
|
|
1132
|
+
this.assertProviderBindingStableDuringActiveRun(existingBinding, resolvedProviderBinding);
|
|
1133
|
+
}
|
|
1134
|
+
if (!activeRun &&
|
|
1135
|
+
isClaudeCompatibleProvider(session.provider) &&
|
|
1136
|
+
externalRuntimeSnapshot &&
|
|
1137
|
+
isActiveRuntimeState(externalRuntimeSnapshot.runningState)) {
|
|
1138
|
+
throw new AppError({
|
|
1139
|
+
statusCode: 409,
|
|
1140
|
+
errorCode: "SESSION_EXTERNAL_RUN_ACTIVE",
|
|
1141
|
+
detail: "当前 Claude 外部会话仍在运行,不能直接追加;请加入队列或等待当前轮结束",
|
|
1142
|
+
field: "sessionId"
|
|
1143
|
+
});
|
|
1144
|
+
}
|
|
1145
|
+
const providerBinding = hasActiveRun
|
|
1146
|
+
? existingBinding
|
|
1147
|
+
: this.persistResolvedSessionProviderBinding(existingBinding, resolvedProviderBinding);
|
|
1148
|
+
const providerLaunchContext = this.sessionProviderConfigService.resolveLaunchContext(providerBinding);
|
|
1069
1149
|
const syntheticForkRawStoreRef = runtimeMode === "start" && shouldResumeCodexSyntheticForkSession(session)
|
|
1070
1150
|
? session.rawStoreRef
|
|
1071
1151
|
: null;
|
|
1152
|
+
const runtimeRawStoreRef = runtimeMode === "start"
|
|
1153
|
+
? syntheticForkRawStoreRef
|
|
1154
|
+
: await this.resolveCodexRuntimeRequestRawStoreRef(session, providerBinding);
|
|
1072
1155
|
const nextUserSequence = runtimeMode === "start"
|
|
1073
1156
|
? 1
|
|
1074
1157
|
: await this.resolveNextUserSequence(input.sessionId, session.messageCount);
|
|
1075
1158
|
const resolvedAttachments = persistedAttachments
|
|
1076
1159
|
?? this.persistMessageAttachments(input.sessionId, input.clientRequestId, input.runtimeOptions?.attachments ?? []);
|
|
1077
1160
|
const providerPrompt = this.sessionMessageAttachmentService.buildProviderPrompt(session.provider, input.content, resolvedAttachments.runtimeAttachments);
|
|
1161
|
+
const resolvedProviderPrompt = this.composeProviderPrompt(session.provider, providerPrompt, providerLaunchContext.runtimeEnv);
|
|
1078
1162
|
const providerInstructionFilePath = resolveRuntimeInstructionFilePath(session.provider, workspace.path, input.runtimeOptions?.providerInstructionFilePath ?? null);
|
|
1079
|
-
this.ensureCapability(capabilities
|
|
1163
|
+
this.ensureCapability(capabilities, "sessionId", "canSendMessage", "provider 不支持实时对话");
|
|
1080
1164
|
const runtimeRequest = {
|
|
1081
1165
|
sessionId: input.sessionId,
|
|
1082
1166
|
workspaceId: session.workspaceId,
|
|
1083
1167
|
workspacePath: workspace.path,
|
|
1084
1168
|
provider: session.provider,
|
|
1085
1169
|
providerSessionId: runtimeMode === "start" ? null : session.providerSessionId,
|
|
1086
|
-
rawStoreRef:
|
|
1170
|
+
rawStoreRef: runtimeRawStoreRef,
|
|
1171
|
+
runtimeHomeDir: providerLaunchContext.runtimeHomeDir,
|
|
1172
|
+
runtimeEnv: providerLaunchContext.runtimeEnv,
|
|
1087
1173
|
sequenceBase: nextUserSequence,
|
|
1088
1174
|
options: {
|
|
1089
1175
|
content: input.content,
|
|
@@ -1091,31 +1177,12 @@ export class SessionLiveRuntimeService {
|
|
|
1091
1177
|
model: input.runtimeOptions?.model ?? null,
|
|
1092
1178
|
reasoningLevel: input.runtimeOptions?.reasoningLevel ?? null,
|
|
1093
1179
|
permissionMode: input.runtimeOptions?.permissionMode ?? null,
|
|
1094
|
-
providerPrompt,
|
|
1180
|
+
providerPrompt: resolvedProviderPrompt,
|
|
1095
1181
|
providerInstructionFilePath,
|
|
1096
1182
|
attachments: resolvedAttachments.runtimeAttachments
|
|
1097
1183
|
}
|
|
1098
1184
|
};
|
|
1099
|
-
|
|
1100
|
-
const activeRun = this.getLiveRuntimeSnapshot(runtimeSessionId);
|
|
1101
|
-
const externalRuntimeSnapshot = this.getFreshExternalRuntimeSnapshot(runtimeSessionId);
|
|
1102
|
-
if (activeRun &&
|
|
1103
|
-
activeRun.provider === "claude-code" &&
|
|
1104
|
-
isActiveRuntimeState(activeRun.runningState)) {
|
|
1105
|
-
this.clearExternalRuntimeSnapshot(runtimeSessionId);
|
|
1106
|
-
}
|
|
1107
|
-
if (!activeRun &&
|
|
1108
|
-
session.provider === "claude-code" &&
|
|
1109
|
-
externalRuntimeSnapshot &&
|
|
1110
|
-
isActiveRuntimeState(externalRuntimeSnapshot.runningState)) {
|
|
1111
|
-
throw new AppError({
|
|
1112
|
-
statusCode: 409,
|
|
1113
|
-
errorCode: "SESSION_EXTERNAL_RUN_ACTIVE",
|
|
1114
|
-
detail: "当前 Claude 外部会话仍在运行,不能直接追加;请加入队列或等待当前轮结束",
|
|
1115
|
-
field: "sessionId"
|
|
1116
|
-
});
|
|
1117
|
-
}
|
|
1118
|
-
if (activeRun && isActiveRuntimeState(activeRun.runningState)) {
|
|
1185
|
+
if (hasActiveRun) {
|
|
1119
1186
|
const submitStartedAtMs = performance.now();
|
|
1120
1187
|
try {
|
|
1121
1188
|
await this.providerRuntimeService.submitToActiveRun(runtimeSessionId, runtimeRequest.options);
|
|
@@ -1125,13 +1192,23 @@ export class SessionLiveRuntimeService {
|
|
|
1125
1192
|
});
|
|
1126
1193
|
}
|
|
1127
1194
|
catch (error) {
|
|
1128
|
-
const mapped = mapSessionProviderError(error)
|
|
1195
|
+
const mapped = appendSessionProviderErrorContext(mapSessionProviderError(error), this.sessionProviderConfigService.describeBinding({
|
|
1196
|
+
provider: session.provider,
|
|
1197
|
+
providerConfigMode: providerBinding.providerConfigMode,
|
|
1198
|
+
providerPresetId: providerBinding.providerPresetId,
|
|
1199
|
+
runtimeHomeDir: providerBinding.runtimeHomeDir
|
|
1200
|
+
}));
|
|
1129
1201
|
// 运行时句柄还没来得及收尾时,steer 可能会撞上 provider 已终态。
|
|
1130
1202
|
// 这里直接失败只会把一条正常消息变成偶发 409,属于纯粹的坏味道。
|
|
1131
1203
|
if (mapped.errorCode === "SESSION_NOT_RUNNING") {
|
|
1132
1204
|
await this.providerRuntimeService.abandonRun(runtimeSessionId);
|
|
1133
1205
|
const restartRuntimeStartedAtMs = performance.now();
|
|
1134
|
-
await this.startRuntimeRun(runtimeRequest, input.userId, runtimeMode
|
|
1206
|
+
await this.startRuntimeRun(runtimeRequest, input.userId, runtimeMode, {
|
|
1207
|
+
provider: session.provider,
|
|
1208
|
+
providerConfigMode: providerBinding.providerConfigMode,
|
|
1209
|
+
providerPresetId: providerBinding.providerPresetId,
|
|
1210
|
+
runtimeHomeDir: providerBinding.runtimeHomeDir
|
|
1211
|
+
});
|
|
1135
1212
|
this.logSendDebugStep(debugTrace, "restart_runtime_after_stale_active_run", restartRuntimeStartedAtMs, {
|
|
1136
1213
|
runtimeMode
|
|
1137
1214
|
});
|
|
@@ -1143,7 +1220,12 @@ export class SessionLiveRuntimeService {
|
|
|
1143
1220
|
}
|
|
1144
1221
|
else {
|
|
1145
1222
|
const startRuntimeStartedAtMs = performance.now();
|
|
1146
|
-
await this.startRuntimeRun(runtimeRequest, input.userId, runtimeMode
|
|
1223
|
+
await this.startRuntimeRun(runtimeRequest, input.userId, runtimeMode, {
|
|
1224
|
+
provider: session.provider,
|
|
1225
|
+
providerConfigMode: providerBinding.providerConfigMode,
|
|
1226
|
+
providerPresetId: providerBinding.providerPresetId,
|
|
1227
|
+
runtimeHomeDir: providerBinding.runtimeHomeDir
|
|
1228
|
+
});
|
|
1147
1229
|
this.logSendDebugStep(debugTrace, "start_runtime_run", startRuntimeStartedAtMs, {
|
|
1148
1230
|
runtimeMode
|
|
1149
1231
|
});
|
|
@@ -1154,7 +1236,7 @@ export class SessionLiveRuntimeService {
|
|
|
1154
1236
|
this.logSendDebugStep(debugTrace, "accepted_user_lookup", acceptedLookupStartedAtMs, {
|
|
1155
1237
|
matched: Boolean(acceptedMessage)
|
|
1156
1238
|
});
|
|
1157
|
-
const acceptedAt = acceptedMessage?.timestamp ??
|
|
1239
|
+
const acceptedAt = acceptedMessage?.timestamp ?? requestStartedAt;
|
|
1158
1240
|
this.sessionHistoryService.resolveMessageOriginByClientRequestId(input.sessionId, input.clientRequestId, acceptedMessage?.messageId ?? null, acceptedAt);
|
|
1159
1241
|
const boundAttachments = this.sessionMessageAttachmentService.bindClientRequestToMessage(input.sessionId, input.clientRequestId, acceptedMessage?.messageId ?? null);
|
|
1160
1242
|
this.refreshSyntheticSessionTitle(session, input.content, input.userId);
|
|
@@ -1186,6 +1268,20 @@ export class SessionLiveRuntimeService {
|
|
|
1186
1268
|
throw error;
|
|
1187
1269
|
}
|
|
1188
1270
|
}
|
|
1271
|
+
composeProviderPrompt(provider, basePrompt, runtimeEnv) {
|
|
1272
|
+
const openCliPrompt = this.openCliSessionPromptService?.buildPrompt({
|
|
1273
|
+
provider,
|
|
1274
|
+
runtimeEnv
|
|
1275
|
+
}) ?? null;
|
|
1276
|
+
if (!openCliPrompt) {
|
|
1277
|
+
return basePrompt;
|
|
1278
|
+
}
|
|
1279
|
+
const normalizedBasePrompt = basePrompt?.trim() ?? "";
|
|
1280
|
+
if (!normalizedBasePrompt) {
|
|
1281
|
+
return openCliPrompt;
|
|
1282
|
+
}
|
|
1283
|
+
return `${normalizedBasePrompt}\n\n${openCliPrompt}`;
|
|
1284
|
+
}
|
|
1189
1285
|
async dispatchNextQueuedMessage(sessionId) {
|
|
1190
1286
|
if (this.queueDispatchSessions.has(sessionId)) {
|
|
1191
1287
|
return;
|
|
@@ -1263,7 +1359,7 @@ export class SessionLiveRuntimeService {
|
|
|
1263
1359
|
if (externalRuntimeSnapshot && isActiveRuntimeState(externalRuntimeSnapshot.runningState)) {
|
|
1264
1360
|
return true;
|
|
1265
1361
|
}
|
|
1266
|
-
if (session.provider
|
|
1362
|
+
if (isClaudeCompatibleProvider(session.provider) && isPendingSessionRunningState(session.runningState)) {
|
|
1267
1363
|
return true;
|
|
1268
1364
|
}
|
|
1269
1365
|
return false;
|
|
@@ -1291,7 +1387,7 @@ export class SessionLiveRuntimeService {
|
|
|
1291
1387
|
}
|
|
1292
1388
|
async resolveQueueDispatchSession(sessionId, userId) {
|
|
1293
1389
|
const session = this.sessionHistoryService.getSession(sessionId, userId);
|
|
1294
|
-
if (session.provider
|
|
1390
|
+
if (!isClaudeCompatibleProvider(session.provider)
|
|
1295
1391
|
|| !isPendingSessionRunningState(session.runningState)) {
|
|
1296
1392
|
return session;
|
|
1297
1393
|
}
|
|
@@ -1305,14 +1401,18 @@ export class SessionLiveRuntimeService {
|
|
|
1305
1401
|
.then((refreshedSession) => refreshedSession ?? session)
|
|
1306
1402
|
.catch(() => session);
|
|
1307
1403
|
}
|
|
1308
|
-
async launchRuntimeRun(request, mode) {
|
|
1404
|
+
async launchRuntimeRun(request, mode, providerBinding) {
|
|
1309
1405
|
try {
|
|
1310
1406
|
return await (mode === "start"
|
|
1311
1407
|
? this.providerRuntimeService.startSession(request)
|
|
1312
1408
|
: this.providerRuntimeService.continueSession(request));
|
|
1313
1409
|
}
|
|
1314
1410
|
catch (error) {
|
|
1315
|
-
|
|
1411
|
+
const mapped = mapSessionProviderError(error);
|
|
1412
|
+
if (!providerBinding) {
|
|
1413
|
+
throw mapped;
|
|
1414
|
+
}
|
|
1415
|
+
throw appendSessionProviderErrorContext(mapped, this.sessionProviderConfigService.describeBinding(providerBinding));
|
|
1316
1416
|
}
|
|
1317
1417
|
}
|
|
1318
1418
|
attachRuntimePersistence(handle, sessionId, workspaceId, userId) {
|
|
@@ -1390,8 +1490,109 @@ export class SessionLiveRuntimeService {
|
|
|
1390
1490
|
});
|
|
1391
1491
|
this.sessionActivityAuthorityService.observe(createRuntimeActivityObservation(input.sessionId, input.snapshot));
|
|
1392
1492
|
}
|
|
1393
|
-
ensurePendingSessionBinding(sessionId, workspaceId, provider) {
|
|
1394
|
-
|
|
1493
|
+
ensurePendingSessionBinding(sessionId, workspaceId, provider, providerBinding) {
|
|
1494
|
+
const snapshot = this.buildBindingSnapshot(sessionId, provider, null, null);
|
|
1495
|
+
const timestamp = nowIso();
|
|
1496
|
+
const existingBinding = this.sessionBindingRepository.findBySessionId(sessionId);
|
|
1497
|
+
this.sessionBindingRepository.upsert({
|
|
1498
|
+
sessionId,
|
|
1499
|
+
workspaceId,
|
|
1500
|
+
provider: snapshot.provider,
|
|
1501
|
+
providerSessionId: snapshot.providerSessionId,
|
|
1502
|
+
rawStoreRef: snapshot.rawStoreRef,
|
|
1503
|
+
providerConfigMode: providerBinding?.providerConfigMode ?? existingBinding?.providerConfigMode ?? "global-default",
|
|
1504
|
+
providerPresetId: providerBinding?.providerPresetId ?? existingBinding?.providerPresetId ?? null,
|
|
1505
|
+
runtimeHomeDir: providerBinding?.runtimeHomeDir ?? existingBinding?.runtimeHomeDir ?? null,
|
|
1506
|
+
createdAt: existingBinding?.createdAt ?? timestamp,
|
|
1507
|
+
updatedAt: timestamp
|
|
1508
|
+
});
|
|
1509
|
+
}
|
|
1510
|
+
resolveEffectiveSessionProviderBinding(session, input) {
|
|
1511
|
+
const existingBinding = this.getSessionBindingOrThrow(session.sessionId);
|
|
1512
|
+
const providerBinding = this.resolveRequestedSessionProviderBinding(session, input, existingBinding);
|
|
1513
|
+
return this.persistResolvedSessionProviderBinding(existingBinding, providerBinding);
|
|
1514
|
+
}
|
|
1515
|
+
getSessionBindingOrThrow(sessionId) {
|
|
1516
|
+
const existingBinding = this.sessionBindingRepository.findBySessionId(sessionId);
|
|
1517
|
+
if (!existingBinding) {
|
|
1518
|
+
throw new AppError({
|
|
1519
|
+
statusCode: 404,
|
|
1520
|
+
errorCode: "SESSION_NOT_FOUND",
|
|
1521
|
+
detail: "session 不存在"
|
|
1522
|
+
});
|
|
1523
|
+
}
|
|
1524
|
+
return existingBinding;
|
|
1525
|
+
}
|
|
1526
|
+
resolveRequestedSessionProviderBinding(session, input, existingBinding) {
|
|
1527
|
+
return this.sessionProviderConfigService.resolveSessionBinding({
|
|
1528
|
+
sessionId: session.sessionId,
|
|
1529
|
+
provider: session.provider,
|
|
1530
|
+
existingBinding,
|
|
1531
|
+
providerConfigMode: input.providerConfigMode,
|
|
1532
|
+
providerPresetId: input.providerPresetId ?? null
|
|
1533
|
+
});
|
|
1534
|
+
}
|
|
1535
|
+
persistResolvedSessionProviderBinding(existingBinding, providerBinding) {
|
|
1536
|
+
if (!this.hasSessionProviderBindingChanged(existingBinding, providerBinding)) {
|
|
1537
|
+
return existingBinding;
|
|
1538
|
+
}
|
|
1539
|
+
const nextBinding = {
|
|
1540
|
+
...existingBinding,
|
|
1541
|
+
providerConfigMode: providerBinding.providerConfigMode,
|
|
1542
|
+
providerPresetId: providerBinding.providerPresetId,
|
|
1543
|
+
runtimeHomeDir: providerBinding.runtimeHomeDir,
|
|
1544
|
+
updatedAt: nowIso()
|
|
1545
|
+
};
|
|
1546
|
+
this.sessionBindingRepository.upsert(nextBinding);
|
|
1547
|
+
return nextBinding;
|
|
1548
|
+
}
|
|
1549
|
+
assertProviderBindingStableDuringActiveRun(existingBinding, requestedBinding) {
|
|
1550
|
+
if (!this.hasSessionProviderBindingChanged(existingBinding, requestedBinding)) {
|
|
1551
|
+
return;
|
|
1552
|
+
}
|
|
1553
|
+
throw new AppError({
|
|
1554
|
+
statusCode: 409,
|
|
1555
|
+
errorCode: "SESSION_PROVIDER_CONFIG_CHANGE_REQUIRES_NEW_RUN",
|
|
1556
|
+
detail: "当前会话仍在执行,不能中途切换模型配置文件;请等本轮结束后再发起新一轮",
|
|
1557
|
+
field: "sessionId"
|
|
1558
|
+
});
|
|
1559
|
+
}
|
|
1560
|
+
hasSessionProviderBindingChanged(currentBinding, nextBinding) {
|
|
1561
|
+
return (currentBinding.providerConfigMode !== nextBinding.providerConfigMode
|
|
1562
|
+
|| normalizeOptionalBindingValue(currentBinding.providerPresetId)
|
|
1563
|
+
!== normalizeOptionalBindingValue(nextBinding.providerPresetId)
|
|
1564
|
+
|| normalizeOptionalBindingValue(currentBinding.runtimeHomeDir)
|
|
1565
|
+
!== normalizeOptionalBindingValue(nextBinding.runtimeHomeDir));
|
|
1566
|
+
}
|
|
1567
|
+
async resolveCodexRuntimeRequestRawStoreRef(session, providerBinding) {
|
|
1568
|
+
if (session.provider !== "codex") {
|
|
1569
|
+
return session.rawStoreRef;
|
|
1570
|
+
}
|
|
1571
|
+
const currentRawStoreRef = session.rawStoreRef?.trim() || null;
|
|
1572
|
+
if (currentRawStoreRef && existsSync(currentRawStoreRef)) {
|
|
1573
|
+
return currentRawStoreRef;
|
|
1574
|
+
}
|
|
1575
|
+
const messages = await Promise.resolve(this.sessionHistoryService.readAllTextHistoryMessages(session.sessionId)).catch(() => []);
|
|
1576
|
+
if (!Array.isArray(messages) || messages.length === 0) {
|
|
1577
|
+
return currentRawStoreRef;
|
|
1578
|
+
}
|
|
1579
|
+
const baseDir = providerBinding.runtimeHomeDir?.trim()
|
|
1580
|
+
|| path.resolve(path.dirname(this.config.databasePath), "runtime", "codex-resume-history");
|
|
1581
|
+
const syntheticDir = path.join(baseDir, ".codingns-synthetic-resume");
|
|
1582
|
+
const syntheticFilePath = path.join(syntheticDir, `${session.sessionId}.jsonl`);
|
|
1583
|
+
const serialized = messages
|
|
1584
|
+
.map((message) => JSON.stringify({
|
|
1585
|
+
timestamp: message.timestamp,
|
|
1586
|
+
type: "event_msg",
|
|
1587
|
+
payload: {
|
|
1588
|
+
type: message.role === "assistant" ? "agent_message" : "user_message",
|
|
1589
|
+
message: message.content
|
|
1590
|
+
}
|
|
1591
|
+
}))
|
|
1592
|
+
.join("\n");
|
|
1593
|
+
mkdirSync(syntheticDir, { recursive: true });
|
|
1594
|
+
writeFileSync(syntheticFilePath, `${serialized}\n`, "utf8");
|
|
1595
|
+
return syntheticFilePath;
|
|
1395
1596
|
}
|
|
1396
1597
|
buildBindingSnapshot(sessionId, provider, providerSessionId, rawStoreRef) {
|
|
1397
1598
|
const pendingValue = `pending://${provider}/${sessionId}`;
|
|
@@ -1762,7 +1963,7 @@ export class SessionLiveRuntimeService {
|
|
|
1762
1963
|
}
|
|
1763
1964
|
}
|
|
1764
1965
|
async resolveNextUserSequence(sessionId, messageCount) {
|
|
1765
|
-
let maxSequence =
|
|
1966
|
+
let maxSequence = 0;
|
|
1766
1967
|
const envelope = await Promise.resolve(this.sessionHistoryService.readRecentHistoryEnvelope(sessionId, 10)).catch(() => {
|
|
1767
1968
|
return null;
|
|
1768
1969
|
});
|
|
@@ -1771,6 +1972,9 @@ export class SessionLiveRuntimeService {
|
|
|
1771
1972
|
maxSequence = message.sequence;
|
|
1772
1973
|
}
|
|
1773
1974
|
}
|
|
1975
|
+
if (maxSequence <= 0) {
|
|
1976
|
+
maxSequence = Math.max(messageCount, 0);
|
|
1977
|
+
}
|
|
1774
1978
|
return Math.max(maxSequence + 1, 1);
|
|
1775
1979
|
}
|
|
1776
1980
|
async waitForResolvedStartBinding(sessionId, workspaceId, provider, handle) {
|
|
@@ -1859,7 +2063,7 @@ export class SessionLiveRuntimeService {
|
|
|
1859
2063
|
};
|
|
1860
2064
|
}
|
|
1861
2065
|
async maybeEmitRuntimeHistoryFallback(sessionId, event) {
|
|
1862
|
-
if (event.provider
|
|
2066
|
+
if (!isClaudeCompatibleProvider(event.provider)) {
|
|
1863
2067
|
return;
|
|
1864
2068
|
}
|
|
1865
2069
|
if (event.status === "starting") {
|
|
@@ -1880,16 +2084,11 @@ export class SessionLiveRuntimeService {
|
|
|
1880
2084
|
this.runtimeHistoryFallbackSentSessions.add(sessionId);
|
|
1881
2085
|
await this.emitExternalRuntimeEnvelope(envelope);
|
|
1882
2086
|
}
|
|
1883
|
-
ensureCapability(
|
|
1884
|
-
if (
|
|
2087
|
+
ensureCapability(capabilities, field, capability, detail) {
|
|
2088
|
+
if (capabilities[capability]) {
|
|
1885
2089
|
return;
|
|
1886
2090
|
}
|
|
1887
|
-
throw
|
|
1888
|
-
statusCode: 400,
|
|
1889
|
-
errorCode: "CAPABILITY_NOT_SUPPORTED",
|
|
1890
|
-
detail,
|
|
1891
|
-
field
|
|
1892
|
-
});
|
|
2091
|
+
throw createProviderCapabilityBlockedError(capabilities, field, detail);
|
|
1893
2092
|
}
|
|
1894
2093
|
upsertSnapshot(sessionId, input) {
|
|
1895
2094
|
this.sessionStatusSnapshotRepository.upsert({
|
|
@@ -1901,7 +2100,7 @@ export class SessionLiveRuntimeService {
|
|
|
1901
2100
|
shouldIgnoreClaudeExternalRuntimeUpdate(sessionId) {
|
|
1902
2101
|
const runtimeSnapshot = this.getLiveRuntimeSnapshot(sessionId);
|
|
1903
2102
|
return Boolean(runtimeSnapshot &&
|
|
1904
|
-
runtimeSnapshot.provider
|
|
2103
|
+
isClaudeCompatibleProvider(runtimeSnapshot.provider) &&
|
|
1905
2104
|
isActiveRuntimeState(runtimeSnapshot.runningState));
|
|
1906
2105
|
}
|
|
1907
2106
|
clearExternalRuntimeSnapshot(sessionId) {
|
|
@@ -1943,7 +2142,7 @@ export class SessionLiveRuntimeService {
|
|
|
1943
2142
|
async resolveActiveClaudePermissionSession(input) {
|
|
1944
2143
|
const activeSnapshots = this.providerRuntimeService
|
|
1945
2144
|
.listSnapshots()
|
|
1946
|
-
.filter((snapshot) => snapshot.provider ===
|
|
2145
|
+
.filter((snapshot) => snapshot.provider === input.provider &&
|
|
1947
2146
|
snapshot.workspaceId === input.workspaceId &&
|
|
1948
2147
|
isActiveRuntimeState(snapshot.runningState));
|
|
1949
2148
|
if (activeSnapshots.length !== 1) {
|
|
@@ -1955,9 +2154,9 @@ export class SessionLiveRuntimeService {
|
|
|
1955
2154
|
}
|
|
1956
2155
|
const rawStoreRef = input.transcriptPath ??
|
|
1957
2156
|
activeSnapshot.rawStoreRef ??
|
|
1958
|
-
|
|
2157
|
+
buildClaudeCompatibleRawStoreRef(this.config, input.provider, input.workspacePath, input.providerSessionId);
|
|
1959
2158
|
this.sessionHistoryService.persistSessionBinding(activeSnapshot.sessionId, input.workspaceId, {
|
|
1960
|
-
provider:
|
|
2159
|
+
provider: input.provider,
|
|
1961
2160
|
providerSessionId: input.providerSessionId,
|
|
1962
2161
|
rawStoreRef
|
|
1963
2162
|
});
|
|
@@ -2272,7 +2471,8 @@ function waitForAcceptedUserLookupWindow() {
|
|
|
2272
2471
|
});
|
|
2273
2472
|
}
|
|
2274
2473
|
function createProviderRuntimeAdapters(config, options = {}) {
|
|
2275
|
-
const claudeHookBridgeConfig = buildClaudeHookBridgeConfig(config);
|
|
2474
|
+
const claudeHookBridgeConfig = buildClaudeHookBridgeConfig(config, "claude-code");
|
|
2475
|
+
const legnaHookBridgeConfig = buildClaudeHookBridgeConfig(config, "legna-code");
|
|
2276
2476
|
const claudeAdapter = process.env.VITEST
|
|
2277
2477
|
? new ClaudeRuntimeAdapter({
|
|
2278
2478
|
homeDir: config.claudeCodeHomeDir,
|
|
@@ -2294,21 +2494,38 @@ function createProviderRuntimeAdapters(config, options = {}) {
|
|
|
2294
2494
|
if ("dispose" in claudeAdapter && typeof claudeAdapter.dispose === "function") {
|
|
2295
2495
|
disposables.push(claudeAdapter);
|
|
2296
2496
|
}
|
|
2297
|
-
const codexTransportHelper = process.env.VITEST
|
|
2298
|
-
? null
|
|
2299
|
-
: new CodexAppServerHelperClient(config.codexCliPath, {
|
|
2300
|
-
homeDir: config.codexHomeDir
|
|
2301
|
-
});
|
|
2302
|
-
if (codexTransportHelper) {
|
|
2303
|
-
disposables.push(codexTransportHelper);
|
|
2304
|
-
}
|
|
2305
2497
|
return {
|
|
2306
2498
|
adapters: [
|
|
2307
2499
|
claudeAdapter,
|
|
2500
|
+
new LegnaRuntimeAdapter({
|
|
2501
|
+
homeDir: config.legnaCodeHomeDir,
|
|
2502
|
+
commandPath: config.legnaCodeCliPath,
|
|
2503
|
+
legacyClaudeHomeDir: config.claudeCodeHomeDir,
|
|
2504
|
+
hookBridge: {
|
|
2505
|
+
url: legnaHookBridgeConfig.bridgeUrl,
|
|
2506
|
+
token: config.claudeHookBridgeToken,
|
|
2507
|
+
scriptPath: legnaHookBridgeConfig.scriptPath
|
|
2508
|
+
}
|
|
2509
|
+
}),
|
|
2308
2510
|
new CodexRuntimeAdapter({
|
|
2309
2511
|
homeDir: config.codexHomeDir,
|
|
2310
2512
|
commandPath: config.codexCliPath,
|
|
2311
|
-
transportFactory:
|
|
2513
|
+
transportFactory: process.env.VITEST
|
|
2514
|
+
? undefined
|
|
2515
|
+
: (request) => {
|
|
2516
|
+
const client = new CodexAppServerHelperClient(config.codexCliPath, {
|
|
2517
|
+
homeDir: request.runtimeHomeDir?.trim() || config.codexHomeDir,
|
|
2518
|
+
runtimeEnv: request.runtimeEnv ?? null
|
|
2519
|
+
});
|
|
2520
|
+
const transport = client.createTransport();
|
|
2521
|
+
return {
|
|
2522
|
+
...transport,
|
|
2523
|
+
close() {
|
|
2524
|
+
transport.close();
|
|
2525
|
+
client.dispose();
|
|
2526
|
+
}
|
|
2527
|
+
};
|
|
2528
|
+
},
|
|
2312
2529
|
handleServerRequest: options.handleCodexServerRequest
|
|
2313
2530
|
}),
|
|
2314
2531
|
new GeminiRuntimeAdapter({
|
|
@@ -2333,20 +2550,27 @@ function resolveRuntimeInstructionFilePath(provider, workspacePath, explicitFile
|
|
|
2333
2550
|
const resolvedExplicit = path.resolve(normalizedExplicit);
|
|
2334
2551
|
return existsSync(resolvedExplicit) ? resolvedExplicit : null;
|
|
2335
2552
|
}
|
|
2336
|
-
|
|
2553
|
+
const defaultInstructionFileNames = {
|
|
2554
|
+
"claude-code": "CLAUDE.md",
|
|
2555
|
+
"legna-code": "LEGNA.md"
|
|
2556
|
+
};
|
|
2557
|
+
const defaultInstructionFileName = defaultInstructionFileNames[provider];
|
|
2558
|
+
const defaultInstructionPath = defaultInstructionFileName
|
|
2559
|
+
? path.join(workspacePath, defaultInstructionFileName)
|
|
2560
|
+
: null;
|
|
2561
|
+
if (!defaultInstructionPath) {
|
|
2337
2562
|
return null;
|
|
2338
2563
|
}
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
? path.resolve(defaultClaudeInstructionPath)
|
|
2564
|
+
return existsSync(defaultInstructionPath)
|
|
2565
|
+
? path.resolve(defaultInstructionPath)
|
|
2342
2566
|
: null;
|
|
2343
2567
|
}
|
|
2344
|
-
function buildClaudeHookBridgeConfig(config) {
|
|
2345
|
-
const bridgeUrl =
|
|
2568
|
+
function buildClaudeHookBridgeConfig(config, provider) {
|
|
2569
|
+
const bridgeUrl = buildClaudeCompatibleHookBridgeUrl(config, provider);
|
|
2346
2570
|
const scriptPath = resolveClaudeHookBridgeScriptPath();
|
|
2347
2571
|
const command = `node "${scriptPath}" --url "${bridgeUrl}" --token "${config.claudeHookBridgeToken}"`;
|
|
2348
2572
|
return {
|
|
2349
|
-
provider
|
|
2573
|
+
provider,
|
|
2350
2574
|
bridgeUrl,
|
|
2351
2575
|
token: config.claudeHookBridgeToken,
|
|
2352
2576
|
scriptPath,
|
|
@@ -2376,26 +2600,30 @@ function resolveClaudeHookBridgeScriptPath() {
|
|
|
2376
2600
|
}
|
|
2377
2601
|
return candidates[0];
|
|
2378
2602
|
}
|
|
2379
|
-
function
|
|
2380
|
-
|
|
2603
|
+
function normalizeOptionalBindingValue(value) {
|
|
2604
|
+
const normalized = value?.trim();
|
|
2605
|
+
return normalized && normalized.length > 0 ? normalized : null;
|
|
2381
2606
|
}
|
|
2382
|
-
function
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
return null;
|
|
2607
|
+
function logOpenCodeOrderEnvelopeDebug(scope, detail) {
|
|
2608
|
+
if (!OPENCODE_ORDER_DEBUG_ENABLED) {
|
|
2609
|
+
return;
|
|
2386
2610
|
}
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
return candidates[0] ?? null;
|
|
2611
|
+
console.info(`[opencode-order-envelope] ${scope}`, {
|
|
2612
|
+
timestamp: new Date().toISOString(),
|
|
2613
|
+
...detail
|
|
2614
|
+
});
|
|
2392
2615
|
}
|
|
2393
|
-
function
|
|
2394
|
-
const
|
|
2395
|
-
const
|
|
2396
|
-
return
|
|
2397
|
-
.
|
|
2398
|
-
.
|
|
2399
|
-
.
|
|
2616
|
+
function summarizeOpenCodeOrderMessage(message) {
|
|
2617
|
+
const content = typeof message.content === "string" ? message.content : "";
|
|
2618
|
+
const normalized = content.replace(/\s+/g, " ").trim();
|
|
2619
|
+
return {
|
|
2620
|
+
messageId: message.messageId ?? null,
|
|
2621
|
+
role: message.role ?? null,
|
|
2622
|
+
kind: message.kind ?? null,
|
|
2623
|
+
sequence: message.sequence ?? null,
|
|
2624
|
+
timestamp: message.timestamp ?? null,
|
|
2625
|
+
rawRef: message.rawRef ?? null,
|
|
2626
|
+
contentPreview: normalized.length > 80 ? `${normalized.slice(0, 80)}...` : normalized
|
|
2627
|
+
};
|
|
2400
2628
|
}
|
|
2401
2629
|
//# sourceMappingURL=session-live-runtime-service.js.map
|