From 148ec0ce853a6da7089481f743454805e63b8437 Mon Sep 17 00:00:00 2001 From: Jakob Wennberg Date: Fri, 21 Aug 2026 13:13:54 +0200 Subject: [PATCH] feat(agent): docked assistant sheet runs general.help on the single-call console (#1769) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RIP-4 stage 1. The app-wide docked "Fråga min assistent" sheet rendered general.help through the streaming AgentChat runtime, so on a local/OpenAI- compatible model it 503'd. It now renders AskConsole for general.help (both a fresh ask and a resumed thread), the same single-call, provider-agnostic path /chat already uses, with the read-only ledger tools + snapshot. Every other intent (the write/staging flows, onboarding, etc.) still renders AgentChat unchanged, so run-turn.ts stays until those migrate in later stages. Resumed free-form threads convert their stored messages to text-only (the console has no tool/staged rows). Fresh asks report the created conversation id back to the sheet via onConversationCreated, same as onConversationIdChange did. Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 --- components/agent/AgentSheet.tsx | 39 ++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/components/agent/AgentSheet.tsx b/components/agent/AgentSheet.tsx index 23faec84..d6aecefa 100644 --- a/components/agent/AgentSheet.tsx +++ b/components/agent/AgentSheet.tsx @@ -18,6 +18,8 @@ import AgentChat, { normalizeStoredMessages, type ChatMessage, } from './AgentChat' +import AskConsole, { type AskConsoleMessage } from './AskConsole' +import { CHAT_INTENT_ID } from '@/lib/agent/ask/persist' import type { AgentPanelFloatRect, StoredStagedOperation } from '@/types' import { DOCK_GUTTER, @@ -756,14 +758,35 @@ export default function AgentSheet({ ) : loaded ? ( - setConversationId(id)} - onStatus={onStatus} + loaded.intentId === CHAT_INTENT_ID ? ( + // Resumed free-form thread: the single-call console (runs on a local + // model). Its turns are text-only, so drop any empty/tool rows. + m.text.trim().length > 0) + .map((m): AskConsoleMessage => ({ role: m.role, text: m.text }))} + contextRef={loaded.contextRef} + /> + ) : ( + setConversationId(id)} + onStatus={onStatus} + /> + ) + ) : intentId === CHAT_INTENT_ID ? ( + // Fresh free-form ask (the FAB's "Fråga min assistent" catch-all). + setConversationId(id)} /> ) : (