From ca9d0c25908439d4efc9871cebb25992328e3096 Mon Sep 17 00:00:00 2001 From: Etienne Lescot Date: Tue, 28 Jul 2026 16:48:50 +0200 Subject: [PATCH 1/2] refactor: drop legacy single-session default chat path --- electron/ai-edition/chat-service.ts | 38 --------------- electron/ipc/handlers.ts | 7 --- electron/ipc/nativeBridge.ts | 33 ------------- .../services/aiEditionService.ts | 22 --------- src/native/browserShim.ts | 46 ------------------- src/native/client.ts | 42 +++-------------- 6 files changed, 6 insertions(+), 182 deletions(-) diff --git a/electron/ai-edition/chat-service.ts b/electron/ai-edition/chat-service.ts index 1dad3ceca..3e9c3e5d7 100644 --- a/electron/ai-edition/chat-service.ts +++ b/electron/ai-edition/chat-service.ts @@ -579,44 +579,6 @@ function emptyDocumentForTextOnly(projectId: string): AxcutDocument { return createEmptyDocument({ title: "Untitled project", projectId }); } -// ponytail: legacy single-session compatibility for the simpler ChatPanel -// consumers. Picks the most recent session (or auto-creates one) so a stale -// caller keeps working. The multi-session UI is the supported path. -function getOrCreateDefaultSession(projectId: string): ChatSession { - const m = getProjectSessions(projectId); - if (m.size > 0) { - const arr = Array.from(m.values()).sort((a, b) => b.createdAt.localeCompare(a.createdAt)); - return arr[0]; - } - const created = createSession(projectId); - const s = m.get(created.id); - if (!s) throw new Error("Chat session unavailable."); - return s; -} - -export async function runChatDefault( - projectId: string, - message: string, - llmConfig: LlmConfigStore, - sink?: ChatEventSink, -): Promise { - const session = getOrCreateDefaultSession(projectId); - return runChat(projectId, session.id, message, llmConfig, undefined, sink); -} - -export function getDefaultChatHistory(projectId: string): AiEditionChatMessage[] { - const m = sessionsByProject.get(projectId); - if (!m || m.size === 0) return []; - const arr = Array.from(m.values()).sort((a, b) => b.createdAt.localeCompare(a.createdAt)); - return [...arr[0].messages]; -} - -export function clearDefaultChatHistory(projectId: string): void { - const m = sessionsByProject.get(projectId); - if (!m) return; - for (const s of m.values()) s.messages = []; -} - // --- Compaction (P3.7) --------------------------------------------------- export interface SessionBudgetSnapshot { diff --git a/electron/ipc/handlers.ts b/electron/ipc/handlers.ts index 64504872b..303974a6a 100644 --- a/electron/ipc/handlers.ts +++ b/electron/ipc/handlers.ts @@ -36,17 +36,14 @@ import type { ProjectPathResult, } from "../../src/native/contracts"; import { - clearDefaultChatHistory, compactSessionNow, createSession, deleteSession, - getDefaultChatHistory, getSessionContextUsage, listSessions, renameSession, rewindToMessage, runChat, - runChatDefault, selectSession, } from "../ai-edition/chat-service"; import { DocumentService } from "../ai-edition/document-service"; @@ -3422,10 +3419,6 @@ export function registerIpcHandlers( compactNow: (projectId, sessionId) => compactSessionNow(projectId, sessionId, aiEditionLlmConfig), getContextUsage: getSessionContextUsage, - runAiEditionChatDefault: (projectId, message, sink) => - runChatDefault(projectId, message, aiEditionLlmConfig, sink), - getAiEditionChatHistoryDefault: (projectId) => getDefaultChatHistory(projectId), - clearAiEditionChatHistoryDefault: (projectId) => clearDefaultChatHistory(projectId), listAiEditionChatSessions: (projectId) => listSessions(projectId), createAiEditionChatSession: (projectId, title) => createSession(projectId, title), selectAiEditionChatSession: (projectId, sessionId) => selectSession(projectId, sessionId), diff --git a/electron/ipc/nativeBridge.ts b/electron/ipc/nativeBridge.ts index 99cb185fb..dabf62955 100644 --- a/electron/ipc/nativeBridge.ts +++ b/electron/ipc/nativeBridge.ts @@ -83,15 +83,6 @@ export interface NativeBridgeContext { projectId: string, sessionId: string, ) => import("../../src/native/contracts").AiEditionChatBudget | null; - runAiEditionChatDefault: ( - projectId: string, - message: string, - sink?: ChatEventSink, - ) => Promise; - getAiEditionChatHistoryDefault: ( - projectId: string, - ) => import("../../src/native/contracts").AiEditionChatMessage[]; - clearAiEditionChatHistoryDefault: (projectId: string) => void; listAiEditionChatSessions: ( projectId: string, ) => import("../../src/native/contracts").AiEditionChatSessionSummary[]; @@ -232,13 +223,10 @@ export function registerNativeBridgeHandlers(context: NativeBridgeContext) { documents: context.getAiEditionDocuments(), llmConfig: context.getAiEditionLlmConfig(), runChat: context.runAiEditionChat, - runChatDefault: context.runAiEditionChatDefault, undoLastToolBatch: context.undoAiEditionToolBatch, rewindToMessage: context.rewindToMessage, compactNow: context.compactNow, getContextUsage: context.getContextUsage, - getDefaultChatHistory: context.getAiEditionChatHistoryDefault, - clearDefaultChatHistory: context.clearAiEditionChatHistoryDefault, listSessions: context.listAiEditionChatSessions, createSession: context.createAiEditionChatSession, selectSession: context.selectAiEditionChatSession, @@ -526,27 +514,6 @@ export function registerNativeBridgeHandlers(context: NativeBridgeContext) { request.payload.sessionId, ), ); - case "chat.runDefault": { - const sink = buildChatEventSink(event.sender, "default"); - return createSuccessResponse( - requestId, - await aiEditionService.chatRunDefault( - request.payload.projectId, - request.payload.message, - sink, - ), - ); - } - case "chat.history": - return createSuccessResponse( - requestId, - aiEditionService.chatHistoryDefault(request.payload.projectId), - ); - case "chat.clear": - return createSuccessResponse( - requestId, - aiEditionService.chatClearDefault(request.payload.projectId), - ); case "chat.listSessions": return createSuccessResponse( requestId, diff --git a/electron/native-bridge/services/aiEditionService.ts b/electron/native-bridge/services/aiEditionService.ts index 343cc5913..e6e0edcb6 100644 --- a/electron/native-bridge/services/aiEditionService.ts +++ b/electron/native-bridge/services/aiEditionService.ts @@ -42,11 +42,6 @@ export interface AiEditionServiceOptions { document?: unknown, sink?: ChatEventSink, ) => Promise; - runChatDefault: ( - projectId: string, - message: string, - sink?: ChatEventSink, - ) => Promise; rewindToMessage: ( projectId: string, sessionId: string, @@ -67,8 +62,6 @@ export interface AiEditionServiceOptions { // ponytail: legacy per-batch undo retired in favor of per-message rewind. // Kept on the surface for IPC compatibility; always returns success=false. undoLastToolBatch: (projectId: string, sessionId: string) => AiEditionChatResult; - getDefaultChatHistory: (projectId: string) => AiEditionChatMessage[]; - clearDefaultChatHistory: (projectId: string) => void; listSessions: (projectId: string) => AiEditionChatSessionSummary[]; createSession: (projectId: string, title?: string) => AiEditionChatSessionSummary; selectSession: (projectId: string, sessionId: string) => AiEditionChatSession | null; @@ -278,21 +271,6 @@ export class AiEditionService { return this.options.compactNow(projectId, sessionId); } - async chatRunDefault( - projectId: string, - message: string, - sink?: ChatEventSink, - ): Promise { - return this.options.runChatDefault(projectId, message, sink); - } - - chatHistoryDefault(projectId: string): AiEditionChatMessage[] { - return this.options.getDefaultChatHistory(projectId); - } - - chatClearDefault(projectId: string): { success: boolean } { - this.options.clearDefaultChatHistory(projectId); - return { success: true }; } chatListSessions(projectId: string): AiEditionChatSessionSummary[] { diff --git a/src/native/browserShim.ts b/src/native/browserShim.ts index 139fa93e4..2a7a961f0 100644 --- a/src/native/browserShim.ts +++ b/src/native/browserShim.ts @@ -471,52 +471,6 @@ function createShimBridgeClient() { success: false, error: "[browser-shim] No agent tool batches to undo in browser mode.", }), - chatRunDefault: (projectId: string, message?: string) => { - // ponytail: legacy single-session consumers — pick the most - // recent session or auto-create one. - const sessions = getSessions(projectId); - let s = [...sessions.values()].sort((a, b) => b.createdAt.localeCompare(a.createdAt))[0]; - if (!s) { - s = { - id: `sess_${Date.now()}`, - projectId, - title: "Conversation 1", - createdAt: new Date().toISOString(), - messages: [], - }; - sessions.set(s.id, s); - } - if (message) { - s.messages.push({ - id: `msg_${Date.now()}_u`, - role: "user", - content: message, - createdAt: new Date().toISOString(), - }); - } - const assistantMessage = { - id: `msg_${Date.now()}_a`, - role: "assistant" as const, - content: - "[browser-shim] AI features need real LLM deps. Configure a provider in Settings, install the LangChain packages, then chat will work for real.", - createdAt: new Date().toISOString(), - }; - s.messages.push(assistantMessage); - persistChat(); - return Promise.resolve({ success: true, assistantMessage }); - }, - chatHistory: (projectId: string) => { - const m = sessionsByProject.get(projectId); - if (!m || m.size === 0) return Promise.resolve([]); - const arr = Array.from(m.values()).sort((a, b) => b.createdAt.localeCompare(a.createdAt)); - return Promise.resolve([...arr[0].messages]); - }, - chatClear: (projectId: string) => { - const m = sessionsByProject.get(projectId); - if (m) for (const s of m.values()) s.messages = []; - persistChat(); - return Promise.resolve({ success: true }); - }, chatListSessions: (projectId: string) => { const m = sessionsByProject.get(projectId); if (!m) return Promise.resolve([]); diff --git a/src/native/client.ts b/src/native/client.ts index b3a00d29a..eed5d68d7 100644 --- a/src/native/client.ts +++ b/src/native/client.ts @@ -3,7 +3,6 @@ import { type AiEditionCaptionTranslateResult, type AiEditionChatBudget, type AiEditionChatCompactResult, - type AiEditionChatMessage, type AiEditionChatResult, type AiEditionChatRewindResult, type AiEditionChatSession, @@ -231,50 +230,21 @@ export const nativeBridgeClient = { }), chatRun: ( projectId: string, - sessionIdOrMessage: string, - message?: string, + sessionId: string, + message: string, document?: unknown, - ): Promise => { - // ponytail: polymorphic — legacy 2-arg callers pass (projectId, message). - // Multi-session callers pass (projectId, sessionId, message[, document]). - // The document snapshot enables the agent tool loop (P1). - if (message === undefined) { - return requireNativeBridgeData({ - domain: "aiEdition", - action: "chat.runDefault", - payload: { projectId, message: sessionIdOrMessage }, - }); - } - return requireNativeBridgeData({ + ): Promise => + requireNativeBridgeData({ domain: "aiEdition", action: "chat.run", - payload: { projectId, sessionId: sessionIdOrMessage, message, document }, - }); - }, + payload: { projectId, sessionId, message, document }, + }), chatUndoLastBatch: (projectId: string, sessionId: string) => requireNativeBridgeData({ domain: "aiEdition", action: "chat.undoLastBatch", payload: { projectId, sessionId }, }), - chatRunDefault: (projectId: string, message: string) => - requireNativeBridgeData({ - domain: "aiEdition", - action: "chat.runDefault", - payload: { projectId, message }, - }), - chatHistory: (projectId: string) => - requireNativeBridgeData({ - domain: "aiEdition", - action: "chat.history", - payload: { projectId }, - }), - chatClear: (projectId: string) => - requireNativeBridgeData<{ success: boolean }>({ - domain: "aiEdition", - action: "chat.clear", - payload: { projectId }, - }), chatListSessions: (projectId: string) => requireNativeBridgeData({ domain: "aiEdition", From 4438e3fb338c52e1b30c6e969bf94b7040e5df2f Mon Sep 17 00:00:00 2001 From: Etienne Lescot Date: Tue, 28 Jul 2026 20:34:25 +0200 Subject: [PATCH 2/2] chore(contracts): drop the three orphaned chat request arms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every producer and handler of chat.runDefault / chat.history / chat.clear is gone, but the request union still type-approved them — a future caller would compile clean and fail at runtime with UNSUPPORTED_ACTION. Deleting them turns that back into a compile error. --- .../native-bridge/services/aiEditionService.ts | 2 -- src/native/contracts.ts | 18 ------------------ 2 files changed, 20 deletions(-) diff --git a/electron/native-bridge/services/aiEditionService.ts b/electron/native-bridge/services/aiEditionService.ts index e6e0edcb6..5d4d12caa 100644 --- a/electron/native-bridge/services/aiEditionService.ts +++ b/electron/native-bridge/services/aiEditionService.ts @@ -271,8 +271,6 @@ export class AiEditionService { return this.options.compactNow(projectId, sessionId); } - } - chatListSessions(projectId: string): AiEditionChatSessionSummary[] { return this.options.listSessions(projectId); } diff --git a/src/native/contracts.ts b/src/native/contracts.ts index ffe3d022e..62deaa2f3 100644 --- a/src/native/contracts.ts +++ b/src/native/contracts.ts @@ -533,24 +533,6 @@ export type NativeBridgeRequest = payload: { projectId: string; sessionId: string }; requestId?: string; } - | { - domain: "aiEdition"; - action: "chat.runDefault"; - payload: { projectId: string; message: string }; - requestId?: string; - } - | { - domain: "aiEdition"; - action: "chat.history"; - payload: { projectId: string }; - requestId?: string; - } - | { - domain: "aiEdition"; - action: "chat.clear"; - payload: { projectId: string }; - requestId?: string; - } | { domain: "aiEdition"; action: "chat.listSessions";