出站 Session 鏡像重構(Issue #1520)

狀態

  • 進行中。
  • 核心 + 外掛頻道路由已針對出站鏡像更新。
  • Gateway send 現在在省略 sessionKey 時推導目標 session。

背景

出站傳送原本鏡像至_當前_代理 session(工具 session key)而非目標頻道 session。入站路由使用頻道/peer session key,因此出站回應落在錯誤的 session 中,而首次聯繫的目標通常缺少 session 項目。

目標

  • 將出站訊息鏡像至目標頻道 session key。
  • 缺少時在出站時建立 session 項目。
  • 保持執行緒/主題範圍與入站 session key 一致。
  • 涵蓋核心頻道加上內建擴充套件。

實作摘要

  • 新的出站 session 路由輔助:
    • src/infra/outbound/outbound-session.ts
    • resolveOutboundSessionRoute 使用 buildAgentSessionKey(dmScope + identityLinks)建構目標 sessionKey。
    • ensureOutboundSessionEntry 透過 recordSessionMetaFromInbound 寫入最小化的 MsgContext
  • runMessageAction(send)推導目標 sessionKey 並傳遞至 executeSendAction 用於鏡像。
  • message-tool 不再直接鏡像;它僅從當前 session key 解析 agentId。
  • 外掛 send 路徑使用推導的 sessionKey 透過 appendAssistantMessageToSessionTranscript 鏡像。
  • Gateway send 在未提供 sessionKey 時推導目標 session key(預設代理),並確保 session 項目存在。

執行緒/主題處理

  • Slack:replyTo/threadId -> resolveThreadSessionKeys(後綴)。
  • Discord:threadId/replyTo -> resolveThreadSessionKeys 搭配 useSuffix=false 以匹配入站(執行緒頻道 id 已限定 session)。
  • Telegram:主題 ID 透過 buildTelegramGroupPeerId 對應至 chatId:topic:<id>

涵蓋的擴充套件

  • Matrix、MS Teams、Mattermost、BlueBubbles、Nextcloud Talk、Zalo、Zalo Personal、Nostr、Tlon。
  • 說明:
    • Mattermost 目標現在去除 @ 用於 DM session key 路由。
    • Zalo Personal 對 1:1 目標使用 DM peer 類型(僅 group: 存在時才為群組)。
    • BlueBubbles 群組目標去除 chat_* 前綴以匹配入站 session key。
    • Slack 自動執行緒鏡像以不區分大小寫方式匹配頻道 id。
    • Gateway send 在鏡像前將提供的 session key 轉為小寫。

決策

  • Gateway send session 推導:若提供 sessionKey 則使用它。若省略,從目標 + 預設代理推導 sessionKey 並鏡像至那裡。
  • Session 項目建立:一律使用 recordSessionMetaFromInbound 搭配與入站格式一致的 Provider/From/To/ChatType/AccountId/Originating*
  • 目標正規化:出站路由在可用時使用已解析的目標(resolveChannelTarget 後)。
  • Session key 大小寫:在寫入和遷移期間將 session key 正規化為小寫。

新增/更新的測試

  • src/infra/outbound/outbound.test.ts
    • Slack 執行緒 session key。
    • Telegram 主題 session key。
    • dmScope identityLinks 搭配 Discord。
  • src/agents/tools/message-tool.test.ts
    • 從 session key 推導 agentId(不傳遞 sessionKey)。
  • src/gateway/server-methods/send.test.ts
    • 省略時推導 session key 並建立 session 項目。

開放項目 / 後續

  • 語音通話外掛使用自訂 voice:<phone> session key。出站對應未在此標準化;若 message-tool 應支援語音通話傳送,需新增明確的對應。
  • 確認是否有外部外掛使用內建集合以外的非標準 From/To 格式。

觸及的檔案

  • src/infra/outbound/outbound-session.ts
  • src/infra/outbound/outbound-send-service.ts
  • src/infra/outbound/message-action-runner.ts
  • src/agents/tools/message-tool.ts
  • src/gateway/server-methods/send.ts
  • 測試:
    • src/infra/outbound/outbound.test.ts
    • src/agents/tools/message-tool.test.ts
    • src/gateway/server-methods/send.test.ts