oh-my-openagent 配置迁移缺陷排查2026-08-reasoning-unification 与模型配置链的一致性修复【免费下载链接】oh-my-openagentOmO: Just type mass ulw keyword with your prompt. Now you are the master of graph engineering.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent本文基于 oh-my-openagentOmO仓库中的 Discord 配置迁移分诊记录triage 文档完整还原一次迁移写入的配置被运行时 Schema 拒绝的仓库自有缺陷repository-owned defect的定位过程从 Discord 报告、GitHub issue #6567 的表象到2026-08-reasoning-unification迁移的源码级实现、AgentOverrideConfigSchema的校验缺口、config-chain 模型输入的遗漏再到测试验证与修复边界。读完本文你将掌握 OmO 配置迁移引擎的完整调用链、reasoning 字段统一化的归一化规则以及如何通过 fixture 测试锁定这类迁移端与校验端不一致的回归。问题表象迁移之后配置失效、委派不再遵循模型2026-08-05KST的分诊记录显示用户通过 Discord 报告报告 ID1534283281300979743反馈了与配置迁移/委派相关的异常核心现象有两个迁移会留下非法配置2026-08-reasoning-unification迁移把规范形态canonical写入agents.*.models但当时origin/dev的AgentOverrideConfigSchema仍然拒绝该键委派停止遵循已配置的模型由于models键被从 config-chain 的模型输入中省略运行时拿不到迁移写入的模型链导致 delegation 不再按用户配置选择模型。分诊小组检查了关联的 Discord 消息及周边迁移/委派讨论、GitHub issue #6567 与相关 PR #6560、#6516并核对了最新origin/dev上的迁移、插件 schema、config-chain、doctor 与运行时加载路径最终给出所有权判定PASS这是仓库自有缺陷。OmO 配置迁移体系全貌发现、计划、执行、转换要理解这个缺陷先看2026-08-reasoning-unification在迁移体系中的位置。根据 config-migration/AGENTS.md该模块负责发现discovery定位遗留配置文件oh-my-opencode/oh-my-openagentJSON[C]、~/.omo/config.jsonc由 discovery.ts 及discovery-roots.ts、discovery-paths.ts实现涉及OPENCODE_CONFIG_MIGRATION_ID与CONFIG_JSONC_MIGRATION_ID两个组计划planning由 migration-plans.ts 的createLegacyConfigMigrationPlans构建迁移计划执行execution由 migration-executor.ts 的executeLegacyConfigMigrationPlan落地支持 dry-run、备份与日志内容转换transformtransform-opencode.ts/transform-config-jsonc.ts以及本次缺陷核心的 reasoning-unification.ts。关键约定见 AGENTS.md转换是纯函数transform 只把加载的源返回为ConfigMigrationTransformResult所有文件系统副作用都经由 omo-config-core 的迁移引擎完成绝不在转换层直接写配置迁移 ID 必须稳定每个迁移以固定 id 记录在目标文件的_migrations数组中已发布的 id 不得复用或改名历史 id 追加到legacy-history.tsno-clobber 语义deep-diff.ts保证已存在的目标值总是优先于迁移值。迁移引擎本体位于packages/omo-config-core/src/migration/。以 commit.ts 为例提交阶段会把_migrations标记写入目标文档const document { ...merged.merged, _migrations: marker }使迁移具备幂等性predicate.ts检查目标中的标记已应用过的迁移不会重复执行。整个链路在 OpenCode 插件启动、Senpi 启动、安装流程与 CLI 中都会触发详见 configuration.md 对两个迁移组的说明。2026-08-reasoning-unification迁移实现剖析迁移的 ID 常量定义在 reasoning-unification.tsexport const REASONING_UNIFICATION_MIGRATION_ID 2026-08-reasoning-unification入口transformReasoningUnification(document)L190-L197返回{ diagnostics, document }其中 diagnostics 收集冲突告警document 是规范化后的配置树。转换逻辑对根级categories、agents、models、[senpi]/[codex]/[opencode]分块以及嵌套profiles做递归处理。底层归一化legacy 模型字段 → canonical 字段迁移的核心归一化来自 omo-config-core 的 fallback-models.tsnormalizeLegacyModelFieldsL38-L72删除variant、reasoningEffort、thinking、textVerbosity、maxTokens、providerOptions等 legacy 键并按下述优先级收敛出规范reasoningreasoning reasoningEffort variant (thinking.type disabled ? off)即显式reasoning优先其次reasoningEffort再次variant若只写了thinking: { type: disabled }则归一化为reasoning: off。thinking: { type: enabled, budgetTokens }与textVerbosity被并入provider_optionsmaxTokenscamelCase归一化为max_tokenscanonicalModelStringL24-L36把三种模型字符串写法统一为provider/model:reasoning冒号后缀形式p/m(xhigh)括号后缀 →p/m:xhighp/m high空格后缀 →p/m:high已带冒号后缀的p/m:minimal保持不变迁移的八条规则与 fixture 验证迁移测试 reasoning-unification.test.ts 的第一个用例声明rules one through eight match exact expected output使用仓库内置 fixture 对拍输入 fixture2026-08-reasoning-unification/fixture-input.json期望输出2026-08-reasoning-unification/fixture-expected.json以categories.quick为例输入为{ model: apitopia/kimi-for-coding-highspeed-unlocked, reasoningEffort: minimal, fallback_models: [ { model: apitopia/z-ai/glm-5.2-ultrafast-unlocked, reasoningEffort: none }, openai-codex/gpt-5.6-luna-fast minimal ], maxTokens: 8192 }迁移后变为{ models: [ { model: apitopia/kimi-for-coding-highspeed-unlocked, reasoning: minimal }, { model: apitopia/z-ai/glm-5.2-ultrafast-unlocked, reasoning: off }, openai-codex/gpt-5.6-luna-fast:minimal ], max_tokens: 8192 }可归纳出如下规则模型链合并model主模型 已有modelsfallback_models后备模型合并进统一的models数组首项为主模型其余为后备随后删除顶层model与fallback_modelsreasoningEffort→reasoning对象项内的 legacy 推理级别归一为reasoningminimal、none→off等模型字符串后缀归一gpt-5.6-luna-fast minimal这类空格后缀改写为冒号形式gpt-5.6-luna-fast:minimalmaxTokens→max_tokenssnake_case 规范化无fallback_models且无冲突时保留单模型形态如categories.deep仅model variant迁移后为{ model: ..., reasoning: medium }冲突诊断同一实体同时出现reasoning、reasoningEffort、variant等多个推理字段时按优先级保留一个其余写入 diagnostics如conflict: categories.conflict dropped varianthigh kept reasoningEffortxhigh[opencode]分块单独处理normalizeOpenCodeBlock只重写 agent/category 已知键native、provider等无关结构原样保留见 L174-L188[senpi]/[codex]则复用同一normalizeTypedBlock递归L158-L160profiles递归profile 内的整块配置继续递归规范化L164-L170。注意第 7 条是缺陷的关键背景迁移对[opencode]块同样会写入规范形态如把variant: high变成reasoning: high、把model fallback_models合并为models数组而 OpenCode 侧的校验 Schema 尚未同步放开。缺陷定位Schema 拒绝、config-chain 遗漏、doctor 告警分诊确认了三个相互咬合的问题点1.AgentOverrideConfigSchema拒绝models键OpenCode 侧的 agent 覆盖 Schema 定义在 agent-overrides.ts。该 Schema 明确允许model标为 deprecated注释说明模型应从 category 默认值继承models有序模型链首项主模型、其余后备……但分诊指出最新origin/dev的AgentOverrideConfigSchema仍拒绝迁移写入的agents.*.models键——即 Schema 的z.object默认 strict/未知键剔除行为把合法迁移结果拦在了校验层之外配置在校验阶段即被判为非法这正是迁移留下 invalid config的直接原因。2. config-chain 模型输入遗漏models即使校验放行config-chain 构造模型输入时也遗漏了models键迁移合并出的完整模型链没有进入运行时模型解析的输入导致 delegation 解析不到配置的模型行为回退到默认值。这与 Discord 报告中委派停止遵循配置模型的现象完全吻合。3.[opencode]的variant/fallback_models兼容告警分诊还观察到doctor/校验链路对[opencode]块中仍然支持的 legacy 键variant、fallback_models发出警告。也就是说迁移端已经完成variant→reasoning、fallback_models→models的统一化而运行时校验端仍处于兼容旧键阶段两端语义不一致迁移改写后variant消失、models出现但校验端还在期待旧键、拒绝新键。三个问题叠加形成完整闭环迁移写 canonical→ Schema拒 canonical→ config-chain漏 canonical→ doctor报 legacy 兼容警告四个环节步调不一。测试验证用 fixture 与引擎 E2E 锁定行为迁移测试 reasoning-unification.test.ts 提供了四层验证纯转换对拍transformReasoningUnification(fixtureInput)的输出与fixtureExpected完全相等并断言 diagnostics 包含冲突记录conflict: categories.conflict dropped varianthigh kept reasoningEffortxhigh优先级语义输入{ reasoning: low, reasoningEffort: xhigh, variant: high }时迁移结果保留reasoning: low且 journal 中不会出现kept reasoningEffortxhigh——验证 canonical 键在冲突中的胜出引擎级 E2E在临时 HOME 下写入.omo/omo.jsonc经createLegacyConfigMigrationPlans找到 reasoning 迁移计划后依次执行 dry-run返回status: planned且 preview 与期望一致与正式执行返回status: migrated最终文件等于fixtureExpected { _migrations: [2026-08-reasoning-unification] }journal diagnostics 正确落盘且目录下出现omo.jsonc.bak.*备份——印证了 dry-run、备份、journal、原子提交、幂等标记五件套typed block 与 opencode 边界[senpi]/[codex]递归规范化、profiles递归、[opencode]只改已知 agent/category 键、native/provider无关结构不被触碰。测试还关联了启动路径packages/omo-opencode/src/startup-migration.test.ts与packages/omo-senpi/src/components/config-startup/index.test.ts均涉及该迁移 ID说明转换确实在 OpenCode/Senpi 启动期被拉起。修复边界与 PR 状态只合入可复现、已测试的子集分诊对相关 PR 做了明确切割PR #6560修复的是生成 JSON Schema 的 identity/required-array 问题与本次运行时迁移路径无关保持独立、另行合入PR #6516目标是规范化的运行时模型链但它是无专属测试的草稿外部 PR且包含更广的 fallback 改动风险不可控本次分支仅实现当前origin/dev上可复现、有测试覆盖的缺陷子集——即修复AgentOverrideConfigSchema对models的接纳、补上 config-chain 模型输入中的models传递、同步[opencode]的 legacy 键告警策略不夹带 PR #6516 的宽泛改动。这一策略体现了分诊的工程纪律修复范围与证据范围严格对齐未经验证的改动不进主线。分诊流程规范证据留存与清理triage 文档还记录了缺陷处置的流程性内容值得作为团队协作参考来源证据保留 issue #6567、PR #6560、PR #6516 的引用作为审计线索信息脱敏Omitted or sanitizedDiscord 凭证、token、认证头与原始凭证文件一律不落入文档无关频道消息与 issue/PR JSON 被剔除缺失的 Discord 可视化负载不臆造由文本、issue、代码与运行时证据独立确立所有权Triage cleanup确认无残留的 Discord 浏览器标签、桌面窗口、服务器进程、端口、临时文件或登录会话避免敏感会话泄漏。总结从一条 Discord 报告到一次体系级修复这次缺陷的本质是迁移端与校验端对canonical 配置形态的定义不同步2026-08-reasoning-unification按照统一reasoning、合并models链的既定方向改写配置而AgentOverrideConfigSchema、config-chain 与 doctor 仍停留在 legacy 键时代导致同一份配置在写入与读取两个阶段被不同对待。修复路径由此清晰让校验层与运行时接受迁移产物agents.*.models、canonicalreasoning同时把[opencode]的 legacy 键兼容告警收敛到与新形态一致。对使用者而言如果遇到升级后配置看似迁移成功、但委派模型不生效的问题可先检查~/.omo/omo.jsonc是否已出现_migrations: [2026-08-reasoning-unification]标记代表迁移已应用再核对agents.*.models是否被运行时接受对维护者而言本文梳理的 reasoning-unification.ts、agent-overrides.ts、fallback-models.ts 与 fixture 对 四件套是复现与回归验证该缺陷的完整入口。【免费下载链接】oh-my-openagentOmO: Just type mass ulw keyword with your prompt. Now you are the master of graph engineering.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考