dsh-session-settings:DSH 每会话设置基础设施

前言

在 DeepSeek Harness(DSH)里做插件时,经常需要「同一个选项,不同会话用不同值」:例如某次对话里关掉某功能、另一会话保持默认。若把覆盖写进会话日志、会话数据或 profile 的 cordis.patch.yml,既难维护,也容易和官方存储边界搅在一起。

下面介绍社区插件 dsh-session-settings(维护者 dongkid):它提供「每会话配置」的基础设施——宿主侧持有配置真身并暴露服务,浏览器侧在右侧栏提供原生设置页,其它插件把声明式选项注册进来即可。

这是什么

dsh-session-settings 是 DSH 的 per-session settings 基础设施:右侧栏原生设置页 + 宿主侧存储与 HTTP 桥接,供其它插件注册会话级选项。

插件分两半协同工作:

  1. 宿主半(lib/index.js):持有每会话配置的真身,对外提供 sessionSettings 服务(register / get / set / reset / subscribe)。
  2. 浏览器半(lib/client.js):在右侧栏注册原生 tab(id 与 kind 均为 session-settings),渲染当前会话下各插件已注册的选项。

覆盖值通过官方 storage 域落盘,路径为 <DSH_HOME>/storages/session_settings/;不会写入会话日志或 profile patch。更完整的设计说明见仓库内 docs/design-v1.md。

核心功能

两层解析与稀疏存储

解析规则只有一层叠加:

解析后的值 = 注册时提供的默认值 → 该会话的覆盖值

默认值的真源在消费插件的注册声明里;本插件只保存「被改过且不同于默认」的部分。值等于默认时会删掉对应覆盖键,避免磁盘膨胀。

sessionSettings 服务(宿主与客户端同名)

消费插件在所在一侧 inject 同名服务 sessionSettings。设计文档中约定的能力包括:

能力 作用
register(registration) 注册一组声明式选项(宿主半);返回 disposer 用于卸载
get / getItem 按会话读取完整解析值或单项
set / reset / resetSession 写入、按插件或按键恢复、清空本会话全部覆盖
subscribe 订阅变更
listRegistrations 枚举当前注册项

声明式控件类型(第一版):switch、text、number、select、stringList。

注册归属(设计稿已确认):声明式项只能由消费插件的 宿主半 注册,以便无页面打开时仍能解析默认值。客户端半不注册声明式项,可提供自定义渲染 registerRenderer(pluginId, itemKey, Component) 以及读取/订阅。

右侧栏设置页

浏览器半通过官方右侧栏扩展注入(package.json 中 dsh.client.inject 包含 @deepseek-ai/dsh-client-ui-sidebar-right 与 @deepseek-ai/dsh-client-ui-slots)。该 tab 为 session 作用域,页面直接拿到 sessionId,用户在本页修改的值只作用于当前会话。

宿主与浏览器的 HTTP 桥

静态安装的插件通过宿主注册的 HTTP 前缀与浏览器通信。设计稿约定路径形态为 /session-settings/api,仅接受 POST,JSON 派发;请求需通过与本机 /api 网关同源的 trustedHosts 校验,未通过则 403。第一版桥方法包括 values.get、values.set、values.reset、registrations.list。

依赖与环境

package.json 中的 peerDependencies(需由 DSH 宿主组合满足):

  • @deepseek-ai/cordis ^4.0.4
  • @deepseek-ai/dsh-client-ui-sidebar-right >=0.2.0-rc.2
  • @deepseek-ai/dsh-host-webserver >=0.2.0-rc.2
  • @deepseek-ai/dsh-session-persistence >=0.2.0-rc.2
  • @deepseek-ai/dsh-storage-domain >=0.2.0-rc.2

运行时依赖 zod(域记录 schema)。升级与依赖对照见仓库 docs/dsh-dependencies.md。

安装与启用

已抓取的 README 与 GitHub 仓库首页未给出形如 dsh plugin add … 的安装命令;安装方式请以 SkillHub 目录页 当前展示为准(页面标注「可安装」,版本 v0.1.0)。

启用后,插件通过 cordis.patch.yml 挂载:补丁中 id / name 为 session-settings / dsh-session-settings。DSH 生态里插件以当前 dsh 进程权限 运行,安装前请自行审阅源码与 MIT 许可证。

典型用法(消费插件侧)

先做宿主半注册,再在需要时从 sessionSettings 读取当前会话的值。

1、在宿主半注册声明式选项

// 消费插件宿主半(示意,字段来自 design-v1.md)
ctx.inject(['sessionSettings'], (sessionSettings) => {
  const dispose = sessionSettings.register({
    pluginId: 'com.example.my-plugin',
    title: '我的插件',
    order: 10,
    items: [
      {
        key: 'enableFeature',
        type: 'switch',
        title: '启用某功能',
        description: '仅对当前会话生效',
        default: false,
      },
    ],
  });
  ctx.effect(() => dispose, 'unregister session settings');
});

2、按会话读取解析后的值

const values = sessionSettings.get('com.example.my-plugin', sessionId);
// 或单项
const on = sessionSettings.getItem('com.example.my-plugin', 'enableFeature', sessionId);

3、用户改值的路径

用户打开右侧栏 session-settings tab 修改后,覆盖写入 <DSH_HOME>/storages/session_settings/ 下对应会话记录;宿主半 subscribe 可收到变更。若存储域不可用,设计稿要求读写返回 503,页面进入只读态,而不是静默使用易丢失的内存值。

导出入口(package.json):主包 "." → lib/index.js,客户端 "./client" → lib/client.js。

适用场景与注意

适合谁

  • 需要为 DSH 会话提供可 UI 配置的、按会话隔离 的插件作者。
  • 希望默认值留在自己插件里、只把「覆盖」交给统一基础设施的团队。

注意

  • 本插件不维护全局默认值层;全局默认仍由消费插件在 register 的 default 字段声明。
  • 存储根目录在 DSH_HOME 下跨 profile 共享,但按 sessionId 分键;设计稿说明会话回收通过对账 sessionPersistence.list() 清理已不存在会话的记录,归档会话配置会保留。
  • 社区目录 SkillHub 是独立站点,与 DeepSeek / 幻方无官方从属关系;插件星标以目录/GitHub 当前展示为准(线索为 0)。

结尾

dsh-session-settings 把「每会话不同」的配置收成一套宿主服务、官方 storage 域、右侧栏页面和 HTTP 桥,让其它插件专注业务默认值与注册声明。若要接入,从设计稿中的 SessionSettingsRegistration 与 sessionSettings.register 入手,并在本机 DSH 0.2.0-rc.2 一带依赖上做一次端到端验证。

  • 目录页:https://www.skillhub.cn/plugins/dongkid/dsh-session-settings
  • GitHub:https://github.com/dongkid/dsh-session-settings
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