Two things the field report asked for.
1) PERSONAL ASSISTANTS (replacing the sunset OpenAI Assistants API)
The old implementation gave three capabilities. Two are reimplemented here,
the third was confirmed unused and is deliberately not replaced:
* per-user persona - it already lived in system_gpt_settings.json; it was
only ever being shipped to OpenAI. It is now the system prompt.
* per-user conversation thread - OpenAI held this server-side. It now lives
in assistant_memory.json, keyed by discord user id, trimmed to the most
recent turns (CONJURER_ASSISTANT_MEMORY_TURNS) and written atomically so a
torn write cannot lose someone's history. Deliberately a plain trim, not
the AI summarisation used for the bar's shared memory: these are private
DMs and must not end up in a public "legend".
* file_search - not replaced. Confirmed not in use.
The conversation goes through handle_response with request_type="NONE" and an
explicit message list, which keeps it out of the bar's shared memory. The big
win: create_chat_assistant hardcoded model="gpt-4o", so assistants were locked
to OpenAI. They now run on whatever $gadaj_teraz selects - Claude and Ollama
included.
create_chat_assistant / chat_with_assistant are gone, and with them the last
call to beta.threads in the startup path - so the cog cannot be killed by that
API again. (add_files_to_vector_store / delete_files_from_vector_store still
reference beta.assistants but are dead code - nothing calls them - so they
cannot crash anything; left alone rather than widening this change.)
2) KEEPING A SELF-HOSTED MODEL WARM
Loading is the slow part - the GPU is shared with other users - so we preload
via Ollama's documented mechanism: /api/generate with a model, a keep_alive
and NO prompt. It loads the model and generates nothing.
* on switching to ollama, $gadaj_teraz fires a preload in the BACKGROUND
(not awaited: loading can take minutes and the command must answer at
once), so the wait lands on the operator rather than the first user;
* a warm loop re-asserts keep_alive every CONJURER_OLLAMA_WARM_MINUTES.
Both are hard-guarded on the ACTIVE provider being ollama. Warming a metered
API would burn tokens and money for nothing, so that guard is pinned by a test
asserting the preload is never called for gpt/claude, and another asserting the
preload body carries no prompt (a prompt would make every warm-up generate).
Tests: 82 unit + 71 integration green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>