From 4614ec56394869c53e56719d02fc00dd3cc8fc98 Mon Sep 17 00:00:00 2001 From: Andrew Beal Date: Sun, 4 Jan 2026 23:59:07 +0000 Subject: [PATCH] feat: add markdown formatting support to AI planning questions Enhance user question display with markdown rendering for better readability. Display formatted questions with emphasis, lists, and code snippets. Adjust input display max-height based on platform (mobile: 15vh, desktop: 30vh). --- .../FunctionDefinitions/Functions/AskUserQuestion.ts | 2 +- Components/ChatWindow.svelte | 9 ++++++++- Components/InputDisplay.svelte | 4 ++-- Modals/HelpModalSvelte.svelte | 1 - 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/AIClasses/FunctionDefinitions/Functions/AskUserQuestion.ts b/AIClasses/FunctionDefinitions/Functions/AskUserQuestion.ts index d863d0d..fdb19ce 100644 --- a/AIClasses/FunctionDefinitions/Functions/AskUserQuestion.ts +++ b/AIClasses/FunctionDefinitions/Functions/AskUserQuestion.ts @@ -18,7 +18,7 @@ Common use cases: properties: { question: { type: "string", - description: "The question to ask the user. Should be clear, specific, and provide enough context for the user to give a meaningful answer. Example: 'I found 3 files matching your criteria. Should I update all of them or would you like to review them first?'" + description: "The question to ask the user. Should be clear, specific, and provide enough context for the user to give a meaningful answer. Use markdown formatting for emphasis, lists, code snippets, or file paths to make the question easier to read. Example: 'I found **3 files** matching your criteria:\n\n- `src/components/Header.tsx`\n- `src/components/Footer.tsx`\n- `src/components/Sidebar.tsx`\n\nShould I update all of them or would you like to review them first?'" }, user_message: { type: "string", diff --git a/Components/ChatWindow.svelte b/Components/ChatWindow.svelte index e8f87e8..32e4113 100644 --- a/Components/ChatWindow.svelte +++ b/Components/ChatWindow.svelte @@ -18,6 +18,8 @@ import type { Attachment } from "Conversations/Attachment"; import ChatPlanArea from "./ChatPlanArea.svelte"; import type { ExecutionPlanStore } from "Stores/ExecutionPlanStore"; + import type { StreamingMarkdownService } from "Services/StreamingMarkdownService"; + import { HTMLService } from "Services/HTMLService"; const plugin: VaultkeeperAIPlugin = Resolve(Services.VaultkeeperAIPlugin); const executionPlanStore: ExecutionPlanStore = Resolve(Services.ExecutionPlanStore); @@ -25,6 +27,8 @@ const chatService: ChatService = Resolve(Services.ChatService); const workSpaceService: WorkSpaceService = Resolve(Services.WorkSpaceService); const conversationService: ConversationFileSystemService = Resolve(Services.ConversationFileSystemService); + const streamingMarkdownService: StreamingMarkdownService = Resolve(Services.StreamingMarkdownService); + const htmlService: HTMLService = Resolve(Services.HTMLService); const abortService: AbortService = Resolve(Services.AbortService); let chatContainer: HTMLDivElement; @@ -123,7 +127,10 @@ busyPlanning = false; }, onPlanningQuestion: async (question) => { - chatInput.setDisplayItem(createEl("span", { text: question })); + const displayEl = createEl("div"); + const formattedHtml = streamingMarkdownService.formatText(question); + htmlService.setHTMLContent(displayEl, formattedHtml); + chatInput.setDisplayItem(displayEl); return new Promise((resolve) => { chatInput.enterQuestionMode(resolve); }); diff --git a/Components/InputDisplay.svelte b/Components/InputDisplay.svelte index fac66a7..6da77c5 100644 --- a/Components/InputDisplay.svelte +++ b/Components/InputDisplay.svelte @@ -1,4 +1,5 @@