Skip to content

feat(skills): let the draft and backtest pages pick the model that runs the work - #508

Merged
Grivn merged 5 commits into
omdsh-dev:mainfrom
gufifbdb:feat/skill-work-model-picks
Oct 28, 2026
Merged

Grivn merged 5 commits into
omdsh-dev:mainfrom
gufifbdb:feat/skill-work-model-picks

Conversation

@gufifbdb

Copy link
Copy Markdown
Contributor

提交 PR 前请阅读贡献指南、Contributing Guide与开发和验证指南 / Development and Verification Guide。
Before opening a PR, read the Contributing Guide, 贡献指南, and the Development and Verification Guide / 开发和验证指南。
PR 标题和提交信息必须使用 Conventional Commits(type(scope): subject),且不得包含 emoji。 / PR titles and commits must use Conventional Commits (type(scope): subject) and must not contain emoji.
本仓库接受 Bug 修复、兼容性适配、现有能力增强、性能或体验优化和维护类 PR。全新能力、Provider、持久化格式或安全边界变更必须先提 Issue 并获得维护者确认。 / This repository accepts bug fixes, compatibility work, improvements to existing capabilities, performance or UX optimization, and maintenance. New capabilities, Providers, persistence formats, or security-boundary changes require prior maintainer approval in an Issue.
外部贡献者的仅文档类 PR 不直接接受;请先提 Issue 讨论。维护者的发布说明与文档维护不受此限制。 / Documentation-only PRs from external contributors are not accepted directly; open an Issue first. Maintainer release notes and documentation maintenance are exempt.

摘要 / Summary

「进化」页的草案生成与「评测」页的回测,原来只能跑任务 Agent 当前继承的那条路由。现在两页各有一个全局模型选择,并支持单项覆盖(草案按建议、回测按技能),回落顺序是:单项 → 页面全局 → 任务 Agent 自己的路由。选择存在 ledger 旁边的 preferences.json,故意不参与 ledger fingerprint,所以换一次选择不会让已打开页面的 revision 失效。Host 会把这条路由透传到它启动的 agent,并停止把继承来的 reasoningEffort 转给词表不同的 Provider。

The draft page and the backtest page could only run on whatever route the task Agent happened to inherit. Both pages now offer a global model pick plus an optional per-item override (per suggestion for drafts, per skill for backtests), falling back to the task Agent's own route. Picks live in preferences.json beside the ledger and are deliberately kept out of the ledger fingerprint, so changing a pick does not invalidate an open page's revision. The Host carries the pick through to the agent it starts and stops forwarding an inherited reasoningEffort to a Provider that spells its levels differently.

关联 Issue 或背景 / Related Issue or Context

Closes #473

该 Issue 在提交本 PR 时尚无维护者回复。改动范围严格限定在 Issue 里描述的方案:draft-preferences / draft-preference 通道带 slot: draft | run、suggestionId、skillName、model: { provider, model } | null,存储不参与 revision,Host 侧把路由挂到 task agent 并在 delegate 里优先使用。如果维护者希望拆分或调整范围,我可以按意见重切成更小的 PR。

The Issue had no maintainer reply when this PR was opened. The scope follows the plan written in the Issue; I am happy to split or narrow it if maintainers prefer.

涉及区域 / Affected Areas

  • Host 激活、Headless 或 bundle / Host activation, Headless, or bundle
  • 运行时记忆 / Runtime Memory
  • 项目档案 / Project Documents
  • 记忆空间或 Provider / Memory Spaces or Providers
  • 子 Agent 或 Agent 工作流 / Subagent or Agent workflow
  • Web UI 或对话交互 / Web UI or conversation interaction
  • 设置、存储或安全 / Settings, storage, or security
  • CLI、RPC、命令或工具 / CLI, RPC, commands, or tools
  • 安装、更新或发布 / Installation, update, or release
  • 测试、构建或文档 / Tests, build, or documentation
  • 其他(请说明)/ Other (explain below)

PR 类型 / PR Type

  • 面向用户的功能或行为变更 / User-facing feature or behavior change
  • Bug 修复 / Bug fix
  • 增强或优化 / Enhancement or optimization
  • 兼容性适配 / Compatibility change
  • 维护或重构 / Maintenance or refactor
  • 测试或构建 / Tests or build

最新代码确认 / Latest Codebase Confirmation

  • 我已基于最新 main 分支开发,或在提交前已 rebase 或合并最新 main。 / I developed from the latest main, or rebased or merged the latest main before submitting.

同步命令 / Sync command:

git fetch origin && git checkout -B feat/skill-work-model-picks origin/main

本分支基于 main 的 58fae98(撰写当天的最新 main);GitHub compare 显示 ahead_by: 1, behind_by: 0, files: 24。

AI 编码披露 / AI Coding Disclosure

  • 完全 AI 编码:全部编程改动由 AI 产出,并由贡献者接受和审查。 / Fully AI-coded: AI produced all programming changes, which the contributor accepted and reviewed.
  • 部分 AI 辅助:AI 帮助编写或修改了部分内容。 / Partially AI-assisted: AI helped write or modify part of the change.
  • 未使用 AI 编码辅助。 / No AI coding assistance was used.

