From 1bbeaf95c77acebea7896d8cc4d40bc544cdb06e Mon Sep 17 00:00:00 2001 From: indifferentketchup Date: Sat, 30 May 2026 20:37:38 +0000 Subject: [PATCH] fix: auto-name uses session model + pane auto-remove on last tab close Two independent UI/UX fixes: - auto_name.ts: pass the session's own model as fallbackModel to taskModelCompletion, so chat rename uses whatever model is already loaded on llama-swap instead of forcing a swap to DEFAULT_MODEL (which times out at 10s when a different model is active). - useWorkspacePanes.ts: when the last tab in a pane is closed and other panes exist, remove the pane entirely instead of leaving an orphaned empty panel. Co-Authored-By: Claude Opus 4.8 (1M context) --- apps/server/src/services/auto_name.ts | 7 +++++-- apps/web/src/hooks/useWorkspacePanes.ts | 7 +++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/server/src/services/auto_name.ts b/apps/server/src/services/auto_name.ts index 38831e9..d058e82 100644 --- a/apps/server/src/services/auto_name.ts +++ b/apps/server/src/services/auto_name.ts @@ -37,9 +37,11 @@ export async function maybeAutoNameChat( if ((counts[0]?.n ?? 0) < 1) return; const chatRows = await ctx.sql< - { id: string; name: string | null; session_id: string }[] + { id: string; name: string | null; session_id: string; model: string | null }[] >` - SELECT id, name, session_id FROM chats WHERE id = ${chatId} + SELECT c.id, c.name, c.session_id, s.model + FROM chats c JOIN sessions s ON s.id = c.session_id + WHERE c.id = ${chatId} `; const chat = chatRows[0]; if (!chat) return; @@ -67,6 +69,7 @@ export async function maybeAutoNameChat( user: namingInput, maxTokens: 30, temperature: 0.3, + fallbackModel: chat.model ?? undefined, }); const name = cleanTitle(raw); if (!name) { diff --git a/apps/web/src/hooks/useWorkspacePanes.ts b/apps/web/src/hooks/useWorkspacePanes.ts index 101193f..14c01f5 100644 --- a/apps/web/src/hooks/useWorkspacePanes.ts +++ b/apps/web/src/hooks/useWorkspacePanes.ts @@ -391,6 +391,13 @@ export function useWorkspacePanes(sessionId: string): UseWorkspacePanesResult { const pane = next[paneIdx]!; const nextIds = pane.chatIds.filter((id) => id !== chatId); if (nextIds.length === 0) { + if (next.length > 1) { + // Last tab closed and other panes exist — remove the whole pane + // instead of leaving an orphaned empty panel. + const spliced = next.filter((_, i) => i !== paneIdx); + setActivePaneIdx((ai) => Math.min(ai, spliced.length - 1)); + return spliced; + } next[paneIdx] = { ...pane, kind: 'empty', chatId: undefined, chatIds: [], activeChatIdx: -1 }; } else { const nextActiveIdx = Math.min(pane.activeChatIdx, nextIds.length - 1);