opencode V2 配置设计详解:11 组字段的评审决策与源码级落地
本文基于 opencode 仓库中的 V2 配置评审规格 specs/v2/config.md,完整讲解 V2 配置如何从遗留(legacy)schema 中拆分、评审并重新设计:11 个评审组里每个字段的 keep / remove / redesign 决策、新的配置形态与完整示例,以及这些决策在 packages/core/src/config.ts 及其子模块中的实际实现。读完后,你将能够准确理解 V2 配置文件(opencode.json / opencode.jsonc)的发现与合并机制,并掌握 providers、agents、permissions、mcp、compaction 等核心配置项的写法与设计依据。
V2 配置的范围与评审方法
specs/v2/config.md 将遗留配置 schema 拆分成小的评审组,要求逐组决策每个字段是“原样移植、删除还是为 v2 重新设计”。文档定义了四种状态标签:
| 标签 | 含义 |
|---|---|
pending |
尚未讨论 |
keep |
按现有语义基本原样移植 |
remove |
不向 v2 携带 |
redesign |
保留能力,但更换形态、作用域或归属模块 |
在 schema 范围上,V2 当前采用单一配置 schema。一些字段(如 autoupdate)本意是全局/用户级配置,但目前拆分为独立的 global 与 location 两套 schema 收益还不够大,若后续仍有更多作用域敏感字段存活下来,再重新评估。
配置文件命名规则是:V2 core 只发现名为 opencode.json 或 opencode.jsonc 的配置文档,发现位置包括:
- 全局配置目录(global config directory);
- 祖先项目目录(ancestor project directories);
.opencode配置目录。
遗留的 config.json 文件名在 V2 中不再支持。
从源码看,这套规则直接实现在 packages/core/src/config.ts 中:
const names = ["opencode.json", "opencode.jsonc"]
发现过程通过 fs.up 从当前 location 目录向上搜索,目标是 .opencode 目录与上述两个文件名,并在项目根目录处停止(config.ts)。注释明确了合并优先级:“离打开目录更近的配置应覆盖更上层”,最终顺序为“全局配置 → 项目文件 → .opencode 文件”(config.ts)。此外,源码中保留了 V1 文档的迁移通道:若解析出的文档被 ConfigMigrateV1.isV1 识别为 V1 配置,会先解码为 V1 schema、执行迁移、再解码进 V2 Info(config.ts)。
Group 1: 文件元数据($schema)
描述配置文件自身而非应用行为的小字段。
| 字段 | 当前用途 | 状态 | 说明 |
|---|---|---|---|
$schema |
供编辑器校验与补全的 JSON schema 引用 | keep | 保留为只读元数据;加载配置时不得为它插入值或创建文件 |
在 V2 的 Config.Info 中,$schema 被声明为可选字符串(config.ts),仅用于编辑器侧校验与补全。
Group 2: 进程与服务设置
影响进程启动、shell 执行或网络服务的设置,需要仔细审查全局专用(global-only)与 location 特定作用域。
| 字段 | 当前用途 | 状态 | 说明 |
|---|---|---|---|
shell |
终端与 shell 工具执行的默认 shell | keep | 作为有效配置移植;整个 opencode 共享这一 shell 选择 |
logLevel |
日志级别配置 | remove | 不移植:不存在消费方,日志从 CLI 输入初始化 |
server |
主机名、端口、mDNS、CORS 设置 | remove | 不移植:location 配置在服务器已运行之后才加载 |
autoupdate |
自动更新或通知行为 | keep | 仅全局的用户偏好;保留 true、false 和 "notify" 三种取值 |
源码中 shell 与 autoupdate 均已落在 V2 Info schema:autoupdate 的类型为 Boolean | "notify"(config.ts),与规格保持一致。
Group 3: 命令与项目资源
引入 location 作用域的项目资源或可发现内容的配置。
| 字段 | 当前用途 | 状态 | 说明 |
|---|---|---|---|
command |
用户自定义命令 | remove | 不作为 v2 配置移植;命名可复用的用户工作流归属 skills |
skills |
附加 skill 位置 | redesign | 用“本地路径或远程 URL 发现源”的单一阵列取代 { paths?, urls? } |
reference |
命名的 git 或本地目录引用 | redesign | 重命名为复数 references;保留命名的本地路径与 Git 仓库外部上下文条目 |
instructions |
附加的环境指令来源 | keep | 保留为“本地路径、glob 模式或远程 URL”的单一数组,提供自动包含的上下文 |
为什么移除 command 配置
V2 不暴露单独的用户自定义 command 配置。命名可复用的提示词工作流应由 skills 承担,无论由用户直接调用还是被 agent 加载。内部命令路由与内建命令可以保留为运行时关注点,而无需创建 command 或 commands 配置字段。这一决策有意不移植遗留的纯 command 行为,例如按命令的 model、agent、subtask、提示词 shell 展开、位置参数/模板替换等;若 v2 需要相关能力,应在其归属域内设计,而不是保留第二套工作流定义系统。
skills:只配置“发现源”,不内联工作流
skills 保持为发现源配置,而不是内联工作流定义。skill 内容由 SKILL.md 拥有,每个 skills 条目要么是本地搜索根目录,要么是远程发现 URL。直接调用行为可以另行设计,而不扩张配置形态。
{
"skills": ["./team-skills", "~/shared-skills", "https://example.com/.well-known/skills/"],
}
instructions:与 skills 分离的环境指令
环境指令(ambient instructions)与 skills 保持分离:instructions 会自动作为模型上下文包含,而 skills 需要被刻意加载或调用。由于每个来源都明确是本地路径/glob 或 URL,v2 保留简单数组形态:
{
"instructions": [
"CONTRIBUTING.md",
"docs/guidelines.md",
".cursor/rules/*.md",
"https://example.com/shared-rules.md",
],
}
references:命名的外部上下文
命名外部上下文引用作为 v2 配置能力保留,重命名为复数 references,因为它是按别名(alias)为键的集合。references 声明本地目录或 Git 仓库,待 v2 运行时实现该行为后,可以 @alias 或 @alias/path 的方式被引用。
{
"references": {
"design-system": { "path": "../ui-library" },
"sdk": { "repository": "github.com/example/sdk", "branch": "main" },
},
}
紧凑字符串形式同样保留:以 .、/、~ 开头的值表示本地路径,其他字符串表示 Git 仓库。
从源码看,packages/core/src/config/reference.ts 中 Entry 是 字符串 | Git | Local 的联合:Git 含 repository、可选 branch/description/hidden,Local 含 path 及同样的元数据字段,与规格中的两种显式形态完全对应;顶层 references 在 Info 中为 Record<string, Entry>(config.ts)。而 skills 与 instructions 均实现为 Schema.String.pipe(Schema.Array, ...) 的简单字符串数组(config.ts)。
Group 4: 插件(plugins)
插件加载具有来源路径与作用域敏感的行为,需要与其他项目资源分开评审。
| 字段 | 当前用途 | 状态 | 说明 |
|---|---|---|---|
plugin |
用户指定的插件模块 | redesign | 重命名为复数 plugins;保留“包名字符串或 { package, options? } 条目”的有序加载 |
插件顺序是 v2 配置契约的一部分,因为钩子的注册与执行可能依赖加载顺序。遗留的选项元组(option tuples)被可读的对象条目取代:
{
"plugins": [
"opencode-helicone-session",
{
"package": "@my-org/audit-plugin",
"options": {
"endpoint": "https://audit.example.com",
},
},
],
}
配置中的 plugins 列表只表示包加载的插件。本地插件代码仍然从 .opencode/plugins/ 之类的插件目录中发现;v2 不向该字段移植任意配置的本地路径或 file URL。
packages/core/src/config/plugin.ts 中 Plugin = Schema.Union([Schema.String, Entry])、Entry 为 { package, options? },Plugins 即其数组,与规格一致。
Group 5: 文件系统与工具运行时
控制本地文件观察、快照、语言工具与工具输出行为的设置。
| 字段 | 当前用途 | 状态 | 说明 |
|---|---|---|---|
watcher |
文件系统监听的忽略模式 | keep | 保留 { ignore?: string[] };它配置文件系统 watcher 子系统 |
snapshot |
启用文件系统快照跟踪 | redesign | 重命名为复数 snapshots;控制用于 undo 与回滚行为的快照创建 |
formatter |
配置格式化工具 | keep | 保留单数 boolean | Record<string, entry> 形态;配置内建启用与命名 formatter 覆盖 |
lsp |
配置语言服务器 | keep | 保留单数 boolean | Record<string, entry> 形态;自定义 server 需要 command 与文件扩展名 |
attachment |
配置附件/图像处理 | redesign | 重命名为复数 attachments;保留 { image?: { auto_resize?, max_width?, max_height?, max_base64_bytes? } } 作为输入规范化限制 |
tool_output |
配置工具输出截断上限 | keep | 保留 { max_lines?, max_bytes? };两个正阈值作用于保存预览的截断行为 |
formatter 与 lsp 各自配置一个项目工具子系统,因此单数名仍然合适:true 启用内建注册,false 禁用,键控对象则在启用内建的同时应用命名覆盖或自定义注册。自定义语言服务器必须声明 extensions,以保证运行时文件附加(file attachment)的确定性;已知内建 server ID 的校验归属于最终的 v2 LSP 集成,而不是聚合的核心配置 schema。
遗留 attachment 在 v2 中重命名为 attachments:该设置控制附件域的处理(未来可能扩展到图像之外),而单数 attachment 已被用作“某个模型是否接受附件”的模型能力标志。
{
"formatter": {
"prettier": { "disabled": true },
"project": { "command": ["./scripts/format", "$FILE"], "extensions": [".foo"] },
},
"lsp": {
"typescript": { "disabled": true },
"project": { "command": ["project-language-server", "--stdio"], "extensions": [".foo"] },
},
"attachments": {
"image": { "auto_resize": true, "max_width": 2000, "max_height": 2000 },
},
"tool_output": { "max_lines": 2000, "max_bytes": 51200 },
}
在 V2 Info 中,对应字段为 snapshots(布尔)、watcher、formatter、lsp、attachments、tool_output,分别指向 packages/core/src/config/ 下的 watcher.ts、formatter.ts、lsp.ts、attachments.ts、tool-output.ts 子模块(config.ts)。
Group 6: 共享与身份(sharing and identity)
影响共享行为或用户/账户身份(而非模型执行)的设置。
| 字段 | 当前用途 | 状态 | 说明 |
|---|---|---|---|
share |
会话共享行为 | keep | 保留 "manual" | "auto" | "disabled";控制手动共享许可与新会话自动共享 |
autoshare |
遗留自动共享标志 | remove | 不移植废弃别名;使用 share: "auto" |
enterprise |
企业 URL 配置 | keep | 保留 { url?: string };当前在没有组织账户激活时选择遗留共享服务端点 |
username |
会话与遥测中显示的 username | keep | 保留字符串身份覆盖;运行时否则可能解析操作系统用户名 |
share 保留为唯一的会话共享设置:"manual" 允许显式共享,"auto" 自动共享新建的顶层会话,"disabled" 禁止共享。遗留 autoshare: true 只是 share: "auto" 的别名,因此 v2 不暴露它。
enterprise.url 保留用于遗留企业共享托管选择;username 是用户可见的身份覆盖。二者都与服务器认证凭据分离——username 标识会话与遥测行为中的用户,而不是 HTTP basic-auth 配置。
{
"share": "disabled",
"enterprise": { "url": "https://share.example.com" },
"username": "developer",
}
源码中 share 被建模为三个字面量的联合(config.ts),enterprise 为 { url?: string } 结构,username 为可选字符串(config.ts)。
Group 7: Provider 与模型选择
Provider 目录定制与模型选择配置,新的 core 工作已从此处开始。
| 字段 | 当前用途 | 状态 | 说明 |
|---|---|---|---|
provider |
自定义 provider 配置与模型覆盖 | redesign | v2 中重命名为复数 providers;不保留遗留单数键。嵌套 provider/model 字段另行评审 |
disabled_providers |
禁用自动加载的 provider | redesign | 替换为 experimental.policies: [{ effect: "deny", action: "provider.use", resource: "..." }] |
enabled_providers |
将启用 provider 限制为白名单 | redesign | 替换为带通配符资源的有序 provider.use allow/deny 语句 |
model |
默认模型选择 | keep | 保留为“活动会话或 agent 未指定模型时”的回退模型 |
small_model |
小模型/工具模型选择 | remove | 不移植;其唯一运行时消费方是标题生成,可用显式的 title agent 模型覆盖实现 |
用 policies 表达 provider 选择规则
Provider 选择规则归属 experimental.policies,而不是 provider 条目或重复的顶层 provider 字段。初始提议形态:
{
"experimental": {
"policies": [
{
"effect": "deny",
"action": "provider.use",
"resource": "*",
},
{
"effect": "allow",
"action": "provider.use",
"resource": "anthropic",
},
],
},
}
provider 策略语义与优先级规则见 specs/v2/provider-policy.md。
策略求值将逆序消费已编写的配置文档,但保留每个文档内部的语句顺序;.opencode 策略源的优先级在 .opencode 配置评审完成前保持开放。这一点在源码中有直接对应:policy.load 接收的正是文档列表 .toReversed() 后展平的 experimental.policies,注释写明“规则使用相反顺序,使用户全局规则可以覆盖仓库规则;每个文件内部语句顺序不变”(config.ts)。
V2 中 provider 配置使用复数 providers 键,这与遗留单数 provider 键有意不同;在配置面尚未定型时,v2 不添加兼容别名。model 保留为默认模型回退——它是应用级行为,在活动会话或 agent 没有显式模型选择时使用,因此不属于任何单个 provider 配置内部。
small_model 不移植:在当前运行时它只在生成会话标题时被咨询——title agent 模型优先,其次是 small_model,最后是自动/当前模型回退。v2 中需要特定标题模型的用户应直接配置 title agent,而不是使用另一个顶层模型设置。
providers 的结构细节
- provider、model、variant 以及临时性的 agent
options都作为**部分补丁(partial patches)**编写,而不是完全物化的运行时选项记录:用户只写需要覆盖的部分(如一个 header 或一个 AI SDK 请求选项),目录状态提供空默认值并按配置顺序合并补丁。 - provider 的
env保留为已识别凭据环境变量名的编写式列表。内建目录 provider 已携带该元数据以实现基于环境的自动可用性,配置的 provider 可能也需要声明同一来源。对配置 provider 而言这是附加元数据,而不是“其中某个变量必须存在”的要求——provider 也可以经由配置的 options、存储的账户或无需凭据的端点可用。 - 在配置的 model 内,遗留上游模型标识
id嵌套到api.id下,与其余模型 API 覆盖放在一起。模型limit是编写式补丁,覆盖可以只改context、input或output。模型cost接受单个简单定价对象或分层定价条目数组;省略的缓存价格默认为零。 - 遗留 provider model 的
reasoning、temperature、interleaved标志不作为一等配置字段移植;provider/请求行为归属结构化的options或 model variants。release_date、status、experimental、whitelist、blacklist也不在本 v2 面中移植。
{
"providers": {
"internal": {
"env": ["INTERNAL_LLM_API_KEY"],
"options": { "headers": { "Authorization": "Bearer {env:API_KEY}" } },
"models": {
"chat": {
"api": { "id": "upstream-chat-model" },
"limit": { "output": 32768 },
"cost": { "input": 1.25, "output": 10 },
"variants": [{ "id": "high", "aisdk": { "request": { "reasoningEffort": "high" } } }],
},
},
},
},
}
源码侧,packages/core/src/config/provider.ts 实现了 ConfigV2.Provider(name、env、api、request、models)与 ConfigV2.Model(family、name、api、capabilities、request、variants、cost、disabled、limit):Limit 恰为 context/input/output 三个可选整数;Cost 支持 { type: "context", size } 分层条件、input/output 数值与 cache: { read?, write? },且顶层 cost 是“单个 Cost 或 Cost 数组”的联合,与规格逐条吻合。
Group 8: Agent 与权限
Agent 行为与工具访问策略。由于 agent 配置可能包含权限与模型选择,需要一起评审。
| 字段 | 当前用途 | 状态 | 说明 |
|---|---|---|---|
default_agent |
选择默认主 agent | remove | 不保留独立的顶层选择器;默认选择应与 v2 agent 配置模型一起设计 |
mode |
遗留 agent 配置别名 | remove | 不移植废弃别名;只通过 v2 agent 面配置 agent |
agent |
配置主 agent、subagent 与专用 agent | redesign | 重命名为复数 agents;保留“内建覆盖与自定义 agent 定义”的命名映射 |
permission |
工具权限规则 | redesign | 重命名为复数 permissions;用 { action, resource, effect } 的有序规则数组取代遗留 map 简写 |
tools |
遗留工具启用/禁用映射 | remove | 不移植布尔启用/禁用别名;工具访问通过 permissions 表达 |
关键决策
- 不移植
default_agent(先行于 v2 agent 设计之前):遗留运行时用它选择可见的、非 subagent 的回退(而不是build),但把这个选择暴露为孤立的顶层字段,会在 agent 与其策略面共同定义之前让 v2 预先承诺遗留 agent 模型。 - 不移植
mode:遗留加载器已把这个废弃别名合并进agent,v2 只暴露一个 agent 定义编写面。 - 重命名为
agents:该设置是按 agent 名为键的集合,应继续支持覆盖build、plan、title等内建 agent,以及声明命名的自定义 agent。嵌套条目 schema 在 agent 本地permission与废弃tools行为敲定前保持开放。 - 保留
agents.<name>.mode,取值为"primary"、"subagent"或"all"。它标识 agent 的运行时角色,与被移除的顶层遗留mode别名(agent 定义的另一种容器)不同。 - 统一
disabled?: boolean约定:对于 v2 中所有按名可配置的条目,条目应“保持已配置但不活跃”时统一使用disabled。agent 定义因此将遗留disable重新设计为disabled,与 formatter、语言服务器、未来的 MCP server 定义和配置的 model 覆盖一致。运行时目录状态仍可以用enabled跟踪活跃可用性,但那不是用户编写的配置。 - 保留 agent 上独立的
model与variant字段:模型引用使用provider/model-id,但模型 ID 本身可能包含斜杠分段(如openrouter/openai/gpt-5),把 variant 追加到该字符串会产生歧义。 - 保留
color:agent 是用户可见、可选择的实体,因此用户编写的显示颜色是 agent 的合适元数据。保留现有配置支持的十六进制颜色与命名主题色。 - agent 本地
options暂时保留,采用与配置的 provider/model 相同结构化的 provider options 形态:headers、body 以及 AI SDK provider/request 覆盖。其长期归属仍开放供团队评审(可复用的 provider 特定预设可以改为建模为 variants)。不保留 agent 专用的temperature或top_p字段。 - 保留
description、hidden、steps:它们定义 agent 的可发现性、可见性与迭代预算,而非模型请求参数。遗留 agentprompt重命名为system,明确其提供持久系统级 agent 内容,且不与顶层环境instructions冲突;废弃的maxSteps以steps取代。
{
"agents": {
"reviewer": {
"model": "openrouter/openai/gpt-5",
"variant": "high",
"options": {
"headers": { "x-agent": "reviewer" },
"body": {},
"aisdk": { "provider": {}, "request": { "reasoningEffort": "high" } },
},
"description": "Review changes for correctness",
"system": "Find regressions and missing tests.",
"mode": "subagent",
"color": "warning",
"steps": 12,
"disabled": false,
"permissions": [{ "action": "edit", "resource": "*", "effect": "deny" }],
},
},
}
tools 既不作为顶层设置、也不作为 agent 条目别名移植。遗留加载器已经把工具布尔值转换为权限规则(包括把写邻近的工具名折叠为 edit);v2 应避免把这个有损的兼容输入携带下去。
permission 重命名为 permissions,暴露已被 PermissionV2.Ruleset 建模的规范化有序规则集。规则除 "allow" 与 "deny" 外还保留交互式 "ask" effect;这与 experimental.policies 不同——后者的 provider 强制目前只需要 allow/deny 决策。同样的 permissions 规则集形态也应用于未来的 agents 条目内部。
{
"permissions": [
{ "action": "bash", "resource": "*", "effect": "ask" },
{ "action": "bash", "resource": "git status", "effect": "allow" },
],
}
packages/core/src/config/agent.ts 中的 ConfigV2.Agent 已体现这些决策:model、variant 分列;mode 限定为 "subagent" | "primary" | "all";color 是十六进制(^#[0-9a-fA-F]{6}$)或 primary/secondary/accent/success/warning/error/info 命名色的联合;steps 为正整数;disabled 替代 disable;并携带 hidden、description、system、permissions(Permission.Ruleset)。从源码结构看,当前实现里 agent 的请求覆盖字段名为 request(headers/body 结构),而规格示例中的 options(含 aisdk)仍是“暂时保留、归属开放”的形态。
Group 9: 集成(MCP)
外部协议与服务集成的配置。
| 字段 | 当前用途 | 状态 | 说明 |
|---|---|---|---|
mcp |
MCP server 定义与启用 | redesign | 保留 opencode 显式的本地/远程 server 条目格式,嵌套到 mcp.servers 下;用 disabled 表示不活跃条目,并把超时默认值移到这里 |
保留 opencode 的 MCP server 条目格式,而不是采用常见的 mcpServers 复制粘贴形态。本地 server 仍是显式的 type: "local" 条目,带 command 数组与 environment;远程 server 仍是显式的 type: "remote" 条目,带 url、headers 与可选 oauth。server 映射嵌套到 mcp.servers 之下,这样协议级设置(如超时默认值)可以与同一子系统放在一起。
MCP 超时区分启动与请求两个预算,单位毫秒:startup 覆盖建立传输并完成 MCP 初始化;request 独立应用于初始化后的每个 MCP 请求。单个 server 可以覆盖任一默认值而无需重复另一个。
{
"mcp": {
"timeout": { "startup": 30000, "request": 300000 },
"servers": {
"github": {
"type": "local",
"command": ["npx", "-y", "@github/github-mcp-server"],
"environment": { "GITHUB_TOKEN": "{env:GITHUB_TOKEN}" },
"disabled": false,
"timeout": { "startup": 60000 },
},
"docs": {
"type": "remote",
"url": "https://docs.example.com/mcp",
"headers": { "Authorization": "Bearer {env:DOCS_TOKEN}" },
"oauth": {
"client_id": "{env:MCP_CLIENT_ID}",
"client_secret": "{env:MCP_CLIENT_SECRET}",
"scope": "read write",
"callback_port": 19876,
"redirect_uri": "http://127.0.0.1:19876/mcp/oauth/callback",
},
"disabled": false,
"timeout": { "request": 600000 },
},
},
},
}
packages/core/src/config/mcp.ts 中,Timeout 的 startup/request 均为正整数毫秒;Local 含 command、cwd(相对路径从工作目录解析)、environment、disabled、timeout;Remote 含 url、headers、oauth(OAuth 结构或字面量 false)、disabled、timeout;OAuth 的 callback_port 约束为 1–65535。Server 是以 type 区分的 tagged union,顶层 Info 即 { timeout?, servers? },与规格完全一致。
Group 10: 会话生命周期(compaction)
影响长对话与上下文管理的行为。
| 字段 | 当前用途 | 状态 | 说明 |
|---|---|---|---|
compaction |
自动压缩、剪枝与上下文保留设置 | redesign | 将逐字保留的历史归入 keep,把上下文余量重命名为 buffer |
保留压缩能力,但重新设计那些含义不清的上限:keep.tokens 是最近历史被序列化进文本压缩检查点(compaction checkpoint)时的 token 预算;buffer 是预留的 token 余量,使自动压缩在输入窗口耗尽之前触发。
{
"compaction": {
"auto": true,
"prune": true,
"keep": {
"tokens": 2000,
},
"buffer": 10000,
},
}
packages/core/src/config/compaction.ts 中的 ConfigV2.Compaction 恰为 auto?: boolean、prune?: boolean、keep?: { tokens?: NonNegativeInt }、buffer?: NonNegativeInt,与规格逐字段对应。
Group 11: 废弃与实验性设置
这些字段不应凭惯性移植,每一项都需要明确的理由。
| 字段 | 当前用途 | 状态 | 说明 |
|---|---|---|---|
layout |
遗留布局选择 | remove | 不移植废弃选项;拉伸布局(stretch layout)始终使用 |
experimental.disable_paste_summary |
禁用粘贴内容摘要行为 | remove | 不移植;粘贴输入的呈现行为归属客户端/UI 面 |
experimental.batch_tool |
启用 batch tool | remove | 不移植;batch tool 不再是受支持的特性 |
experimental.openTelemetry |
启用 AI SDK 遥测 span | remove | 不移植;可观测性是进程级的,应使用标准 OpenTelemetry 环境或声明式配置 |
experimental.primary_tools |
将工具限制在主 agent | remove | 不移植过时的门控;agent 工具访问通过 permissions 配置 |
experimental.continue_loop_on_deny |
被拒绝工具调用后继续循环 | remove | 不移植遗留的被拒工具循环行为 |
experimental.mcp_timeout |
MCP 请求超时 | redesign | 默认值移到 mcp.timeout.request,单 server 覆盖移到 mcp.servers.<name>.timeout.request |
评审顺序
除非决策之间的依赖关系变得明显,按以下顺序逐组推进:
- File Metadata(文件元数据)
- Process And Server Settings(进程与服务设置)
- Providers And Model Selection(Provider 与模型选择)
- Commands And Project Resources(命令与项目资源)
- Plugins(插件)
- Filesystem And Tool Runtime(文件系统与工具运行时)
- Sharing And Identity(共享与身份)
- Agents And Permissions(Agent 与权限)
- Integrations(集成)
- Conversation Lifecycle(会话生命周期)
- Deprecated And Experimental Settings(废弃与实验性设置)
源码映射:决策如何落在 v2 Config.Info
packages/core/src/config.ts 的 Config.Info(L29-L107)是 V2 配置字段的聚合 schema,规格中的决策大部分已体现:
| 决策类别 | 源码字段 | 子模块 |
|---|---|---|
| 保留 | $schema、shell、model、autoupdate、share、enterprise、username |
内联于 Info |
| 重命名(复数化) | snapshots、attachments、references、plugins、agents、permissions、providers |
config/ 下对应模块 |
| 结构重组 | mcp(timeout + servers)、compaction(auto/prune/keep/buffer) |
config/mcp.ts、config/compaction.ts |
| 数组化发现源 | skills、instructions(string[]) |
内联于 Info |
需要注意的两点边界:其一,experimental 字段在源码中由 config/experimental.ts 承载,其中包含 policies 的策略输入;其二,当前 Info 中仍可看到 default_agent 与 commands 字段,而规格将二者标记为 remove/remove——从源码结构看,schema 尚处过渡期,这两个字段预期随 agent 设计与“命令归属 skills”的决策落地后清理。另外,Config.entries 返回的条目按“从低到高优先级”排列(config.ts),latest 帮助函数取“最后一个”非空定义,这正是“更近的 .opencode/项目文件覆盖全局配置”的读取语义。
编写 V2 配置的实战要点
- 只使用
opencode.json/opencode.jsonc文件名,放在全局配置目录、项目祖先目录或.opencode目录;config.json不再支持(V1 文档由加载器迁移)。 - 全局 → 项目文件 →
.opencode的覆盖顺序由近及远生效;而experimental.policies求值顺序相反(全局优先)。 - 按名集合统一用
disabled?: boolean(agents、formatters、LSP servers、MCP servers、model 覆盖)。 - provider/model/agent 的选项一律按“部分补丁”编写,只写需要覆盖的字段。
- provider 启用/禁用、工具访问控制分别走
experimental.policies的provider.use语句与permissions规则集(allow/deny/ask),不要再使用enabled_providers/disabled_providers/tools这类遗留开关。 - 长对话的上下文预算用
compaction.keep.tokens与compaction.buffer表达;MCP 的启动/请求超时用mcp.timeout与单 servertimeout覆盖表达。
上述要点与完整字段依据均可回查 specs/v2/config.md 及 specs/v2/ 目录下的姊妹规格(如 provider-model.md、provider-policy.md),实现细节则以 packages/core/src/config.ts 与 packages/core/src/config/ 子模块为准。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00