# =============================================================================
# AtomCode 配置模板
#
# 复制到 ~/.atomcode/config.toml 后按需修改。Provider 可声明多个,
# 在 TUI 中用 /provider 或 /model 切换。
# =============================================================================

# ---- 默认 provider(必须匹配下方某个 [providers.*] 的键名)----
default_provider = "deepseek"

# ---- 自动更新 / 自动提交(顶层键,必须在任何 [表] 之前)----
# auto_update: 每小时轮询新版本并预暂存,下次启动时应用(/upgrade 仍可手动)
# auto_commit: 每轮 agent 结束后自动提交改动的文件(仅在 git 仓库内生效)
auto_update = true
auto_commit = false

# ---- 离线 / 内网无公网环境开关(顶层键)----
# offline_mode: 离线 / 内网无公网环境开关。
#   "off"  (默认) — 正常联网行为,一切不变。
#   "on"   — 移除 web_fetch/web_search,停用遥测与自动更新,并告知模型处于离线环境
#            (优先离线友好写法:不引外部 CDN、不做联网安装)。
#   "auto" — 乐观联网;观察到一次联网失败后自动转为离线。
# 环境变量 ATOMCODE_OFFLINE=1|0|auto 覆盖此项(优先级更高)。
offline_mode = "off"

# offline_note (可选): 声明本机内网可用的镜像/私服,会拼接进离线系统提示,
# 让模型知道哪些私服可用(如 npm 私服),避免过度保守。留空则不拼接。
# offline_note = "npm 私服 registry=http://nexus.internal:8081(可正常 npm install);Maven 走内部仓库;pip index 已配"

# =============================================================================
# Provider 示例
# =============================================================================

# ─── Example: AtomGit CodingPlan (recommended) ───
# Run `atomcode login` to auto-configure via OAuth, which writes
# providers like the one below. Manual setup is for reference only.
#
# [providers.AtomGit-deepseek-v4-flash]
# type = "openai"
# api_key = "<your-codingplan-api-key>"
# model = "deepseek-v4-flash"
# base_url = "https://llm-api.atomgit.com/v1"
# context_window = 1000000
#
# [providers.AtomGit-Qwen-Qwen3-VL-8B-Instruct]
# type = "openai"
# api_key = "<your-codingplan-api-key>"
# model = "Qwen/Qwen3-VL-8B-Instruct"
# base_url = "https://llm-api.atomgit.com/v1"
# context_window = 64000
# ─────────────────────────────────────────────────

# -------- DeepSeek ----------
[providers.deepseek]
type = "openai"
api_key = "sk-..."
model = "deepseek-chat"
base_url = "https://api.deepseek.com/v1"
context_window = 64000
# Total attempts including the first request. Default: 3; set 1 to disable retries.
# retry_max_attempts = 5

# DeepSeek V4 专属:推理历史回显策略
# (unset = auto-detect: deepseek-v4* → include, deepseek-reasoner/r1 → exclude)
# reasoning_history = "include"  # 或 "exclude"
# reasoning_effort = "high"

# -------- 智谱 GLM-5.2(通过 Zhipu API)----------
[providers.glm]
type = "openai"
api_key = "sk-..."
model = "glm-5.2"
base_url = "https://open.bigmodel.cn/api/paas/v4"
context_window = 1000000
max_tokens = 131072

# 推理强度调节(high / max)
# 参考:https://docs.z.ai/guides/llm/glm-5.2

# -------- 智谱 GLM-5.2 1M 上下文(显式启用)----------
# [providers."glm-5.2-1m"]
# type = "openai"
# api_key = "sk-..."
# model = "glm-5.2[1m]"
# base_url = "https://open.bigmodel.cn/api/paas/v4"
# context_window = 1000000

# -------- Claude(Anthropic)----------
[providers.claude]
type = "claude"
api_key = "sk-ant-..."
model = "claude-sonnet-4-6"
base_url = "https://api.anthropic.com/v1"
context_window = 200000

# -------- OpenAI ----------
[providers.openai]
type = "openai"
api_key = "sk-proj-..."
model = "gpt-4o"
base_url = "https://api.openai.com/v1"
context_window = 128000

# -------- Ollama(本地)----------
[providers.ollama]
type = "ollama"
model = "qwen3:14b"
base_url = "http://localhost:11434"
context_window = 32000

# -------- 通义千问 Qwen ----------
[providers.qwen]
type = "openai"
api_key = "sk-..."
model = "qwen-plus"
base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
context_window = 131072

# -------- SiliconFlow ----------
[providers.siliconflow]
type = "openai"
api_key = "sk-..."
model = "deepseek-ai/DeepSeek-V3"
base_url = "https://api.siliconflow.cn/v1"
context_window = 64000

# -------- 小米 MiMo ----------
[providers.xiaomi-mimo]
type = "openai"
api_key = "sk-..."
model = "mimo-v2.5-pro"
base_url = "https://api.xiaomimimo.com/v1"
context_window = 1000000
max_tokens = 131072

