Skip to main content
An LLM is optional; canonic’s answer path is fully deterministic and never calls one. It’s only used to draft semantics/knowledge during setup and reconciliation. The llm: block in canonic.yaml supports four providers, all behind the same interface.
Local runtimes (Ollama, vLLM, LM Studio, llama.cpp, TGI) or any hosted OpenAI-compatible endpoint. base_url is required; a key is optional (local servers typically need none):
llm:
  provider: openai_compatible
  base_url: http://127.0.0.1:11434/v1   # Ollama; swap for any OpenAI-compatible endpoint
  model: gemma-4-e2b-it-4bit
  api_key_ref: env:CANONIC_LLM_API_KEY   # optional

One interface, any provider

All four are reached through litellm behind one interface; no per-provider branching anywhere else in canonic. tasks: optionally overrides the model per task (draft, reconcile):
llm:
  provider: anthropic
  model: claude-haiku-4-5
  api_key_ref: env:ANTHROPIC_API_KEY
  tasks:
    reconcile: claude-opus-4-8   # a harder task gets a stronger model

Air-gapped mode

Under runtime.air_gapped: true, only a local endpoint (loopback, or an allowlisted host via runtime.allow_cidrs) is accepted; openai, anthropic, and github_copilot all call a fixed public endpoint and are rejected outright in that mode.