Skip to content

fix(inject): read assistant body from data.message.content (Issue #129) - #136

Merged
modusensus merged 1 commit into
slow-stack:mainfrom
aizhimoran:fix/inject-assistant-message-content
Sep 11, 2026
Merged

modusensus merged 1 commit into
slow-stack:mainfrom
aizhimoran:fix/inject-assistant-message-content

Conversation

@aizhimoran

@aizhimoran aizhimoran commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

承接 Issue #129。维护者建议直接提 PR,并补一个「assistant 轮带 message.content」的用例。

问题

热记忆块([短期上下文])里每一轮的 A 恒为空。

根因在 src/inject.js 的 textOf:它只读 event?.data?.content。而 DSH 的事件契约对两种消息用两种嵌套层级(@deepseek-ai/dsh-session 的 assertMessageEventShape 一行写死):

const message = type === "user/message" ? record : record?.["message"];

即 user/message 的正文在 data.content,而 assistant/message(以及 tool/result)的消息体嵌在 data.message,正文在 data.message.content。同仓库的 src/summarize.js 走的正是正确路径(case "assistant/message": const msg = data?.message;),所以这是 inject.js 单处的漏改。

改动

src/inject.js:用 ?? 兜底,而不是直接替换成 data.message.content —— 这样 user 消息与旧的扁平形状都照旧可用。

-      const parts = event?.data?.content;
+      const parts = event?.data?.content ?? event?.data?.message?.content;

lib/inject.js 由 npm run sync 生成(本仓库约定:src/ 是唯一事实源,不手改 lib/);test/lib-smoke.test.js 的 src↔lib 逐文件一致性守卫通过。

测试

顺带修正了一处夹具错误(我认为这正是这个回归能溜过去的原因):

原用例 extracts hot rounds from snapshotEvents() when Session.events is absent 给 assistant/message 喂的是 data: { content: [...] } —— 与当时有 bug 的实现是同一个错误假设,所以它对这个回归永远是无感的。已改为真实形状:

-      { type: "assistant/message", data: { content: [{ type: "text", text: "用 viewBox 单位跑模拟" }] } }
+      { type: "assistant/message", data: { message: { content: [{ type: "text", text: "用 viewBox 单位跑模拟" }] } } }

新增两个用例:

  • Issue #129: response 取自 data.message.content,N 轮不再出现空 A —— issue 里的复现(两轮,断言四个片段都在)。
  • Issue #129: 扁平的 data.content 形状仍被兼容 —— 锁住 ?? 的向后兼容语义,防止将来被「简化」成直接替换。

验证

npm test
ℹ tests 814   ℹ pass 813   ℹ fail 0   ℹ skipped 1   ℹ duration_ms 11036

(Node v24.18.0 / npm 11.16.0;npm ci 后全新环境跑出。)

影响面

只改热记忆块的读取路径。textOf 仍是纯读取 + 容错(非数组即返回 ""),没有引入新的失败点,符合仓库「后台路径 fail-safe、不阻塞主流程」的约定。

Closes #129

Summary by CodeRabbit

  • Bug Fixes

    • Assistant and tool responses now display correctly when their content is stored in a nested message payload.
    • Existing message formats remain supported, preventing blank responses in previously compatible data.
  • Tests

    • Added coverage for nested assistant responses and continued support for the legacy flat content format.

…w-stack#129)

assistant/message(以及 tool/result)的消息体嵌在 data.message 下(DSH 侧由
@deepseek-ai/dsh-session 的 assertMessageEventShape 写死:type === "user/message"
? record : record?.["message"]),而 textOf 只读 event.data.content,于是热记忆块里
每一轮的 A 恒为空。

改用 ?? 兜底而不是直接替换:user 消息与旧的扁平形状都照旧可用。

同时修正一处测试夹具错误:原用例给 assistant 事件喂的是 data.content,与当时有 bug
的实现是同一个错误假设,因此永远抓不到这个回归;已改为真实形状,并补两个用例
(N 轮 A 不空 / 扁平形状仍兼容)。

npm test: 814 tests, 813 pass, 0 fail, 1 skipped.
@coderabbitai

coderabbitai Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 7b332fd8-2e92-4241-856a-f8bf420223e5

📥 Commits

Reviewing files that changed from the base of the PR and between 3b2b443 and 260482b.

📒 Files selected for processing (3)
  • dsh-mneme/lib/inject.js
  • dsh-mneme/src/inject.js
  • dsh-mneme/test/inject.test.js

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

extractRounds now reads assistant and tool content from data.message.content when needed. Existing flat data.content events remain supported. Tests cover nested multi-round responses and legacy flat messages.

Changes

Hot-memory content extraction

Layer / File(s) Summary
Content fallback implementation
dsh-mneme/src/inject.js, dsh-mneme/lib/inject.js
textOf reads data.content first and falls back to data.message.content.
Fallback regression coverage
dsh-mneme/test/inject.test.js
Tests cover nested assistant responses across multiple rounds and preserve support for flat assistant content.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: modusensus

Merge Risk: ⚪ Minimal · up to 26048

The hot-memory extraction now supports nested assistant content while retaining the legacy flat message shape, with regression coverage for both paths.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main fix: reading assistant message content from the nested data.message.content field. It also identifies the affected module and Issue #129.
Linked Issues check ✅ Passed PR #129 的编码要求已满足。src/inject.js 和同步生成的 lib/inject.js 使用 event?.data?.content ?? event?.data?.message?.content,因此支持 assistant 的嵌套正文、user 的 data.content 和旧扁平结构。Array.isArray 检查及空字符串返回逻辑保持不变,因此无…
Out of Scope Changes check ✅ Passed 变更均直接服务于 Issue #129。实现文件同步修改、测试夹具修正、回归测试新增,以及相关注释均围绕消息正文路径和兼容性展开。未发现无关功能或无关文件变更。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 3 files.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Sep 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@modusensus
modusensus merged commit 7c75690 into slow-stack:main Sep 11, 2026
6 checks passed
@modusensus

Copy link
Copy Markdown
Member

感谢精准的定位,尤其是把测试夹具里「与 bug 相同的错误假设」一并挖出来——这正是这个回归能溜过去的原因,这个修复质量很高。已 squash 合并进 main,将随下一版发布(Closes #129)。

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.

[hot-memory] 短期上下文里 A 恒为空:textOf 只读 data.content,漏了 assistant 的 data.message.content

2 participants