← Back to PRs

#11123: Fix webchat→external channel cross-delivery

by jingkang0822 open 2026-02-07 12:32 View on GitHub →
docs app: web-ui gateway stale
## Summary - Preserve external channel origin when webchat sends messages (prevent `deriveSessionOrigin` from overwriting `provider: "telegram"` with `provider: "webchat"`) - Forward user messages and assistant replies from webchat to the session's originating external channel (Telegram, Discord, Slack, etc.) via `routeReply` ## Problem When a user sends a message via webchat on a session that originated from an external channel (e.g., Telegram), the reply only appeared in webchat. The external channel never saw the message or reply, creating a conversation gap. ## Changes - **`src/config/sessions/metadata.ts`**: Early-return guard in `deriveSessionOrigin()` — returns `undefined` for webchat provider so `mergeOrigin()` preserves existing external origin - **`src/gateway/server-methods/chat.ts`**: Forward user message (with `[Control UI]` prefix) and assistant reply to external channel via fire-and-forget `routeReply()` with `mirror: false` ## Test plan - [ ] `pnpm build` passes - [ ] Open a Telegram session in webchat, send message → both `[Control UI] message` and assistant reply appear in Telegram - [ ] Webchat-only sessions (no external origin) are unaffected <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR preserves an existing external `SessionOrigin` when messages come from webchat, and adds cross-delivery in the `chat.send` gateway handler so Control UI messages and resulting assistant replies are forwarded to the session’s originating external channel via `routeReply(mirror: false)`. It also extracts JSONL transcript append logic into `src/config/sessions/transcript-raw.ts` and uses it for some non-agent and CLI paths. Key integration points are `deriveSessionOrigin()` (session metadata updates during dispatch), `chat.send` (webchat entrypoint that now routes to external origins), and the new raw transcript helpers shared between gateway and agent runner code. <h3>Confidence Score: 3/5</h3> - This PR is close to mergeable but has a few correctness/consistency issues around when forwarding triggers and transcript-writing consistency. - Core behavior change (preserving external origin + forwarding via routeReply) is straightforward, but current implementation risks unintended forwarding in non-webchat invocations of chat.send, silently drops transcript append failures in CLI runs, and duplicates transcript append logic in chat.inject, which can drift from the new shared helper. - src/gateway/server-methods/chat.ts, src/config/sessions/metadata.ts, src/auto-reply/reply/agent-runner-execution.ts <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> **Context used:** - Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8)) - Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13)) <!-- /greptile_comment -->

Most Similar PRs