@jingyi0605/codingns 0.6.0 → 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-uFwDdN-F.js → AdaptiveButlerPage-Dw72U3hG.js} +3 -3
- package/dist/public/assets/{App-BZvapsi8.js → App-Dsf3ooXU.js} +3 -3
- package/dist/public/assets/{BootstrapPage-gHSoa4JN.js → BootstrapPage-CE0m1qSR.js} +1 -1
- package/dist/public/assets/ConversationPage-8wOY7SX-.js +4 -0
- package/dist/public/assets/{DesktopDetachPreviewPage-4eMRxiBW.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-Bwv8Ovm_.js → MobileTopHeaderFrame-C5rIKQT6.js} +1 -1
- package/dist/public/assets/MobileWorkspaceSwitcherHeader-CfUnHgv_.js +1 -0
- package/dist/public/assets/{RelayConnectEntryPage-D_4YL-YH.js → RelayConnectEntryPage-CgMvVZwa.js} +1 -1
- package/dist/public/assets/{ServerSettingsModal-CMSm3BZU.js → ServerSettingsModal-CFul__z1.js} +1 -1
- 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-DaooFaJ4.js → TerminalPage-DWHv6mlu.js} +1 -1
- package/dist/public/assets/TerminalRuntimeFallbackModal-B29YxbQe.js +1 -0
- package/dist/public/assets/{ToolFilesPage-CGxBvYG0.js → ToolFilesPage-Dx9cv9hu.js} +1 -1
- 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-0tPIIhca.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-BZpL17fc.js → client-runtime-manager-DROQJ9v3.js} +1 -1
- package/dist/public/assets/{file-tree-icon-Db5LXC8h.js → file-tree-icon-Bp3Ntt7u.js} +1 -1
- 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-1mxe_Oh8.js → login-direct-candidate-resolver-DotM530R.js} +1 -1
- package/dist/public/assets/model-switch-api-Bh9nYslz.js +1 -0
- package/dist/public/assets/{preferences-service-DWnzl5a0.js → preferences-service-BG6GKG29.js} +1 -1
- package/dist/public/assets/{relay-entry-C5_Iay0I.js → relay-entry-pmr-c42O.js} +1 -1
- package/dist/public/assets/session-runtime-machine-YN84QBlr.js +21 -0
- package/dist/public/assets/{terminal-runtime-meta-cdtWVfCm.js → terminal-runtime-meta-8_uRZf7h.js} +1 -1
- package/dist/public/assets/useRegisteredDebugTemplates-DWX7LXQu.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/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 +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-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/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 +12 -2
- package/dist/server/modules/sessions/session-history-service.js +284 -16
- package/dist/server/modules/sessions/session-history-service.js.map +1 -1
- package/dist/server/modules/sessions/session-live-runtime-service.d.ts +15 -2
- package/dist/server/modules/sessions/session-live-runtime-service.js +265 -50
- 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/server/create-server.js +11 -8
- package/dist/server/server/create-server.js.map +1 -1
- 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 +19 -0
- package/dist/server/storage/sqlite/client.js.map +1 -1
- package/dist/server/storage/sqlite/schema.sql +5 -0
- package/dist/server/types/domain.d.ts +6 -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 +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 +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/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/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
|
@@ -6,7 +6,7 @@ import type { SessionIndexRepository } from "../../storage/repositories/session-
|
|
|
6
6
|
import type { SessionSendQueueRepository } from "../../storage/repositories/session-send-queue-repository.js";
|
|
7
7
|
import type { SessionStateRepository } from "../../storage/repositories/session-state-repository.js";
|
|
8
8
|
import type { SessionStatusSnapshotRepository } from "../../storage/repositories/session-status-snapshot-repository.js";
|
|
9
|
-
import type { SessionActivityConfidence, SessionInterruptSource, SessionActivityResolutionSource, SessionListItem, SessionResolvedRunningState, SessionSendQueueItemRecord } from "../../types/domain.js";
|
|
9
|
+
import type { SessionActivityConfidence, SessionInterruptSource, SessionActivityResolutionSource, SessionListItem, SessionProviderConfigMode, SessionResolvedRunningState, SessionSendQueueItemRecord } from "../../types/domain.js";
|
|
10
10
|
import { SessionActivityAuthorityService, type SessionActivityObservation } from "./session-activity-authority-service.js";
|
|
11
11
|
import { SessionChangedFileService } from "./session-changed-file-service.js";
|
|
12
12
|
import type { WorkspaceService } from "../workspace/workspace-service.js";
|
|
@@ -14,6 +14,7 @@ import type { SessionAttachmentInput } from "./session-message-attachment-servic
|
|
|
14
14
|
import { SessionMessageAttachmentService } from "./session-message-attachment-service.js";
|
|
15
15
|
import { type SessionPermissionEnvelope, type SessionPermissionReplyInput, type SessionPermissionRequestView } from "./session-permission-request-service.js";
|
|
16
16
|
import type { SessionHistoryEnvelope, SessionHistoryMessageWithOrigin, SessionHistoryService } from "./session-history-service.js";
|
|
17
|
+
import { SessionProviderConfigService } from "./session-provider-config-service.js";
|
|
17
18
|
interface RuntimeSendOptions {
|
|
18
19
|
model?: string | null;
|
|
19
20
|
reasoningLevel?: string | null;
|
|
@@ -31,6 +32,8 @@ interface StartLiveSessionInput {
|
|
|
31
32
|
sessionKind?: "default" | "annotation";
|
|
32
33
|
annotationSourceMessageId?: string | null;
|
|
33
34
|
annotationSourceText?: string | null;
|
|
35
|
+
providerConfigMode?: SessionProviderConfigMode;
|
|
36
|
+
providerPresetId?: string | null;
|
|
34
37
|
runtimeOptions?: RuntimeSendOptions;
|
|
35
38
|
}
|
|
36
39
|
interface SendLiveMessageInput {
|
|
@@ -38,6 +41,8 @@ interface SendLiveMessageInput {
|
|
|
38
41
|
userId: string;
|
|
39
42
|
content: string;
|
|
40
43
|
clientRequestId: string | null;
|
|
44
|
+
providerConfigMode?: SessionProviderConfigMode;
|
|
45
|
+
providerPresetId?: string | null;
|
|
41
46
|
runtimeOptions?: RuntimeSendOptions;
|
|
42
47
|
}
|
|
43
48
|
interface LiveMessageAcceptedResult {
|
|
@@ -181,6 +186,7 @@ export declare class SessionLiveRuntimeService {
|
|
|
181
186
|
private readonly sessionIndexRepository;
|
|
182
187
|
private readonly sessionStateRepository;
|
|
183
188
|
private readonly sessionStatusSnapshotRepository;
|
|
189
|
+
private readonly sessionProviderConfigService;
|
|
184
190
|
private readonly config;
|
|
185
191
|
private readonly providerRuntimeService;
|
|
186
192
|
private readonly sessionActivityAuthorityService;
|
|
@@ -196,7 +202,7 @@ export declare class SessionLiveRuntimeService {
|
|
|
196
202
|
private readonly queueDispatchSessions;
|
|
197
203
|
private readonly queueRetryTimers;
|
|
198
204
|
private readonly pendingSendDebugTracesBySessionId;
|
|
199
|
-
constructor(sessionHistoryService: SessionHistoryService, sessionMessageAttachmentService: SessionMessageAttachmentService, workspaceService: WorkspaceService, sessionChangedFileService: SessionChangedFileService, sessionBindingRepository: SessionBindingRepository, authUserRepository: AuthUserRepository, sessionSendQueueRepository: SessionSendQueueRepository, sessionIndexRepository: SessionIndexRepository, sessionStateRepository: SessionStateRepository, sessionStatusSnapshotRepository: SessionStatusSnapshotRepository, config: HostConfig, sessionActivityAuthorityService?: SessionActivityAuthorityService);
|
|
205
|
+
constructor(sessionHistoryService: SessionHistoryService, sessionMessageAttachmentService: SessionMessageAttachmentService, workspaceService: WorkspaceService, sessionChangedFileService: SessionChangedFileService, sessionBindingRepository: SessionBindingRepository, authUserRepository: AuthUserRepository, sessionSendQueueRepository: SessionSendQueueRepository, sessionIndexRepository: SessionIndexRepository, sessionStateRepository: SessionStateRepository, sessionStatusSnapshotRepository: SessionStatusSnapshotRepository, sessionProviderConfigService: SessionProviderConfigService, config: HostConfig, sessionActivityAuthorityService?: SessionActivityAuthorityService);
|
|
200
206
|
startLiveSession(input: StartLiveSessionInput): Promise<LiveMessageAcceptedResult>;
|
|
201
207
|
sendLiveMessage(input: SendLiveMessageInput): Promise<LiveMessageAcceptedResult>;
|
|
202
208
|
listQueuedMessages(sessionId: string, userId: string): Promise<SessionQueueItemView[]>;
|
|
@@ -244,6 +250,13 @@ export declare class SessionLiveRuntimeService {
|
|
|
244
250
|
private resolveStartedSession;
|
|
245
251
|
private upsertRuntimeBackedSessionRecords;
|
|
246
252
|
private ensurePendingSessionBinding;
|
|
253
|
+
private resolveEffectiveSessionProviderBinding;
|
|
254
|
+
private getSessionBindingOrThrow;
|
|
255
|
+
private resolveRequestedSessionProviderBinding;
|
|
256
|
+
private persistResolvedSessionProviderBinding;
|
|
257
|
+
private assertProviderBindingStableDuringActiveRun;
|
|
258
|
+
private hasSessionProviderBindingChanged;
|
|
259
|
+
private resolveCodexRuntimeRequestRawStoreRef;
|
|
247
260
|
private buildBindingSnapshot;
|
|
248
261
|
private persistRuntimeEvent;
|
|
249
262
|
private emitTerminalStateEvent;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { existsSync, readdirSync } from "node:fs";
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, 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";
|
|
@@ -9,9 +9,10 @@ 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
11
|
import { SessionPermissionRequestService } from "./session-permission-request-service.js";
|
|
12
|
-
import { mapSessionProviderError } from "./session-provider-error-mapper.js";
|
|
12
|
+
import { appendSessionProviderErrorContext, mapSessionProviderError } from "./session-provider-error-mapper.js";
|
|
13
13
|
import { ClaudeRuntimeHelperAdapter } from "./claude-runtime-helper-client.js";
|
|
14
14
|
import { CodexAppServerHelperClient } from "./codex-app-server-helper-client.js";
|
|
15
|
+
const OPENCODE_ORDER_DEBUG_ENABLED = /^(1|true|yes)$/i.test(process.env.CODINGNS_OPENCODE_ORDER_DEBUG?.trim() ?? "");
|
|
15
16
|
const RUNTIME_START_BINDING_WAIT_TIMEOUT_MS = 10_000;
|
|
16
17
|
const START_BINDING_POLL_INTERVAL_MS = 50;
|
|
17
18
|
const EXTERNAL_RUNTIME_INTERRUPT_SUPPRESSION_MS = 30_000;
|
|
@@ -27,6 +28,7 @@ export class SessionLiveRuntimeService {
|
|
|
27
28
|
sessionIndexRepository;
|
|
28
29
|
sessionStateRepository;
|
|
29
30
|
sessionStatusSnapshotRepository;
|
|
31
|
+
sessionProviderConfigService;
|
|
30
32
|
config;
|
|
31
33
|
providerRuntimeService;
|
|
32
34
|
sessionActivityAuthorityService;
|
|
@@ -42,7 +44,7 @@ export class SessionLiveRuntimeService {
|
|
|
42
44
|
queueDispatchSessions = new Set();
|
|
43
45
|
queueRetryTimers = new Map();
|
|
44
46
|
pendingSendDebugTracesBySessionId = new Map();
|
|
45
|
-
constructor(sessionHistoryService, sessionMessageAttachmentService, workspaceService, sessionChangedFileService, sessionBindingRepository, authUserRepository, sessionSendQueueRepository, sessionIndexRepository, sessionStateRepository, sessionStatusSnapshotRepository, config, sessionActivityAuthorityService = new SessionActivityAuthorityService()) {
|
|
47
|
+
constructor(sessionHistoryService, sessionMessageAttachmentService, workspaceService, sessionChangedFileService, sessionBindingRepository, authUserRepository, sessionSendQueueRepository, sessionIndexRepository, sessionStateRepository, sessionStatusSnapshotRepository, sessionProviderConfigService, config, sessionActivityAuthorityService = new SessionActivityAuthorityService()) {
|
|
46
48
|
this.sessionHistoryService = sessionHistoryService;
|
|
47
49
|
this.sessionMessageAttachmentService = sessionMessageAttachmentService;
|
|
48
50
|
this.workspaceService = workspaceService;
|
|
@@ -53,6 +55,7 @@ export class SessionLiveRuntimeService {
|
|
|
53
55
|
this.sessionIndexRepository = sessionIndexRepository;
|
|
54
56
|
this.sessionStateRepository = sessionStateRepository;
|
|
55
57
|
this.sessionStatusSnapshotRepository = sessionStatusSnapshotRepository;
|
|
58
|
+
this.sessionProviderConfigService = sessionProviderConfigService;
|
|
56
59
|
this.config = config;
|
|
57
60
|
this.sessionActivityAuthorityService = sessionActivityAuthorityService;
|
|
58
61
|
this.sessionPermissionRequestService = new SessionPermissionRequestService(sessionHistoryService, sessionBindingRepository, authUserRepository, workspaceService, config, async (envelope) => {
|
|
@@ -79,7 +82,19 @@ export class SessionLiveRuntimeService {
|
|
|
79
82
|
});
|
|
80
83
|
try {
|
|
81
84
|
const capabilities = this.sessionHistoryService.getProviderCapabilitiesSnapshot(input.provider);
|
|
82
|
-
this.
|
|
85
|
+
const providerBinding = this.sessionProviderConfigService.prepareSessionBinding({
|
|
86
|
+
sessionId,
|
|
87
|
+
provider: input.provider,
|
|
88
|
+
providerConfigMode: input.providerConfigMode,
|
|
89
|
+
providerPresetId: input.providerPresetId ?? null
|
|
90
|
+
});
|
|
91
|
+
const providerLaunchContext = this.sessionProviderConfigService.resolveLaunchContext({
|
|
92
|
+
provider: input.provider,
|
|
93
|
+
providerConfigMode: providerBinding.providerConfigMode,
|
|
94
|
+
providerPresetId: providerBinding.providerPresetId,
|
|
95
|
+
runtimeHomeDir: providerBinding.runtimeHomeDir
|
|
96
|
+
});
|
|
97
|
+
this.ensurePendingSessionBinding(sessionId, workspace.id, input.provider, providerBinding);
|
|
83
98
|
const persistedAttachments = this.persistMessageAttachments(sessionId, input.clientRequestId, input.runtimeOptions?.attachments ?? []);
|
|
84
99
|
const providerPrompt = this.sessionMessageAttachmentService.buildProviderPrompt(input.provider, input.content, persistedAttachments.runtimeAttachments);
|
|
85
100
|
const providerInstructionFilePath = resolveRuntimeInstructionFilePath(input.provider, workspace.path, input.runtimeOptions?.providerInstructionFilePath ?? null);
|
|
@@ -93,6 +108,8 @@ export class SessionLiveRuntimeService {
|
|
|
93
108
|
provider: input.provider,
|
|
94
109
|
providerSessionId: null,
|
|
95
110
|
rawStoreRef: null,
|
|
111
|
+
runtimeHomeDir: providerLaunchContext.runtimeHomeDir,
|
|
112
|
+
runtimeEnv: providerLaunchContext.runtimeEnv,
|
|
96
113
|
sequenceBase: 1,
|
|
97
114
|
options: {
|
|
98
115
|
content: input.content,
|
|
@@ -104,7 +121,12 @@ export class SessionLiveRuntimeService {
|
|
|
104
121
|
providerInstructionFilePath,
|
|
105
122
|
attachments: persistedAttachments.runtimeAttachments
|
|
106
123
|
}
|
|
107
|
-
}, "start"
|
|
124
|
+
}, "start", {
|
|
125
|
+
provider: input.provider,
|
|
126
|
+
providerConfigMode: providerBinding.providerConfigMode,
|
|
127
|
+
providerPresetId: providerBinding.providerPresetId,
|
|
128
|
+
runtimeHomeDir: providerBinding.runtimeHomeDir
|
|
129
|
+
});
|
|
108
130
|
this.logSendDebugStep(debugTrace, "launch_runtime", launchRuntimeStartedAtMs, {
|
|
109
131
|
userId: input.userId
|
|
110
132
|
});
|
|
@@ -203,6 +225,7 @@ export class SessionLiveRuntimeService {
|
|
|
203
225
|
}
|
|
204
226
|
async enqueueLiveMessage(input) {
|
|
205
227
|
const session = await this.resolveQueueDispatchSession(input.sessionId, input.userId);
|
|
228
|
+
this.resolveEffectiveSessionProviderBinding(session, input);
|
|
206
229
|
this.persistMessageAttachments(input.sessionId, input.clientRequestId, input.runtimeOptions?.attachments ?? []);
|
|
207
230
|
const timestamp = nowIso();
|
|
208
231
|
const queueItem = {
|
|
@@ -649,6 +672,16 @@ export class SessionLiveRuntimeService {
|
|
|
649
672
|
if (!envelope) {
|
|
650
673
|
return;
|
|
651
674
|
}
|
|
675
|
+
logOpenCodeOrderEnvelopeDebug("runtime.envelope.forward", {
|
|
676
|
+
sessionId,
|
|
677
|
+
runtimeSessionId,
|
|
678
|
+
provider: event.provider ?? null,
|
|
679
|
+
eventType: event.type ?? null,
|
|
680
|
+
envelopeType: envelope.type,
|
|
681
|
+
message: "message" in envelope && envelope.message
|
|
682
|
+
? summarizeOpenCodeOrderMessage(envelope.message)
|
|
683
|
+
: null
|
|
684
|
+
});
|
|
652
685
|
await onEnvelope(envelope);
|
|
653
686
|
});
|
|
654
687
|
const externalSubscription = this.subscribeExternalRuntime(runtimeSessionId, async (envelope) => {
|
|
@@ -1027,14 +1060,14 @@ export class SessionLiveRuntimeService {
|
|
|
1027
1060
|
void this.dispatchNextQueuedMessage(input.sessionId);
|
|
1028
1061
|
}
|
|
1029
1062
|
}
|
|
1030
|
-
async startRuntimeRun(request, userId, mode) {
|
|
1063
|
+
async startRuntimeRun(request, userId, mode, providerBinding) {
|
|
1031
1064
|
this.runtimeMessageSeenSessions.delete(request.sessionId);
|
|
1032
1065
|
this.runtimeHistoryFallbackSentSessions.delete(request.sessionId);
|
|
1033
1066
|
this.clearExternalRuntimeInterruptSuppression(request.sessionId);
|
|
1034
1067
|
if (request.provider === "claude-code") {
|
|
1035
1068
|
this.clearExternalRuntimeSnapshot(request.sessionId);
|
|
1036
1069
|
}
|
|
1037
|
-
const handle = await this.launchRuntimeRun(request, mode);
|
|
1070
|
+
const handle = await this.launchRuntimeRun(request, mode, providerBinding);
|
|
1038
1071
|
const snapshot = handle.getSnapshot();
|
|
1039
1072
|
const currentState = this.sessionStateRepository.findBySessionAndUser(request.sessionId, userId);
|
|
1040
1073
|
this.attachRuntimePersistence(handle, request.sessionId, request.workspaceId, userId);
|
|
@@ -1066,9 +1099,43 @@ export class SessionLiveRuntimeService {
|
|
|
1066
1099
|
const capabilities = await this.sessionHistoryService.getSessionCapabilities(input.sessionId);
|
|
1067
1100
|
const workspace = this.workspaceService.getWorkspaceOrThrow(session.workspaceId);
|
|
1068
1101
|
const runtimeMode = shouldStartNativeSessionOnFirstMessage(session);
|
|
1102
|
+
const existingBinding = this.getSessionBindingOrThrow(session.sessionId);
|
|
1103
|
+
const resolvedProviderBinding = this.resolveRequestedSessionProviderBinding(session, input, existingBinding);
|
|
1104
|
+
const runtimeSessionId = this.resolveRuntimeSessionId(input.sessionId);
|
|
1105
|
+
const activeRun = this.getLiveRuntimeSnapshot(runtimeSessionId);
|
|
1106
|
+
const externalRuntimeSnapshot = this.getFreshExternalRuntimeSnapshot(runtimeSessionId);
|
|
1107
|
+
const hasActiveRun = Boolean(activeRun && isActiveRuntimeState(activeRun.runningState));
|
|
1108
|
+
if (hasActiveRun && activeRun?.provider === "claude-code") {
|
|
1109
|
+
this.clearExternalRuntimeSnapshot(runtimeSessionId);
|
|
1110
|
+
}
|
|
1111
|
+
if (hasActiveRun
|
|
1112
|
+
|| (!activeRun &&
|
|
1113
|
+
session.provider === "claude-code" &&
|
|
1114
|
+
externalRuntimeSnapshot &&
|
|
1115
|
+
isActiveRuntimeState(externalRuntimeSnapshot.runningState))) {
|
|
1116
|
+
this.assertProviderBindingStableDuringActiveRun(existingBinding, resolvedProviderBinding);
|
|
1117
|
+
}
|
|
1118
|
+
if (!activeRun &&
|
|
1119
|
+
session.provider === "claude-code" &&
|
|
1120
|
+
externalRuntimeSnapshot &&
|
|
1121
|
+
isActiveRuntimeState(externalRuntimeSnapshot.runningState)) {
|
|
1122
|
+
throw new AppError({
|
|
1123
|
+
statusCode: 409,
|
|
1124
|
+
errorCode: "SESSION_EXTERNAL_RUN_ACTIVE",
|
|
1125
|
+
detail: "当前 Claude 外部会话仍在运行,不能直接追加;请加入队列或等待当前轮结束",
|
|
1126
|
+
field: "sessionId"
|
|
1127
|
+
});
|
|
1128
|
+
}
|
|
1129
|
+
const providerBinding = hasActiveRun
|
|
1130
|
+
? existingBinding
|
|
1131
|
+
: this.persistResolvedSessionProviderBinding(existingBinding, resolvedProviderBinding);
|
|
1132
|
+
const providerLaunchContext = this.sessionProviderConfigService.resolveLaunchContext(providerBinding);
|
|
1069
1133
|
const syntheticForkRawStoreRef = runtimeMode === "start" && shouldResumeCodexSyntheticForkSession(session)
|
|
1070
1134
|
? session.rawStoreRef
|
|
1071
1135
|
: null;
|
|
1136
|
+
const runtimeRawStoreRef = runtimeMode === "start"
|
|
1137
|
+
? syntheticForkRawStoreRef
|
|
1138
|
+
: await this.resolveCodexRuntimeRequestRawStoreRef(session, providerBinding);
|
|
1072
1139
|
const nextUserSequence = runtimeMode === "start"
|
|
1073
1140
|
? 1
|
|
1074
1141
|
: await this.resolveNextUserSequence(input.sessionId, session.messageCount);
|
|
@@ -1083,7 +1150,9 @@ export class SessionLiveRuntimeService {
|
|
|
1083
1150
|
workspacePath: workspace.path,
|
|
1084
1151
|
provider: session.provider,
|
|
1085
1152
|
providerSessionId: runtimeMode === "start" ? null : session.providerSessionId,
|
|
1086
|
-
rawStoreRef:
|
|
1153
|
+
rawStoreRef: runtimeRawStoreRef,
|
|
1154
|
+
runtimeHomeDir: providerLaunchContext.runtimeHomeDir,
|
|
1155
|
+
runtimeEnv: providerLaunchContext.runtimeEnv,
|
|
1087
1156
|
sequenceBase: nextUserSequence,
|
|
1088
1157
|
options: {
|
|
1089
1158
|
content: input.content,
|
|
@@ -1096,26 +1165,7 @@ export class SessionLiveRuntimeService {
|
|
|
1096
1165
|
attachments: resolvedAttachments.runtimeAttachments
|
|
1097
1166
|
}
|
|
1098
1167
|
};
|
|
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)) {
|
|
1168
|
+
if (hasActiveRun) {
|
|
1119
1169
|
const submitStartedAtMs = performance.now();
|
|
1120
1170
|
try {
|
|
1121
1171
|
await this.providerRuntimeService.submitToActiveRun(runtimeSessionId, runtimeRequest.options);
|
|
@@ -1125,13 +1175,23 @@ export class SessionLiveRuntimeService {
|
|
|
1125
1175
|
});
|
|
1126
1176
|
}
|
|
1127
1177
|
catch (error) {
|
|
1128
|
-
const mapped = mapSessionProviderError(error)
|
|
1178
|
+
const mapped = appendSessionProviderErrorContext(mapSessionProviderError(error), this.sessionProviderConfigService.describeBinding({
|
|
1179
|
+
provider: session.provider,
|
|
1180
|
+
providerConfigMode: providerBinding.providerConfigMode,
|
|
1181
|
+
providerPresetId: providerBinding.providerPresetId,
|
|
1182
|
+
runtimeHomeDir: providerBinding.runtimeHomeDir
|
|
1183
|
+
}));
|
|
1129
1184
|
// 运行时句柄还没来得及收尾时,steer 可能会撞上 provider 已终态。
|
|
1130
1185
|
// 这里直接失败只会把一条正常消息变成偶发 409,属于纯粹的坏味道。
|
|
1131
1186
|
if (mapped.errorCode === "SESSION_NOT_RUNNING") {
|
|
1132
1187
|
await this.providerRuntimeService.abandonRun(runtimeSessionId);
|
|
1133
1188
|
const restartRuntimeStartedAtMs = performance.now();
|
|
1134
|
-
await this.startRuntimeRun(runtimeRequest, input.userId, runtimeMode
|
|
1189
|
+
await this.startRuntimeRun(runtimeRequest, input.userId, runtimeMode, {
|
|
1190
|
+
provider: session.provider,
|
|
1191
|
+
providerConfigMode: providerBinding.providerConfigMode,
|
|
1192
|
+
providerPresetId: providerBinding.providerPresetId,
|
|
1193
|
+
runtimeHomeDir: providerBinding.runtimeHomeDir
|
|
1194
|
+
});
|
|
1135
1195
|
this.logSendDebugStep(debugTrace, "restart_runtime_after_stale_active_run", restartRuntimeStartedAtMs, {
|
|
1136
1196
|
runtimeMode
|
|
1137
1197
|
});
|
|
@@ -1143,7 +1203,12 @@ export class SessionLiveRuntimeService {
|
|
|
1143
1203
|
}
|
|
1144
1204
|
else {
|
|
1145
1205
|
const startRuntimeStartedAtMs = performance.now();
|
|
1146
|
-
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
|
+
});
|
|
1147
1212
|
this.logSendDebugStep(debugTrace, "start_runtime_run", startRuntimeStartedAtMs, {
|
|
1148
1213
|
runtimeMode
|
|
1149
1214
|
});
|
|
@@ -1305,14 +1370,18 @@ export class SessionLiveRuntimeService {
|
|
|
1305
1370
|
.then((refreshedSession) => refreshedSession ?? session)
|
|
1306
1371
|
.catch(() => session);
|
|
1307
1372
|
}
|
|
1308
|
-
async launchRuntimeRun(request, mode) {
|
|
1373
|
+
async launchRuntimeRun(request, mode, providerBinding) {
|
|
1309
1374
|
try {
|
|
1310
1375
|
return await (mode === "start"
|
|
1311
1376
|
? this.providerRuntimeService.startSession(request)
|
|
1312
1377
|
: this.providerRuntimeService.continueSession(request));
|
|
1313
1378
|
}
|
|
1314
1379
|
catch (error) {
|
|
1315
|
-
|
|
1380
|
+
const mapped = mapSessionProviderError(error);
|
|
1381
|
+
if (!providerBinding) {
|
|
1382
|
+
throw mapped;
|
|
1383
|
+
}
|
|
1384
|
+
throw appendSessionProviderErrorContext(mapped, this.sessionProviderConfigService.describeBinding(providerBinding));
|
|
1316
1385
|
}
|
|
1317
1386
|
}
|
|
1318
1387
|
attachRuntimePersistence(handle, sessionId, workspaceId, userId) {
|
|
@@ -1390,8 +1459,109 @@ export class SessionLiveRuntimeService {
|
|
|
1390
1459
|
});
|
|
1391
1460
|
this.sessionActivityAuthorityService.observe(createRuntimeActivityObservation(input.sessionId, input.snapshot));
|
|
1392
1461
|
}
|
|
1393
|
-
ensurePendingSessionBinding(sessionId, workspaceId, provider) {
|
|
1394
|
-
|
|
1462
|
+
ensurePendingSessionBinding(sessionId, workspaceId, provider, providerBinding) {
|
|
1463
|
+
const snapshot = this.buildBindingSnapshot(sessionId, provider, null, null);
|
|
1464
|
+
const timestamp = nowIso();
|
|
1465
|
+
const existingBinding = this.sessionBindingRepository.findBySessionId(sessionId);
|
|
1466
|
+
this.sessionBindingRepository.upsert({
|
|
1467
|
+
sessionId,
|
|
1468
|
+
workspaceId,
|
|
1469
|
+
provider: snapshot.provider,
|
|
1470
|
+
providerSessionId: snapshot.providerSessionId,
|
|
1471
|
+
rawStoreRef: snapshot.rawStoreRef,
|
|
1472
|
+
providerConfigMode: providerBinding?.providerConfigMode ?? existingBinding?.providerConfigMode ?? "global-default",
|
|
1473
|
+
providerPresetId: providerBinding?.providerPresetId ?? existingBinding?.providerPresetId ?? null,
|
|
1474
|
+
runtimeHomeDir: providerBinding?.runtimeHomeDir ?? existingBinding?.runtimeHomeDir ?? null,
|
|
1475
|
+
createdAt: existingBinding?.createdAt ?? timestamp,
|
|
1476
|
+
updatedAt: timestamp
|
|
1477
|
+
});
|
|
1478
|
+
}
|
|
1479
|
+
resolveEffectiveSessionProviderBinding(session, input) {
|
|
1480
|
+
const existingBinding = this.getSessionBindingOrThrow(session.sessionId);
|
|
1481
|
+
const providerBinding = this.resolveRequestedSessionProviderBinding(session, input, existingBinding);
|
|
1482
|
+
return this.persistResolvedSessionProviderBinding(existingBinding, providerBinding);
|
|
1483
|
+
}
|
|
1484
|
+
getSessionBindingOrThrow(sessionId) {
|
|
1485
|
+
const existingBinding = this.sessionBindingRepository.findBySessionId(sessionId);
|
|
1486
|
+
if (!existingBinding) {
|
|
1487
|
+
throw new AppError({
|
|
1488
|
+
statusCode: 404,
|
|
1489
|
+
errorCode: "SESSION_NOT_FOUND",
|
|
1490
|
+
detail: "session 不存在"
|
|
1491
|
+
});
|
|
1492
|
+
}
|
|
1493
|
+
return existingBinding;
|
|
1494
|
+
}
|
|
1495
|
+
resolveRequestedSessionProviderBinding(session, input, existingBinding) {
|
|
1496
|
+
return this.sessionProviderConfigService.resolveSessionBinding({
|
|
1497
|
+
sessionId: session.sessionId,
|
|
1498
|
+
provider: session.provider,
|
|
1499
|
+
existingBinding,
|
|
1500
|
+
providerConfigMode: input.providerConfigMode,
|
|
1501
|
+
providerPresetId: input.providerPresetId ?? null
|
|
1502
|
+
});
|
|
1503
|
+
}
|
|
1504
|
+
persistResolvedSessionProviderBinding(existingBinding, providerBinding) {
|
|
1505
|
+
if (!this.hasSessionProviderBindingChanged(existingBinding, providerBinding)) {
|
|
1506
|
+
return existingBinding;
|
|
1507
|
+
}
|
|
1508
|
+
const nextBinding = {
|
|
1509
|
+
...existingBinding,
|
|
1510
|
+
providerConfigMode: providerBinding.providerConfigMode,
|
|
1511
|
+
providerPresetId: providerBinding.providerPresetId,
|
|
1512
|
+
runtimeHomeDir: providerBinding.runtimeHomeDir,
|
|
1513
|
+
updatedAt: nowIso()
|
|
1514
|
+
};
|
|
1515
|
+
this.sessionBindingRepository.upsert(nextBinding);
|
|
1516
|
+
return nextBinding;
|
|
1517
|
+
}
|
|
1518
|
+
assertProviderBindingStableDuringActiveRun(existingBinding, requestedBinding) {
|
|
1519
|
+
if (!this.hasSessionProviderBindingChanged(existingBinding, requestedBinding)) {
|
|
1520
|
+
return;
|
|
1521
|
+
}
|
|
1522
|
+
throw new AppError({
|
|
1523
|
+
statusCode: 409,
|
|
1524
|
+
errorCode: "SESSION_PROVIDER_CONFIG_CHANGE_REQUIRES_NEW_RUN",
|
|
1525
|
+
detail: "当前会话仍在执行,不能中途切换模型配置文件;请等本轮结束后再发起新一轮",
|
|
1526
|
+
field: "sessionId"
|
|
1527
|
+
});
|
|
1528
|
+
}
|
|
1529
|
+
hasSessionProviderBindingChanged(currentBinding, nextBinding) {
|
|
1530
|
+
return (currentBinding.providerConfigMode !== nextBinding.providerConfigMode
|
|
1531
|
+
|| normalizeOptionalBindingValue(currentBinding.providerPresetId)
|
|
1532
|
+
!== normalizeOptionalBindingValue(nextBinding.providerPresetId)
|
|
1533
|
+
|| normalizeOptionalBindingValue(currentBinding.runtimeHomeDir)
|
|
1534
|
+
!== normalizeOptionalBindingValue(nextBinding.runtimeHomeDir));
|
|
1535
|
+
}
|
|
1536
|
+
async resolveCodexRuntimeRequestRawStoreRef(session, providerBinding) {
|
|
1537
|
+
if (session.provider !== "codex") {
|
|
1538
|
+
return session.rawStoreRef;
|
|
1539
|
+
}
|
|
1540
|
+
const currentRawStoreRef = session.rawStoreRef?.trim() || null;
|
|
1541
|
+
if (currentRawStoreRef && existsSync(currentRawStoreRef)) {
|
|
1542
|
+
return currentRawStoreRef;
|
|
1543
|
+
}
|
|
1544
|
+
const messages = await Promise.resolve(this.sessionHistoryService.readAllTextHistoryMessages(session.sessionId)).catch(() => []);
|
|
1545
|
+
if (!Array.isArray(messages) || messages.length === 0) {
|
|
1546
|
+
return currentRawStoreRef;
|
|
1547
|
+
}
|
|
1548
|
+
const baseDir = providerBinding.runtimeHomeDir?.trim()
|
|
1549
|
+
|| path.resolve(path.dirname(this.config.databasePath), "runtime", "codex-resume-history");
|
|
1550
|
+
const syntheticDir = path.join(baseDir, ".codingns-synthetic-resume");
|
|
1551
|
+
const syntheticFilePath = path.join(syntheticDir, `${session.sessionId}.jsonl`);
|
|
1552
|
+
const serialized = messages
|
|
1553
|
+
.map((message) => JSON.stringify({
|
|
1554
|
+
timestamp: message.timestamp,
|
|
1555
|
+
type: "event_msg",
|
|
1556
|
+
payload: {
|
|
1557
|
+
type: message.role === "assistant" ? "agent_message" : "user_message",
|
|
1558
|
+
message: message.content
|
|
1559
|
+
}
|
|
1560
|
+
}))
|
|
1561
|
+
.join("\n");
|
|
1562
|
+
mkdirSync(syntheticDir, { recursive: true });
|
|
1563
|
+
writeFileSync(syntheticFilePath, `${serialized}\n`, "utf8");
|
|
1564
|
+
return syntheticFilePath;
|
|
1395
1565
|
}
|
|
1396
1566
|
buildBindingSnapshot(sessionId, provider, providerSessionId, rawStoreRef) {
|
|
1397
1567
|
const pendingValue = `pending://${provider}/${sessionId}`;
|
|
@@ -1762,7 +1932,7 @@ export class SessionLiveRuntimeService {
|
|
|
1762
1932
|
}
|
|
1763
1933
|
}
|
|
1764
1934
|
async resolveNextUserSequence(sessionId, messageCount) {
|
|
1765
|
-
let maxSequence =
|
|
1935
|
+
let maxSequence = 0;
|
|
1766
1936
|
const envelope = await Promise.resolve(this.sessionHistoryService.readRecentHistoryEnvelope(sessionId, 10)).catch(() => {
|
|
1767
1937
|
return null;
|
|
1768
1938
|
});
|
|
@@ -1771,6 +1941,9 @@ export class SessionLiveRuntimeService {
|
|
|
1771
1941
|
maxSequence = message.sequence;
|
|
1772
1942
|
}
|
|
1773
1943
|
}
|
|
1944
|
+
if (maxSequence <= 0) {
|
|
1945
|
+
maxSequence = Math.max(messageCount, 0);
|
|
1946
|
+
}
|
|
1774
1947
|
return Math.max(maxSequence + 1, 1);
|
|
1775
1948
|
}
|
|
1776
1949
|
async waitForResolvedStartBinding(sessionId, workspaceId, provider, handle) {
|
|
@@ -2294,21 +2467,33 @@ function createProviderRuntimeAdapters(config, options = {}) {
|
|
|
2294
2467
|
if ("dispose" in claudeAdapter && typeof claudeAdapter.dispose === "function") {
|
|
2295
2468
|
disposables.push(claudeAdapter);
|
|
2296
2469
|
}
|
|
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
2470
|
return {
|
|
2306
2471
|
adapters: [
|
|
2307
2472
|
claudeAdapter,
|
|
2473
|
+
new LegnaRuntimeAdapter({
|
|
2474
|
+
homeDir: config.legnaCodeHomeDir,
|
|
2475
|
+
commandPath: config.legnaCodeCliPath,
|
|
2476
|
+
legacyClaudeHomeDir: config.claudeCodeHomeDir
|
|
2477
|
+
}),
|
|
2308
2478
|
new CodexRuntimeAdapter({
|
|
2309
2479
|
homeDir: config.codexHomeDir,
|
|
2310
2480
|
commandPath: config.codexCliPath,
|
|
2311
|
-
transportFactory:
|
|
2481
|
+
transportFactory: process.env.VITEST
|
|
2482
|
+
? undefined
|
|
2483
|
+
: (request) => {
|
|
2484
|
+
const client = new CodexAppServerHelperClient(config.codexCliPath, {
|
|
2485
|
+
homeDir: request.runtimeHomeDir?.trim() || config.codexHomeDir,
|
|
2486
|
+
runtimeEnv: request.runtimeEnv ?? null
|
|
2487
|
+
});
|
|
2488
|
+
const transport = client.createTransport();
|
|
2489
|
+
return {
|
|
2490
|
+
...transport,
|
|
2491
|
+
close() {
|
|
2492
|
+
transport.close();
|
|
2493
|
+
client.dispose();
|
|
2494
|
+
}
|
|
2495
|
+
};
|
|
2496
|
+
},
|
|
2312
2497
|
handleServerRequest: options.handleCodexServerRequest
|
|
2313
2498
|
}),
|
|
2314
2499
|
new GeminiRuntimeAdapter({
|
|
@@ -2333,12 +2518,16 @@ function resolveRuntimeInstructionFilePath(provider, workspacePath, explicitFile
|
|
|
2333
2518
|
const resolvedExplicit = path.resolve(normalizedExplicit);
|
|
2334
2519
|
return existsSync(resolvedExplicit) ? resolvedExplicit : null;
|
|
2335
2520
|
}
|
|
2336
|
-
|
|
2521
|
+
const defaultInstructionPath = provider === "claude-code"
|
|
2522
|
+
? path.join(workspacePath, "CLAUDE.md")
|
|
2523
|
+
: provider === "legna-code"
|
|
2524
|
+
? path.join(workspacePath, "LEGNA.md")
|
|
2525
|
+
: null;
|
|
2526
|
+
if (!defaultInstructionPath) {
|
|
2337
2527
|
return null;
|
|
2338
2528
|
}
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
? path.resolve(defaultClaudeInstructionPath)
|
|
2529
|
+
return existsSync(defaultInstructionPath)
|
|
2530
|
+
? path.resolve(defaultInstructionPath)
|
|
2342
2531
|
: null;
|
|
2343
2532
|
}
|
|
2344
2533
|
function buildClaudeHookBridgeConfig(config) {
|
|
@@ -2398,4 +2587,30 @@ function workspaceSlug(workspacePath) {
|
|
|
2398
2587
|
.replaceAll("\\", "-")
|
|
2399
2588
|
.replaceAll("/", "-");
|
|
2400
2589
|
}
|
|
2590
|
+
function normalizeOptionalBindingValue(value) {
|
|
2591
|
+
const normalized = value?.trim();
|
|
2592
|
+
return normalized && normalized.length > 0 ? normalized : null;
|
|
2593
|
+
}
|
|
2594
|
+
function logOpenCodeOrderEnvelopeDebug(scope, detail) {
|
|
2595
|
+
if (!OPENCODE_ORDER_DEBUG_ENABLED) {
|
|
2596
|
+
return;
|
|
2597
|
+
}
|
|
2598
|
+
console.info(`[opencode-order-envelope] ${scope}`, {
|
|
2599
|
+
timestamp: new Date().toISOString(),
|
|
2600
|
+
...detail
|
|
2601
|
+
});
|
|
2602
|
+
}
|
|
2603
|
+
function summarizeOpenCodeOrderMessage(message) {
|
|
2604
|
+
const content = typeof message.content === "string" ? message.content : "";
|
|
2605
|
+
const normalized = content.replace(/\s+/g, " ").trim();
|
|
2606
|
+
return {
|
|
2607
|
+
messageId: message.messageId ?? null,
|
|
2608
|
+
role: message.role ?? null,
|
|
2609
|
+
kind: message.kind ?? null,
|
|
2610
|
+
sequence: message.sequence ?? null,
|
|
2611
|
+
timestamp: message.timestamp ?? null,
|
|
2612
|
+
rawRef: message.rawRef ?? null,
|
|
2613
|
+
contentPreview: normalized.length > 80 ? `${normalized.slice(0, 80)}...` : normalized
|
|
2614
|
+
};
|
|
2615
|
+
}
|
|
2401
2616
|
//# sourceMappingURL=session-live-runtime-service.js.map
|