fix(journal): chat-only system prompt; don't pre-warm OLLAMA_MODEL

Two architectural bugs in the conversation+curator rollout that
explain the no-response chat in dev:

1. Journal system prompt still instructed tool calls.
   JOURNAL_CALIBRATION instructed the model to CALL record_moment,
   search_notes, save_person, etc. — but the chat surface ships tools=[]
   per the new architecture. The model received contradictory orders
   ('use these tools' + 'you have no tools') and produced either empty
   output or tool-call-shaped text that gets stripped to empty content,
   surfacing as status=error or stuck status=generating messages.
   Replaced with a chat-only calibration: ~25 lines focused on tone,
   length, anti-coaching, and the load-bearing rule 'never claim to
   have done anything for the user' (the curator handles capture
   silently and separately). JOURNAL_PERSONA also rewritten to drop
   the 'use tools to act on their behalf' line.

2. Pre-warm warmed Config.OLLAMA_MODEL ahead of user's real choice.
   _pull_model(Config.OLLAMA_MODEL, warm=True) at boot pushed the
   system default (qwen3:latest) into VRAM before _warm_user_models()
   ran for each user's actual default_model setting. On a single-GPU
   setup the second warm could swap the first out — so the user's
   chat model wasn't necessarily resident when their first message
   landed. Now we just pull the supporting models without warming
   them; only user-configured chat models get warm.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-22 16:42:33 -04:00
parent dac5433353
commit 49325816a3
2 changed files with 41 additions and 105 deletions
+9 -2
View File
@@ -301,8 +301,15 @@ def create_app() -> Quart:
if warm:
await _warm_model(model)
# Ensure system-default models are present, then pull/warm user-configured ones.
asyncio.create_task(_pull_model(Config.OLLAMA_MODEL, warm=True))
# Pull supporting models without warming them — embedding model and
# the configured background model load on demand without competing
# for VRAM. The chat model is warmed by _warm_user_models() which
# uses each user's *actual* default_model setting; warming
# Config.OLLAMA_MODEL unconditionally (the OLD behaviour) blasted
# the system default into VRAM ahead of the user's real preference,
# which on a single-GPU setup pushed the user's chat model out
# before they ever sent a message.
asyncio.create_task(_pull_model(Config.OLLAMA_MODEL, warm=False))
asyncio.create_task(_pull_model(Config.EMBEDDING_MODEL, warm=False))
asyncio.create_task(_pull_model(Config.OLLAMA_BACKGROUND_MODEL, warm=False))
asyncio.create_task(_warm_user_models())