# turnstone.toml — shared bootstrap configuration # # This file is read once at startup. Values here are overridden by # environment variables, which are in turn overridden by CLI flags. # # All sections are optional. Missing sections use binary defaults. # Config file location precedence: # 1. --config flag # 2. $TURNSTONE_CONFIG env var # 3. ~/.config/turnstone/config.toml # --- LLM API (turnstone, node, eval) --- [api] # base_url = "" # API endpoint; empty = binary default # api_key = "" # env: OPENAI_API_KEY or ANTHROPIC_API_KEY # --- Default Model (turnstone, node, eval) --- [model] # name = "" # Model ID; empty = provider default (gpt-5 / claude-sonnet-4) # temperature = 0.0 # 0 = provider default # reasoning_effort = "" # "none", "minimal", "low", "medium", "high", "xhigh", "max" # context_window = 0 # 0 = auto-detect from provider capabilities # max_tokens = 0 # 0 = provider default # # Sub-agent routing (task_agent tool). Falls back to agent_model when # unset, then to the session model. # agent_model = "" # legacy single-knob alias used as fallback # task_model = "" # task_agent override (e.g. "local" for cheap subtasks) # task_effort = "" # reasoning effort for task_agent (default: inherit session) # # At call time, the calling LLM may also pass `model=""` to # task_agent to override these per-invocation. Tool descriptions list # available aliases dynamically; bad aliases return an error so the # model retries with a valid choice. # --- Named Models (turnstone, node, eval) --- # Define model aliases with per-model overrides. Useful for local model # servers or mixing providers. Reference by name with --model flag. # # [models.local] # name = "llama-3-70b" # provider = "openai" # base_url = "http://localhost:8000/v1" # context_window = 8192 # # [models.local.capabilities] # supports_vision = false # supports_web_search = false # # [models.claude] # name = "claude-opus-4-8" # provider = "anthropic" # --- Database (turnstone, node, console) --- [database] # url = "" # postgres://user:pass@host/db or /path/to.db # env: TURNSTONE_DB_URL # listen_url = "" # direct-to-postgres URL for the console's # dedicated LISTEN connection. Set this when # `url` points at pgbouncer in transaction # pooling mode (LISTEN holds session state and # is incompatible with transaction pooling — # see docs/pgbouncer.md). Defaults to `url` # when unset. env: TURNSTONE_DB_LISTEN_URL # SSL params (passed through to SQLAlchemy connection): # sslmode = "prefer" # disable, allow, prefer, require, verify-ca, verify-full # sslrootcert = "" # path to CA cert for verify-ca/verify-full # sslcert = "" # path to client cert (mTLS) # sslkey = "" # path to client key (mTLS) # --- Auth (node, console) --- [auth] # Auth is always enabled. JWT secret is required. # jwt_secret = "" # HS256 signing secret (min 32 bytes recommended) # env: TURNSTONE_JWT_SECRET # --- Logging (turnstone, node, console) --- [log] # level = "" # "debug", "info", "warn", "error" # empty = binary default (warn for CLI, info for servers) # env: TURNSTONE_LOG_LEVEL # json = false # JSON output; auto-enabled when stderr is not a TTY # --- Session (turnstone, node) --- [session] # instructions = "" # Default system message # compact_max_tokens = 32768 # Max tokens for context compaction summary # auto_compact_pct = 0.8 # Trigger compaction at this % of context window # --- Tools (turnstone, node) --- [tools] # timeout = 120 # Tool execution timeout in seconds # skip_permissions = false # Auto-approve all tool calls # # web_search backend (local/vLLM models only — commercial providers use their # own native server-side search). The docker-compose stack bundles a SearxNG # service and points at it by default. # web_search_backend = "" # "" (auto), "searxng", or "mcp:server:tool" # searxng_url = "http://searxng:8080" # SearxNG base URL; env: TURNSTONE_SEARXNG_URL # (the admin Settings value, if set, wins; clear it # there to disable web search) # searxng_engines = "" # comma-separated engines (e.g. "duckduckgo,wikipedia"); # empty = the instance's default mix # env: TURNSTONE_SEARXNG_ENGINES # # workspace_dir = "/workspace" # directory surfaced to the model as its workspace # (informational only — does not chdir or confine # tools; skipped if the directory doesn't exist). # The Docker image presets this to /workspace. # env: TURNSTONE_WORKSPACE # # Reranking (optional, disabled by default). Turnstone runs no reranker itself — # it POSTs to an external Cohere/Jina-compatible /rerank endpoint (self-hosted # vLLM/TEI/llama.cpp, or hosted Cohere/Jina/Voyage) to reorder results by query # relevance. The endpoint is a per-model definition: add a model in the admin # Models tab with capability {"supports_rerank": true} and base_url set to the # full /rerank endpoint, then pick it under Models -> Roles -> Reranker. The # settings below are global knobs — there is no rerank_url-style endpoint setting. # rerank_web_search = true # rerank web_search results (when an endpoint is set) # rerank_bm25 = true # rerank BM25 retrieval: tool search, skill search, memory # rerank_bm25_threshold = 0.0 # 0-1 relevance floor for proactive memory; 0 = off (reorder # only). Per-model: set via `turnstone-admin rerank-calibrate`. # rerank_instruction = "" # for instruction-aware rerankers (Qwen3) when the endpoint # does NOT apply the model's chat template, e.g. "Given a web # search query, retrieve relevant passages that answer the # query". Prefer vLLM's --chat-template; don't use both. # NB: serving Qwen3-Reranker via vLLM REQUIRES --chat-template # (the model's chat_template.jinja) or scores are near-random. # --- Judge (turnstone, node) --- [judge] # enabled = true # Enable intent validation # smart_approvals = false # Auto-approve high-confidence "approve" LLM verdicts (opt-in) # confidence_threshold = 0.95 # Smart Approvals auto-approve bar (LLM recommendation=approve) # output_guard = true # Scan tool output for security signals # redact_secrets = true # Redact detected credentials in output # --- Memory (turnstone, node) --- [memory] # relevance_k = 5 # Top-K memories for context injection # fetch_limit = 50 # Max memories to fetch for ranking # max_content = 32768 # Max memory content size in chars # nudge_cooldown = 300 # Min seconds between metacognitive nudges # nudges = true # Enable memory nudges # --- MCP (turnstone, node) --- [mcp] # config_path = "" # Path to MCP servers config file (JSON) # --- Server (node, console) --- [server] # max_workstreams = 50 # Maximum concurrent workstreams per node # env: TURNSTONE_MAX_WORKSTREAMS