From da1194e8a5a2a623734e06902c46445c264def24 Mon Sep 17 00:00:00 2001 From: Anders Holck Date: Wed, 27 May 2026 11:08:25 +0200 Subject: [PATCH] AI edit: return only changes, not full document - Edit prompt asks for APPEND/PREPEND/REPLACE + only new content - Frontend applies the edit surgically (append/prepend/replace) - Much faster: AI only generates the new text, not the whole doc - Chat mode still streams response progressively --- frontend/src/App.vue | 17 ++++++++++++++--- internal/api/ai.go | 7 +++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/frontend/src/App.vue b/frontend/src/App.vue index b74b2c8..2d8d4ce 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1038,9 +1038,7 @@ async function sendAiChat() { try { const token_text = JSON.parse(data) fullText += token_text - if (action === 'edit') { - content.value = fullText - } else { + if (action !== 'edit') { aiChatResponse.value = fullText } } catch {} @@ -1048,6 +1046,19 @@ async function sendAiChat() { } if (action === 'edit') { + // Parse location hint from AI response + const firstNewline = fullText.indexOf('\n') + const hint = firstNewline > -1 ? fullText.substring(0, firstNewline).trim().toUpperCase() : '' + const editContent = firstNewline > -1 ? fullText.substring(firstNewline + 1) : fullText + + if (hint === 'APPEND') { + content.value = content.value.trimEnd() + '\n\n' + editContent + } else if (hint === 'PREPEND') { + content.value = editContent + '\n\n' + content.value + } else { + // REPLACE or unknown — replace entire document + content.value = hint === 'REPLACE' ? editContent : fullText + } isDirty.value = true aiChatResponse.value = 'Document updated.' } diff --git a/internal/api/ai.go b/internal/api/ai.go index 6475933..c695c76 100644 --- a/internal/api/ai.go +++ b/internal/api/ai.go @@ -158,8 +158,11 @@ func (s *Server) handleAIChat(w http.ResponseWriter, r *http.Request) { var systemPrompt, userMsg string if req.Mode == "edit" { systemPrompt = "You are a document editor. The user will give you a markdown document and an instruction. " + - "Apply the instruction and return the COMPLETE updated document. " + - "Do not add explanations or wrap in code fences. Return raw markdown only." + "Return ONLY the new or changed text that should be inserted/replaced. " + + "Do not return the entire document. Do not add explanations or wrap in code fences. " + + "If adding content, return only the addition. If modifying, return only the modified section. " + + "Start your response with a location hint on the first line: APPEND (add to end), PREPEND (add to start), or REPLACE (replace entire document). " + + "Then the content on the next line." userMsg = "Document:\n\n" + req.Content + "\n\nInstruction: " + req.Message } else { systemPrompt = "You are a helpful writing assistant. The user has a markdown document open. Answer concisely in markdown."