CopilotKit / CopilotKit/outpost

Orphaned-reply handling is Teams-only

Open
#177 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area: integrations roadmap roadmap: next
Dominant language
TypeScript
Stars
7
Forks
3
Avg merge
7d 16h
Merged PRs (30d)
15

Description

InboundHandler.handleReply has a fallback: when a reply arrives and no ticket matches its thread, it creates a ticket and persists the message — but never answers it. The reasoning is that dropping a customer's words is worse than filing an oddly-titled ticket a human can pick up.

That reasoning is written as a general principle. In practice only one platform reaches it.

Platform Behaviour on an untracked reply
Teams reaches the fallback — ticket filed, no AI answer
Discord events/message-create.ts returns early when no ticket matches — message dropped
Slack events/message.ts pre-filters untracked replies — message dropped
GitHub webhooks/issue-comment.ts returns when no ticket matches — comment dropped. Never uses InboundHandler at all
Email honours the principle, but implements it locally in postmark/route.ts rather than through the shared handler

So a customer message that arrives without a matching ticket is preserved on Teams and email, and silently discarded on Discord, Slack and GitHub.

Why it matters

The discard cases are not hypothetical. Any thread that predates Outpost's deployment in a channel has no ticket, so every reply in it is dropped. Same for a thread whose ticket was deleted, and for a reply that arrives before its own thread-create event.

Nobody notices, because dropping is silent by construction — there is no error, no ticket, and no log the team watches.

The decision

Three defensible answers, and it is a product call:

  1. Unify on preserve. Remove the pre-filters so every platform files the ticket. Costs: some noise from threads Outpost was never meant to see, and each ticket is titled with a mid-conversation fragment.
  2. Unify on drop. Remove the fallback and accept that an untracked reply is not ours. Simpler, and arguably correct if channels are deliberately scoped — but it loses real customer messages.
  3. Keep the split deliberately, on the grounds that Teams and email are lower-volume and higher-value than a public Discord. That is a legitimate position; it just needs to be stated rather than inherited from whoever wrote each pre-filter first.

The current comment in platforms/inbound.ts documents which platforms reach the branch, so the code is at least honest. This issue is about picking one.

Related: #174 (human-presence gate) touches the same code path and may change what "should we answer this" means.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with platforms/inbound.ts and trace InboundHandler.handleReply alongside events/message-create.ts, events/message.ts, webhooks/issue-comment.ts, and postmark/route.ts. First resolve which untracked-reply behavior is intended, considering related issue #174; done means the chosen policy is implemented consistently and covered for each listed platform.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.