From 590a07bc1393695373712c2449594fe055a8fde7 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Sun, 26 Apr 2026 16:10:57 -0400 Subject: [PATCH] =?UTF-8?q?fix(journal):=20tighten=20prep=20prompt=20?= =?UTF-8?q?=E2=80=94=20direct=20briefing,=20not=20flowery=20letter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous system prompt asked for "warm, conversational, like a friend writing a letter" which produced flowery preludes that buried the actual data. Rewritten to: - Lead with practical data (tasks, events, weather) — concrete and specific - 4-7 sentences total, tight prose, no padding - Recent moments / open threads mentioned briefly at the END as context, not as the lead - Voice: "competent assistant briefing the user" not "friend writing a letter" - Close with a short journal invitation under 8 words Also dropped max_tokens 600 -> 400 to bias toward concision. Co-Authored-By: Claude Opus 4.7 --- src/fabledassistant/services/journal_prep.py | 30 +++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/fabledassistant/services/journal_prep.py b/src/fabledassistant/services/journal_prep.py index 28b8c54..27a0335 100644 --- a/src/fabledassistant/services/journal_prep.py +++ b/src/fabledassistant/services/journal_prep.py @@ -232,20 +232,22 @@ def _render_sections_for_prompt(sections: dict) -> str: _PREP_SYSTEM_PROMPT = ( - "You are opening the user's daily journal with a warm, conversational greeting. " - "Weave the data they're handing you into a flowing prose welcome — like a " - "thoughtful friend recapping what's on the user's plate today and gently inviting " - "them to journal about it.\n\n" + "You are briefing the user on their day. Direct and informative — tell them what's " + "actually on their plate so they can step into the day with a clear picture.\n\n" "Rules:\n" - "- Write flowing sentences. NO markdown, NO bullet points, NO headers.\n" - "- Reference items that genuinely matter; skip categories with no real data.\n" - "- If RECENT JOURNAL MOMENTS are present, briefly acknowledge what they were doing, thinking, or feeling.\n" - "- If OPEN THREADS are present, gently surface one or two as questions worth revisiting.\n" - "- Aim for 5 to 9 sentences. Warm but brief.\n" - "- Close with one short open invitation to journal — examples: \"What's on your mind?\", " - "\"How are you starting the day?\", \"Anything you want to set down before this kicks off?\"\n" - "- Don't fabricate details. If a category is empty, just skip it; don't lie about what's there.\n" - "- Don't list things mechanically (\"You have 3 tasks today...\"). Talk like a person." + "- LEAD with the practical data: tasks due today, calendar events, weather.\n" + "- Be specific and concrete. Use real task titles, event times, temperatures, " + "precipitation chances. Don't paraphrase data into vague summaries.\n" + "- Write in flowing sentences — no markdown, no bullet points, no headers — but " + "keep the prose factual and useful, not sentimental.\n" + "- 4 to 7 sentences total. Tight. No padding, no flowery openings, no \"Good morning\" " + "greetings unless the actual content warrants two clauses' worth.\n" + "- If RECENT JOURNAL MOMENTS or OPEN THREADS are present, mention one or two BRIEFLY " + "at the end as context — not as the lead. Skip them if nothing notable.\n" + "- Close with one short invitation to journal: \"What's on your mind?\", " + "\"Anything to set down?\", \"How's the morning shaping up?\" — pick one, keep it under 8 words.\n" + "- Don't fabricate. Skip categories with no data; don't acknowledge their absence.\n" + "- Voice is competent assistant briefing the user. Not a friend writing a letter." ) @@ -285,7 +287,7 @@ async def _generate_prep_prose( prose = await generate_completion( messages=messages, model=model, - max_tokens=600, + max_tokens=400, ) except Exception: logger.exception("Daily prep prose generation failed for day %s", day_date)