CopilotKit / CopilotKit/outpost
Replace the one-response counter with a human-presence gate
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7
- Forks
- 3
- Avg merge
- 7d 16h
- Merged PRs (30d)
- 15
Description
#172 caps the bot at one AI response per ticket, ever. The stated intent was different: "a human owns the thread from the first response onward." Those are not the same rule, and the gap costs a real case.
The two rules, and where they differ
| Scenario | "Answer once, ever" (shipped) | "Stay out once a human speaks" (intended) |
|---|---|---|
| Maintainer posts the solution, bot would follow up | silent ✅ | silent ✅ |
| Maintainer asks the reporter a question | silent ✅ | silent ✅ |
| Reporter adds a stack trace 30s later, no human has replied | silent ❌ | answers ✅ |
The third row is the regression. The bot has spent its one turn on a question that was missing the detail that would have made the answer useful, and it cannot use the new detail. Nobody has been interrupted — there is no human in the thread yet — so the reason for staying quiet does not apply.
Why it shipped as a counter
The counter is a circuit breaker. It was the right call under time pressure: it is trivially verifiable, it cannot mis-fire, and it made both incidents impossible. A presence gate is the correct rule but has more moving parts, and getting it subtly wrong reintroduces public bot chatter.
Worth recording precisely because a hotfix can quietly become permanent product behaviour. In six months nobody will remember this started as a response to two Discord threads.
What a presence gate needs
The signal already exists. InboundHandler.isTeamMember resolves a platform user to a TeamMember via User.externalId + source → email, and it is still computed on every reply for status transitions. #172 removed it as a gate, and that removal was correct — it was pointed at the wrong question.
- Wrong question: "did a team member send this message?" That is what it answered before, which is why a third party's follow-up still got an AI reply.
- Right question: "has a team member spoken anywhere in this thread?" That is a property of the ticket, not of the message.
So the shape is roughly: on a reply, if any prior message on the ticket is from a team member, stay silent permanently; otherwise the AI may respond. That wants to live next to the existing re-answer gate in ai-response.ts rather than at the enqueue sites, since it depends on ticket history.
Open questions worth deciding rather than discovering
- Does a human reply from the dashboard count? It persists as
type: 'BOT',isAiGenerated: false, so it is distinguishable — but only if the check looks for it. - Should there be a cap anyway? A reporter who posts eight follow-ups before any human arrives could draw eight AI replies under a pure presence gate. A small ceiling, or a "no more than one response per N minutes" rule, may be wanted alongside.
- Does "a human spoke" include a third party? A community member answering another community member is common in our Discord and is arguably exactly when the bot should stop.
- Depends on the identity work in #173 — the model cannot currently tell these participants apart even when the gate can.
Decision owner
If "answer once, ever" is a deliberate product stance, say so and close this. If it was a hotfix, this issue is the path back.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in ai-response.ts, alongside the existing re-answer gate, and trace how InboundHandler.isTeamMember and ticket history are available. Resolve the listed questions, including dashboard replies, third-party messages, a remaining cap, and the dependency on #173; done means the agreed human-presence behavior is implemented without unwanted bot replies.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- ai, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100