fix(notify): 回信地址的 path 位按「Agent 有工作目录、人没有」给 —— 用户从通知里看出的地址不一致
用户 2026-09-15 原话:「这个地址明显核心拼错了」。实情是**同一个地址有两种口径**: 插件印给模型看的(new_mail 的 reply_address):dsh@.鸿蒙客户端与-WebUI-界面对齐 ← 空 path suggest_address / 邮件表的 from_workspace: dsh@/home/program/agentmail.鸿蒙… ← 有 path 根因在 notify/mail.go:`reply_address` 的 path 位硬编码成空串,注释给的理由 ("path 的语义是发件人该在哪儿干活,而人没有工作目录")**只对人成立**。 发件方是 Agent 时,空 path 把它的工作目录丢了,而插件会把 reply_address 原样印给 模型、模型照它回信 —— 收信方的 path 位就空了,插件只能自己拼临时目录 (同一封信的每个参与方落在不同空目录里,正是"未分组"那类症状的源头)。 修:path 只看**发件身份**是不是人(repo.IsHumanUser),不是人就用会话工作目录 (repo.SessionWorkspaceOf),并沿用 forward.go 的同一条守卫:`path == 名字` 是历史脏数据(agent 名曾被当路径存过),丢弃。 判据(新增,两侧都写 + 变异验证过): - Agent 发件方 → reply_address 必须带 path; - 人发件方 → 必须**不**带(给人写工作目录是另一种错地址)。 两次变异(退回空串 / 不分人机都给)都必须变红,实测都红。 测试夹具踩了一个坑并记在注释里:attach 的闭包总从头扫、返回第一帧, 同一个客户端连收两封时会读到上一封 —— 所以新加了 attachLast 并对主题断言。
This commit is contained in:
@ -137,6 +137,29 @@ func Recipients(ctx context.Context, m Mail) {
|
||||
}
|
||||
}
|
||||
|
||||
// 回信地址的 path 位:**Agent 才有工作目录**。
|
||||
//
|
||||
// 原先这里硬编码空串,理由是「path 的语义是发件人该在哪儿干活,而人没有工作目录」。
|
||||
// 那个理由只对**人**成立 —— 发件方是 Agent 时,空 path 就把它的工作目录丢了,
|
||||
// 于是同一个地址出现两种口径:
|
||||
// 这里(插件印给模型看的回信地址):`dsh@.鸿蒙客户端与-WebUI-界面对齐`
|
||||
// suggest_address / 邮件表的 from_workspace:`dsh@/home/program/agentmail.鸿蒙…`
|
||||
//
|
||||
// 2026-09-15 用户直接从通知里看出了不对(「这个地址明显核心拼错了」)。
|
||||
// 后果不只是难看:插件把 reply_address 原样印给模型,模型照它回信时,
|
||||
// 收信方的 path 位就空了 —— 而 path 是「去哪个目录干活」的唯一提示,
|
||||
// 插件只能自己拼临时目录(同一封邮件的每一方都落在不同空目录里)。
|
||||
//
|
||||
// 人的地址保持无 path(那是「人没有工作目录」的正确表达)。
|
||||
replyPath := ""
|
||||
if human, err := repo.IsHumanUser(ctx, replyTo); err == nil && !human {
|
||||
replyPath = repo.SessionWorkspaceOf(ctx, m.SessionID)
|
||||
if replyPath == replyTo {
|
||||
// 历史脏数据:Agent 名曾被当成路径存下来,那不是地址(同 forward.go 的 senderAddress)
|
||||
replyPath = ""
|
||||
}
|
||||
}
|
||||
|
||||
payload := func(role, workspace, forName string) map[string]interface{} {
|
||||
p := map[string]interface{}{
|
||||
"mail_id": m.MailID.String(),
|
||||
@ -160,7 +183,7 @@ func Recipients(ctx context.Context, m Mail) {
|
||||
// 地址里没有 path 不会丢工作目录 —— 收信方回信时,发信端会用
|
||||
// `sessions.workspace` 把它补齐(见 handler/mail.go 的“收件方是
|
||||
// Agent 且地址里没写 path”那段),所以这里不必也不应该自己填。
|
||||
"reply_address": models.FormatAddress(replyTo, "", alias),
|
||||
"reply_address": models.FormatAddress(replyTo, replyPath, alias),
|
||||
// self_address 是对方应当用来称呼自己的地址,供转发/报告时引用。
|
||||
"self_address": models.FormatAddress(forName, workspace, alias),
|
||||
// platform_session_id 非空时,这封邮件要投进**平台侧已经存在的
|
||||
|
||||
Reference in New Issue
Block a user