Skip to content

dsh-ai-session-title

Verified

dsh-ai-session-title · v0.4.6 · MIT · Web UI

AI-generated session titles for DeepSeek Harness: one-click generation inside the session rename dialog.

Install

dsh plugin add dsh-ai-session-title

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Tags

Creators

Readme

AI 会话标题

为 DeepSeek Harness(DSH)的会话重命名对话框加一个 AI 生成按钮:读取真实对话内容(以及你已经输入的草稿),让当前会话所用的模型写一个短标题,填进输入框——你确认后按「重命名」,不满意就继续改。

English | 中文

npm license dsh node

要求:dsh ≥ 0.2.1-rc.3、Node ≥ 20。

效果

重命名对话框里的 AI 生成按钮

  • 打开任意会话自带的「重命名会话」对话框(侧栏 ··· → 重命名会话)。
  • 输入框内右侧、同一条边框里多一个星标按钮——不是新弹窗,就是原生那个框。
  • 点一下:读取该会话的对话记录,连同你已输入的草稿一起作为参考,生成标题并填回输入框。
  • 底部仍然是原生的「取消 / 重命名」;生成不会自己改名,必须你点确认。

安装

从 npm 安装(推荐)

dsh plugin --profile <你的 profile> add dsh-ai-session-title

然后重启 dsh web 并刷新页面。

自带 dsh 的桌面版请在 App 内 设置 → 插件 里安装,不要用命令行——App 运行期间不会让 CLI 改写它自己的 profile。

从本仓库安装

plugin_manager install_bundle  target = <本目录的绝对路径>

或者让 agent 用 plugin_manager 工具装。装完刷新 Web 界面。

从插件市场安装

市场读取的是 awesome-dsh-plugin 这份目录,而不是本仓库。目录收录之后,在 插件 → 发现 里搜索安装即可。

工作原理

一个包,两半:

半边 文件 作用
Host index.js 注册全局命令 /ai-title。读会话事件日志、按下一次请求要用的路由(session.requestHeader().config,取不到时回退到最新一条助手消息)选模型,用 ctx.llm 以 purpose: 'session-title' 流式生成一条,清洗后返回。命令名后面的文本视为用户的草稿标题。
Client client.js 监听原生对话框的会话名输入框,就地装饰一个星标按钮;点击后调用 ctx.remote.commands.execute(sessionId, '/ai-title <草稿>', []),把返回的标题用原生 input 事件写回该输入框。

两个实现细节值得说明:

  • 为什么装饰 DOM 而不是注册插槽:原生对话框把目标会话存在组件内部 state 里,通过 shell.overlay 渲染,内部没有暴露任何插槽,所以插件拿不到插入点,只能就地装饰它;会话 id 则通过输入框预填的标题在 Workspace Service 的会话列表里反查。
  • 为什么走命令:客户端到 host 的 RPC 接口是构建期生成的,第三方 bundle 无法新增方法,命令是唯一稳定的调用通道。代价是每次生成会在会话流里留下一条 command/run + command/done 记录——这也是生成过程中唯一的可见反馈。

配置(可选)

装好之后打开 更多 → 设置,左侧导航里会多出一项 「AI 会话标题」,改完点保存即可:

字段 说明
style 标题结构,决定生成出来的标题长什么样,见下表
datePrefix 是否在标题前加「月-日」前缀,默认关
prompt 自定义结构提示词,只在 style 选“自定义”时生效;留空按“主题”处理
maxTitleChars 标题字符上限,默认 30

四种结构对应四种“以后怎么把会话找回来”的方式:

style 名称 示例 适合
concise 主题 登录超时排查 默认。3~8 字名词短语,侧栏最窄时也能一眼扫过去
descriptive 动作 重构登录状态管理 动词开头,回看时知道这次做了什么
outcome 主题 + 结论 分页错位 · 定位到索引边界 先主题再产出,复盘时最能看出这次值不值
custom 自定义 由提示词决定 用 prompt 描述你自己想要的格式

日期单独是一个开关,不是第五种结构:打开 datePrefix,上面任何一种结构都会多出 10-30 前缀,所以「日期 + 主题」「日期 + 主题 + 结论」都是两次点击的事,不用为每种组合再列一张卡片。

datePrefix 的日期不是模型编的:插件读会话第一条消息的时间,自己补 MM-DD ,并且先从前缀里扣掉 6 个字符再要求模型写正文,所以总长度仍然守得住 maxTitleChars。

不管选哪种结构,硬性要求都不变:只输出一行纯文本,不加引号、前缀或 Markdown,语言跟随对话。结构只换措辞,不会把生成结果弄脏。

早先版本里的 english / dated 两个结构值仍然被接受:english 照旧输出英文标题,dated 等价于「主题 + 打开 datePrefix」,所以旧配置升级后不会挂。

这一页由插件自己注册(settings.section),读写的就是插件自己的配置项 ai-session-title,和下面手写 cordis.patch.yml 完全等价。

少数高级项不放在设置页里,需要时写进 profile 的 cordis.patch.yml:

- id: ai-session-title
  name: dsh-ai-session-title
  config:
    provider: deepseek
    model: deepseek-chat
    maxOutputTokens: 1024
键 含义
provider / model 强制指定路由。要么都配、要么都不配;默认按下一次请求的路由,取不到再用最新一条助手消息的路由。
timeoutMs 生成超时,默认 60000。
maxOutputTokens 单次调用的输出预算,默认 1024。思考型模型如果先思考、把预算耗光才轮到你看到的标题,会报 max-tokens,把它调大即可。

兼容性

engines.dsh 声明为 ^0.2.1-rc.3。DSH 只按 engines.dsh 判断兼容性(没有该字段时才回退到 @deepseek-ai/dsh-* 的 peer 范围),插件市场的卡片上也会显示这个要求。

这个插件在运行时只导入一个 @deepseek-ai/* 包:host 半边用 @deepseek-ai/schemastery 声明 Config(harness 自带),其余只用 ctx.commands / ctx.llm;client 半边只用 ctx.remote 和 DOM API。好处是任何 profile 都不需要额外装依赖就能加载;代价是如果上游改了这些服务的签名或重命名对话框的结构,就需要跟着发新版本。

开发

npm test        # host 半边的冒烟测试,不需要 harness、也不需要模型

client 半边没有构建步骤:client.js 按原样被加载。改完刷新 Web 界面即可(profile 里是 link: 安装,不用重装)。

目录结构

cordis.patch.yml     把行 id `ai-session-title` 插入为本包
index.js             host 半边(命令 + 生成)
client.js            client 半边(就地装饰 + 远程调用)
test/host.smoke.mjs  host 半边冒烟测试(npm test)
locale/*.json        插件展示信息(标题 / 描述)
icon.svg             插件图标
screenshots.json     市场卡片用的截图声明
docs/screenshot.png  截图

常见问题

按钮没出现? 确认插件已启用、刷新过页面,且 dsh 版本满足 ^0.2.1-rc.3。

报「模型没有返回可用的标题」? 多数是思考型模型把输出预算全用在推理上,调大 maxOutputTokens。

报「无法确定要命名的会话」? 说明输入框里的标题在会话列表里匹配不到(例如同名的会话刚被改名)。先在侧栏打开该会话再试一次。

License

MIT,见 LICENSE。