LLM providers¶
Every LLM call in Jarvis — capture triage, homelab proposals, RAG answers —
goes through a single seam (agent-runtime/src/jarvis_agent/llm.py). Only
one thing decides which provider that seam uses:
LLM_PROVIDER=stub
Providers¶
| Provider | LLM_PROVIDER |
Network | Notes |
|---|---|---|---|
| Stub | stub (default) |
none | Offline, deterministic. No key required. complete() echoes the prompt; propose() returns an empty value per declared parameter type. Used automatically until you configure a real provider. |
| DeepSeek | deepseek |
yes | OpenAI-compatible API. Requires DEEPSEEK_API_KEY. |
Env vars¶
| Env var | Required | Default | Purpose |
|---|---|---|---|
LLM_PROVIDER |
no | stub |
Selects the provider (stub or deepseek) |
DEEPSEEK_API_KEY |
only for deepseek |
— | DeepSeek API key |
DEEPSEEK_BASE_URL |
no | https://api.deepseek.com |
OpenAI-compatible base URL |
LLM_MODEL |
no | deepseek-chat |
Model id passed to the provider |
Switch to DeepSeek¶
Add the key to .env and restart the stack:
LLM_PROVIDER=deepseek
DEEPSEEK_API_KEY=sk-...
Leaving LLM_PROVIDER unset (or stub) keeps every module fully offline —
no key needed, no request ever leaves the box.
Every cloud call is audited¶
The propose_audited chokepoint
Modules never call an LLMProvider directly for a "propose" step —
every capture and homelab LLM call goes through
jarvis_agent.audit.propose_audited, the single cloud chokepoint:
- Fail-closed — if any item in the call is sensitive, the provider is
never touched;
propose_auditedraisesRedactionRefusalinstead. - Redacted — the system and user text sent to the provider is passed through the shared redactor first.
- One repair round — if the returned proposal fails validation, the provider is asked exactly once more, with the violations listed as a repair note.
- Logged — every dispatched call is recorded to the caller's own
*_llm_logcollection (e.g.hl_llm_log,conv_llm_log), with the post-redaction payload preview and a token estimate — never the raw pre-redaction text.
Capture's poll and backfill paths make zero cloud calls — normalization and
routing there are plain code, not LLM calls, so LLM_PROVIDER doesn't affect
them at all.