Files
turnstone/turnstone.example.toml
Patrick Buckley 8b4b8b3fd5 refactor(rerank): reranker is a per-model definition only (drop global endpoint settings)
The reranker_alias -> model-definition path (added when reranking became a model
role) made the older global endpoint settings redundant. Resolve reranking
solely through the Reranker role and remove the parallel global config.

- Removed settings tools.rerank_url / rerank_model / rerank_api_key, their
  config.py getters (+ $TURNSTONE_RERANK_URL / $TURNSTONE_RERANK_MODEL and the
  module caches), and the fallback branch in resolve_rerank_client_from. The
  resolver now returns a client only when a Reranker model (capability
  supports_rerank, base_url = its /rerank endpoint) is selected, else None.
- Kept as global knobs: reranker_alias (the selector), rerank_web_search,
  rerank_bm25, rerank_bm25_threshold, and rerank_instruction -- a task-level
  query knob (Qwen3-style), not endpoint identity.
- The Settings tab is registry-driven, so the three fields disappear with their
  SettingDefs. Updated the Reranker role help, example config, and docs/tools.md.

BREAKING: a reranker configured via [tools] rerank_url (config.toml / env /
Settings tab) no longer works -- add the reranker in the admin Models tab and
pick it under Models -> Roles -> Reranker. No migration: reranking is days old
and disabled by default, so any orphaned tools.rerank_* config rows are inert.

Tests: the resolver covers no-store / no-alias / non-rerank-alias -> None and the
model-definition happy path; the obsolete global-fallback tests are removed.
2026-06-01 21:34:12 -07:00

159 lines
7.3 KiB
TOML

# 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="<alias>"` 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
#
# 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