Skip to content

fix(llm): 消息补 source 字段——严格 provider 下不再于序列化阶段抛 TypeError(#189) - #190

Merged
modusensus merged 1 commit into
slow-stack:mainfrom
heptaspirit:fix/llm-message-source
Sep 15, 2026
Merged

modusensus merged 1 commit into
slow-stack:mainfrom
heptaspirit:fix/llm-message-source

Conversation

@heptaspirit

@heptaspirit heptaspirit commented Sep 15, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #189

问题

dsh-llm 的消息契约要求每条消息带 source(lib/types/message.d.ts:119-129,注释原文「Required source fields supplied by the producer」)。mneme 手拼的 13 处 LLM 消息缺该字段;遇到会读 message.source.kind 的 provider 适配器(本机是 @mars-sea/[email protected] 的 messagesToCC)时,请求在序列化阶段同步抛 TypeError —— 0–8 ms 失败,且不发出任何网络请求。内置 dsh-llm-deepseek 从不读该字段,所以这个契约违背长期潜伏,只在更换 provider 时一次性暴露。

改动

按契约给这 13 处补 source: { kind: "plugin", plugin: "dsh-mneme" },不改 content 形状、不新增 import(peer 0.1.0-rc.8 未导出 createSystemMessage,用字面量才能同时兼容 rc.6 / rc.8 / 2.0.x):

  • dream.js ×2(consolidation / dream summary)
  • dream/sleep.js ×2(conflict / pattern)
  • entities/extractor.js ×1
  • summarize.js ×2(system 消息 + createUserMessage 调用)
  • api.js ×1(连接探测用的 system 消息)

system 消息也一并补上:当前只有 user 角色会被读取(commandcode 会跳过 role system,避免与 options.system 重复),但契约对所有消息生效,补上不留同类缺口。

验证

  • 新增 test/llm-message-source.test.js:4 个用例以严格桩驱动真实管线(dream / summarize / sleep / entity extraction),逐条断言 message.source.kind === "plugin"。
  • node --test --test-isolation=none test/*.test.js:全量 1 033/1 035(唯一失败是受限沙箱下的 spawn EPERM 环境限制,与本改动无关)。
  • npm run sync 后 scripts/check-sync.js 逐字节一致(37 文件)。
  • 应用内 A/B(0.8.1 + 本补丁):修前两管线 0–8 ms TypeError;修后 summarize success 8 450 / 14 240 / 11 337 ms,dream_consolidate success 90 104 ms + dream_summarize success 4 571 ms,dream_runs 由 failed, applied=0 变为 ok, applied=51,期间 121 条记忆被实际更新。

遗留

@mars-sea/dsh-commandcode-provider 那四处读法加可选链(message.source?.kind)即可挡下这类消息;该插件归其作者维护,不在本仓库范围。

Summary by CodeRabbit

  • 改进

    • 为插件发起的 AI 请求补充来源标识,便于准确区分和追踪由 dsh-mneme 产生的消息。
    • 该标识已覆盖连接测试、摘要、梦境处理、冲突分析、模式发现和实体提取等流程。
    • 请求内容、处理逻辑及生成结果保持不变。
  • 测试

    • 新增回归测试,验证相关 AI 请求均包含正确的插件来源信息。

)

dsh-llm 的消息契约要求每条消息带 source(lib/types/message.d.ts:119-129,
「Required source fields supplied by the producer」)。mneme 手拼的 13 处
LLM 消息缺该字段,遇到会读 message.source.kind 的 provider 适配器
(如 dsh-commandcode-provider 的 messagesToCC)时,请求在序列化阶段同步抛
TypeError —— 0–8ms 失败且不发出任何网络请求。内置 dsh-llm-deepseek 从不读
该字段,所以这个契约违背长期潜伏,只在更换 provider 时一次性暴露。

按契约补 source: { kind: "plugin", plugin: "dsh-mneme" },不改 content 形状、
不新增 import(peer 0.1.0-rc.8 未导出 createSystemMessage,用字面量才能同时
兼容 rc.6 / rc.8 / 2.0.x)。

覆盖 13 处:dream.js ×2(consolidation / dream summary)、dream/sleep.js ×2
(conflict / pattern)、entities/extractor.js、summarize.js(system 消息 +
createUserMessage 调用)、api.js(连接探测用的 system 消息)。

新增 test/llm-message-source.test.js:4 个用例以严格桩驱动真实管线
(dream / summarize / sleep / entity extraction),逐条断言
message.source.kind === "plugin"。
@coderabbitai

coderabbitai Bot commented Sep 15, 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 576111c7-0535-4cd6-86cb-57320d5d3a1e

📥 Commits

Reviewing files that changed from the base of the PR and between 00c67ea and 641aa67.

📒 Files selected for processing (11)
  • dsh-mneme/lib/api.js
  • dsh-mneme/lib/dream.js
  • dsh-mneme/lib/dream/sleep.js
  • dsh-mneme/lib/entities/extractor.js
  • dsh-mneme/lib/summarize.js
  • dsh-mneme/src/api.js
  • dsh-mneme/src/dream.js
  • dsh-mneme/src/dream/sleep.js
  • dsh-mneme/src/entities/extractor.js
  • dsh-mneme/src/summarize.js
  • dsh-mneme/test/llm-message-source.test.js

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

本次修改为 dsh-mneme 各条 LLM 调用管线的消息增加插件来源元数据,并新增回归测试验证 dream、summarize、sleep 和实体抽取流程。

Changes

LLM 消息来源标记

Layer / File(s) Summary
LLM 消息来源接入
dsh-mneme/src/*.js, dsh-mneme/src/dream/*.js, dsh-mneme/src/entities/*.js, dsh-mneme/lib/*.js
连接测试、dream、sleep、实体抽取和摘要消息均新增 source: { kind: "plugin", plugin: "dsh-mneme" }。消息角色、文本和处理流程保持不变。
来源元数据回归验证
dsh-mneme/test/llm-message-source.test.js
新增四组测试,严格检查各管线发送的消息包含 source.kind === "plugin",并验证相关 LLM 调用和结果。

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 641aa

The affected LLM request paths now provide the required source metadata, with regression coverage for the primary pipelines. No actionable merge risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 43.48% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 23 functions across 11 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了主要变更:为 LLM 消息补充 source 字段,并修复严格 provider 下序列化阶段的 TypeError。
Linked Issues check ✅ Passed PR 满足 #189 的编码要求。lib/ 和同步的 src/ 在 dream consolidation、dream summary、sleep conflict、sleep pattern、entity extraction、summarize 以及 API connectivity 的全部相关消息上加入 `source: { kind: "plugin", plugin: "dsh-…
Out of Scope Changes check ✅ Passed 变更均围绕 #189 的消息契约修复。代码只补充消息来源字段,并同步更新 src/ 与 lib/;新增测试直接验证四条相关 LLM 管线。未发现与该问题无关的功能、依赖或公共 API 变更。
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@codecov

codecov Bot commented Sep 15, 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 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复验通过,逐项核对:

契约与根因:@deepseek-ai/dsh-llm 的 lib/types/message.d.ts 对 Message.source 的注释原文确为 "Required source fields supplied by the producer"(必填);dsh-llm-deepseek 不读该字段所以官方路由长期不显现,第三方适配器一读就炸——报告的机制判断准确。

改动面:13 处手拼消息(dream ×4、sleep ×4、entity extraction ×2、summarize ×2、连接探测 ×1)全部补上 source: { kind: "plugin", plugin: "dsh-mneme" },src/lib 双侧同步,无 content 形状变化、无新增 import,兼容取舍(不引 createSystemMessage 以兼容 rc.6/rc.8)合理。

测试:test/llm-message-source.test.js 用严格桩驱动四条真实管线(dream / summarize / sleep / entity extraction)并逐消息断言 source.kind === "plugin"——不是空转测试,任何新增消息漏了 source 都会红。本地全量跑过:新用例 4/4,整体 1 034 pass + 1 环境跳过、0 fail,与 CI 矩阵一致。

A/B 数据:修前 0–8 ms 序列化阶段 TypeError vs 修后 summarize/dream 全 success、applied=51——指纹(毫秒级失败 = 请求根本没发出去)抓得很准。

后续两点记下了:@mars-sea/dsh-commandcode-provider 侧的可选链加固由报告者知会其作者(不在本仓范围);dsh-llm 的 forAdapter 裸读点属于宿主侧,我们会在宿主反馈线里提。感谢 @heptaspirit —— 报告、修复、回归测试、A/B 一条龙,这正是我们想要的贡献形态。

@modusensus
modusensus merged commit bea030e into slow-stack:main Sep 15, 2026
6 checks passed
modusensus added a commit that referenced this pull request Sep 16, 2026
实测 0.1.6-alpha.1 上 test-model 返回 502「INVALID_REQUEST: messages:
at least one message is required」:新适配器把 system 消息抽成顶层
参数后,探测此前发送的 system-only 单条消息成了零条对话,官方 API
整单拒绝。同一探测在 0.1.2-rc.1 时代(system 进 messages)一直正常。

探测改为一条 user 消息(保留 #189 的 source 标注)——user 在任何
适配器/校验下都是合法对话,不怕 host 侧继续演进。回归断言锁定
role=user + source.kind=plugin。

主链路无恙:dream/summarize/实体抽取本就发送 system+user,alpha 上
实测 dream_consolidate success(53.8s 真实运行)。

(叠在 #190 之上,先合 #190 再合本 PR。)
modusensus added a commit that referenced this pull request Sep 16, 2026
实测 0.1.6-alpha.1 上 test-model 返回 502「INVALID_REQUEST: messages:
at least one message is required」:新适配器把 system 消息抽成顶层
参数后,探测此前发送的 system-only 单条消息成了零条对话,官方 API
整单拒绝。同一探测在 0.1.2-rc.1 时代(system 进 messages)一直正常。

探测改为一条 user 消息(保留 #189 的 source 标注)——user 在任何
适配器/校验下都是合法对话,不怕 host 侧继续演进。回归断言锁定
role=user + source.kind=plugin。

主链路无恙:dream/summarize/实体抽取本就发送 system+user,alpha 上
实测 dream_consolidate success(53.8s 真实运行)。

(叠在 #190 之上,先合 #190 再合本 PR。)
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.

[Bug] LLM 消息缺 source 字段:严格 provider 下 dream/summarize 在序列化阶段抛 TypeError(0.8.1)

2 participants