{ // Default provider/model. Runtime model switches only affect the current session and are not written back here. "provider": "anthropic", "model": "claude-sonnet-4-6", "small_model": "claude-haiku-4-5", // auto-filled from provider config or main model // Per-provider credentials and model catalog. // Provider names are free-form; use "type" to specify the API protocol. "providers": { "anthropic": { "api_key": "", "models": ["claude-sonnet-4-6", "claude-opus-4-6"], "small_model": "claude-haiku-4-5" // sub-agents model; omit to use main model }, "openai": { "api_key": "", "base_url": "", "models": ["gpt-5.4", "gpt-5.3-codex"], "small_model": "gpt-5-mini" }, "openrouter": { "api_key": "", "base_url": "https://openrouter.ai/api/v1", "small_model": "stepfun/step-3.5-flash:free", "models": ["stepfun/step-3.5-flash:free", "openrouter/hunter-alpha", "openrouter/healer-alpha"] // no small_model — sub-agents will use the main model }, "gemini": { "api_key": "", "models": ["gemini-3.1-pro", "gemini-2.5-flash"], "small_model": "gemini-2.5-flash" }, "deepseek": { "api_key": "", "models": ["deepseek-chat", "deepseek-reasoner"], "small_model": "deepseek-chat" }, // Custom proxy example: "type" specifies the API protocol (openai/anthropic/gemini). // Omit "type" for well-known provider names — it will be inferred automatically. "my-proxy": { "type": "openai", "api_key": "sk-xxx", "base_url": "https://proxy.example.com/v1", "models": ["gpt-5", "claude-sonnet-4-5"], "small_model": "gpt-4o-mini" } }, "thinking_level": "low", // off | low | medium | high | xhigh "max_turns": 30, // Cap the effective compaction window: effective = min(detected, compact_window). // Useful for forcing earlier compaction on 1M-window models that suffer attention decay past ~200k. // Never exceeds the model's real window. Omit / 0 = use detected window. "compact_window": 300000, "compact_ratio": 0.85, "search_provider": "tavily", // tavily | jina "search_api_key": "", // Hooks: shell commands triggered on lifecycle events. // Global + project-level hooks are merged (appended, not replaced). "hooks": { "PreToolUse": [ { "type": "command", "command": "echo $HOOK_TOOL_NAME >> ~/.codebot/audit.log", "matcher": "bash", "blocking": true, "timeout": 10 } ], "PostToolUse": [ { "type": "command", "command": "echo done" } ], "TaskCreated": [ { "type": "command", "command": "echo created:$HOOK_TOOL_NAME" } ], "TaskCompleted": [ { "type": "command", "command": "echo completed:$HOOK_TOOL_NAME" } ], "Notification": [ { "type": "command", "command": "notify-send 'codebot' 'Agent finished'" } ] }, // Filesystem authorization roots. // Defaults: read_roots / write_roots both contain only the current working directory ".". // Add extra directories explicitly; write_roots should usually be stricter than read_roots. // Note: roots strictly govern file tools (read/write/edit/glob/grep/ls). // bash is only constrained at launch (workdir) and never guarantees actual access scope — always requires approval. "permissions": { "read_roots": [ ".", "../shared" ], "write_roots": [ "." ], "allow": [], "deny": [] }, // MCP servers: stdio (local process) or http (remote endpoint) "mcp_servers": { "context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp"] }, "remote-api": { "type": "http", "url": "https://mcp.deepwiki.com/mcp", "headers": { "Authorization": "Bearer your-token-here" } } } }