deepseek-harness/apps/web/tests/expected/models-settings/configured.expected.md

39 lines
1.1 KiB
Markdown
Raw Normal View History

- dialog "设置":
- navigation:
- text: 设置
- button "通用设置":
- img
- text: 通用设置
- button "模型":
- img
- text: 模型
- button "插件":
- img
- text: 插件
fix(web): return every service a host row injects, and run the browser lane The browser e2e lane had been failing wholesale since this stack moved the agent plane into presets, and nothing caught it: 34 of 48 files. Two of the causes are product defects, not test breakage. `bashEnv` goes back to the host plane. `apps/cli/src/web.ts` injects it to publish `DSH_WEB_URL`/`DSH_WEB_MODE`, so the earlier note that "nothing outside the agent plane injects bashEnv" was simply wrong — behind a preset's `shell` realm those variables reached no shell at all, and a `dsh web` agent could not find the address of its own interface. This is the same criterion that returned `subagents`: a host row that injects a service resolves before any session exists and has no agent to key by, so the service is host-plane. `tool-bash` consumes the host registry from inside the preset, which works because an agent context chains to the host; only the reverse is invisible. `tool-subagent-report` goes back with it. It is not a tool this agent calls: it registers a continuable SETUP on the host `subagents` singleton, and that list is not scope-aware. One copy per mounted preset meant every child was handed `report` once per live session, so the second registration threw and a cold subagent resume failed with `subagent-not-resumable` — a diagnostic three layers removed from the cause. The lane's own composition facts follow. Skill roots resolve inside a preset now, a subtree include patches cannot reach, so the scaffold pins the roots' documented environment fallback for its whole lifetime rather than for the boot — presets mount per session. Without it the developer's real `~/.dsh/skills` enters replay requests and goldens while CI sees none. The `apps/cli` composition test pins `storage-json` for the same reason: unpinned it wrote, and then read back, the developer's own `~/.dsh/storages/`. Three tests now address through an agent what they used to read off the root context, because that is where the thing lives: the tool catalog, the skill registry, and the token meter. The seeded-history projection baseline asserts the opposite of what it did — a detached session yields a preset-plane projection only from a durable checkpoint written while it was live, and this seed was written straight to persistence and never ran. Goldens re-recorded for the hero's preset chip and the settings nav entry.
2026-08-06 19:14:13 +08:00
- button "Agent 预设":
- img
- text: Agent 预设
- button "打开配置文件"
- button "关闭":
- img
- text: 关闭
- heading "模型" [level=2]
- paragraph: 填入各提供方的 API 密钥即可使用其模型。
- region "Subagent 自选模型":
- heading "Subagent 自选模型" [level=3]
- paragraph: 允许新会话为 subagent 选择提供方、模型和推理强度。运行中的会话不会改变。
- switch "允许 subagent 自选模型"
- status: 已保存 minimax-cn。
- list:
- listitem:
- text: minimax-cn
- img "API 密钥已配置"
- button "编辑 minimax-cn": 编辑
- button "删除 minimax-cn": 删除
- button "添加提供方":
- img
- text: 添加提供方
feat(web): declare a provider and its models from the Models page The Models page could name a provider's key and little else. Adding an OpenAI-compatible gateway meant opening $DSH_HOME/settings.yaml and knowing the profile shape; correcting a stale context window meant the same. This layer puts both on the page: a card that declares a route pi-ai does not ship — id, endpoint, protocol, key, models — and a model list on the pi-ai editor that can ask the provider what it serves and adopt the answer. It follows the DeepSeek catalog editor that landed in #1050 rather than inventing a second look for the same job. Both editors now share the section shell and heading, the danger-tinted delete, the add-model button, the empty state, the per-row validator that names a bad row by its position, and one K/M capacity vocabulary — 256K and 1M are read and spelled back, while settings.yaml still stores plain token counts. The row type is structurally open like that editor's, so a profile field this card does not edit survives an edit here. Three of that editor's decisions replaced weaker ones this branch had made. Inheritance now reads the composition base rather than the effective value, which would echo an override back the moment a reset dropped it. Validation names the offending row instead of stating a blanket problem. And emptying the list is no longer conflated with handing the catalog back to the adapter — those are separate acts, with separate affordances. The create write carries the revision the card opened at, so a route another tab declared meanwhile is a conflict rather than a silent overwrite of its profile.
2026-08-05 18:53:37 +08:00
- button "添加自定义提供方":
- img
- text: 添加自定义提供方