Something went wrong. Try again.
forked niri
Something went wrong. Try again.
nano config.example.toml
6.8 kB · 189 lines
TOML
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190# Example coral config. Copy to config.toml and tweak.# Secrets belong in secrets.toml.env, not here.## Launch with:# coral --config /path/to/config.toml --secrets /path/to/secrets.toml.env
# ── Model presets ────────────────────────────────────────────────────────────# Define named model configurations once, then reference them from [model],# [fallback], [summary], and [embeddings] via `preset = "name"`.# Secrets (api_key) are deep-merged from the secrets file into the same# [models.<name>] table, so they don't need to be repeated here.
[models.umans]provider = "openai"model = "umans-glm-5.2"base_url = "https://api.code.umans.ai/v1"tool_choice = "required"enable_thinking = truethinking_effort = "low"
[models.glm_openrouter]provider = "openrouter"model = "zai-org/glm-4.7-flash"base_url = ""tool_choice = "required"referer = ""title = ""n_ctx = 4096context_margin = 256hard_overflow_tokens = 1024# enforce_context_limit = false
[models.gemini_embedding]provider = "openai"model = "google/gemini-embedding-2-preview"base_url = "https://openrouter.ai/api/v1"dimensions = 3072referer = ""title = ""
# ── LLM bridge (our own OpenRouter) ──────────────────────────────────────────# Optional unified inference proxy. Accepts OpenAI-format requests and routes to# the best provider (pi-ai registry + custom providers below). Claude models are# discovered dynamically from Anthropic's /v1/models — nothing is hardcoded.# [llm_bridge]# enabled = true# host = "127.0.0.1"# port = 4040## [[llm_bridge.providers]]# name = "umans"# api_key = "sk-..." # or deep-merged from secrets.toml.env# base_url = "https://api.code.umans.ai/v1"## [[llm_bridge.providers]]# name = "anthropic-oauth"# # pi-ai auth.json: { "anthropic": { "type": "oauth", "refresh", "access", "expires" } }# # Tokens refresh + rotate back in place, just like codex's ~/.codex/auth.json.# auth_path = "~/.pi/auth.json"
[server]port = 3000
[agent]# Display name used in summarizer prompt and grounding context.name = "niri"# Set to "local" to skip the primary model and route everything through the fallback.env = "default"# Boredom wake: if > 0, wake the agent after this many minutes of inactivity.# Any real wake (DM, heartbeat, etc.) resets the timer. 0 disables.# boredom_wake_min = 0# Git upstream check: when true, runs `git fetch` on every file read/write# and nags the agent if the remote has changed. Throttled to 10 min per repo.# git_upstream_nag = false
# Optional: route shell tools through a Docker container instead of the local shell.# Set both to enable. Mutually exclusive with [ssh].[container]name = ""user = ""
# Optional: route shell tools through SSH instead. Mutually exclusive with [container].[ssh]target = ""identity = ""
[model]# Reference a preset defined under [models.<name>], or set fields directly.preset = "umans"# Any field here overrides the preset.
[fallback]# Used when the primary endpoint is unreachable or rate-limited (429/5xx).preset = "glm_openrouter"
[summary]# Optional dedicated summarizer model. Leave empty to reuse primary/fallback.preset = "glm_openrouter"
[embeddings]# Reference a preset, or set fields directly.preset = "gemini_embedding"
[context]compact_target_tokens = 65000compact_trigger_tokens = 90000compact_recent_messages = 80compact_chunk_messages = 32compact_summary_max_chars = 16000# 0 disables idle compaction.idle_compaction_minutes = 45# When true, no summaries are produced — the conversation stays raw to# preserve prompt cache. When false, old large tool results are proactively# summarized using the [summary] model (or primary model if no [summary] is set).respect_cache = true# Minimum number of turns (assistant messages) that must pass after a tool# result before it's eligible for proactive compaction. Only applies when# respect_cache = false.compaction_turn_age = 5# Minimum character length for a tool result to be considered "large" enough# to summarize. Only applies when respect_cache = false.compaction_min_chars = 2000
[runner]# Hard cap on assistant turns in a single wake cycle.max_turns = 120# Stop if the same assistant tool call + result pattern repeats.max_identical_tool_turns = 6
[image_tool]# Max bytes accepted before rejecting an image attachment.max_bytes = 150000# Absolute image root exposed to the agent. Defaults based on container/ssh mode.root = ""
[discord]gateway_enabled = truegateway_trace = falsegateway_raw_fallback = truegateway_raw_fallback_all = false# Channel ids scanned by discord_scan when no channel_ids arg is passed.scan_channel_ids = []wake_on_event = falsewake_on_dm = truebatch_interval_ms = 60000batch_only_configured = truepending_auto_seen_minutes = 10batch_scan = truebatch_max_messages = 40rest_max_attempts = 3rest_retry_base_ms = 1000# Auto-detected from the gateway READY payload if left blank.bot_user_id = ""
[metrics]retention_days = 3
# ── Tool filtering (main agent) ───────────────────────────────────────────────# Control which tools the main agent can use.# - enabled_tools: if empty (default), ALL tools are enabled.# If non-empty, only the listed tools are available.# - blacklisted_tools: always removed from the available set, regardless of# enabled_tools.## [tools]# enabled_tools = ["shell", "read_file", "memory_search"]# blacklisted_tools = ["rest"]
# ── Subagents ─────────────────────────────────────────────────────────────────# Define named subagents the main agent can spawn via the `subagent` tool.# Each [[subagents]] entry creates a new subagent with its own system prompt,# tool set, and turn limit. Subagents run a simplified loop — no event waiting,# no compaction, no Discord access, no nesting.## [[subagents]]# name = "researcher"# model = "" # blank = inherit main agent's model# system_prompt = "You are a research assistant. Be thorough and cite sources."# enabled_tools = ["shell", "read_file", "memory_search"] # blank = all (minus auto-blacklisted)# blacklisted_tools = ["edit_file"] # additional exclusions# max_turns = 30## [[subagents]]# name = "writer"# model = ""# system_prompt = "You are a technical writer. Produce clean, concise prose."# enabled_tools = []# blacklisted_tools = []# max_turns = 20