Skip to content

adr: model-providers

Status: accepted · Context: the dev machine (M5 Max, 128 GB) can host several local models via Ollama, and games may want different models for different roles. LLM access must not be hard-wired to one vendor.

Decision

The engine talks to models through a single provider abstraction, not a direct Anthropic SDK call. A provider implements one method:

propose(role, system_prompt, state_json, player_text, schema) -> validated_json

Adapters behind that interface:

  • fake — scripted/canned proposals for tests and offline dev (the only one usable in CI or any env without model access). Deterministic.
  • anthropic — the hosted Anthropic API (needs ANTHROPIC_API_KEY).
  • ollama — local models over the Ollama HTTP API (OpenAI-compatible), no key, runs on the dev machine.

Per-role model assignment. Each LLM role in a game (e.g. director, adjudicator) is bound to a provider+model independently, so a heavy model can run the once-a-day Director while light/local models handle frequent adjudication. Default binding: a fast model (Haiku tier) for all roles; switch a role to a stronger model in the launcher for an expensive/quality run.

Runtime selection in the launcher UI. The shared launcher exposes a model picker that lists available providers/models (including whatever Ollama reports locally) and lets a role be reassigned without a code change. Selection is config, passed to the engine per session — never baked into a game's content.

Why

  • Keeps the door open to a genuinely multi-model game (local + hosted, several at once) which is viable on this hardware.
  • Isolates the "no key in this environment" reality: everything is built and tested against fake; real adapters are swapped in on the dev machine.
  • Reinforces the engine/content seam — model choice is engine/runtime config, not game content.

Consequences

  • Every LLM call site goes through the abstraction; no direct vendor SDK use in game or engine logic.
  • Providers must normalize to the same structured-output contract (schema validation + retry lives in the engine, above the provider).
  • Ollama/Anthropic adapters ship but are verified by the human on the dev machine; CI exercises only fake.