本文档列出 settings.json 中所有合法配置项及其作用。配置文件只接受文档声明的键:未知键会被忽略(兼容旧版本残留的配置项,如已移除功能的 showKeyHints,并在下次保存该作用域时清除);点号属性名和类型错误仍会导致该次加载失败,并保留上一份有效快照。分组配置必须使用嵌套 JSON,例如 autodream.enabled 写为 { "autodream": { "enabled": true } }。
OneCode 支持两级配置文件:
| 级别 | 路径 | 作用域 |
|---|---|---|
| 全局 | ~/.onecode/settings.json |
所有项目共享,存储 API 密钥、信任目录等 |
| 项目级 | <cwd>/.onecode/settings.json |
仅当前项目生效,覆盖全局同名键 |
项目级配置优先于全局配置。allowedDirectories 等项目特定配置应写入项目级文件,避免跨项目污染。
OneCode 由 ConfigManager 统一按以下优先级解析(高 → 低):
- 会话覆盖:只影响当前进程,不持久化
- 环境变量
ONECODE_*:只读覆盖,设置页不会回写 - 项目级
settings.json:<cwd>/.onecode/settings.json - 用户级
settings.json:~/.onecode/settings.json - 内置默认值
业务组件通常只读取统一的 ConfigSnapshot,不再自行读取 ONECODE_API_KEY、ONECODE_MODEL 等环境变量。例外:AutoDream 的门控开关(ONECODE_REMOTE、ONECODE_AUTODREAM)由服务自身直接读取且优先于 settings.json(见 后台服务 §5.6)。
配置写入采用显式作用域 Patch,只修改目标文件中本次提交涉及的键;不会把项目值或环境变量值复制进用户配置。
/config list
/config get <key>
/config set <user|project|session> <key> <value>
/config remove <user|project|session> <key>
list 可写作 ls;set <scope> <key> <value> 中 value 之后的参数会以空格拼回一个值。
remove 删除指定作用域中的覆盖值,使该键恢复继承下一级配置。旧的无作用域 /config set <key> <value> 语法不再支持。
在交互式 TUI 中执行 /config 会打开设置弹窗:底部提供“保存”和“取消”按钮,也可使用 Ctrl+S 保存、Esc 取消。API Key 使用单个掩码输入框显示当前有效值;内容不变时不会重复写入,修改后替换当前作用域密钥,清空后保存则删除当前作用域密钥并恢复继承。其他配置如需恢复继承,使用显式 /config remove <scope> <key>,不在常规设置表单中提供任意键删除入口。
| 类型 | 配置项 | 语义 |
|---|---|---|
| 立即生效 | showThinking、trustedDirectories、allowedDirectories、hasTrustAccepted |
保存后立即更新当前进程 |
| 下次操作生效 | model、fastModel、permissionMode、思考参数、maxTurns、maxBudgetTokens、webSearchProvider、通知、autodream.*、goal.*、agents.* |
不影响正在执行的请求,下一次操作读取新快照 |
| 重启后生效 | provider、baseUrl、apiKey、ollamaContextWindow、ollama.temperature、streamIdleTimeoutSeconds、streamMaxRetries |
IChatClient 构造时固化,重启后应用 |
| 键 | 类型 | 默认值 | 作用 |
|---|---|---|---|
apiKey |
string |
— | LLM 服务商 API 密钥。可被环境变量 ONECODE_API_KEY 覆盖 |
baseUrl |
string |
— | 自定义 API 基址,用于代理或自托管端点。可被 ONECODE_BASE_URL 覆盖 |
provider |
string |
anthropic |
模型提供方标识:anthropic / openai / ollama。可被 ONECODE_PROVIDER_OVERRIDE 覆盖 |
model |
string |
— | 主模型 ID(如 claude-sonnet-4-6)。可被 ONECODE_MODEL 覆盖 |
fastModel |
string |
— | 辅助/快速模型 ID,供 hooks、记忆提取、下一步提示建议等轻量调用使用。未配置时回退到主模型。推荐通过 /fastmodel 命令调整,内部通过 ModelManager.GetFastModel() 消费 |
示例:
{
"apiKey": "sk-ant-...",
"provider": "anthropic",
"model": "claude-sonnet-4-6",
"fastModel": "claude-haiku-4-6"
}| 键 | 类型 | 默认值 | 级别 | 作用 |
|---|---|---|---|---|
permissionMode |
string |
default |
全局 / 项目级 | 权限策略模式,见下表 |
trustedDirectories |
string[] |
[] |
全局 | 已信任项目列表,首次进入时不再弹信任提示。存储用户已确认信任的目录,子目录隐式继承 |
allowedDirectories |
string[] |
[] |
全局 / 项目级(另有会话级) | 工作区允许访问的额外目录白名单(路径遍历防护)。工具可读写 cwd 外的这些目录。/add-dir --persist 写入项目级;/add-dir 写入会话级 |
hasTrustAccepted |
bool |
false |
全局 | 全局信任开关:为 true 时信任一切目录、跳过所有项目信任提示;不是「当前项目已信任」的记录 |
trustedDirectories vs allowedDirectories:
trustedDirectories:信任记忆。记住用户已确认信任的项目目录,避免重复弹窗。全局存储,不参与运行时路径校验。allowedDirectories:额外目录白名单。允许工具访问 cwd 之外的目录(如 monorepo 子项目)。项目级存储,参与运行时路径校验。两者职责不同,不应合并。若合并会导致
/add-dir添加的目录被当作“已信任目录”,从而在直接启动该目录时跳过信任确认,绕过安全门禁。
permissionMode 可选值(PermissionMode 枚举,可写 7 个成员):
| 值 | 说明 |
|---|---|
default |
BUILD 模式默认档位:只读工具与只读 Shell 直接放行,写文件(Write/Edit/Delete)与非只读 Shell 弹窗请求用户审批(无论直接切到 BUILD 提问还是从 PLAN 批准计划转入 BUILD,均走一致审批规则) |
bypassPermissions |
跳过所有权限检查(危险,仅限可信环境;Layer 0 安全不变量仍生效) |
plan |
持久化"启动即 PLAN 工作模式":只读 + 规划辅助白名单放行,写操作拒绝;交互启动时经 WorkingModeBridge 进入完整计划工作流 |
auto |
YOLO 自动分类模式,启用 LLM 安全分类器自动判断 |
acceptEdits |
文件写入 + 常规 Shell 自动放行,危险 Shell 按规则评估或弹窗审批 |
dontAsk |
不询问,直接拒绝需审批操作 |
goalAuto |
GOAL 模式自动派生:工作区内读写与常规开发命令自动放行,破坏性高危 Shell 直接 Deny |
Shell 的路径操作数必须能在执行前静态证明位于授权目录内。PowerShell 中的变量、命令展开和 脚本表达式(如
$PWD、$env:OUT、$(Resolve-Path .))一律 fail-closed;请改写为工作区内的 字面路径。工作区内的字面路径与 glob 静态前缀仍可正常使用。
PermissionModeProvider.CurrentMode用Enum.TryParse(..., ignoreCase: true)解析本键,因此上述成员均可手写; 未识别的值会回落为default。goalAuto是 GOAL 工作模式在运行期派生的内部值—— 手写在交互启动时会被WorkingModeBridge.SyncInitialState覆盖为 BUILD 默认档,因此只应作为派生结果出现。 会话级一次性配置请用/permissions <mode> --session(别名--once;只设运行时覆盖、不写本键), 例如/permissions bypass --session仅在本次对话全放行;plan/goalAuto不是/permissions的合法参数(那是工作模式,用 Tab 切换)。
| 键 | 类型 | 默认值 | 作用 |
|---|---|---|---|
maxTurns |
int |
100 |
单次会话最大对话轮数 |
maxBudgetTokens |
long |
5000000 |
预算熔断上限(可计费 token,达到后短路后续 LLM 调用)。0 = 不设限。计量口径与模式语义见下节 |
maxBudgetTokens 的计量口径与模式语义
- 计量口径(可计费 token):
可计费 = 非缓存输入 + 输出 + 缓存写入 + 缓存读 × 10%。 缓存读是对同一段上下文的重复计费(真实价格约为非缓存输入的一折),按全额累计会让长会话 每轮请求把整个上下文重算一遍而误触熔断;按 10% 折算既贴近真实成本,又保留对失控循环 (纯缓存命中打转)的检测能力。/status与状态栏展示的仍是原始四维计数,仅熔断判断用可计费口径。 - 模式语义:BUILD 模式按 run 独立计量——run 启动时对当前累计做快照,预算只衡量本次计划
执行的增量消耗(Plan 阶段的调研不占用 Build 的额度);有会话的 PLAN / GOAL 维持会话级累计;
无会话路径以当前全局用量为基线,同样只衡量本次 run 的增量。
计量账本(
ITokenLedger)在内存中即时累计,后台把待写增量合并为单批跨进程事务,run 与宿主收尾 再执行有界 flush;预算判断因此不受磁盘 I/O 影响,进程崩溃最多丢失最近尚未 flush 的一小段用量。JsonUsageStateStore落盘到~/.onecode/usage/usage.json并在启动时水合,跨进程锁与原子替换 防止多进程用旧快照互相覆盖,单个.bak用于主文件损坏时恢复有效状态。GOAL 的分解 / Replan、 显式/compact的摘要消耗计入对应会话桶;AutoDream 后台整合只计入全局后台账本。 - 调整方法:
settings.json(项目级 / 用户级)或运行时/config(下一次 run 生效); 设为0关闭预算熔断。 - 分级行为:70% / 90% 时在对话流发布黄 / 橙预警横幅;100% 时交互模式弹窗询问
(追加预算继续 / 收尾总结 / 直接停止),无人值守路径(GOAL 编排、cron 任务、后台子代理)
硬停短路并以
BudgetExceeded正常收口,不抛异常。
| 键 | 类型 | 默认值 | 作用 |
|---|---|---|---|
nextPromptSuggesterEnabled |
bool |
true |
是否生成下一步输入建议 |
notificationsEnabled |
bool |
false |
是否启用本地 OS 桌面通知(Windows toast / macOS osascript / Linux notify-send)。触发点:cron 完成/失败、hook 通知、审批挂起超 30 秒宽限、交互运行超过 2 分钟的任务完成(无人值守路径由 cron 通知,不双发) |
日志级别由构建模式决定:Debug 构建记录 Debug 及以上,Release 构建记录 Warning 及以上(含 Error),
两者都同时写控制台与文件 ~/.onecode/debug/<sessionId>.log。没有运行时覆盖开关,也不属于持久化配置。
| 键 | 类型 | 默认值 | 作用 |
|---|---|---|---|
webSearchProvider |
string |
duckduckgo |
WebSearch 主提供方(duckduckgo / tavily);失败时自动回退另一提供方,未配置 Key 的 Tavily 自动跳过 |
webSearchApiKeys.tavily |
string |
— | Tavily 搜索 API 密钥(tavily.com 免费注册,1000 次/月,无需信用卡) |
| 键 | 类型 | 默认值 | 作用 |
|---|---|---|---|
effortValue |
string |
medium |
推理努力级别:low / medium / high / max。决定 thinking 预算和自适应启用阈值 |
thinkingEnabled |
bool |
false |
是否启用扩展思考(extended thinking) |
showThinking |
bool |
false |
是否在 TUI 中显示思考内容 |
effortValue、thinkingEnabled属于“下次操作生效”。设置页、/config与/think均通过同一配置服务写入,并同步当前运行时状态;已经开始执行的请求仍使用启动时捕获的参数。
| 键 | 类型 | 默认值 | 作用 |
|---|---|---|---|
ollamaContextWindow |
int |
32768 |
Ollama 请求的 num_ctx 上下文窗口;重启后生效 |
ollama.temperature |
double |
0.15 |
Ollama 采样温度(并固定 top_p=0.9, top_k=40, repeat_penalty=1.1 以抑制小模型 tool-call JSON 幻觉);重启后生效 |
streamIdleTimeoutSeconds |
int |
180 |
流式 chunk 间空闲停滞判定上限(秒):收到过数据后连续无新 chunk 超过该时长即判定连接停滞并重试;重启后生效 |
streamMaxRetries |
int |
6 |
流式请求过载/停滞的最大重试次数(最坏反馈时长约为(次数+1)×空闲上限);重启后生效 |
本地模型的窗口真相源:models.dev 不覆盖本地 Ollama 模型,因此该值同时决定三件事——下发给服务端的
num_ctx(服务端真正强制的窗口)、上下文预算,以及自动压缩阈值。catalog 中同名字符串对本地模型无效。 只对provider: "ollama"生效:云端 provider(包括 OpenRouter 上托管的小模型)仍以 models.dev 为准, 本项不参与其窗口解析。用本地部署跑大模型时把该值调大,即可同时恢复窗口与预算 (num_ctx随重启生效,预算侧跟随配置快照)。
运行前置:新建 GoalRun 要求目标目录是 Git 仓库且工作区无未提交改动;运行在隔离 worktree 中执行,完成并通过硬门禁后 cherry-pick 合入。发布时目标分支 HEAD 必须仍等于启动基线,且工作区指纹不得漂移。
| 键 | 类型 | 默认值 | 作用 |
|---|---|---|---|
goal.maxSubGoalAttempts |
int |
20 |
单次 Goal 运行允许的子目标尝试总数 |
goal.maxTurnsPerSubGoal |
int |
50 |
每个子目标允许的最大轮数 |
goal.maxTotalTokens |
long |
200000 |
Goal 运行的总 Token 预算;≤0 表示不限制 |
goal.maxWallClockHours |
double |
2.0 |
Goal 运行的最长墙钟时间(小时);≤0 表示不限制 |
≤0 语义:
goal.maxTotalTokens/goal.maxWallClockHours配 0 或负值时归一为“不限制”(ModeBudgetSettings.TotalTokenLimit/MaxWallClock);Stage 4b 引入统一预算配置之前该配置会因除零被立即判定为预算耗尽。
| 键 | 类型 | 默认值 | 作用 |
|---|---|---|---|
loop.maxIterations |
int |
3 |
/loop 单次循环调用 agent 的硬上限,取值被夹在 1..20;/loop --max <n> 可逐次覆盖 |
上限语义与 MAF
LoopAgentOptions.MaxIterations一致:限制的是 agent 调用次数,达到上限时先停后判, 因此 3 = 3 次调用 + 最多 2 次完整“检查 → 重试”。评估器无法突破该上限。缺省值刻意低于框架默认的 10—— 每轮是一次完整 agent run,成本远高于一次工具调用。详见 /loop 与 代理循环边界。
磁盘格式使用嵌套对象,例如:
{
"goal": {
"maxSubGoalAttempts": 20,
"maxTurnsPerSubGoal": 50,
"maxTotalTokens": 200000,
"maxWallClockHours": 2.0
},
"loop": {
"maxIterations": 5
}
}派工出去的子代理(Agent / ParallelAgents)有轮数与墙钟两道预算,避免简单调研跑满几十轮:
| 键 | 类型 | 默认值 | 作用 |
|---|---|---|---|
agents.defaults.maxTurns |
int |
0 |
子代理轮数上限(按模型往返计,同轮并行工具调用不重复计数)。0 = 自动:只读 profile(Explore / Plan)用 15,通用(general-purpose / 自定义)用 50 |
agents.defaults.timeoutMinutes |
int |
10 |
子代理墙钟超时(分钟),到时走收尾总结并以 partial 结果返回。≤0 表示不限制 |
上限分层(高优先级在前,只在一个地方解析):
- 派工时的可选
maxTurns工具参数——只能收窄,不能抬高下面各层给出的上限 - 自定义代理 frontmatter 的
max_turns(.onecode/agents/*.md) - 本节
agents.defaults.maxTurns - profile 内置默认(只读 15 / 通用 50)
到达轮数上限时不会硬杀:子代理会补一次禁用工具的收尾调用,总结已完成工作与剩余事项;
墙钟超时则直接以无输出的 partial 收场。结果标记 [PARTIAL] 返回父代理,父代理应直接使用已有发现而非重复派发。轮次预算另有 80% 收尾提醒:子代理跑满
八成轮数时先收到一条"开始收尾"的注入提醒(见 docs/sub-agents.md),多数失控
循环在此自然收敛,轮数上限只作最后兜底。工具调用另有安全上限(轮数上限的倍数),
用于拦截单轮内并行的失控工具循环。
{
"agents": {
"defaults": {
"maxTurns": 40,
"timeoutMinutes": 15
}
}
}AutoDream 默认开启,在 BUILD 模式任务正常完成时通过零 Token 增量快检触发。如需关闭,可在 settings.json 中配置:
| 键 | 类型 | 默认值 | 作用 |
|---|---|---|---|
autodream.enabled |
bool |
true |
是否启用 AutoDream。设为 false 关闭 |
示例:
{
"autodream": {
"enabled": true
}
}模型:AutoDream 直接复用已有的
fastModel(未配置时回退到主model),不需要单独配置模型。远程模式:
ONECODE_REMOTE=true时无论配置如何都自动关闭 AutoDream。详见 后台服务文档。
以下环境变量映射到配置键并覆盖 settings.json 中的对应值(除 TAVILY_API_KEY 外均带 ONECODE_ 前缀):
| 环境变量 | 覆盖的配置键 |
|---|---|
ONECODE_API_KEY |
apiKey |
ONECODE_BASE_URL |
baseUrl |
ONECODE_PROVIDER_OVERRIDE |
provider |
ONECODE_MODEL |
model |
ONECODE_WEB_SEARCH_PROVIDER |
webSearchProvider |
TAVILY_API_KEY |
webSearchApiKeys.tavily |
ONECODE_AUTODREAM |
autodream.enabled |
ONECODE_REMOTE |
true 时强制关闭 AutoDream(远程模式) |
环境变量由
ConfigManager映射到配置键并标记来源为Environment。环境变量作用域只读,任何保存操作都不会将其值持久化到settings.json。
ONECODE_REMOTE属于进程运行标志,不是持久化配置项。
Hook 定义存放在独立文件中,不在 settings.json 内:
| 文件 | 作用域 | 优先级 |
|---|---|---|
~/.onecode/hooks.json |
用户级 | 100 |
<cwd>/.onecode/hooks.json |
项目级 | 200 |
hooks.json 的根对象即为 hooks 内容(不再是 settings.json 的子属性),示例:
{
"pre_tool_call": [
{
"matcher": "Edit",
"hooks": [
{ "type": "command", "command": "echo 'About to edit'" }
]
}
],
"post_tool_call": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "notify-send 'Command finished'" }
]
}
]
}Hook 策略由独立的 Hook 子系统管理,不属于 settings.json 配置。通过 /hooks 命令可查看已注册 Hook 和当前工作区信任状态。
更多详情:Hook 子系统的完整设计、拦截点清单、执行器类型、扩展指南参见 Hook 模块文档,架构决策与实现细节参见 Hook 模块架构设计。
{
"apiKey": "sk-ant-...",
"provider": "anthropic",
"model": "claude-sonnet-4-6",
"fastModel": "claude-haiku-4-6",
"permissionMode": "default",
"trustedDirectories": ["/home/user/projects"],
"hasTrustAccepted": true,
"maxTurns": 100,
"maxBudgetTokens": 5000000,
"webSearchProvider": "duckduckgo",
"effortValue": "medium",
"thinkingEnabled": false,
"showThinking": false,
"nextPromptSuggesterEnabled": true,
"notificationsEnabled": false,
"ollamaContextWindow": 32768,
"streamIdleTimeoutSeconds": 180,
"streamMaxRetries": 6
}{
"allowedDirectories": [
"../shared-lib",
"../common-utils"
]
}| 配置键 | 常量定义 | 消费位置 |
|---|---|---|
apiKey |
ConfigKeys.ApiKey |
AppSettings.ApiKey、TuiHostConfigurator |
baseUrl |
ConfigKeys.BaseUrl |
AppSettings.BaseUrl、TuiHostConfigurator |
provider |
ConfigKeys.Provider |
AppSettings.Provider、TuiHostConfigurator |
model |
ConfigKeys.Model |
AppSettings.Model、ModelManager.GetMainModel |
fastModel |
ConfigKeys.FastModel |
ModelManager.GetFastModel、FastModelCommand、TuiHostConfigurator、SettingsOverlay |
permissionMode |
ConfigKeys.PermissionMode |
AppSettings.PermissionMode |
trustedDirectories |
—(字面量) | AppSettings.TrustedDirectories(全局) |
allowedDirectories |
—(字面量) | AppSettings.AllowedDirectories(项目级覆盖全局) |
hasTrustAccepted |
—(字面量) | AppSettings.HasTrustAccepted |
maxTurns |
ConfigKeys.MaxTurns |
AppSettings.MaxTurns |
maxBudgetTokens |
ConfigKeys.MaxBudgetTokens |
AppSettings.MaxBudgetTokens |
webSearchProvider |
ConfigKeys.WebSearchProvider |
AppSettings.WebSearchProvider |
webSearchApiKeys.tavily |
ConfigKeys.TavilyApiKey |
AppSettings.TavilyApiKey |
effortValue |
—(字面量) | SettingsOverlay、TuiHostConfigurator、ThinkingParamsResolver、InteractiveBootstrapService、ConfigCommand、ThinkCommand、StatusCommand(经 AppState) |
thinkingEnabled |
—(字面量) | SettingsOverlay、TuiHostConfigurator、ThinkingParamsResolver、InteractiveBootstrapService、ConfigCommand、ThinkCommand、StatusCommand(经 AppState) |
showThinking |
—(字面量) | SettingsOverlay、TuiHostConfigurator、InteractiveBootstrapService、ConfigCommand、ThinkCommand、StatusCommand(经 AppState) |
nextPromptSuggesterEnabled |
ConfigKeys.NextPromptSuggesterEnabled |
AppSettings.NextPromptSuggesterEnabled |
notificationsEnabled |
ConfigKeys.NotificationsEnabled |
AppSettings.NotificationsEnabled |
ollamaContextWindow |
ConfigKeys.OllamaContextWindow |
AppSettings.OllamaContextWindow |
ollama.temperature |
ConfigKeys.OllamaTemperature |
AppSettings.OllamaTemperature |
streamIdleTimeoutSeconds |
ConfigKeys.StreamIdleTimeoutSeconds |
AppSettings.StreamIdleTimeoutSeconds |
streamMaxRetries |
ConfigKeys.StreamMaxRetries |
AppSettings.StreamMaxRetries |
agents.defaults.maxTurns |
ConfigKeys.AgentsDefaultMaxTurns |
ForkedAgentRunner(子代理默认最大轮次;未配置时按角色回退 Session.SubAgentMaxTurns* 常量) |
agents.defaults.timeoutMinutes |
ConfigKeys.AgentsDefaultTimeoutMinutes |
ForkedAgentRunner(子代理超时分钟数;内置默认 Session.SubAgentTimeoutMinutesDefault = 10) |
autodream.* |
—(字面量) | AutoDreamService |
goal.* |
ConfigKeys.GoalMax* |
ModeBudgetSettings.FromSettings(由 OrchestrationStreamService 调用) |
loop.maxIterations |
ConfigKeys.LoopMaxIterations |
ModeBudgetSettings.FromSettings(/loop);可经 settings.json、/config set、/loop --max 设置,超上限由 ModeBudgetSettings.MaxLoopIterationsUpperBound 夹取 |
配置元数据真相源:
src/OneCode.Core/Config/ConfigModels.cs中的SettingDescriptors。新增配置项时必须同时声明生效模式、密钥属性和项目作用域权限,并更新本文档。