DSH Hub

hg1048596-pixel/dsh-recall-unread

dsh-recall-unread

UIMemory126 GitHub stars· updated 2026-10-03

dsh-recall-unread is a community DeepSeek Harness plugin. Read the repository README before installing.

Install

npx @deepseek-ai/dsh plugin --profile web add github:hg1048596-pixel/dsh-recall-unread

Restart `dsh web` after install. Bundle APIs can change during the developer preview.

README badge

dsh-recall-unread DSH Hub badge
[![DSH Hub](https://dshhub.dev/badge/dsh-recall-unread.svg)](https://dshhub.dev/plugins/dsh-recall-unread)

Paste this into your README. The star count updates with every catalog sync.

From the README

Excerpt from hg1048596-pixel/dsh-recall-unread, cleaned of badges and images.

dsh-recall-unread

DeepSeek Harness (DSH) 插件:撤回「已发送但尚未被模型读取」的文字消息。

在模型运行中发送文字(插话发送)时,消息会以“待处理”气泡的形式出现在对话尾部——在模型认领(读取)之前,你可以一键撤回,避免把还没想好的话发给模型。

截图占位:可将实际效果截图保存为 docs/screenshot.png,并取消上方 ![screenshot] 的注释。


✨ 功能特性

  • 启用即生效:在插件市场(dsh-market)或插件管理页启用本插件后,「未读消息」条带立即生效;停用即整体不加载。不依赖任何启动器菜单。
  • 未读消息条带:在输入框上方(conversation.input.dock 插槽)列出所有已发送但模型尚未读取的插话消息(0.2.x 取 inbox['next-step'] 的用户插话,0.1.x 取 placement === 'steering')。
  • 单条撤回:每条消息显示预览文本 + 「撤回」按钮,点击后消息从对话中移除,并提示“已撤回一条消息”。
  • 全部撤回:存在多条未读消息时提供「全部撤回」一键操作。
  • 只读语义:消息一旦被模型认领(开始读取)会自动离开条带,此时无法撤回——严格符合“仅未读取可撤回”。
  • 优雅降级:撤回失败(消息已开始发送)时给出明确提示,不会破坏会话。

🔍 工作原理

DSH 中“已发送但未读取”的消息 = 仍停留在 Agent inbox(待处理队列)中的消息:0.2.x 是 inbox['next-turn'] / inbox['next-step'] 里的 pending 项,0.1.x 是会话快照 ConversationSnapshot.queue。它有两种 placement:

placement含义官方界面现状
queued运行中排队等待下一轮官方队列坞已有「删除」按钮
steering运行中插话发送,显示为对话尾部待处理气泡没有任何撤回入口 ← 本插件补上

撤回实现分两个版本:

  • 静态版(推荐):Client 直接调用官方会话 RPC session.updateQueue(itemId, { kind: 'remove' })(与官方队列坞的「删除」同一实现)。
  • 动态版:通过包内私有 RPC 完成:
Client  (撤回按钮)
   │  host.call('recall', { sessionId, itemId })
   ▼
Host    harness.handle('recall')
   │  agents.get(sessionId).inbox.remove(itemId)
   ▼
效果   消息从 inbox 移除 → inbox 投影更新 → 气泡与条带同步消失

🧩 运行时兼容(DSH 0.1.x / 0.2.x)

运行时「未读插话」数据源撤回调用
0.2.x(含 desktop profile)useProjection('inbox')['next-step'] 中 source.kind === 'user' 的行sessions.binding(sessionId).session.updateQueue(id, { kind: 'remove' })(失败码带命名空间:session/queue-item-not-found)
0.1.x会话快照 session.queue 中 placement === 'steering' 的行同上(失败码 queue-item-not-found)
  • 0.2.x 的 SessionSnapshot 已移除 queue 字段,本地回显改到 pendingSubmissions;插话被接纳后进入 inbox['next-step'],在模型下一步读取前仍可撤回。
  • 官方队列坞只覆盖 next-turn(排队消息,已有删除按钮),next-step(插话)这一格由本插件补齐。

Host 端逻辑与官方 session.updateQueue 中 kind: 'remove' 的内部实现一致(agent.inbox.remove)。

📁 目录结构

dsh-recall-unread/
├── README.md                  # 本文件
├── LICENSE                    # MIT 许可证
├── .gitignore                 # Git 忽略规则
├── package.json               # 项目元数据(GitHub 展示用)
├── plugin.json                # 插件清单(名称 / ID 前缀 / 代码来源)
├── src/
│   ├── host.js                # Host 半端源码(动态版,可直接作为 code.host)
│   └── client.js              # Client 半端源码(动态版,可直接作为 code.client)
├── plugin/                    # 静态 web profile 插件包(安装后随 DSH 加载,推荐)
│   ├── package.json           # 安装包元数据(含 dsh.client 声明)
│   ├── host.js                # Host 半端(空实现占位,撤回走客户端官方 RPC)
│   └── client.js              # Client bundle(__ModuleLoader__ 注册)
└── docs/                      # 截图等附加资源(可选)

🚀 安装与激活

方式一:静态安装(推荐,随 DSH 加载,重启不丢失)

把 plugin/ 目录安装为 DSH web profile 的静态插件:

  1. 将 plugin/ 整个目录复制到 web profile 的 node_modules 下:
    ~/.dsh/profiles/web/node_modules/dsh-recall-unread/
    
  2. 在 ~/.dsh/profiles/web/cordis.patch.yml 末尾追加加载行:
    - insert:
        - id: recall-unread
          name: dsh-recall-unread
    
  3. 重启 DSH。插件启用后「未读消息」条带即生效;可在插件市场(dsh-market)或插件管理页随时停用/启用。

说明:静态版在 Client 端直接调用官方会话 RPC session.updateQueue(itemId, { kind: 'remove' })(与官方队列坞的「删除」同一实现),无需动态 RPC,与官方界面行为完全一致。插件不依赖 Amadeus。

方式二:动态插件(临时体验,重启后失效)

本项目也可作为 DSH 动态 Cordis 插件(进程级定义)临时体验:

…

Related plugins