From a20aa845d9c8a9e50ecadf1316773e5fbe75107c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sun, 5 Jul 2026 14:59:05 +0200 Subject: [PATCH] fix(ai): ask for blank-line paragraphs in the assessment and briefing output formats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The shared formatting contract asks every narrative surface for short blank-line paragraphs, but two field-level instructions overrode it: the assessment OUTPUT FORMAT pinned 'flowing prose (2-4 sentences)' and the briefing paragraph asked for 'a connected 70-160 word read' — so both consistently arrived as one unbroken block regardless of the contract. Both now spell out 1-3 short paragraphs separated by a blank line written as \n\n inside the JSON string. --- src/lib/ai/prompts/base-system.ts | 4 ++-- src/lib/ai/prompts/insight-generator.ts | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/lib/ai/prompts/base-system.ts b/src/lib/ai/prompts/base-system.ts index 6804b4f44..d3b78e88c 100644 --- a/src/lib/ai/prompts/base-system.ts +++ b/src/lib/ai/prompts/base-system.ts @@ -219,9 +219,9 @@ Synthese statt Aufzählung: die Geschichte dessen, was die Daten bedeuten, zähl }, { id: "output", - en: `OUTPUT FORMAT: Reply with valid JSON only, in exactly this schema. The "summary" field holds the complete assessment as English flowing prose (2-4 sentences): + en: `OUTPUT FORMAT: Reply with valid JSON only, in exactly this schema. The "summary" field holds the complete assessment in English: 1-3 short paragraphs of 1-3 sentences each, separated by a blank line written as \\n\\n INSIDE the JSON string. A steady one-liner stays a single paragraph: { "summary": "..." }`, - de: `AUSGABEFORMAT: Antworte ausschließlich mit validem JSON in genau diesem Schema. Das Feld "summary" enthält die komplette Einschätzung als deutscher Fließtext (2-4 Sätze): + de: `AUSGABEFORMAT: Antworte ausschließlich mit validem JSON in genau diesem Schema. Das Feld "summary" enthält die komplette Einschätzung auf Deutsch: 1-3 kurze Absätze mit je 1-3 Sätzen, getrennt durch eine Leerzeile als \\n\\n INNERHALB des JSON-Strings. Ein stabiler Einzeiler bleibt EIN Absatz: { "summary": "..." }`, }, ]; diff --git a/src/lib/ai/prompts/insight-generator.ts b/src/lib/ai/prompts/insight-generator.ts index 84159c2f3..8ffd561e8 100644 --- a/src/lib/ai/prompts/insight-generator.ts +++ b/src/lib/ai/prompts/insight-generator.ts @@ -259,8 +259,10 @@ gib die obige Verweigerung zurück.`, warm, and motivating. Lead with NOW; draw on history for context, but the user opens this to learn what is happening TODAY and what one thing they can do about it. Fields: - - paragraph: a connected 70-160 word read of TODAY the user sees - at the top of /insights. SENTENCE 1 is the day's VERDICT in plain + - paragraph: a 70-160 word read of TODAY the user sees at the top + of /insights, written as 2-3 SHORT PARAGRAPHS separated by a + blank line (\\n\\n inside the JSON string) — never one unbroken + block. SENTENCE 1 is the day's VERDICT in plain words — the overall picture, NOT a number ("Today reads like a recovery day", "A steady day, nothing demanding your attention"). Then weave the 2-3 most salient signals into ONE story: lead from @@ -452,8 +454,10 @@ gib die obige Verweigerung zurück.`, JETZT; nutze die Historie als Kontext, aber der Nutzer öffnet das, um zu erfahren, was HEUTE passiert und welche eine Sache er dagegen tun kann. Felder: - - paragraph: ein zusammenhängender 70-160 Wörter langer Tages-Read, - den der Nutzer oben auf /insights liest. SATZ 1 ist das URTEIL des + - paragraph: ein 70-160 Wörter langer Tages-Read, den der Nutzer + oben auf /insights liest — geschrieben als 2-3 KURZE ABSÄTZE, + getrennt durch eine Leerzeile (\\n\\n innerhalb des JSON-Strings), + nie als ein durchgehender Block. SATZ 1 ist das URTEIL des Tages in klaren Worten — das Gesamtbild, KEINE Zahl ("Heute liest sich wie ein Erholungstag", "Ein ruhiger Tag, nichts, das deine Aufmerksamkeit braucht"). Dann verwebe die 2-3 wichtigsten Signale