fix(session-group): 非文本种子开的群转发原消息并补上 AI 命名 - #1379
Open
deepcoldy wants to merge 1 commit into
Open
Conversation
私聊 group 模式下,用「合并转发消息集合 / 图片 / 文件」开的会话群会停在占位名 「新会话」,群里只留一条「(非文本消息)」,看不出这个群是怎么来的。 根因:出生流程的标题来源是 extractMessageTextForRouting 这个文本窥视,它只认 text/post,非文本种子拿到空串。而 scheduleSessionGroupTitle 的空串拦截在**异步体 内**——同步闸已经把这次尝试登记掉了,于是空调用白烧一轮有限重试(共 3 轮)并挂上 30s 退避,群就再也改不了名。 改动: - 出生侧只在窥视真拿到文本时才调度 AI 命名,并用 RoutingContext.sessionGroupTitleScheduled 告知下游;非文本种子改由递归回来的 handleNewTopic 在**消息完整解析之后**调度 (合并转发已展开成 <forwarded_messages>、语音已转写),标题直接从转发内容里总结。 两处严格二选一,避免重复调用再烧一轮重试。 - 新增 forwardMessage(im.v1.message.forward,注意 uuid 在 params 而非 data), 出生时把原私聊消息转发进新群当第一条消息:图片/文件/合并转发没法从事件里复刻, 只有转发能原样带过去。转发件由 bot 自己发出,回声是自发消息,dispatcher 只放行 /close,不会二次触发会话。 - 引言相应简化为一行「原消息已转发到本群」;转发被关掉或失败时回落到旧的正文摘录形态。 - 回复锚点回落链 intro → forwarded,保证始终指向群内消息(会话 rootMessageId / 首轮引用都取这个 id),两者都失败才退化到私聊。 - 新增 sessionGroup.forwardOrigin 开关(默认开)。 Co-Authored-By: Claude Code <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
私聊
p2pMode='group'下,用合并转发的飞书消息集合(以及图片 / 文件等任何非文本消息)开的会话群有两个毛病:根因
出生流程(
maybeBirthSessionGroup)的标题来源是extractMessageTextForRouting,那是个只认text/post的文本窥视,图片 / 文件 / 合并转发在那里一律返回null→ 占位名回落「新会话」、引言回落「(非文本消息)」、scheduleSessionGroupTitle({ userText: '' })。关键在于空串调度不是无害的 no-op:
scheduleSessionGroupTitle的同步闸(in-flight / 重试预算)先把这次尝试登记掉,if (!userText.trim()) return;才在异步体内生效,finally里还会markSessionGroupTitleFailed。于是这一次空调用白烧掉 3 轮有限重试中的一轮并挂上 30s 退避——这正是「转发消息集合开的群从不改名」的直接原因。改了什么
① AI 命名挪到「消息完整解析之后」(非文本种子)
RoutingContext.sessionGroupTitleScheduled告诉下游「已经调过了」;handleNewTopicAdmitted调度——那时parsed.content已经是完整内容(合并转发已展开成<forwarded_messages>、语音已转写),标题直接从转发进来的对话本身总结,比从空串猜强得多;titled/ in-flight 闸在异步体内,出生侧刚发起的那次此刻两者都还没置上,重复调用只会再白烧一轮。② 把原私聊消息转发进新群当第一条消息
forwardMessage()(im.v1.message.forward)。uuid在params里而不是data,与 create / reply 不同,已在 transport boundary 用例里按精确形状断言住;/close,不会二次触发会话;intro → forwarded,保证始终指向群内消息(会话rootMessageId/ 首轮引用都取这个 id),两者都失败才退化到私聊;sessionGroup.forwardOrigin开关,默认开,置false即回到只发引言的旧形态。影响面
src/im/lark/client.ts只新增forwardMessage,未改任何既有原语;RoutingContext只新增一个可选字段;SessionGroupConfig新增一个可选 key(与既有dmReceipt同级,同样无需 dashboard / 文档联动)。p2pMode='group'的会话群出生这一条路径。普通话题会话、solo 群会话、adopt/restore 完全不经过这里;p2pMode非 group 的私聊不受影响。ctx.messageId仍指向原私聊消息(资源下载 / 合并转发子消息的 key 依赖它)等既有不变量均未改动。测试验证
新增
test/session-group-birth-forward-seed.test.ts(8 例,跑真实的建群递归,只替身飞书外部副作用):覆盖:合并转发种子会被转发 + 引言不再是「(非文本消息)」;AI 命名恰好调度一次且
userText是展开后的<forwarded_messages>;占位名仍是「新会话」且titled未置;转发失败 → 引言回落且锚点走 intro;引言失败 → 锚点走转发件(不是私聊消息 id);文本种子对照组仍在出生侧调度一次;forwardOrigin: false时不转发但命名照常。相关既有套件 + 边界:
全量:
这 12 个失败与本改动无关,已逐一证实:
daemon-pinned-working-dir、group-join-shared-routing、doc-comment-audit-gate、doc-comment-daemon-concurrency)单独重跑全绿(4 passed / 69 tests passed),是全量并发下的资源争用抖动;e636f93cb,未带本 PR 任何改动)上跑,失败文件与失败数逐条一致:原因两类:① 本机 bun 是 1.4.0、仓库钉 1.4.2(用例里直接断言
expected '1.4.0' to be '1.4.2'),影响两个 sqlite 套件;② 其余依赖 user namespace / bwrap 等沙箱能力。Live 验证未做(会切走全局 shim 影响所有 bot),本改动的外部副作用只有一次
im.v1.message.forward调用,已在 transport boundary 用例里按精确请求形状断言。🤖 Generated with Claude Code