573 lines
27 KiB
TOML
573 lines
27 KiB
TOML
# OpenSquilla Configuration
|
|
# Copy to opensquilla.toml and edit as needed:
|
|
# cp opensquilla.toml.example opensquilla.toml
|
|
#
|
|
# Precedence: env vars > opensquilla.toml > defaults
|
|
# Also searched: ~/.opensquilla/config.toml (global user config)
|
|
#
|
|
# Applying changes: edits made through the RPC/Web UI (config.set/patch/apply)
|
|
# hot-apply immediately. Hand-edits to this file are only read at boot — run
|
|
# `opensquilla gateway reload` (or restart) to pick them up. Channel, memory
|
|
# embedding/retrieval-mode, and sandbox/permissions changes always need a full
|
|
# `opensquilla gateway restart`; auth, host/port, file logging, and the search
|
|
# provider are also read only at boot (reload updates the stored values but
|
|
# the running components keep the boot-time ones).
|
|
|
|
# Workspace/state defaults
|
|
# Defaults:
|
|
# workspace_dir = "~/.opensquilla/workspace"
|
|
# state_dir = "~/.opensquilla/state"
|
|
# memory.source = "workspace"
|
|
# workspace_dir = "/path/to/workspace"
|
|
# state_dir = "/path/to/state"
|
|
# workspace_strict = true # true restricts read-side file tools to workspace
|
|
# Realtime feedback timing. Heartbeats are non-persistent UI/CLI liveness
|
|
# events while a run is active; stream idle timeout is the real upstream stall
|
|
# detector. Keep browser grace above stream idle so server terminal errors win.
|
|
# agent_stream_heartbeat_interval_seconds = 15.0
|
|
# agent_stream_idle_timeout_seconds = 180.0
|
|
# webui_stream_idle_grace_seconds = 210.0
|
|
|
|
# WebSocket per-connection outbound writer queue. When enabled (default),
|
|
# each WS connection gets a bounded asyncio queue + dedicated writer task.
|
|
# Producers enqueue and return immediately; slow clients trigger a fast
|
|
# 1011 close instead of back-pressuring the gateway. Disable to fall back
|
|
# to the legacy direct-`ws.send_text` path under a per-connection lock.
|
|
# Kill switch affects new connections only; existing connections retain
|
|
# their startup-time behavior.
|
|
# Env override: OPENSQUILLA_WS_WRITER_QUEUE_ENABLED=true|false
|
|
# ws_writer_queue_enabled = true
|
|
# Env override: OPENSQUILLA_WS_WRITER_QUEUE_MAXSIZE=512
|
|
# ws_writer_queue_maxsize = 512
|
|
|
|
# Gateway debug file logging. Raw prompt/tool call capture is separate from
|
|
# debug.log and standard diagnostics; it is opt-in through
|
|
# OPENSQUILLA_TURN_CALL_LOG=1 or `opensquilla diagnostics on --raw`.
|
|
# log_file_enabled = true
|
|
# log_level = "DEBUG" # CRITICAL/FATAL/ERROR/WARNING/WARN/INFO/DEBUG/TRACE
|
|
# log_file_max_bytes = 5000000
|
|
# log_file_backup_count = 3
|
|
|
|
# Developer diagnostics. debug is security-sensitive; keep it false in shared
|
|
# deployments. diagnostics_enabled enables standard diagnostics at startup.
|
|
# Raw turn-call capture remains a separate explicit runtime/env switch.
|
|
# debug = false
|
|
# diagnostics_enabled = false
|
|
|
|
[control_ui]
|
|
# Vue is the product UI. Use "legacy" only as a maintainer rollback fallback
|
|
# for the frozen vanilla-JS frontend; changing this requires a gateway restart.
|
|
# Env override: OPENSQUILLA_CONTROL_UI_FRONTEND=vue|legacy
|
|
frontend = "vue"
|
|
|
|
# Web search settings
|
|
# Use DuckDuckGo for the no-key path, or configure Bocha, Brave, IQS, Tavily, or Exa.
|
|
# search_provider = "duckduckgo" # "duckduckgo", "bocha", "brave", "iqs", "tavily", or "exa"
|
|
# search_api_key = "" # one-time pasted key; prefer search_api_key_env
|
|
# search_api_key_env = "" # BOCHA_SEARCH_API_KEY, BRAVE_SEARCH_API_KEY, IQS_SEARCH_API_KEY, TAVILY_API_KEY, or EXA_API_KEY
|
|
# search_max_results = 5
|
|
# search_proxy = "" # e.g. "http://127.0.0.1:7890"
|
|
# search_use_env_proxy = false # true = allow HTTP_PROXY/HTTPS_PROXY if search_proxy is empty
|
|
# search_fallback_policy = "off" # "off" or "network" retry via DuckDuckGo
|
|
# search_diagnostics = false # true = include provider-attempt diagnostics
|
|
|
|
# Tool safety settings.
|
|
# Some local proxy/fake-IP DNS setups resolve public domains through RFC 2544
|
|
# test-network addresses (198.18.0.0/15). Leave this empty unless you trust
|
|
# that fake-IP resolver; other private/internal ranges remain hard-blocked.
|
|
# [tools]
|
|
# trusted_fake_ip_cidrs = ["198.18.0.0/15"]
|
|
|
|
# Attachment ingestion. Any file type is accepted by default: rendered
|
|
# families (images, PDF, text, Office, email) are extracted or inlined for
|
|
# the model; everything else stages as an opaque agent-workspace file whose
|
|
# bytes are never parsed or inlined into a prompt.
|
|
# Env prefix: OPENSQUILLA_ATTACHMENTS_
|
|
# [attachments]
|
|
# accept_opaque = true # false = legacy rendered-types-only admission
|
|
# opaque_max_bytes = 31457280 # 30 MiB per-file ceiling for opaque types
|
|
# upload_store_max_total_bytes = 314572800 # 300 MiB staged-upload RAM ceiling
|
|
# # (raise-only; <=0 = default)
|
|
# workspace_attachment_disk_budget_bytes = 1073741824 # 1 GiB workspace copies
|
|
# # (<=0 = unbounded)
|
|
# persist_transcripts = true
|
|
# transcript_disk_budget_bytes = 2147483648
|
|
# artifact_max_bytes = 31457280
|
|
# artifact_disk_budget_bytes = 536870912
|
|
|
|
[llm]
|
|
provider = "tokenrhythm"
|
|
model = "deepseek-v4-pro"
|
|
# api_key = "" # TokenRhythm API key; env TOKENRHYTHM_API_KEY also works
|
|
base_url = "https://tokenrhythm.studio/v1"
|
|
# proxy = "" # e.g. http://127.0.0.1:7890
|
|
|
|
# Provider quick reference. Support levels marked compat_mock_verified are
|
|
# verified by local mocked-contract tests, not by live vendor calls.
|
|
#
|
|
# provider env var default base_url
|
|
# tokenrhythm TOKENRHYTHM_API_KEY https://tokenrhythm.studio/v1
|
|
# openrouter OPENROUTER_API_KEY https://openrouter.ai/api/v1
|
|
# openai OPENAI_API_KEY https://api.openai.com/v1
|
|
# openai_responses OPENAI_API_KEY https://api.openai.com/v1 (native Responses-API shape; chat+responses)
|
|
# anthropic ANTHROPIC_API_KEY https://api.anthropic.com
|
|
# ollama none http://localhost:11434
|
|
# deepseek DEEPSEEK_API_KEY https://api.deepseek.com
|
|
# gemini GEMINI_API_KEY https://generativelanguage.googleapis.com/v1beta/openai
|
|
# dashscope DASHSCOPE_API_KEY https://dashscope.aliyuncs.com/compatible-mode/v1
|
|
# moonshot MOONSHOT_API_KEY https://api.moonshot.ai/v1
|
|
# mistral MISTRAL_API_KEY https://api.mistral.ai/v1
|
|
# groq GROQ_API_KEY https://api.groq.com/openai/v1
|
|
# zhipu ZAI_API_KEY https://open.bigmodel.cn/api/paas/v4
|
|
# siliconflow SILICONFLOW_API_KEY https://api.siliconflow.cn/v1
|
|
# volcengine VOLCENGINE_API_KEY https://ark.cn-beijing.volces.com/api/v3
|
|
# volcengine_coding_plan VOLCENGINE_API_KEY https://ark.cn-beijing.volces.com/api/coding/v3
|
|
# byteplus BYTEPLUS_API_KEY https://ark.ap-southeast.bytepluses.com/api/v3
|
|
# vllm none explicit base_url required
|
|
# custom CUSTOM_LLM_API_KEY (optional) explicit base_url required
|
|
# lm_studio none http://localhost:1234/v1
|
|
# ovms none http://localhost:8000/v3
|
|
# qianfan QIANFAN_API_KEY https://qianfan.baidubce.com/v2
|
|
# aihubmix AIHUBMIX_API_KEY https://aihubmix.com/v1
|
|
# minimax MINIMAX_API_KEY https://api.minimaxi.com/anthropic (Anthropic-shape backend)
|
|
# minimax_openai MINIMAX_API_KEY https://api.minimax.io/v1 (OpenAI-compatible variant)
|
|
# azure provider-specific unsupported_for_A
|
|
#
|
|
# Example direct DeepSeek config:
|
|
# provider = "deepseek"
|
|
# model = "deepseek-v4-flash"
|
|
# api_key = "" # env DEEPSEEK_API_KEY also works
|
|
# base_url = "https://api.deepseek.com"
|
|
#
|
|
# Example direct TokenRhythm config (aggregator: DeepSeek/GLM/MiniMax/Kimi/
|
|
# MiMo/Qwen families on one key). Every served model streams
|
|
# reasoning_content, and reasoning tokens count against max_tokens — keep
|
|
# max_tokens = 0 (auto) rather than setting small caps:
|
|
# provider = "tokenrhythm"
|
|
# model = "deepseek-v4-pro"
|
|
# api_key = "" # env TOKENRHYTHM_API_KEY also works
|
|
# base_url = "https://tokenrhythm.studio/v1"
|
|
#
|
|
# Example self-hosted / custom OpenAI-compatible endpoint (vLLM, SGLang, TGI,
|
|
# llama.cpp server, or any proxy speaking the Chat Completions API):
|
|
# provider = "custom"
|
|
# base_url = "http://127.0.0.1:8000/v1" # required — no default endpoint
|
|
# model = "qwen3-32b-awq"
|
|
# # api_key is optional: set env CUSTOM_LLM_API_KEY (or api_key here) only if
|
|
# # your endpoint enforces one. Declare the endpoint's real context window via
|
|
# # [models.custom."qwen3-32b-awq"] — see the per-model overrides section below.
|
|
|
|
# Pin each model to its native upstream provider on OpenRouter.
|
|
# Sends provider.only=[slug] + allow_fallbacks=true per request.
|
|
[llm.provider_routing]
|
|
"anthropic/claude-opus-4.8" = "anthropic"
|
|
"anthropic/claude-sonnet-4.6" = "anthropic"
|
|
"deepseek/deepseek-v4-flash" = "deepseek"
|
|
"google/gemini-3.5-flash" = "google"
|
|
"moonshotai/kimi-k2.6" = "moonshotai"
|
|
"openai/gpt-5.4-mini" = "openai"
|
|
"openai/gpt-5.5" = "openai"
|
|
"qwen/qwen3-coder-plus" = "qwen"
|
|
"x-ai/grok-4.3" = "x-ai"
|
|
"z-ai/glm-4.6" = "z-ai"
|
|
"z-ai/glm-5.1" = "z-ai"
|
|
"z-ai/glm-5.2" = "z-ai"
|
|
|
|
# LLM ensemble routing — the DEFAULT routing surface.
|
|
# A fresh install ships enabled = true with selection_mode =
|
|
# "static_openrouter_b5": each turn fans out to a fixed five-member
|
|
# OpenRouter proposer set and fuses their candidates into one answer.
|
|
#
|
|
# Upgrade note (0.5.0rc1 → current):
|
|
# * static_openrouter_b5 is the default for FRESH installs only. Configs
|
|
# saved by earlier versions keep their stored `enabled` value.
|
|
# * Enabling the ensemble now selects "static_openrouter_b5", where
|
|
# 0.5.0rc1's enable toggle gave "router_dynamic". Set
|
|
# selection_mode = "router_dynamic" to restore the rc1 behavior.
|
|
#
|
|
# Credential requirement: static_openrouter_b5 runs its members on
|
|
# OpenRouter, so it needs a resolvable OpenRouter credential — the [llm]
|
|
# api_key when the active provider is "openrouter", or OPENROUTER_API_KEY
|
|
# in the environment otherwise. Without one the ensemble is inactive and
|
|
# every turn falls back to the single configured provider —
|
|
# `opensquilla doctor` reports this as the llm_ensemble finding
|
|
# "LLM ensemble is enabled but cannot run".
|
|
# "static_tokenrhythm_b5" is the TokenRhythm mirror of the same lineup
|
|
# (deepseek-v4-pro, glm-5.2, kimi-k2.7-code, qwen3.7-max + glm-5.2
|
|
# aggregator) and needs a TokenRhythm credential the same way (the [llm]
|
|
# api_key when the active provider is "tokenrhythm", or
|
|
# TOKENRHYTHM_API_KEY in the environment).
|
|
#
|
|
# The keys below are also writable at runtime via the Web UI / the
|
|
# `onboarding.ensemble.configure` RPC; omitted keys keep their current
|
|
# values. Changes take effect on the next turn without a gateway restart.
|
|
[llm_ensemble]
|
|
enabled = true
|
|
# "static_openrouter_b5": fixed five-member OpenRouter proposer set (default).
|
|
# "static_tokenrhythm_b5": the same lineup served through TokenRhythm.
|
|
# "custom_b5": an explicit user-authored lineup from [[llm_ensemble.candidates]]
|
|
# — 2-6 enabled proposer rows plus at most one role = "aggregator" row (the
|
|
# member that fuses drafts into the final answer; omitted = the current chat
|
|
# model fuses). Proposer roles ("primary", "contrast", "fast_check",
|
|
# "critic") are advisory labels shown in the UI and decision trace.
|
|
# "router_dynamic": legacy automatic selection; kept readable for existing
|
|
# configs but no longer offered in the Web UI.
|
|
selection_mode = "static_openrouter_b5"
|
|
# Explicit lineup for custom_b5 (ignored by the static profiles):
|
|
# [[llm_ensemble.candidates]]
|
|
# provider = "volcengine"
|
|
# model = "doubao-2.0-pro"
|
|
# role = "primary"
|
|
# [[llm_ensemble.candidates]]
|
|
# provider = "volcengine"
|
|
# model = "deepseek-v4-pro"
|
|
# role = "aggregator"
|
|
#
|
|
# Candidate pool for the legacy router_dynamic mode (ignored otherwise).
|
|
model_options = [
|
|
"deepseek/deepseek-v4-pro",
|
|
"z-ai/glm-5.2",
|
|
"qwen/qwen3.7-plus",
|
|
"deepseek/deepseek-v4-flash",
|
|
"qwen/qwen3.7-max",
|
|
"moonshotai/kimi-k2.6",
|
|
"moonshotai/kimi-k2.7-code",
|
|
"minimax/minimax-m3",
|
|
]
|
|
# Minimum proposers that must succeed before aggregation (>= 1). The fixed
|
|
# lineups (static profiles and custom_b5) replace the untouched default of 1
|
|
# with their own quorum at runtime: 3-of-4 for the static profiles, N-1 for a
|
|
# custom lineup of N proposers.
|
|
min_successful_proposers = 1
|
|
# When aggregation cannot proceed: "fallback_single" (single-provider turn) or "error".
|
|
all_failed_policy = "fallback_single"
|
|
|
|
# Advanced knobs — TOML-only (not on the configure RPC surface). Defaults:
|
|
# mode = "b5_fusion" # only supported ensemble mode
|
|
# proposer_tools = false # allow tool calls inside proposer turns
|
|
# candidate_max_chars = 24000 # per-candidate transcript budget (0 = unlimited)
|
|
# proposer_timeout_seconds = 3600.0
|
|
# aggregator_timeout_seconds = 3600.0
|
|
# shuffle_candidates = true # shuffle candidate order before aggregation
|
|
# record_candidates = false # persist per-proposer candidates for replay/debug
|
|
|
|
# Model metadata catalog (added in 0.5.x; schema only — wiring lands in a
|
|
# follow-up release). Offline-first: with refresh = "off" (the default) the
|
|
# gateway never fetches model metadata (context windows, output caps, pricing,
|
|
# capability flags) from the network. Today's OpenRouter live model-list fetch
|
|
# is a separate, existing mechanism that this flag does NOT govern yet.
|
|
# Downgrade note: model_catalog and the models tables below are top-level
|
|
# sections written to disk only when a config persist re-materializes the full
|
|
# file. 0.5.0rc1 and older reject unknown top-level keys, so delete both
|
|
# sections before downgrading (same class as config_version; see the 0.5.x
|
|
# release notes).
|
|
# [model_catalog]
|
|
# refresh = "off" # "off" | "startup" (fetch once at gateway boot)
|
|
# pin_path = "" # local JSON/TOML catalog override for air-gapped deploys
|
|
# stale_after_days = 45 # advisory doctor threshold for metadata age (days)
|
|
|
|
# Per-model metadata overrides (added in 0.5.x), keyed
|
|
# [models.<provider_id>."<model_id>"]. Quote model ids that contain dots or
|
|
# slashes. Exact ids only — globs are not supported in user config. Every
|
|
# field is optional; anything unset keeps resolving from catalog/registry
|
|
# metadata as before.
|
|
#
|
|
# Self-hosted example: a vLLM endpoint declaring its real context window so
|
|
# context budgeting and compaction stop assuming a conservative default:
|
|
# [models.vllm."qwen3-32b-awq"]
|
|
# context_window = 131072
|
|
# max_output_tokens = 8192
|
|
# supports_tools = true
|
|
#
|
|
# The generic `custom` provider (any self-hosted OpenAI-compatible endpoint;
|
|
# see the [llm] example above) uses the same override table, keyed by its
|
|
# served model id:
|
|
# [models.custom."qwen3-32b-awq"]
|
|
# context_window = 131072
|
|
# max_output_tokens = 8192
|
|
# supports_tools = true
|
|
#
|
|
# [models.openrouter."z-ai/glm-5.2"]
|
|
# # reasoning_format: openrouter | openai | deepseek | gemini | zai |
|
|
# # dashscope | moonshot | volcengine | none
|
|
# reasoning_format = "openrouter"
|
|
# supports_reasoning = true
|
|
# input_cost_per_mtok = 0.5 # USD per million input tokens (example value)
|
|
# output_cost_per_mtok = 2.0 # USD per million output tokens (example value)
|
|
# cache_read_cost_per_mtok = 0.05 # USD per million cached-prompt-read tokens (example value)
|
|
# cache_write_cost_per_mtok = 0.6 # USD per million cached-prompt-write tokens (example value)
|
|
# thinking_level_map = { high = "high", medium = "medium" }
|
|
|
|
[memory]
|
|
# "workspace" stores MEMORY.md and memory/*.md under workspace_dir.
|
|
# SQLite indexes still live under state_dir.
|
|
source = "workspace"
|
|
# Long-term memory vector indexing defaults to provider="auto": it tries the
|
|
# bundled local BGE-small ONNX model first, then a memory-specific remote key
|
|
# if one is configured, then FTS-only. Chat LLM/OpenRouter credentials are not
|
|
# used for memory embeddings unless explicitly configured below.
|
|
# retrieval_mode = "hybrid" # "hybrid" | "fts_only"
|
|
#
|
|
# [memory.embedding]
|
|
# provider = "auto" # "auto" | "none" | "local" | "openai" | "openai-compatible" | "ollama"
|
|
#
|
|
# [memory.embedding.local]
|
|
# onnx_dir = "" # optional; empty uses bundled BGE; supports absolute, ~, or process-relative paths
|
|
#
|
|
# [memory.embedding.remote]
|
|
# api_key = ""
|
|
# base_url = "https://api.openai.com/v1"
|
|
# model = "text-embedding-3-small"
|
|
# headers = {}
|
|
#
|
|
# [memory.embedding.ollama]
|
|
# base_url = "http://localhost:11434"
|
|
# model = "nomic-embed-text"
|
|
# Turn capture writes memory/archive/** audit transcripts by default.
|
|
# These archives are not searchable memory unless explicitly opted in.
|
|
# capture_user = true
|
|
# capture_assistant = false
|
|
# index_captured_turns = false
|
|
# capture_excluded_run_kinds = ["recall", "session_recall"]
|
|
# capture_excluded_provenance_kinds = ["recall", "tool_result", "memory_injected"]
|
|
|
|
[memory.dream]
|
|
# Dream consolidation is safety-first by default. Background scheduling and
|
|
# curated MEMORY.md writes require explicit opt-in.
|
|
enabled = false
|
|
preview_mode = true
|
|
auto_schedule = false
|
|
# interval_h = 24
|
|
# cron = "0 3 * * *"
|
|
|
|
[skills]
|
|
# Experimental skill relevance filtering. Default is off; deterministic
|
|
# skill gating still runs for visibility, platform, and tool availability.
|
|
filter_enabled = false
|
|
filter_top_k = 5
|
|
max_skills_prompt_chars = 8000
|
|
# injection_mode = "system" # "system", "user_context", or "user_message"
|
|
|
|
# The default lexical strategy is dependency-free. "semantic" and "hybrid"
|
|
# are legacy experimental modes that need the bundled BGE ONNX backend
|
|
# (onnxruntime + transformers tokenizer + the int8 ONNX export shipped under
|
|
# squilla_router/models/v4.2_phase3_inference/bge_onnx/). Install via
|
|
# `uv sync --extra recommended`. If unavailable, they degrade to lexical-only.
|
|
# filter_strategy = "lexical" # "lexical" | "semantic" | "hybrid"
|
|
# filter_lexical_top_n = 20
|
|
# filter_semantic_top_n = 20
|
|
# filter_rrf_k = 60
|
|
# filter_embedding_model = "BAAI/bge-small-zh-v1.5"
|
|
|
|
[task_runtime]
|
|
# Server-side agent turn queue. Same-session tasks are serialized;
|
|
# different sessions can run concurrently up to this limit.
|
|
max_concurrency = 4
|
|
# Waiting tasks per session before new follow-up work is rejected.
|
|
max_pending_per_session = 64
|
|
|
|
[squilla_router]
|
|
enabled = true # V4 model router
|
|
auto_thinking = true
|
|
rollout_phase = "full"
|
|
strategy = "v4_phase3"
|
|
# Optional provider tier profile. Leave unset to preserve the built-in
|
|
# OpenRouter defaults below. If set, it must match [llm].provider; the router
|
|
# does not switch providers at runtime.
|
|
# tier_profile = "dashscope" # openrouter | dashscope | deepseek | gemini | volcengine | openai | zhipu | moonshot
|
|
# Bundled router prerequisites:
|
|
# 1. install with `uv sync --extra model-router` or `uv sync --extra recommended`
|
|
# 2. hydrate model assets via:
|
|
# git lfs pull --include="src/opensquilla/squilla_router/models/**"
|
|
default_tier = "c1"
|
|
confidence_threshold = 0.5
|
|
v4_use_aux_head = true
|
|
kv_cache_anti_downgrade_enabled = true
|
|
kv_cache_anti_downgrade_window_seconds = 600
|
|
complaint_upgrade_enabled = true
|
|
complaint_upgrade_steps = 1
|
|
complaint_upgrade_max_chars = 160
|
|
require_router_runtime = true
|
|
estimated_output_savings_pct = 0.03
|
|
upgrade_to_c3_compaction_enabled = true
|
|
# What routing does when a tier names a provider other than [llm].provider
|
|
# while cross_provider_tiers is off. "route" (default) preserves the historical
|
|
# behavior: the mismatch is logged but the tier's model runs on the active
|
|
# provider's credentials. "veto" instead rebinds the turn to the nearest tier
|
|
# that executes on the active provider (or the default tier).
|
|
# tier_provider_mismatch = "route" # route | veto
|
|
|
|
# TokenRhythm serves every model in reasoning-streaming mode and rejects
|
|
# thinking-toggle request fields, so these tiers set no thinking_level.
|
|
[squilla_router.tiers.c0]
|
|
provider = "tokenrhythm"
|
|
model = "deepseek-v4-flash"
|
|
description = "Fast DeepSeek V4 Flash route for trivial chat, short rewrites, extraction, and low-risk simple Q&A"
|
|
supports_image = false
|
|
|
|
[squilla_router.tiers.c1]
|
|
provider = "tokenrhythm"
|
|
model = "deepseek-v4-pro"
|
|
description = "Default balanced text model for normal agent work, coding assistance, debugging, and moderate analysis"
|
|
supports_image = false
|
|
|
|
[squilla_router.tiers.c2]
|
|
provider = "tokenrhythm"
|
|
model = "kimi-k2.7-code"
|
|
description = "Stronger Kimi K2.7 Code route for multi-step coding, structured reasoning, larger context synthesis, and harder analysis"
|
|
supports_image = false
|
|
|
|
[squilla_router.tiers.c3]
|
|
provider = "tokenrhythm"
|
|
model = "glm-5.2"
|
|
description = "Highest-tier GLM 5.2 route for difficult planning, deep review, complex debugging, and high-stakes synthesis"
|
|
supports_image = false
|
|
|
|
[squilla_router.tiers.image_model]
|
|
provider = "tokenrhythm"
|
|
model = "kimi-k2.6"
|
|
description = "Image model: vision-capable route for user-supplied image attachments, screenshots, diagrams, and visual question answering"
|
|
supports_image = true
|
|
image_only = true
|
|
|
|
# Example: DashScope profile requires:
|
|
# [llm]
|
|
# provider = "dashscope"
|
|
# model = "qwen3.6-plus"
|
|
# api_key = "${DASHSCOPE_API_KEY}"
|
|
# base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
|
|
#
|
|
# [squilla_router]
|
|
# tier_profile = "dashscope"
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Tool policy
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
#
|
|
# Optional coding/repo-coding narrowed tool surface. Keep commented unless you
|
|
# are intentionally narrowing the tool surface for a scripted run.
|
|
#
|
|
# [tools]
|
|
# profile = "coding"
|
|
# also_allow = ["retrieve_tool_result"]
|
|
# deny = ["execute_code", "background_process", "process"]
|
|
# file_edit_requires_fresh_read = true
|
|
# file_edit_flexible_recovery = true # default; records used/rejected recovery events
|
|
# workspace_write_deny_globs = []
|
|
|
|
[agent_token_saving]
|
|
# Project fresh tool results with the built-in tokenjuice reducer before they
|
|
# are fed back into the model. Raw tool responses remain available through the
|
|
# tool-result store when configured by the gateway runtime.
|
|
tool_result_projection_max_inline_chars = 60000
|
|
tool_result_store_max_bytes = 8388608
|
|
tool_result_store_disk_budget_bytes = 268435456
|
|
tool_result_store_retention_seconds = 604800
|
|
|
|
[compaction]
|
|
enabled = true
|
|
# model = "" # None = use session model
|
|
# timeout_seconds = 30.0
|
|
|
|
[sandbox]
|
|
# Per-command ephemeral sandbox + security grading.
|
|
#
|
|
# sandbox on -> processes run under namespace/profile isolation
|
|
# off -> host execution is allowed (logs a WARNING per run)
|
|
# security_grading on -> action_kind drives the selected SecurityLevel
|
|
# off -> a fixed STANDARD policy is used, no approval flow
|
|
#
|
|
# Both default to false for the out-of-box bypass posture. Turning sandbox off
|
|
# while grading stays on is silently coerced to grading=false with a warning.
|
|
sandbox = false
|
|
security_grading = false
|
|
# default_level = "STANDARD" # DISABLED | STANDARD | STRICT | LOCKED
|
|
# backend = "auto" # auto | bubblewrap | seatbelt | windows_default | noop
|
|
# allow_legacy_mode = false # required for default_level = DISABLED
|
|
# network_default = "proxy_allowlist" # none | proxy_allowlist
|
|
# denial_threshold = 3 # pause autonomous runs after N denials
|
|
# extra_ro_mounts = []
|
|
# extra_rw_mounts = []
|
|
# cpu_seconds = 30
|
|
# memory_mb = 1024
|
|
# wall_seconds = 60
|
|
|
|
[permissions]
|
|
# Owner/operator default permission mode. The shipped default is "bypass", which
|
|
# runs local/operator tool execution on the host while still blocking sensitive
|
|
# paths. Use `opensquilla sandbox on|bypass|full|reset` to update this together
|
|
# with the sandbox section.
|
|
default_mode = "bypass" # off | on | bypass | full
|
|
|
|
# [auth]
|
|
# mode = "none" # none | token | password
|
|
# token = ""
|
|
|
|
# [cors]
|
|
# Cross-origin browser access to the gateway HTTP API. Off by default: the
|
|
# Web UI is served same-origin from the gateway itself and non-browser
|
|
# clients (CLI, desktop app, curl) never need CORS. Only list origins here
|
|
# if you host a separate frontend on another origin; avoid "*", especially
|
|
# together with allow_credentials.
|
|
# allowed_origins = []
|
|
# allow_credentials = true
|
|
|
|
# [channels]
|
|
# [[channels.channels]]
|
|
# name = "my-slack"
|
|
# type = "slack"
|
|
# token = "xoxb-..."
|
|
# connection_mode = "socket" # socket = no public URL; webhook = Events API
|
|
# app_token = "xapp-..." # required for Slack Socket Mode
|
|
# signing_secret = "" # required for Slack webhook mode
|
|
# slack_channel_id = "C12345"
|
|
# reply_in_thread = false
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Meta-Skill subsystem
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
[meta_skill]
|
|
# Master gate. When false the meta-skill subsystem is fully off: meta-skills are
|
|
# not injected into prompts, meta_invoke is not surfaced, and the /meta command
|
|
# refuses (both list and run). Default: true.
|
|
# enabled = true
|
|
|
|
# Automatic activation. When false (the default), meta-skills are MANUAL-ONLY:
|
|
# no system-prompt guidance, no keyword/semantic auto-trigger, meta_invoke is not
|
|
# offered for automatic invocation, and meta-skills are hidden from automatic
|
|
# skill listings.
|
|
# They run only via the explicit `/meta <name>` command. Set true to restore the
|
|
# previous automatic behavior. Default: false.
|
|
# auto_trigger = false
|
|
|
|
[meta_skill.persistence]
|
|
# Whether to write meta-skill execution traces to SQLite (G4 traceable audit).
|
|
# Disabling drops the writer to no-op; the CLI `skills meta runs ...` will
|
|
# report no rows. Default: true.
|
|
# enabled = true
|
|
|
|
# How long (seconds) a 'running' row may live before boot cleanup marks it
|
|
# 'failed' as an orphan from a crashed prior process. Only applies to rows
|
|
# whose owner_pid differs from the current process pid. Default: 3600 (1h).
|
|
# orphan_cleanup_age_seconds = 3600
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# Meta-Skill auto-propose: unattended synthesis from co-occurrence patterns
|
|
#
|
|
# Two independent triggers feed the same library function
|
|
# (skills.creator.auto_propose):
|
|
# * `enabled` — schedule a recurring cron job (Path 1)
|
|
# * `on_dream_complete` — piggyback on memory-consolidation dreams (Path 2)
|
|
# Both default OFF. Operators turn them on after reviewing how
|
|
# meta-skill-creator's gated output looks once.
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
[meta_skill.auto_propose]
|
|
# enabled = false # Path 1 cron toggle
|
|
# cron = "0 5 * * *" # 5-field local-time cron; daily 05:00
|
|
# window_days = 30 # log-history window for co-occurrence
|
|
# min_freq = 3 # drop chains observed fewer than N times
|
|
# top_k = 5 # consider at most N patterns per fire
|
|
# on_dream_complete = false # Path 2 dream-hook toggle (independent)
|
|
# agent_ids = ["main"] # empty/omitted = all configured agents
|