Repository navigation
Description
Pre-submission checklist | 提交前检查
- I have searched existing issues and this hasn't been mentioned before | 我已搜索现有问题,确认此问题尚未被提及
- I have read the project documentation and confirmed this issue doesn't already exist | 我已阅读项目文档并确认此问题尚未存在
- This issue is specific to MemOS and not a general software issue | 该问题是针对 MemOS 的,而不是一般软件问题
Bug Description | 问题描述
fter upgrading DeepSeek Harness (DSH) from 0.1.5-rc.2 to 0.1.7-rc.1, the DeepSeek Harness adapter stops working: the web UI shows 本轮运行失败 on every message, and the underlying error is
format v4 message requires a producer-owned source kind
DSH 0.1.7 introduced session format v4, which retires the bare kind: "plugin" message source. Every message must now carry a producer-owned kind (for example plugin:memos-local-memory), and the old kind: "plugin" + plugin pair is rejected outright:
// @deepseek-ai/dsh-session-format-v3-to-v4
if (... typeof value["kind"] !== "string" || value["kind"].length === 0 || value["kind"] === "plugin")
throw new SessionFormatError("format v4 message requires a producer-owned source kind");
The adapter still writes the retired v3 shape for the messages it injects, so the turn fails the moment the recall message is persisted.
Expected: memory recall keeps working on DSH 0.1.7 exactly as it does on 0.1.5-rc.2.
How to Reproduce | 如何重现
1.Install DSH 0.1.7-rc.1 and enable @memtensor/memos-local-plugin@2.0.20 in a profile's dsh.profile.bundles.
2.Start dsh web and open a session that has at least one memory hit, so the agent/pre-step recall injection fires.
3.Send any message → the turn fails immediately with the error above.
The session log stops right after turn/start, i.e. during agent/pre-step, before any assistant output is produced. Every later message fails the same way.
Reverting DSH to 0.1.5-rc.2 with no plugin change fixes it immediately, which points at the source-kind shape rather than at the recall logic itself.
Environment | 环境信息
Python version: not applicable — this report concerns the DeepSeek Harness adapter (adapters/deepseek-harness/), not the Python package.
Operating System: Windows 11
MemOS version (pip show memoryos): not applicable; plugin version is @memtensor/memos-local-plugin@2.0.20 (current npm latest)
Node.js: v24.20.0
DSH: 0.1.7-rc.1 (the release that ships @deepseek-ai/dsh-session-format-v3-to-v4 and the v4 admission check). Reproduces on 0.1.7-rc.1; does not reproduce on 0.1.5-rc.2.
Additional Context | 其他信息
Root cause — two message sources still use the retired shape:
apps/memos-local-plugin/adapters/deepseek-harness/index.ts:387-392 (the recall message built for agent/pre-step):
createRecallMessage: (text) => createUserMessage({
content: [{ type: "text", text }],
source: {
kind: "plugin",
plugin: DEEPSEEK_HARNESS_PLUGIN, // "memos-local-memory"
form: "recall",
},
}),
apps/memos-local-plugin/adapters/deepseek-harness/host-llm.ts:369:
source: { kind: "plugin", plugin: HOST_LLM_MESSAGE_SOURCE },
The recall message is appended in bridge.ts:273 (messages: [...decision.messages, this.createRecallMessage(context)]), is persisted as a durable user/message event, and is therefore subject to the v4 admission check.
Evidence from the session logs
On 0.1.5-rc.2 the recall rows are stored as {"kind":"plugin","plugin":"memos-local-memory","form":"recall"} (9 occurrences in a single session).
DSH's own v3→v4 migration rewrites those rows into the producer-owned shape {"kind":"plugin:memos-local-memory","form":"recall"} — same metadata, only the identity form changes.
New runtime writes never reach the log at all: the session file ends at turn/start.
Suggested fix (identical to what DSH's producerKind() derives when migrating the old rows, so it stays readable on 0.1.5 as well):
// adapters/deepseek-harness/index.ts
source: { kind: plugin:${DEEPSEEK_HARNESS_PLUGIN}, form: "recall" }
// adapters/deepseek-harness/host-llm.ts
source: { kind: plugin:${HOST_LLM_MESSAGE_SOURCE} }
No other plugin-side change is required: the v4 check only rejects the bare plugin kind (and empty/missing kinds), and the plugin's own message filters match on source.kind === "user".
Willingness to Implement | 实现意愿
- I'm willing to implement this myself | 我愿意自己解决
- I would like someone else to implement this | 我希望其他人来解决
Activity
Memtensor-AI commentedon Sep 24, 2026
🤖 AutoDev has picked up this issue and started working on it.
Task ID:
24e2ae38193f9c6fWorking branch:
bugfix/autodev-2405-20260924123345867Target branch:
latest dev* branchWorkflow: opsp (analysis → coding → testing → PR)
I will post the PR link here once done. If I need more information, I will ask in the comments.
Pasitearko commentedon Sep 24, 2026
中文摘要
DSH 从 0.1.5-rc.2 升到 0.1.7-rc.1 后,插件注入的记忆召回消息仍使用旧版 kind: "plugin" 来源形式,而 0.1.7 引入的会话格式 v4 已废弃该写法,要求使用生产者自有 kind(如 plugin:memos-local-memory)。该消息在落盘校验时被拒,导致每轮对话直接失败(界面显示「本轮运行失败」)。涉及 adapters/deepseek-harness/index.ts 的 createRecallMessage 与 host-llm.ts 两处,改为 kind:
plugin:${...}并去掉 plugin 字段即可,与 DSH 自身 v3→v4 迁移产出的形式一致。仓库当前 main 分支与 v2.0.34 tag 均未修复。fix: upgrade DSH adapter message sources to session format v4
Memtensor-AI commentedon Sep 24, 2026
✅ AutoDev task
24e2ae38193f9c6fcompleted.Summary: Fixed DSH 0.1.7 session format v4 compatibility issue that caused memory recall messages to fail with "format v4 message requires a producer-owned source kind" error.
Root Cause
DSH 0.1.7 introduced session format v4, which retired the v3 message source shape (kind: "plugin" + plugin field) and now requires producer-owned kinds (kind: "plugin:producer-name"). Two message sources in the DeepSeek Harness adapter were still using the retired v3 format, causing the v4 admission check to reject recall messages during agent/pre-step execution.
Changes Made
kind: "plugin", plugin: "memos-local-memory"tokind: "plugin:memos-local-memory"Compatibility
The v4 format maintains backward readability on DSH 0.1.5 and matches DSH's own v3→v4 migration logic. No other plugin-side changes are required since the v4 check only rejects the bare "plugin" kind, and existing message filters continue to work (they match on source.kind === "user").
Testing
Updated 4 test files to reflect the v4 message source format. The fix is minimal and surgical, changing only the source kind format without altering any logic or behavior.
Base branch:
mainBranch:
bugfix/autodev-2405-20260924123345867Commit:
5f5d63fPR: #2406
Assigned to: @syzsunshine219
Reviewers: @whipser030, @hijzy
Pasitearko commentedon Sep 24, 2026
The automated PR #2406 for this issue was closed without being merged, and its branch (
bugfix/autodev-2405-20260924123345867) has since been deleted, so the fix never landed:closed,merged: false— closed 12:49:13Z, one second after Open Code Review asked for a follow-up fix5f5d63f2("fix: upgrade DSH adapter message sources to session format v4") exists but is not contained in any branchdev-v2.0.36andmainstill containsource: { kind: "plugin", plugin: ... }atadapters/deepseek-harness/index.ts:390andhost-llm.ts:369@memtensor/memos-local-pluginis still2.0.20, so users have no fixed release to installThe commit content itself looked correct — both message sources were moved to
kind: `plugin:<producer>`with thepluginfield removed — so could it be re-submitted or merged manually?One note for whoever picks this up: the Open Code Review finding about
host-llm.tsneeding aformproperty does not apply. The DSH v4 admission check only requiressource.kindto be a non-empty string other than"plugin"(seesource()in@deepseek-ai/dsh-session-format-v3-to-v4), and this plugin's own message filters match onsource.kind === "user", so addingformis unnecessary.Thanks!
fix(dsh): use DSH 0.1.7 producer-owned source kind format
docs(dsh): explain why host-llm v4 source omits form and update match…
Memtensor-AI commentedon Sep 24, 2026
✅ AutoDev task
24e2ae38193f9c6fcompleted.Summary: OCR round 1/2 repair for PR #2406 pushed as 226e0fa. Verified against DSH 0.1.7-rc.1 types that ContextForm is a closed vocabulary and form?: never is a valid documented variant, then documented the intentional omission with a 7-line block comment above toDshMessage in host-llm.ts and updated the matching test expectation to the v4 kind shape. All 4 DSH adapter test suites green (53/53).
Base branch:
mainBranch:
bugfix/autodev-2405-20260924123345867Commit:
226e0faPR: #2406
Assigned to: @syzsunshine219
Reviewers: @whipser030, @hijzy
VillagerUncle02 commentedon Sep 24, 2026
补充一份独立复现,并补一个原报告没有的关键细节:这个失败是条件触发的,不是每一轮必现。
Independent reproduction on DSH 0.1.7-rc.2 (npm
next; the original report used rc.1) — still broken, andmainstill carries the old shape.环境 / Environment
@deepseek-ai/dsh@0.1.7-rc.2(全局 npm 安装),profileweb,Windows 11@memtensor/memos-local-plugin@2.0.20(npm latest)关键细节:只在"召回真的注入消息"的那一轮失败
同一个 profile 下:
turn/start→step/start→user/message(source.kind="user")→user/message(agent-instructions/runtime-context/skill-catalog)→request/header→assistant/message…,一切正常;turn/start之后,正常应紧跟的step/start与那批注入消息一条都没有 —— 被拒的事件在落盘前就被拒了,日志没有损坏行,会话本身是干净的,重发仍会以同样方式失败。这个时机与
createRecallMessage(agent/pre-step 注入召回)完全吻合:没命中召回的轮次正常,命中召回的轮次必失败。所以"每轮都失败"其实取决于召回是否注入 —— 复现时建议开启recallEnabled并让召回命中。一个与 PR #2406 略有不同、同样可行的写法
我本地把
index.ts/host-llm.ts的kind: "plugin"改成kind: `plugin:${DEEPSEEK_HARNESS_PLUGIN}`(即plugin:memos-local-memory),两个文件node --check通过、回合恢复。差别是:我保留了plugin字段,即0.1.7-rc.2 的 V4 准入门禁同样通过 —— 印证了上面 @Pasitearko 的说明:V4 只要求
source.kind是非空且不为"plugin"的字符串(未知归属会被保留),plugin/form都不是必需。所以plugin字段去掉或保留都可以,不必为form?: never纠结。现状
刚用代码搜索确认:
main上apps/memos-local-plugin/adapters/deepseek-harness/index.ts(createRecallMessage)与host-llm.ts(toDshMessage)仍是kind: "plugin",npm 上也仍是 2.0.20 —— 与 #2407 的记录一致。能否把 #2406 的修复重新提交或手工合并?有修复版发布后我会撤掉本地补丁。lby9201-arch commentedon Sep 28, 2026
中文摘要: 在 macOS + 官方 DSH 桌面版(Electron 44 / DSH
0.1.7-rc.2)上独立复现同一问题,确认失败只在召回真的注入消息的那一轮发生;补上宿主侧的精确证据(v4 准入按事件整批校验,被拒时连用户自己那条消息都不会落盘)。本地按 #2406 的方式改dist后已做完端到端验证:召回消息现在能正常落盘。main与 npm2.0.20仍未修复,能否重新提交/合并 #2406 并发一个修复版?Environment
0.1.7-rc.2(Electron 44 / bundled Node 24.18.1),profiledesktop@memtensor/memos-local-plugin@2.0.20(npmlatest)~/.memos-shared(459 episodes;recallEnabled+hostLlmEnabled均开启)This is a third independent environment after the original rc.1 report and @VillagerUncle02's Windows +
webprofile run — the packaged desktop app fails the same way.Confirmed: the failure is conditional on recall actually injecting
On this machine I scanned every
session.v4.jsonl.zstdunder~/.dsh/sessions(all workspaces): zero rows carry the retired"kind":"plugin"shape. The failing session's log ends exactly like this:which matches "the injected event was refused before any row was appended" — the log stays clean and resending fails identically.
The host-side reason the user's own message is never written either: admission is per event, and for
agent/inbox/splicedit validates every message indata.inserted:The query and the injected recall context travel in the same pre-step decision, so the batch is rejected as a whole.
formvsplugin: settled against the host's own codeI extracted the running app's real
source()implementation out ofapp.asarand asserted directly against it:{kind:"plugin", plugin:"memos-local-memory", form:"recall"}{kind:"plugin:memos-local-memory", form:"recall"}{kind:"plugin:memos-local-memory"}{kind:"user"}So #2406's shape is sufficient, and the Open Code Review note about
host-llm.ts"needingform" is a non-issue — as @Pasitearko already pointed out. Precedent in the same ecosystem:@xmanrui/dsh-imshipped exactly this change in 4.28.1 (kind: plugin:<name>), sokind: `plugin:<producer>`is the ecosystem-correct shape.End-to-end verification after applying the #2406 change locally
I patched the two shipped
distfiles the same way (kind: `plugin:${...}`,pluginfield dropped), restarted DSH, and then ran a turn where recall does return hits:user/messagewithsource: {"kind":"plugin:memos-local-memory","form":"recall"}(seq 365)That is the exact write path that used to throw, now passing in a real install — stronger than unit-test-only evidence.
Ask
Verified again today (2026-09-28):
mainstill carries the retired shape atapps/memos-local-plugin/adapters/deepseek-harness/index.ts:390-391andhost-llm.ts:369, and npmlatestis still2.0.20. Could #2406 (commits5f5d63f/226e0fa) be re-submitted or merged manually and a patch release published? I'll drop the local patch as soon as a fixed version is on npm. Thanks!0100z1 commentedon Oct 14, 2026
One more environment on a newer DSH line, plus a reproducible check — and a note on PR #2455
补充一个更新的 DSH 环境、一个可复现的判定方法,以及关于 PR #2455 的说明。
Environment | 环境
desktop, Windows 11@deepseek-ai/dsh-session-format-v3-to-v4@0.2.0-rc.2@memtensor/memos-local-plugin@2.0.20(npmlatest)recallEnabled: true,hostLlmEnabled: true,captureEnabled: trueThis is a newer DSH line than any report so far (previous reports were 0.1.7-rc.1 / 0.1.7-rc.2), so the bug is not confined to 0.1.7 — it persists into 0.2.0.
这是比此前所有报告都更新的 DSH 产品线(此前为 0.1.7-rc.1 / rc.2),说明该 bug 并非只存在于 0.1.7,而是延续到了 0.2.0。
Still broken on
mainand in the published package |main与已发布版本仍未修复apps/memos-local-plugin/adapters/deepseek-harness/index.ts:390— stillkind: "plugin", plugin: DEEPSEEK_HARNESS_PLUGIN,apps/memos-local-plugin/adapters/deepseek-harness/host-llm.ts:369— stillsource: { kind: "plugin", plugin: HOST_LLM_MESSAGE_SOURCE },dist-tags.latestis still2.0.20, published 2026-09-21 — i.e. before this issue was filed, so there is no fixed release for users to install.Reproducible check with DSH's own exported validator | 用 DSH 自带校验器复现
Rather than patching and eyeballing the result, the two source shapes can be judged directly with DSH's released V4 codec, taken from the installed app:
Results:
sourceencodeEventassertV4RowAdmission{ kind: "plugin", plugin: "memos-local-memory", form: "recall" }SessionFormatError: format v4 message requires a producer-owned source kind{ kind: "plugin", plugin: "memos-local-memory" }{ kind: "plugin:memos-local-memory", form: "recall" }{ kind: "plugin:memos-local-memory" }{ kind: "runtime-context", form: "snapshot" }(DSH's own current shape)Note that
assertV4RowAdmissionrejects the retired shape too. That is the gate DSH runs before recoverable-suffix suppression, which is why this is a hard refusal rather than a row that gets skipped — consistent with the clean logs other reporters described (no corrupt row; the event simply never lands).The fix is behaviour-preserving | 该修复不改变既有行为
The plugin's own read-side filters compare
kindagainst the literal"user":dist/adapters/deepseek-harness/bridge.js:149—if (event.data.source.kind !== "user") return;dist/adapters/deepseek-harness/bridge.js:675—.filter((message) => message.source.kind === "user")Since
"plugin:memos-local-memory" !== "user", recall messages remain excluded from captured user text exactly as before. The change only affects what the format validator accepts.About PR #2455 — it looks blocked on CI, not on code | 关于 PR #2455:卡在 CI,不是代码问题
As of this comment, PR #2455 reports:
The diff is the correct change (
index.ts+host-llm.ts, plus test expectations), it has no conflicts, and it has no review comments. It appears to be stalled purely because the Open Code Review check itself failed to execute. Could someone with write access re-run that check, or merge it manually? PR #2406 was closed without merging for this same area earlier, so a second one stalling would leave users with no fixed release at all.One more thing: the peer range no longer covers current DSH | 另外:peer 范围已不覆盖当前 DSH
package.jsondeclares:DSH is now 0.2.0-rc.2, which falls outside
<0.2.0. Worth widening while fixing the source kind, otherwise the plugin will keep reporting an unsatisfied peer range on current DSH even after the format bug is fixed.endxxxx commentedon Oct 29, 2026
Fixed by #2519, merged into main and released in @memtensor/memos-local-plugin 2.0.21.
Both automatic recall messages and auxiliary host-LLM messages now use the producer-owned source kind plugin:memos-local-memory, replacing the retired { kind: "plugin", plugin: "..." } shape rejected by DSH session format V4. Regression tests cover both writers using the official V4 admission validator.