Configuration Reference¶
All configuration is centralized in the .olav/config/api.json file. Running olav init creates a baseline version.
Feature Claims
| ID | Claim | Status |
|---|---|---|
| C-L2-38 | agent_overrides assigns different LLM models to different Agents |
✅ v0.10.0 |
| C-L2-39 | OLAV_LLM_* environment variables override config file |
✅ v0.10.0 |
Protect your config file
api.json contains API keys — do not commit it to Git. Add .olav/config/ to your .gitignore.
File Structure¶
{
"shared": { ... },
"llm": { ... },
"embedding": { ... },
"reranker": { ... },
"auth": { ... },
"agent_overrides": { ... }
}
Deployment Tiers¶
The LLM, embedding, and reranker endpoints are independently switchable. The three tiers below are all contractually supported — pick whichever fits your network / compliance / hardware constraints.
Local SentenceTransformer for embedding, reranker disabled. Zero cloud keys, nothing leaves the host. The embedding model auto-downloads from HuggingFace on first run (~440 MB).
{
"llm": {
"provider": "ollama",
"model": "qwen3.6:27b",
"base_url": "http://localhost:11434/v1",
"model_provider": "openai",
"context_budget": 64000
},
"embedding": {
"mode": "local",
"local": { "model": "BAAI/bge-base-en-v1.5", "device": "cpu" }
},
"reranker": { "enabled": false },
"auth": { "mode": "token" }
}
Memory is fully usable: semantic search + BM25/FTS. Lighter alternative: swap bge-base-en-v1.5 → bge-small-en-v1.5 (130 MB, 384-dim).
No embedding, no reranker. Memory degrades to BM25 keyword search; semantic recall is gone, but no crashes. Good for test containers, isolated networks, or strictly-LLM use cases.
Cloud LLM + cloud embedding + cloud reranker. Each endpoint carries its own API key; per-section precedence keeps them from cross-pollinating.
{
"llm": {
"provider": "custom",
"model": "google/gemma-4-31b-it:free",
"base_url": "https://openrouter.ai/api/v1",
"model_provider": "openai",
"api_key": "sk-or-v1-XXXXX",
"context_budget": 64000
},
"embedding": {
"mode": "api",
"api": {
"model": "pplx-embed-v1-0.6b",
"base_url": "https://api.perplexity.ai/v1",
"api_key": "pplx-XXXXX"
}
},
"reranker": {
"enabled": true,
"kind": "openrouter",
"model": "cohere/rerank-4-fast",
"base_url": "https://openrouter.ai/api/v1",
"api_key": "sk-or-v1-XXXXX"
},
"auth": { "mode": "token" }
}
Mix-and-match is supported: "Cloud LLM + local embedding + no reranker" is a common cost-effective combo.
Switching Between Tiers¶
- Edits to
api.jsontake effect on next launch — restart theolavprocess or open a new session, no rebuild needed. - Changing embedding dimension triggers a LanceDB rebuild — different models have different dims (
bge-base=768/pplx-embed=1024/text-embedding-3-small=1536). LanceDB locks the dim per table; mismatches raiseEmbeddingDimMismatchError. Two ways to fix:olav agent install <wheel>for any skill — enters theallow_dim_swap=Truepath, rebuilds the table, and re-primes guides. User-authored memories are dropped, but system-level guides / expert KB rebuild automatically.- Manual backup + rebuild:
mv .olav/databases/memory.lance{,.backup}then run any command that re-primes (e.g./netops_init).
shared.api_keyshould usually stay empty. Only set it when LLM + embedding + reranker all share the same provider and same key (rare). For multi-provider deployments, leave it blank and use per-section keys.
Shared Configuration¶
The shared section holds cross-endpoint defaults.
| Field | Required | Default | Description |
|---|---|---|---|
api_key |
"" |
Cross-endpoint API key. Use only when LLM + embed + rerank all sit on the same provider; leave empty for multi-provider deployments | |
timeout |
120 |
Default request timeout in seconds |
API key precedence (Patch B / 2026-05)¶
Each endpoint resolves its api_key independently:
- per-section —
llm.api_key/embedding.api.api_key/reranker.api_key(preferred) - shared —
shared.api_key(fallback for homogeneous deployments) - environment —
OPENAI_API_KEY/ANTHROPIC_API_KEY(last resort)
Per-section beating shared means heterogeneous setups don't get cross-contaminated: you can run llm.api_key=sk-or-v1-... alongside embedding.api.api_key=pplx-... and each endpoint picks up its own key.
LLM Configuration¶
OLAV supports multiple LLM providers. Select the one you use:
LLM Field Reference¶
| Field | Required | Default | Description |
|---|---|---|---|
provider |
✅ | Provider: openai / anthropic / azure_openai / ollama / groq / mistral / custom |
|
model |
✅ | Model ID (e.g., gpt-4o, claude-3-5-sonnet-20241022) |
|
api_key |
Per-provider override (usually use shared.api_key instead) |
||
base_url |
Required for custom provider; optional for others (use for self-hosted proxies) |
||
temperature |
0.1 |
Generation temperature — lower values produce more deterministic output | |
max_tokens |
32000 |
Maximum number of tokens to generate |
Embedding Configuration¶
The knowledge base and agent memory use vector embeddings for semantic search. Three modes are supported:
"embedding": {
"mode": "api",
"api": {
"model": "openai/text-embedding-3-small",
"base_url": "https://openrouter.ai/api/v1",
"api_key": "sk-or-v1-..."
},
"fallback": { "enabled": true }
}
fallback is enabled, the system falls back to a local model if the API is unreachable (requires the local block to be configured too).
| Model | dim | Size | Notes |
|---|---|---|---|
BAAI/bge-base-en-v1.5 |
768 | 440 MB | High quality, CPU-friendly |
BAAI/bge-small-en-v1.5 |
384 | 130 MB | Ultra-light |
BAAI/bge-small-zh-v1.5 |
512 | 90 MB | Chinese |
paraphrase-multilingual-MiniLM-L12-v2 |
384 | 470 MB | 50+ languages |
Reranker Configuration¶
The reranker adds a cross-encoder re-ranking pass after memory recall to improve top-K relevance. Disabled by default — quality is highly model-dependent (some local rerankers actually make results worse).
llama-server started with --reranking flag, loading a BERT-class cross-encoder (e.g. bge-reranker-v2-m3).
"reranker": {
"enabled": true,
"kind": "openrouter",
"model": "cohere/rerank-4-fast",
"base_url": "https://openrouter.ai/api/v1",
"api_key": "sk-or-v1-..."
}
kind accepts openrouter / cohere / openai_compat / openai, all routed to POST {base_url}/rerank with body {query, documents, model}. api_key falls back to shared.api_key if absent.
Reranker Fields¶
| Field | Required | Description |
|---|---|---|
enabled |
✅ | true / false |
kind |
when enabled | llama_cpp / openrouter / cohere / openai_compat / openai / ollama |
base_url |
when enabled | Endpoint root path (do NOT append /rerank) |
model |
cloud kinds | Model ID |
api_key |
cloud kinds (or shared fallback) | Bearer token |
OLAV_RERANKER_DISABLE=1 environment variable disables the reranker without editing the file.
Authentication Mode¶
Configured in the auth section to determine how user identity is established:
| Mode | Use Case | Description |
|---|---|---|
none |
Personal use, local development | Default — uses the OS username |
token |
Small teams | Built-in OLAV token authentication |
ldap |
Enterprise | Connects to an LDAP directory |
ad |
Enterprise | Connects to Active Directory |
oidc |
SSO | Connects to OpenID Connect |
Assigning Different Models to Different Agents¶
You can use different LLM models for specific Agents — for example, a cheap small model for quick queries and a powerful large model for complex analysis:
"agent_overrides": {
"core": { "model": "gpt-4o-mini" },
"audit": { "provider": "anthropic", "model": "claude-3-5-sonnet-20241022" }
}
Agents not listed in agent_overrides use the top-level llm configuration.
Environment Variables¶
All configuration can be overridden via environment variables, which take precedence over api.json:
| Environment Variable | Config Equivalent | Description |
|---|---|---|
OLAV_LLM_MODEL |
llm.model |
Model ID |
OLAV_LLM_API_KEY |
shared.api_key |
API key |
OLAV_LLM_BASE_URL |
llm.base_url |
API endpoint |
OPENAI_API_KEY |
shared.api_key |
OpenAI shortcut |
ANTHROPIC_API_KEY |
shared.api_key |
Anthropic shortcut |
OLAV_WEB_PORT |
Web service port (Round 19 added env override) | |
OLAV_WEB_HOST |
Web service bind address |
Context / prompt-budget debug env vars¶
Post-R36/R42 the platform exposes two operator-level observability
switches. They're off by default — set to 1 / true / yes / on
to enable.
| Environment Variable | Since | Purpose |
|---|---|---|
OLAV_DEBUG_CONTEXT |
Round 36 | When enabled, agent._inject_static_context emits a multi-line INFO log per agent listing each injected reference's bytes / estimated tokens and the total vs the active tier's context_budget. Useful for "why is this agent starting at 6K tokens?" diagnostics. |
OLAV_DEBUG_SUMMARIZATION |
Round 42 | When enabled, build_summarization_middleware logs the resolved tier + trigger + keep settings so operators can verify the tier-aware summarization policy (small=50% / medium=65% / large=80% of context_budget) took effect. |
OLAV_STATIC_CONTEXT_MODE |
Round 24 | Force a static_context mode regardless of per-agent frontmatter: always / on_intent / lazy. |
Tier + resolver switches¶
| Environment Variable | Since | Purpose |
|---|---|---|
OLAV_LLM_MODEL_TIER |
Sprint 0b | Force small / medium / large tier without editing config. Drives every TIER_DEFAULTS key (context_budget, recall_top_k, return_compact_chars, summarization_trigger_pct, execute_sql_context_rows, search_logs_default_limit, …). |
OLAV_BACKUP_COMMANDS_PATH |
Round 46 | Priority-0 override for the backup_only_commands.yaml lookup. When set to an existing file, it wins over the three default candidates. Missing-file values fall through to defaults (typo-safe). |
OLAV_SANDBOX_NETNS |
— | 1 forces network-namespace isolation for every sandbox subprocess. |
OLAV_MEMORY_DB_PATH |
— | Override the LanceDB memory store path used by olav_recall_memory. |
Use environment variables in CI/CD
In CI/CD pipelines, pass secrets via environment variables rather than files to avoid writing them to disk.
Remote AsyncSubAgents¶
OLAV can connect to remote LangGraph Cloud or self-hosted LangGraph deployments as AsyncSubAgents. Add an async_subagents array to api.json:
{
"async_subagents": [
{
"name": "remote-ops",
"description": "High-capacity ops agent running on LangGraph Cloud",
"url": "https://my-deployment.langsmith.com",
"assistant_id": "ops",
"api_key_env": "LANGGRAPH_API_KEY"
}
]
}
| Field | Required | Description |
|---|---|---|
name |
✅ | Unique subagent name (used by olav_delegate tool) |
description |
✅ | Human-readable description for orchestrator routing |
url |
✅ | LangGraph deployment base URL |
assistant_id |
✅ | Graph/assistant ID on the remote deployment |
api_key_env |
❌ | Env var name holding the API key. Falls back to LANGGRAPH_API_KEY |
Remote subagents are loaded at startup alongside local workspace subagents. Failures are skipped gracefully — they never block local agent initialization.
Hook System¶
Configure external commands triggered by OLAV session events in ~/.olav/hooks.json:
{
"hooks": [
{ "event": "session.start", "command": "notify-send 'OLAV session started'" },
{ "event": "tool.call", "command": "logger -t olav 'Tool: $OLAV_HOOK_TOOL'" }
]
}
See Agent Harness → Event Hook System for the full event reference.
workspace.yaml — Skill Declaration¶
Each skill workspace can include a workspace.yaml that declares metadata and optional integration features.
name: my-skill
version: 1.0.0
description: Human-readable description of the skill
route_keywords:
- keyword1
- keyword2
# Optional: inject selected tools into Core Agent at install time
inject_into_core:
tools:
- tool_function_name # must match a @tool function in tools.py
description: "Short description shown in Core Agent's tool listing"
Fields¶
| Field | Required | Description |
|---|---|---|
name |
✅ | Skill identifier (must match workspace directory name) |
version |
❌ | Semver string (shown in olav skill list) |
description |
❌ | Human-readable summary |
route_keywords |
❌ | Keywords used for automatic query routing |
inject_into_core |
❌ | Tools to inject into Core Agent (see below) |
inject_into_core Fields¶
| Field | Required | Description |
|---|---|---|
tools |
✅ | List of tool function names to inject |
description |
❌ | Label shown in Core Agent's injected-tools section |
Injected tools are added to .olav/workspace/core/AGENT.md at install time and removed at uninstall. See Build a Skill → Injecting Tools into Core Agent for usage examples.