2026-08-04 00:25:19 +08:00
# dsh-client-ui-agent-preset
[English ](README.md ) | 中文
2026-08-05 18:51:11 +08:00
agent preset 的各个表层:General 设置中的一行,用于选择新建会话据以组装的 [preset ](../../preset/agent-presets/README.md );新建会话界面上的一枚 chip,用于选择**下一个会话**的 preset;会话标题旁的一个只读标签;以及一个设置页分区,用于创作组装本身。
2026-08-04 00:25:19 +08:00
## 为什么它是"新建会话"的偏好设置
会话的 preset 在创建时即固定——宿主拒绝以不同 preset 接管已存在的会话,因为该会话的历史是在最初那份 preset 的工具下产生的。因此本行不可能是实时切换,它也如实说明了这一点:更改只对此后开启的会话生效,而运行中的会话保持它们开始时的组装。
2026-08-05 18:51:11 +08:00
## 新建会话 chip
2026-08-04 10:54:13 +08:00
2026-08-05 18:51:11 +08:00
第二个表层,位于新建会话界面上、工作区选择器旁边。它落在这里而非 composer,是因为这里才是选择仍然成立的地方:一个大部分时间处于禁用状态的控件,属于它仍然可用的那个界面。
2026-08-04 10:54:13 +08:00
2026-08-05 18:51:11 +08:00
chip 以部署默认值打开,其选择是**暂存**的——该界面先于它要应用到的会话存在。暂存值会在某个会话成为当前会话且仍为空白时抵达该会话;这既覆盖工作区连接新建的会话,也覆盖它复用的那个空白会话,而搭 `sessions.create` 的便车会漏掉后者。暂存值一经使用即被清空,因此下一个新会话重新以默认值打开——与它旁边的工作区选择器完全一致。
已经开始的会话会被直接拒绝而非排队:宿主返回 `agent-preset-locked` ,暂存值随之丢弃,而不是去等一个永远不会接受它的会话。
## 会话标题旁的标签
第三个表层,位于会话标题旁:**本会话**所运行的 preset,作为静态装饰呈现。在那里放一个控件,等于承诺一次宿主会断然拒绝的切换。它从会话自身的摘要读取 preset——被恢复的会话运行的是它创建时的那一份,而非今天的默认值——并在 General 行所读的同一份名单上解析显示名称。
2026-08-04 10:54:13 +08:00
2026-08-04 00:25:19 +08:00
## 它读什么、写什么
选项与当前默认值都来自同一次 `agentPreset.list` 调用。名单本身已经报告了"未显式选择的会话会得到哪个 id",因此本行无需对 settings schema 做内省;写入目标是 `agent-presets` settings 命名空间的 `default` 字段,也正是宿主在创建时解析的那个字段。
本地创作的 preset 的权限恰好等于它所引用的插件,因此列表会标注 `user` 行,而不是把每个 preset 都呈现为随附且已审核的。
本行在自身命名空间的 `settings/changed` 以及 `connection/reset` 时重新读取:名单是一个活动目录,默认值是一项设置,外部编辑与重新连接都可能改变它。
2026-08-04 12:23:40 +08:00
## 管理分区
2026-08-04 00:25:19 +08:00
2026-08-05 18:51:11 +08:00
第四个表层,独立的设置页(`settings.section` , id 为 `agent-presets` ,排在「模型」之后——选模型是日常操作,而组装 agent 是它背后那件塑造部署形态的事):名单以行呈现,同一时刻有一份组装在 YAML 编辑器中打开。
2026-08-04 12:23:40 +08:00
随部署提供的 preset 以只读方式打开。它是本地 preset 据以编写的已知良好组装,因此能读到它正是意义所在,而覆写它则不是——部署自带的那一份正是用来对照有问题的本地 preset 的。因此创作从复制开始:**新建 preset** 复制当前默认值,**复制**则复制任意一行;无论文本来自何处,副本总是落在本地根目录,所以副本总是可写的。
id 会成为目录名,因此编辑器复刻宿主自身的约束规则(`[a-z0-9][a-z0-9-]*` ),并拒绝已被占用的名称——新建若落在已存在的名称上,就会覆盖用户从未打开过的 preset。这两项检查只是便利:宿主会连同组装的形状一起重新校验,失败时编辑器报告的正是宿主的答复。能解析的保存也仅仅是保存;引用了不存在插件的组装,会在下一个选择它的会话处失败。
删除会移除该文件。已据其组装的会话继续运行——组装在会话创建时挂载一次,此后没有任何东西会重新读取该文件。
2026-08-04 13:34:22 +08:00
设置默认值写入的是 `agent-presets` settings 命名空间,宿主需将其暴露给配置客户端([`dsh-apiproxy` ](../../host/apiproxy/README.md ) 维护一份显式白名单——不在其中的命名空间会让选择器动一下然后悄悄忘记)。
2026-08-04 12:23:40 +08:00
`agentPreset.read` 、`write` 、`remove` 与 `select` 被固定在环回地址(见 [`dsh-client-connection` ](../connection/README.md )):组装指明了一个会话所运行的插件,因此读取它是侦察,写入它是任意能力。`agentPreset.list` 不在其中——它只携带 id 与信任级别,而局域网客户端的选择器需要它。
## 何时不显示这些表层
2026-08-05 18:51:11 +08:00
未组装任何 preset 的部署返回空名单,本行、chip、标签与分区都不渲染任何内容——此时每个会话共用宿主组装,也就无从选择或管理。未配置可写根目录的部署返回 `authorable: false` ,分区随之退化为只读浏览:各行仍可打开,但任何位置都不提供"新建",而不是给出一个保存必然失败的按钮。
2026-08-04 00:25:19 +08:00
## Model Experience
Indirectly, through the preset a later session is composed from; [`dsh-agent-presets` ](../../preset/agent-presets/README.md ) owns what that composition puts in front of the model.
#### KV Cache effect
没有直接的失效影响。更改默认值绝不触及运行中会话的前缀;此后创建的会话依据它自己的组装建立自己的前缀。
## Known Limitations and Deferred Work
2026-08-05 18:51:11 +08:00
- **没有元数据的 preset 按 id 列出** —— 展示文本是可选的,未发布任何展示文本的 preset(每个由复制他人而来的 preset 起初都是如此)显示的是它的目录名。
2026-08-04 12:23:40 +08:00
- **编辑器是纯文本域** —— 没有 YAML 语法高亮、折叠或 schema 补全;保存时宿主的形状检查是唯一的校验。
- **保存的组装不会被挂载** —— 能解析但引用了缺失插件的 preset 会被接受,并在下一个选择它的会话处失败。