CopilotKit / CopilotKit/outpost

Slack ticket mirror: reply-level dedup, surrogate-safe truncation, WebClient reuse

Open
#152 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

Follow-ups deliberately left open by #150 (the Slack ticket mirror). All three were raised by the CR rounds on that PR and verified; none blocks the mirror shipping inert.

1. A duplicate reply job re-posts its message

handleSlackMirror makes the TicketExternalLink row the idempotent identity of the thread, so two jobs can no longer open rival threads. It does not dedupe reply posts: if a reply job is retried after its postMessage succeeded (a job timeout that does not cancel the handler, a throw in reportProgress, a re-thrown transient error), the same message is posted into the thread again.

Fixing this needs a per-message marker — e.g. a mirroredAt column on Message, or a metadata entry on the link row keyed by message id — checked before posting. That is a schema decision, which is why it was not smuggled into #150.

packages/outpost/queue/src/handlers/slack-mirror.ts — the idempotency docblock states this limitation explicitly.

2. truncate splits surrogate pairs

value.slice(0, max - 1) can cut an astral character (emoji, many CJK extension chars) in half, producing a lone surrogate in the Slack payload. Use Array.from / Intl.Segmenter or a code-point-aware slice.

3. A new WebClient per job

buildPoster constructs a fresh @slack/web-api client on every job. At mirror volumes this is minor, but it discards connection reuse and the client's rate-limit state, which is precisely the state you want shared across posts. Cache one client per token.

Found by: CR rounds 1-2 on #150.

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 in packages/outpost/queue/src/handlers/slack-mirror.ts, reading the idempotency docblock and tracing handleSlackMirror, truncate, and buildPoster. Decide on the per-message marker described in the issue, then verify that retried replies are not reposted, truncation preserves surrogate pairs, and WebClient instances are reused per token.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.