Skip to content

feat: dsh 插件新增 meX 记忆面板(右下角 + Add to MeX 一键抽取记忆) - #3

Merged
MickLife merged 8 commits into
developfrom
feature/dsh-mex-ui-panel
Aug 20, 2026
Merged

MickLife merged 8 commits into
developfrom
feature/dsh-mex-ui-panel

Conversation

@MickLife

Copy link
Copy Markdown
Owner

概述

为 dsh 的 mex-dsh-plugin 增加浏览器 UI 面板与"一键抽取记忆"能力。

新增功能

  1. meX 记忆面板(Client half,client.js)

    • 注册到 shell.overlay 浮动层,默认停靠页面右下角
    • 每轮对话(dsh Turn)结束后圆点变绿、提示"可加入记忆"
    • Add to MeX 按钮:点击触发抽取,显示"抽取中 → 已写入 N 条记忆"
  2. Host 侧抽取逻辑(panel.js)

    • 监听 agent/turn-stopping 缓存本轮对话文本
    • 注册 /mex/panel-state(状态轮询)与 /mex/extract(触发抽取)
    • 通过 subagents.start('spawn', ...) 触发一轮全新 agent 对话,由该 agent 调用 mex_add/mex_update 等工具写入记忆
  3. 抽取 prompt(参考 prompts.py 精简):画像 vs 画像外、置信度五档(禁止 confirmed)、质量标准、时间规范,并引导先 mex_profile/mex_list 查重

关键修复

panel.js 用 ctx.inject(['webServer'], cb) 等待服务可用后再注册路由——修复了 bundle 插件 apply 早于 webServer 注册导致路由缺失、抽取请求落到 SPA fallback 返回 405 空 body(前端 Unexpected end of JSON input)的问题。

改动文件

文件 说明
src/mex/integration/dsh/client.js 新增:Client half 面板
src/mex/integration/dsh/panel.js 新增:Host 抽取逻辑
src/mex/integration/dsh/index.js 接入面板逻辑
src/mex/integration/dsh/package.json 声明 dsh.client 入口,版本 0.2.0
src/mex/services/integrate.py DSH bundle 清单扩展为六件套
tests/services/test_integrate.py dsh 测试覆盖六件套与关键内容

验证

  • 全套测试 584 passed(含远端 develop 新测试)
  • ruff 检查通过、JS 语法检查通过
  • 生成产物与模板逐文件一致

- Client half(client.js):注册 shell.overlay 浮动层,默认停靠右下角,
  显示本轮对话状态,点击 Add to MeX 触发抽取;
- Host half(panel.js):监听 agent/turn-stopping 缓存每轮对话,
  注册 /mex/panel-state 与 /mex/extract 接口,通过 spawn 子代理执行抽取,
  子代理用 mex_* 工具写入记忆;
- 抽取 prompt 参考 llm/prompts.py 规范精简:画像/画像外、置信度五档、
  质量标准、时间规范,并引导先 profile/list 查重;
- package.json 声明 dsh.client 入口;integrate.py 文件清单扩展为六件套;
- 测试覆盖 dsh bundle 生成与文件内容。
根因:panel.js 用 ctx.get('webServer') 一次性获取服务,而 bundle 插件
apply 时机可能早于 webServer 服务注册(Cordis 按 inject 依赖激活,mex
只依赖 subprocess/tools),拿到 undefined 后静默降级,/mex/* 路由从未
注册,POST 落到 SPA fallback 返回 405 空 body,前端 res.json() 报
"Unexpected end of JSON input"。

修复:
- panel.js 改用 ctx.inject(['webServer'], cb) 等待服务可用后再注册路由
  (标准做法,headless 无 webServer 时回调不执行、不影响 mex 工具);
- client.js 增加 parseJson 容错:空响应/非 JSON 转结构化错误提示,
  不再抛 SyntaxError。
docs/dsh-integration.md 记录 dsh 侧实现细节:
- 整体架构(Client 面板 → Host 缓存/路由 → spawn 子代理 → mex CLI → SQLite);
- 触发链路逐步说明(turn-stopping 缓存、prompt 组装、防重复机制);
- 关键设计决策(为何用子代理、为何 ctx.inject 等待 webServer、log vs events);
- 与 ADR-12 的关系(用户主动触发 vs 自动实时抽取,不冲突)。

dsh 插件 README 补充指向该设计文档的链接。
- panel.js:onExtract 改为异步触发(立即返回 childSessionId,不等待
  result、不 dispose),子代理保留在当前会话的侧边栏目录;
  监听 subagent/end 标记抽取完成(防重复 + 记录写入条数);
  panel-state 增加 extraction 运行状态(running/done)。
- client.js:注入 sessions 服务,点击 Add to MeX 后调
  sessions.openSubagent 打开抽取子代理会话视图(非黑盒);
  面板显示抽取中/完成状态与查看运行过程按钮。
- 文档:dsh-integration.md 更新 4.5/4.8/5/6/7(透明可见设计),
  README 同步说明。
根因:panel-state 的 hasNew 只比较缓存轮次 > 已抽取轮次,未检查 agent
运行状态。对话进行中(等待模型输出 / 执行工具,如 deep diving)时
pendingTurns 仍留着上一轮数据,按钮一直亮着,用户可能误以为本轮已结束。

修复:
- panel.js:panel-state 增加 agentRunning 字段,agent.status==='running'
  时 hasNew 恒为 false;extract 接口同样拒绝 running 中的抽取请求;
- client.js:canRun 增加 !agentRunning 门控,按钮禁用、提示文案改为
  '对话进行中,本轮结束后可加入记忆';
- 文档:dsh-integration.md 记录该门控设计。
根因:client.js 面板使用硬编码深色背景(rgba(24,24,27,0.92)),
浅色主题下仍是深色卡片,与 dsh 主题不符。

修复:面板全部颜色改用 dsh 主题 token(CSS 变量):
- 背景 var(--dsw-alias-bg-overlay)、文字 label-primary/secondary、
  边框 border-l1、成功绿 state-success-primary、警示黄 state-warn-primary、
  禁用背景 bg-layer-1、阴影 shadow-lv3(fallback);
主题系统在 body[data-ds-dark-theme] 上按偏好解析变量,面板位于
shell.overlay(body 内),颜色自动跟随三种主题,无需感知主题偏好。
文档:dsh-integration.md 新增 §4.0 主题适配;README 同步。
- 配色:按 body[data-ds-dark-theme] 区分主题(MutationObserver 监听
  切换),深色用 dsh token,浅色微调——背景 #f5f6f8(非常浅灰,比
  bg-overlay 更浅)、提示绿 #15803d(比 state-success-primary 更深、
  浅底可读)、主文字 #1f2328、次要文字 #6b7280;
- 拖拽:标题栏(⣿ 手柄)cursor: move,mousedown/mousemove/mouseup
  拖动,位置持久化 localStorage['mex-panel-pos'],未拖拽默认右下角;
- 文档:dsh-integration.md §4.0 重写为主题适配+拖拽,README 同步。
深色背景从 var(--dsw-alias-bg-overlay)(neutral-bluish-700,
rgb(97,102,107) 中灰)改为 var(--dsw-specific-menu)(bg-layer-3 =
neutral-bluish-800,rgb(53,54,56) 更深),与 dsh 官方弹层/菜单一致,
仍走主题 token 体系。
@MickLife
MickLife merged commit c30627c into develop Aug 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant