版本(Version)
1.26.0
环境(Environment)
- OS:Windows 11 (10.0.22631) - Node:24.18.1(DeepSeek Harness 自带运行时) - 宿主:DeepSeek Harness 桌面版 0.1.7-rc.1(@deepseek-ai/dsh-desktop 0.1.7-rc.1.20260924.1) - 会话格式:DSH session format v4 - 接入方式:dsh plugin --profile desktop add @roarpeng/graphflow(作为 profile bundle)
复现步骤(Steps to reproduce)
- 在 DSH profile 中安装本插件(使其 dsh/plugin.mjs 的 agent/pre-step 钩子生效):
dsh plugin --profile desktop add @roarpeng/graphflow
- 启动 DSH(桌面版或 dsh web),新建一个会话。
- 发送第一条用户消息(任意内容,例如 hi)。
期望行为(Expected behavior)
首轮 hint 正常随该 step 注入,会话正常执行。
实际行为(Actual behavior)
整个轮次失败(不是只丢这一条消息),DSH 报:
format v4 message requires a producer-owned source kind
补充信息(可选)
根因
dsh/plugin.mjs 的 buildHintMessage() 给注入消息打的是 DSH V3 时代的 kind: "plugin":
该消息经 agent/pre-step 的 decision.messages 追加进入会话后,会被 V4 会话格式的原生准入校验拒绝
(@deepseek-ai/dsh-session-format-v3-to-v4/lib/index.js):
注意 || value["kind"] === "plugin" 是硬拒绝:kind 只要等于 "plugin" 就直接抛错。
报错发生在落盘/adoption 阶段,所以表现为整轮失败,而不是静默丢弃该消息。
这与 PR #34(修复 #28)相关:那次改动把 hint 从 agent.inject() 改成直接扩展
decision.messages(dsh/plugin.mjs 的 agent/pre-step 监听器内),方向是对的,但注入消息的
source 仍是旧格式,因此在 V4 会话下必然失败。
建议的修法
DSH 官方在同一个迁移模块里给出了 V4 的 producer-kind 命名规则:
即第三方插件应使用 plugin:<插件标识>,本插件对应 plugin:graphflow-dsh。
⚠️ 注意:必须同时更新 isUserOriginatedMessage(),否则会引入第二个 bug
dsh/plugin.mjs 中的:
hint 消息的 role 是 "user"。若只把 source.kind 改成 plugin:graphflow-dsh 而不更新这个黑名单,
SYSTEM_MESSAGE_SOURCE_KINDS.has(kind) 会返回 false,函数走到兜底行、
把 hint 当成真实用户提问(进而被 recordDialogueFromInbox() 记录为对话图节点)。
建议追加前缀判断,一劳永逸覆盖所有插件的 producer-owned 形式:
本地验证
两份改动都已在本地应用并验证(提取函数实跑,14 项断言全通过):
用例 | 结果
-- | --
原 kind: "plugin" 经 V4 准入 | ❌ 抛 format v4 message requires a producer-owned source kind(与线上报错一致)
改后 kind: "plugin:graphflow-dsh" | ✅ 通过
hint 经 isUserOriginatedMessage() | ✅ 仍判定为「非用户消息」(未污染对话图)
真实用户消息 / tool 消息 | ✅ 行为不变(回归通过)
已在本地应用的最小补丁:
Workaround(供其他用户临时自救)
修改 ~/.dsh/profiles/<profile>/node_modules/@roarpeng/graphflow/dsh/plugin.mjs 中上述两处
(插件升级会覆盖,需重打)。
版本(Version)
1.26.0
环境(Environment)
复现步骤(Steps to reproduce)
dsh plugin --profile desktop add @roarpeng/graphflow
期望行为(Expected behavior)
首轮 hint 正常随该 step 注入,会话正常执行。
实际行为(Actual behavior)
整个轮次失败(不是只丢这一条消息),DSH 报:
format v4 message requires a producer-owned source kind
补充信息(可选)
根因
dsh/plugin.mjs的buildHintMessage()给注入消息打的是 DSH V3 时代的kind: "plugin":该消息经
agent/pre-step的decision.messages追加进入会话后,会被 V4 会话格式的原生准入校验拒绝 (@deepseek-ai/dsh-session-format-v3-to-v4/lib/index.js):注意
|| value["kind"] === "plugin"是硬拒绝:kind 只要等于"plugin"就直接抛错。 报错发生在落盘/adoption 阶段,所以表现为整轮失败,而不是静默丢弃该消息。这与 PR #34(修复 #28)相关:那次改动把 hint 从
agent.inject()改成直接扩展decision.messages(dsh/plugin.mjs的agent/pre-step监听器内),方向是对的,但注入消息的 source 仍是旧格式,因此在 V4 会话下必然失败。建议的修法
DSH 官方在同一个迁移模块里给出了 V4 的 producer-kind 命名规则:
即第三方插件应使用
plugin:<插件标识>,本插件对应plugin:graphflow-dsh。isUserOriginatedMessage(),否则会引入第二个 bugdsh/plugin.mjs中的:hint 消息的
role是"user"。若只把source.kind改成plugin:graphflow-dsh而不更新这个黑名单,SYSTEM_MESSAGE_SOURCE_KINDS.has(kind)会返回 false,函数走到兜底行、 把 hint 当成真实用户提问(进而被recordDialogueFromInbox()记录为对话图节点)。建议追加前缀判断,一劳永逸覆盖所有插件的 producer-owned 形式:
本地验证
两份改动都已在本地应用并验证(提取函数实跑,14 项断言全通过):
用例 | 结果 -- | -- 原 kind: "plugin" 经 V4 准入 | ❌ 抛 format v4 message requires a producer-owned source kind(与线上报错一致) 改后 kind: "plugin:graphflow-dsh" | ✅ 通过 hint 经 isUserOriginatedMessage() | ✅ 仍判定为「非用户消息」(未污染对话图) 真实用户消息 / tool 消息 | ✅ 行为不变(回归通过)已在本地应用的最小补丁:
Workaround(供其他用户临时自救)
修改
~/.dsh/profiles/<profile>/node_modules/@roarpeng/graphflow/dsh/plugin.mjs中上述两处 (插件升级会覆盖,需重打)。