# -------- AtomGit CodingPlan(OAuth 自动配置)----------
# /login 命令会自动写入,无需手动填写 api_key
# 以下仅为展示格式,实际由系统自动生成。
# [providers."AtomGit-GLM-5.2"]
# type = "openai"
# model = "GLM-5.2"
# base_url = "https://llm-api.atomgit.com/v1"
# context_window = 1000000
# max_tokens = 131072
#
# [providers."AtomGit-deepseek-v4-flash"]
# type = "openai"
# model = "deepseek-v4-flash"
# base_url = "https://llm-api.atomgit.com/v1"
# context_window = 1000000
#
# [providers."AtomGit-Qwen-Qwen3-VL-8B-Instruct"]
# type = "openai"
# model = "Qwen/Qwen3-VL-8B-Instruct"
# base_url = "https://llm-api.atomgit.com/v1"
# context_window = 64000

# =============================================================================
# 视觉预处理(当主 provider 不支持图片时,用此 provider 代为识别)
# =============================================================================
# vision_preprocessor_provider = "qwen-vl"

# [providers."qwen-vl"]
# type = "openai"
# api_key = "sk-..."
# model = "Qwen/Qwen3-VL-8B-Instruct"
# base_url = "https://llm-api.atomgit.com/v1"
# context_window = 64000

# =============================================================================
# 多 provider 切换快捷键
# =============================================================================
# 在 TUI 中输入 /provider 打开 provider 管理界面
# 输入 /model 在当前 provider 下切换模型

# =============================================================================
# 数据日志(每轮对话写入 Markdown 摘要 + 每次 LLM 请求 JSONL)
# 日志包含未经脱敏的提示词、响应、工具输入和输出,请按敏感数据保护。
# =============================================================================
[datalog]
enabled = false
dir = "~/.atomcode/datalog"

# =============================================================================
# 通知
# =============================================================================
[notifications]
enabled = true
min_duration_secs = 8
terminal = true
system = true
bell = true
background_only = true

# =============================================================================
# 网络代理
# =============================================================================
[network.proxy]
# follow_system (default): respect the launch environment / system proxy.
# default_proxy: pin the values below. no_proxy: bypass all proxies.
mode = "follow_system"
# http = "http://127.0.0.1:7890"
# https = "http://127.0.0.1:7890"
# all = "socks5://127.0.0.1:7890"
# no_proxy = "localhost,127.0.0.1"

# Lifecycle hooks — run custom scripts on key events.
# Hooks are NOT configured in this file. Use separate config files instead:
#   TOML: ~/.atomcode/hooks/hooks.toml (recommended, supports ScriptHook + Webhook)
#   JSON: ~/.atomcode/hooks.json (CC-compatible, lightweight)
# See docs/hooks.md for full reference.
#
# Available events (JSON CC format; TOML ScriptHook uses different trigger names — see docs/hooks.md):
#   pre_tool_use    — before each tool call (can block via stdout {"action":"block","reason":"..."})
#   post_tool_use   — after each tool call
#   user_prompt_submit — when the user submits a prompt (can block via stdout {"decision":"block","reason":"..."} or inject context via {"hookSpecificOutput":{"additionalContext":"..."}})
#   session_start   — when a new session begins
#   session_end     — when a session ends
#
# JSON CC scripts receive context via env vars: ATOMCODE_HOOK_EVENT, ATOMCODE_TOOL_NAME,
# ATOMCODE_HOOK_CONTEXT (JSON string). TOML ScriptHook uses stdin instead — see docs/hooks.md.
# JSON CC PreToolUse stdout supports (TOML ScriptHook uses text protocol ok/deny:/modify: — see docs/hooks.md):
#   {"action":"allow"} or {"action":"block","reason":"..."} or {"action":"modify","args":{...}}
#
# Example ~/.atomcode/hooks.json (JSON CC format; TOML uses [[hooks]] with trigger/script/timeout_secs — see docs/hooks.md):
# {
#   "hooks": {
#     "verify-gate": {
#       "event": "post_tool_use",
#       "command": "python ~/.atomcode/scripts/verify-gate.py",  # ~ 不会自动展开,需用绝对路径(如 C:\Users\you\.atomcode\scripts\verify-gate.py 或 /home/you/.atomcode/scripts/verify-gate.py)
#       "timeout_ms": 30000  # default is 10000 (10s); set 30s here because verify may be slow
#     }
#   }
# }

# =============================================================================
# Agent 循环保险(环境变量)
# =============================================================================
# 普通 coding 回合默认不设模型轮次上限;精确无进展防护仍然生效。
# 无人值守或成本敏感的部署可显式设置额外的变化型 runaway 高水位:
#   ATOMCODE_TURN_MAX_ROUNDS=200
# 精确无进展防护比较“实际工具名 + 规范化参数 + 有效 cwd + 模型可见结果 + 错误状态”;
# 默认第 3 次提醒、第 4 次完成真实工具结果后停止。合法任务若明确需要重复相同调用和
# 相同结果,可提高这两个阈值;STOP 设为 0 可关闭:
#   ATOMCODE_TOOL_LOOP_WARNING_THRESHOLD=3
#   ATOMCODE_TOOL_LOOP_STOP_THRESHOLD=4
# goal 另有独立轮次上限(无套餐信息时默认 300 轮,会按套餐调用额度调整);
# 墙钟上限默认关闭。二者设为 0 均表示不设上限:
#   ATOMCODE_GOAL_MAX_ROUNDS=300
#   ATOMCODE_GOAL_MAX_DURATION_SECS=0
# /loop 使用 [loop_config] 的 max_rounds,并可由 ATOMCODE_LOOP_MAX_ROUNDS 覆盖;0 表示不设上限。
# 内嵌 code_review 在父回合等待期间有自己的默认保险(200 轮/900 秒),均可覆盖,0 为关闭:
#   ATOMCODE_REVIEW_MAX_ROUNDS=200
#   ATOMCODE_REVIEW_MAX_DURATION_SECS=900
[coding]
max_rounds = 0

[loop_config]
max_rounds = 100

# Todo 任务跟踪。ATOMCODE_TODO 环境变量仍可覆盖 enabled;修改 enabled 后需重启当前 runtime。
# eager: auto(DeepSeek V4 Flash 自动增强)| preferred(复杂任务优先提醒)| always(provider 支持时强制先建表)
[tools.todo]
enabled = true
eager = "auto"

# =============================================================================
# 权限预授权(`[permissions]`)
# =============================================================================
# 给常用命令/路径开白名单,省掉每次都弹的审批框——不用再上 `--dangerously-skip-permissions`
# 那种全局全开的核选项。规则语法与 Claude Code 的 `permissions.allow/deny` 兼容,
# 从 CC 的 settings.json 里抄过来即可用。
#
#   Bash                     —— 整个 bash 工具
#   Bash(git *)              —— 以 `git ` 开头的命令;`*` 会跨 `/`(命令不是路径)
#   Bash(npm run test:*)     —— CC 的 `:*` 前缀写法,等价于 `npm run test*`
#   Bash(cargo test)         —— 精确匹配(空格/注释归一化后比较)
#   Read(~/.zshrc)           —— 路径规则,`~` 展开、相对路径按当前工作目录解析
#   Edit(src/**)             —— src/ 下的编辑
#   mcp__server__tool        —— 指定 MCP 工具
#   *                        —— 所有工具(一般只在 deny 里用)
#
# 工具名大小写与下划线不敏感,且认 CC 的简称:Read/Write/Edit/LS/MultiEdit
# 分别对应 read_file/write_file/edit_file/list_directory/parallel_edit_files。
#
# 两条铁律:
#   1. deny 先判、且优先于 allow;
#   2. allow 永远不对「敏感路径」生效(~/.ssh、.env、凭证文件等)——这类调用照旧走审批,
#      免得一条宽泛的 `Bash(rm *)` 变成静默的密钥删除/外泄通道。
# 凭证守卫、plan 模式、敏感路径读取守卫都排在本规则之前,用户规则只能省掉「提示」,
# 不能解开任何安全闸门。写错的规则会被忽略并在 stderr 告警,不会静默放宽策略。
#
# [permissions]
# allow = ["Bash(git *)", "Bash(cargo test*)", "Read(src/**)"]
# deny  = ["Bash(rm -rf *)"]

# =============================================================================
# Subagent 设置(`task` 工具:主 agent 把子任务派发给隔离上下文的子 agent)
# =============================================================================
# 总开关是环境变量 ATOMCODE_SUBAGENT(默认开启)——用 `ATOMCODE_SUBAGENT=0` 关闭。
# 下面的 `enabled` 字段是历史遗留、当前不生效;真正开关看上面的环境变量。
# 生效旋钮:max_concurrent(并发数)和 max_rounds(单任务模型轮次高水位)。
# timeout_secs 仅为兼容旧配置保留,不再限制 subagent 的总运行时间。
# max_rounds 可由 ATOMCODE_SUBAGENT_MAX_ROUNDS 覆盖。
[subagent]
enabled = true          # 遗留字段,不生效(改这个不会关掉 subagent;用 ATOMCODE_SUBAGENT=0)
initial_turns = 4       # 遗留字段,不生效
max_turns = 12          # 遗留字段,不生效
max_concurrent = 3      # 生效:并发子 agent 上限(下限 1)
timeout_secs = 900      # 遗留字段:仍可解析,但不生效
max_rounds = 200        # 生效:单个子任务模型轮次高水位(0=不设上限;继承上面的精确防护策略)

# =============================================================================
# LSP(语言服务器协议)
# =============================================================================
[lsp]
enabled = false
auto_detect = false
diagnostics_settle_delay_ms = 150

# =============================================================================
# 插件
# =============================================================================
[plugin]
auto_install_default_skills = true
auto_update_marketplaces = true

# =============================================================================
# UI
# =============================================================================
[ui]
theme = "auto"
# /resume 初次回放到终端原生 scrollback 的视觉行上限。
# 省略时按终端自动选择;0 表示完整回放(长会话恢复会更慢)。
# history_replay_max_rows = 5000