Files
deepseek-harness/packages/client/ui-agent-preset/README.zh.md
Yichen Jiang 9edfdb589d fix(web): persist the default agent preset, and give its page an identity
Three fixes to the settings surface.

The default never reached settings.yaml. The api-proxy keeps an explicit
allowlist of settings namespaces it exposes to configuration clients, and
`agent-presets` was never added — so both pickers moved and then silently
forgot, which is worse than refusing the control. The host seam was fine all
along; only the wire boundary refused. The regression test fails with the
namespace removed.

The nav row showed the fallback gear and read `Agent preset` in Chinese,
matching neither sibling (通用设置 / 模型). It is now 智能体 with the think
glyph, the only unused icon in the set whose semantics point at the agent
rather than at tuning sliders (Personalization is already the workspace
browser's filter control).
2026-08-07 00:41:50 +08:00

5.1 KiB
Raw Blame History

dsh-client-ui-agent-preset

English | 中文

agent preset 的各个表层General 设置中的一行,用于选择新建会话据以组装的 presetcomposer 中的一个座位,用于选择本会话的 preset以及一个设置页分区用于创作组装本身。

为什么它是"新建会话"的偏好设置

会话的 preset 在创建时即固定——宿主拒绝以不同 preset 接管已存在的会话,因为该会话的历史是在最初那份 preset 的工具下产生的。因此本行不可能是实时切换,它也如实说明了这一点:更改只对此后开启的会话生效,而运行中的会话保持它们开始时的组装。

composer 座位

第二个表层,位于 composer 工具行、模型选择器左侧:本会话所运行的 preset。它显示会话自身记录的 preset 而非部署默认值,因为被恢复的会话运行的是它创建时的那一份。

切换只在对话尚未开始时存在。第一个轮次之后,该座位变为纯文本标签——展示一个禁用的菜单会让人以为这个选择只是暂时不可用,而非已经消失。宿主执行同一条规则并返回 agent-preset-locked,因此过期的客户端无法绕过它。

它读什么、写什么

选项与当前默认值都来自同一次 agentPreset.list 调用。名单本身已经报告了"未显式选择的会话会得到哪个 id",因此本行无需对 settings schema 做内省;写入目标是 agent-presets settings 命名空间的 default 字段,也正是宿主在创建时解析的那个字段。

本地创作的 preset 的权限恰好等于它所引用的插件,因此列表会标注 user 行,而不是把每个 preset 都呈现为随附且已审核的。

本行在自身命名空间的 settings/changed 以及 connection/reset 时重新读取:名单是一个活动目录,默认值是一项设置,外部编辑与重新连接都可能改变它。

管理分区

第三个表层,独立的设置页(settings.sectionid 为 agent-presets,排在「模型」之后——选模型是日常操作,而组装 agent 是它背后那件塑造部署形态的事):名单以行呈现,同一时刻有一份组装在 YAML 编辑器中打开。

随部署提供的 preset 以只读方式打开。它是本地 preset 据以编写的已知良好组装,因此能读到它正是意义所在,而覆写它则不是——部署自带的那一份正是用来对照有问题的本地 preset 的。因此创作从复制开始:新建 preset 复制当前默认值,复制则复制任意一行;无论文本来自何处,副本总是落在本地根目录,所以副本总是可写的。

id 会成为目录名,因此编辑器复刻宿主自身的约束规则([a-z0-9][a-z0-9-]*),并拒绝已被占用的名称——新建若落在已存在的名称上,就会覆盖用户从未打开过的 preset。这两项检查只是便利宿主会连同组装的形状一起重新校验失败时编辑器报告的正是宿主的答复。能解析的保存也仅仅是保存引用了不存在插件的组装会在下一个选择它的会话处失败。

删除会移除该文件。已据其组装的会话继续运行——组装在会话创建时挂载一次,此后没有任何东西会重新读取该文件。

设置默认值写入的是 agent-presets settings 命名空间,宿主需将其暴露给配置客户端(dsh-apiproxy 维护一份显式白名单——不在其中的命名空间会让选择器动一下然后悄悄忘记)。

agentPreset.readwriteremoveselect 被固定在环回地址(见 dsh-client-connection):组装指明了一个会话所运行的插件,因此读取它是侦察,写入它是任意能力。agentPreset.list 不在其中——它只携带 id 与信任级别,而局域网客户端的选择器需要它。

何时不显示这些表层

未组装任何 preset 的部署返回空名单,本行、座位与分区都不渲染任何内容——此时每个会话共用宿主组装,也就无从选择或管理。未配置可写根目录的部署返回 authorable: false,分区随之退化为只读浏览:各行仍可打开,但任何位置都不提供"新建",而不是给出一个保存必然失败的按钮。

Model Experience

Indirectly, through the preset a later session is composed from; dsh-agent-presets owns what that composition puts in front of the model.

KV Cache effect

没有直接的失效影响。更改默认值绝不触及运行中会话的前缀;此后创建的会话依据它自己的组装建立自己的前缀。

Known Limitations and Deferred Work

  • preset 按 id 列出 —— preset 不携带展示用元数据,因此菜单与各行显示的是目录名。
  • 编辑器是纯文本域 —— 没有 YAML 语法高亮、折叠或 schema 补全;保存时宿主的形状检查是唯一的校验。
  • 保存的组装不会被挂载 —— 能解析但引用了缺失插件的 preset 会被接受,并在下一个选择它的会话处失败。