fix(messaging): preserve conversation channel in agent replies

Agents always replied with channel="direct" regardless of the original
message's channel, creating new DM conversations instead of replying
in the existing group chat (department/company/project/incident).

Root cause: three layers of the system guided agents toward direct-only
replies:
1. Prompt instructions (wake-reasons, IC/manager operating instructions)
   hardcoded channel="direct" and toAgentId=fromAgentId for all replies
2. Standup API omitted toAgentId from unread messages, removing context
   about who the original message was addressed to
3. Inbox projection contained no reply-routing metadata, so the agent's
   LLM had no signal about which channel to respond in

Fixes:
- routes-agents-standup.ts: include toAgentId in unread message payload
- wake-reasons/en.ts: differentiate direct vs group channel reply format
- operating-en.ts: same channel-preserving guidance for IC and manager
- inbox-projection.ts: embed reply-to routing context in message header
  so the LLM sees channel + target alongside the message body
This commit is contained in:
ZacharyZhang-NY committed 2026-04-29 20:25:18 -04:00
1 parent 1e36259c5d
commit b3da6dbf8a
4 files changed
+12 -8

No files matched your search

+5 -2
View File
@@ -83,9 +83,12 @@ export function projectInboxMessageToPi(
): AgentMessage {
const senderLabel = resolveSenderLabel(record, directory);
const channelLabel = formatChannelLabel(record);
const replyContext = record.channel === "direct"
? `reply-to: channel=direct, toAgentId=${record.fromAgentId}`
: `reply-to: channel=${record.channel}, channelTargetId=${record.channelTargetId ?? ""}`;
const header = channelLabel
? `[Message from ${senderLabel} · ${channelLabel}]`
: `[Message from ${senderLabel}]`;
? `[Message from ${senderLabel} · ${channelLabel} | ${replyContext}]`
: `[Message from ${senderLabel} | ${replyContext}]`;
const subject = record.subject ? truncate(cleanText(record.subject), MAX_SUBJECT_LENGTH) : "";
const body = truncate(cleanText(record.body), MAX_MESSAGE_BODY_LENGTH);