使用的 AI 模型 / AI model used:

deepseek-v4.1-flash

使用的编码 Agent 工具 / Coding Agent tool used:

DeepSeek Harness(社区版桌面宿主 DSH NEXT 2.0.19-next,内核 0.2.1-rc.2)

仓库规范检查 / Repository Rules

  • 未修改 DSH 官方源码,未让 tsconfig 指向 DSH 源码 checkout,仅使用正式的 @deepseek-ai/* NPM 契约。 / I did not modify DSH source or point tsconfig at a DSH source checkout, and used only published @deepseek-ai/* NPM contracts.
  • Client 与 Host 边界仍以浏览器安全的 src/host/protocol.ts 为准,没有在两侧重复定义 wire DTO。 / The Client and Host boundary still uses browser-safe src/host/protocol.ts as the source for wire DTOs.
  • 持久化格式、RPC 权限、路径或凭据处理的变更包含兼容或拒绝路径、安全分析和相应测试。 / Changes to persistence formats, RPC authority, paths, or credentials include compatibility or rejection paths, security analysis, and tests.
  • 没有提交 token、密钥、私有记忆、未脱敏日志或生成的 lib/ 文件。 / I did not commit tokens, credentials, private memory, unredacted logs, or generated lib/ files.
  • 用户可见文案和长期文档已同步维护中文与英文版本,命令、配置键和路径保持一致。 / User-facing copy and long-lived documentation are synchronized in Chinese and English, with matching commands, configuration keys, and paths.
  • 会改变发布制品或其元数据的 PR 已添加 changeset;仅测试、CI 或站点文档变更可不添加。 / A PR that changes a published artifact or its metadata includes a changeset; test-only, CI-only, and site-documentation-only changes may omit one.
  • 新增和修改的代码、注释、文档、提交信息不含 emoji。 / New and modified code, comments, documentation, and commits contain no emoji.

兼容性与数据安全 / Compatibility and Data Safety

  • 持久化格式:新增 <dataDir>/skills/preferences.json,且它是可选文件。不存在时 store.preferences() 返回 { version: 1, suggestionModels: {}, skillRunModels: {} },两页的选择器显示「跟随默认」,行为与改动前一致;回滚到旧版本时该文件被忽略,无需迁移。写入复用与 ledger 相同的原子写(同目录临时文件 + rename)并落在同一条内存锁内。
  • 不进 revision:preferences() 故意不参与 fingerprint()(该指纹只覆盖 ledger.json 与 evals.json 的大小与 mtime),所以改一次选择不会让已打开页面的 revision 失效,也不会触发整页重拉。
  • RPC 权限:只新增 read draft-preferences 与 mutate draft-preference / suggestion-delete / draft-delete,全部走既有 management 通道与既有 text() / optionalText() 校验:slot 只接受 draft / run(给建议传 slot: run 会被拒绝)、provider 上限 100、model 上限 200、model 必须是对象或 null。没有新增进程、网络出站或凭据读取,权限面不变。
  • 模型路由:选择只带 provider + model,并显式剥离继承来的 reasoningEffort。改动前把 A 家的 max 透给词表不同的 B 家会让整轮运行以 UNSUPPORTED_REASONING_EFFORT 失败;现在目标 Provider 自己决定档位,除非选择里显式给了档位。
  • 既有数据:不改 ledger.json 的既有字段语义。唯一的状态机补丁是把「宿主在上次写草案途中退出、停在 drafting 的建议」放回 pending 并写 lastError——这类建议在改动前既不能重试也不能删除,属于死状态。判据是 updatedAt 早于本进程启动时刻(PROCESS_STARTED_AT),因此不会误伤真正在写的那一条。
  • 回滚:删掉 preferences.json 即回到「全部跟随默认」;代码侧回滚到本 PR 之前,该文件成为孤儿文件,无副作用。

本地验证 / Local Validation

执行的命令 / Commands run:

pnpm run verify:docs
pnpm run typecheck
pnpm run build
pnpm run verify:build
pnpm --config.ignoreWorkspaceCycles=true --workspace-concurrency=4 -r build
pnpm --config.ignoreWorkspaceCycles=true --workspace-concurrency=4 -r typecheck
pnpm --dir plugins/dsh-mnemon-source-skills exec vitest run tests/client.spec.tsx
pnpm --dir plugins/dsh-mnemon-source-skills exec vitest run
pnpm run test:root

结果摘要 / Result summary:

  • pnpm run verify:docs — PASS:Documentation verified: 5556 local links, 425 Markdown anchors, bilingual paths and official plugin coverage.
  • pnpm run typecheck(根包)— exit 0
  • pnpm run build — PASS(tsdown + tsc -p tsconfig.types.json + link-bundle-declarations.mjs)
  • pnpm run verify:build — PASS:Verified deterministic output for 57 files.
  • pnpm -r build / pnpm -r typecheck 不加 --config.ignoreWorkspaceCycles=true 会在 Windows 上报 ERR_PNPM_TASK_CYCLE(仓库既有的环依赖:source-skills 与 strategy-default-three-tier 等四组),加上该开关后全 workspace build 与 typecheck 均 exit 0。
  • plugins/dsh-mnemon-source-skills 的 vitest run tests/client.spec.tsx — 26 passed(含本 PR 新增的 4 项选择器用例)。
  • plugins/dsh-mnemon-source-skills 的 vitest run — 70 passed / 1 failed / 2 skipped。唯一失败是既有的 Windows 路径分隔符用例 skill catalog > reads the four roots with DSH rules and marks the skill DSH loads(期望 templates/note.md,实际 templates\note.md),在未改动的 main 上同样失败。
  • pnpm run test:root — 有若干失败(侧栏与设置页 CSS 布局不变量、插件元数据、Starter 激活用例、若干 30 s 超时用例)。判据见下。

为什么这些失败不是本 PR 引入的(同集对照):
git stash push -u 后在同一棵树、同一 Node/pnpm 版本上跑
pnpm exec vitest run tests/client-sidebar-css.spec.ts tests/plugin-metadata.spec.ts tests/composable-plugin-bundle.spec.ts
得到 9 failed / 17 passed;git stash pop 恢复本 PR 改动后跑同一组,结果同样是 9 failed / 17 passed,失败项逐条相同。失败均为 Windows CRLF 环境差异(例如 expected '/*\r\n * ...' to contain '.toggleRow {\n ...')。

没能跑的项:pnpm run verify:plugins 在 Windows 上抛 ENOENT: spawn pnpm,因为 scripts/verify-plugin-artifacts.mjs 直接 spawn('pnpm', ...),而 Windows 只有 pnpm.cmd shim、没有可 spawn 的 pnpm.exe;git diff --stat scripts/ 为空,脚本未被本 PR 修改,这是环境限制。同理 pnpm run verify:package 未纳入本次实跑。

用户可见变更证据 / Local Feature Evidence

证据 / Evidence:

运行环境:本 PR 的编译产物已装入桌面宿主并重启加载;界面为中文。

  1. 进化页:顶部左「全局模型」两行显示 DeepSeek-V4.1-Flash - x0.11 与 CodeBuddy (腾讯);右「所选草案模型」显示 跟随默认,两列与下方列表、详情卡片左缘对齐。
    evolution
  2. 评测页:同款两行 trigger,右为「所选回测模型 / 跟随默认」。
    evals
  3. 工具栏放大:模型名在上、Provider 灰字在下的两行呈现。
    bar

截图已裁掉左侧会话与工作区侧栏,只保留技能管理面板,不含凭据、私有记忆或敏感路径。

gufifbdb and others added 5 commits October 27, 2026 18:55
…ns the work

Drafting a suggestion and backtesting a skill always ran on whatever route the
task Agent happened to inherit, so there was no way to try a cheaper or a
stronger model for one page, one suggestion, or one skill.

Both pages now offer a global pick and an optional per-item override: an
override per suggestion on 进化, and one per skill on 评测, each falling back to
the page's global pick and then to the task Agent's own route. The picks live in
a `preferences.json` beside the ledger — deliberately outside the ledger
fingerprint, so changing a pick does not invalidate an open page's revision.

The Host carries the pick down to the agent it starts. While doing so it stops
forwarding the inherited `reasoningEffort`: a Provider spells its levels in its
own words, so passing one Provider's `max` to another that has no such level
made the run die with UNSUPPORTED_REASONING_EFFORT. The picked Provider now
decides its own effort unless the pick names one.

Two related repairs come with it, because the pages could not be used without
them. A suggestion whose draft write died with the previous Host stays in
`drafting` forever and refuses both a retry and a delete; the store now puts
such a suggestion back to `pending` with an explanation, both when the ledger is
read and once when the source starts. And a suggestion or a draft can be deleted
from its card, which is what the drafting state was blocking.

The model selectors also repeat the chosen Provider under the model name, and
flip their menu above the button when there is no room below: the menu is
clamped into the viewport by measuring the selector before it opens, so a long
directory no longer covers the button it belongs to.
The client declaration entry re-exported TaskAgentModelCatalog from
src/host/protocol.ts. Following that import puts lib/types/src/host/protocol.d.ts
into the client's published declarations, and from there into the standalone
typecheck of every plugin that imports dsh-mnemon/client: the SDK's cordis
Context augmentation is then declared twice and the two copies are not
assignable to each other, so verify:public-entries and the packed-plugin
typecheck both fail.

Move the four catalogue interfaces into a browser-safe contract module,
src/core/contracts/task-agent-model.ts, and have the Host protocol re-export
them, so there is still one declaration while the client side never names a
Host module.
@Grivn
Grivn merged commit c2433a2 into omdsh-dev:main Oct 28, 2026
7 checks passed
@Grivn Grivn mentioned this pull request Oct 29, 2026
12 of 28 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants