首页
/ opencode V2 配置设计详解:11 组字段的评审决策与源码级落地

opencode V2 配置设计详解:11 组字段的评审决策与源码级落地

2026-09-06 14:47:42作者:侯霆垣

本文基于 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.jsonopencode.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 Infoconfig.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 仅全局的用户偏好;保留 truefalse"notify" 三种取值

源码中 shellautoupdate 均已落在 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 加载。内部命令路由与内建命令可以保留为运行时关注点,而无需创建 commandcommands 配置字段。这一决策有意不移植遗留的纯 command 行为,例如按命令的 modelagentsubtask、提示词 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.tsEntry字符串 | Git | Local 的联合:Gitrepository、可选 branch/description/hiddenLocalpath 及同样的元数据字段,与规格中的两种显式形态完全对应;顶层 referencesInfo 中为 Record<string, Entry>config.ts)。而 skillsinstructions 均实现为 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.tsPlugin = 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? };两个正阈值作用于保存预览的截断行为

formatterlsp 各自配置一个项目工具子系统,因此单数名仍然合适: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(布尔)、watcherformatterlspattachmentstool_output,分别指向 packages/core/src/config/ 下的 watcher.tsformatter.tslsp.tsattachments.tstool-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 是编写式补丁,覆盖可以只改 contextinputoutput。模型 cost 接受单个简单定价对象或分层定价条目数组;省略的缓存价格默认为零。
  • 遗留 provider model 的 reasoningtemperatureinterleaved 标志作为一等配置字段移植;provider/请求行为归属结构化的 options 或 model variants。release_datestatusexperimentalwhitelistblacklist 也不在本 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.Providernameenvapirequestmodels)与 ConfigV2.Modelfamilynameapicapabilitiesrequestvariantscostdisabledlimit):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 名为键的集合,应继续支持覆盖 buildplantitle 等内建 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 上独立的 modelvariant 字段:模型引用使用 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 专用的 temperaturetop_p 字段。
  • 保留 descriptionhiddensteps:它们定义 agent 的可发现性、可见性与迭代预算,而非模型请求参数。遗留 agent prompt 重命名为 system,明确其提供持久系统级 agent 内容,且不与顶层环境 instructions 冲突;废弃的 maxStepssteps 取代。
{
  "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 已体现这些决策:modelvariant 分列;mode 限定为 "subagent" | "primary" | "all"color 是十六进制(^#[0-9a-fA-F]{6}$)或 primary/secondary/accent/success/warning/error/info 命名色的联合;steps 为正整数;disabled 替代 disable;并携带 hiddendescriptionsystempermissionsPermission.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" 条目,带 urlheaders 与可选 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 中,Timeoutstartup/request 均为正整数毫秒;Localcommandcwd(相对路径从工作目录解析)、environmentdisabledtimeoutRemoteurlheadersoauthOAuth 结构或字面量 false)、disabledtimeoutOAuthcallback_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?: booleanprune?: booleankeep?: { 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

评审顺序

除非决策之间的依赖关系变得明显,按以下顺序逐组推进:

  1. File Metadata(文件元数据)
  2. Process And Server Settings(进程与服务设置)
  3. Providers And Model Selection(Provider 与模型选择)
  4. Commands And Project Resources(命令与项目资源)
  5. Plugins(插件)
  6. Filesystem And Tool Runtime(文件系统与工具运行时)
  7. Sharing And Identity(共享与身份)
  8. Agents And Permissions(Agent 与权限)
  9. Integrations(集成)
  10. Conversation Lifecycle(会话生命周期)
  11. Deprecated And Experimental Settings(废弃与实验性设置)

源码映射:决策如何落在 v2 Config.Info

packages/core/src/config.tsConfig.InfoL29-L107)是 V2 配置字段的聚合 schema,规格中的决策大部分已体现:

决策类别 源码字段 子模块
保留 $schemashellmodelautoupdateshareenterpriseusername 内联于 Info
重命名(复数化) snapshotsattachmentsreferencespluginsagentspermissionsproviders config/ 下对应模块
结构重组 mcp(timeout + servers)、compaction(auto/prune/keep/buffer) config/mcp.tsconfig/compaction.ts
数组化发现源 skillsinstructionsstring[] 内联于 Info

需要注意的两点边界:其一,experimental 字段在源码中由 config/experimental.ts 承载,其中包含 policies 的策略输入;其二,当前 Info 中仍可看到 default_agentcommands 字段,而规格将二者标记为 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.policiesprovider.use 语句与 permissions 规则集(allow/deny/ask),不要再使用 enabled_providers/disabled_providers/tools 这类遗留开关。
  • 长对话的上下文预算用 compaction.keep.tokenscompaction.buffer 表达;MCP 的启动/请求超时用 mcp.timeout 与单 server timeout 覆盖表达。

上述要点与完整字段依据均可回查 specs/v2/config.mdspecs/v2/ 目录下的姊妹规格(如 provider-model.mdprovider-policy.md),实现细节则以 packages/core/src/config.tspackages/core/src/config/ 子模块为准。

登录后查看全文
热门项目推荐
相关项目推荐