Skip to content

slack: light working pill immediately when a Slack human relays a prompt#85

Merged
rogeriochaves merged 1 commit into
mainfrom
fix/slack-pill-on-relay
Jun 6, 2026
Merged

slack: light working pill immediately when a Slack human relays a prompt#85
rogeriochaves merged 1 commit into
mainfrom
fix/slack-pill-on-relay

Conversation

@rogeriochaves
Copy link
Copy Markdown
Contributor

Summary

  • Posts a single eyes emoji as a minimal bot-authored anchor in the agent's channel right after the bridge pastes a relayed Slack-human prompt into tmux, and lights assistant.threads.setStatus on that post.
  • Without this anchor the channel looks dead for the 10-20s gap between the human typing and the agent's first text post — that text post is what the existing rollout-tail flow uses as the natural pill anchor, so there is no signal in between.
  • Slack's setStatus only accepts thread roots authored by the app itself (invalid_thread_ts on user-channel ts, see slack-setstatus-app-authored-threads-only memory from the earlier revert), so pinning the pill to the human's own message is not viable. The single-emoji anchor is the lowest-noise placeholder that still gives setStatus something valid to attach to.
  • The agent's first real text post supersedes the anchor as the new thread root in the existing post loop, so tool calls accumulated in the interim drain under the eyes anchor and the pill moves onto the narrative reply.

Test plan

  • All 242 existing CLI tests pass.
  • On the box, after relaunching agents-slack-bridge.service on this branch: typing a prompt in any agent channel surfaces an eyes-emoji bot post + working pill within a second, and the pill moves onto the agent's first real text post when it lands.
  • No invalid_thread_ts errors in journalctl -u agents-slack-bridge.service.

…a prompt

The bridge already suppresses the daemon's UserPromptSubmit echo for
Slack-relayed prompts (they're already in the channel as the human's
message), which leaves nothing bot-authored for assistant.threads.setStatus
to attach to. Result: the channel looks dead for the 10-20s between the
human typing and the agent's first text post, which is the natural pill
anchor for the existing rollout-tail flow.

Post a single eyes emoji as a minimal bot-authored anchor right after we
paste into tmux, then setStatus the working pill onto it. The agent's
first real text post lands as a new thread root via the existing post
loop, draining any accumulated tool calls under the eyes and moving the
pill onto the narrative reply — same shape as the existing scheduled-nudge
path.

setStatus only works on app-authored thread roots (Slack rejects
event.ts of a user-channel message with invalid_thread_ts), so pinning the
pill directly to the human's own message is not an option. The single-
emoji anchor is the lowest-noise placeholder that still gives the pill
something valid to anchor to.
@rogeriochaves rogeriochaves merged commit a5d9426 into main Jun 6, 2026
1 check passed
rogeriochaves added a commit that referenced this pull request Jun 7, 2026
… reply

Bringing back the eyes anchor that PR #85 introduced and PR #87 dropped,
with the missing half: the ack message gets deleted from the channel the
moment the agent posts its first real reply. So the channel sees a
visible "received, working" beat in the 10-20s gap before the agent
replies, and the ack disappears as soon as the reply lands — no
persistent "👀" sitting under every relayed prompt forever.

Mechanics:
- The bridge posts "👀" as a bot message right after pasteTmuxPrompt and
  anchors the working pill on it via assistant.threads.setStatus.
- The ts is persisted to ~/.kanban-code/eyes-anchors/<slug> via
  eyes-anchor.ts (same atomic write pattern as active-pill /
  thread-root). A bridge restart in the gap between the ack and the
  agent's first reply still finds the record and finishes the cleanup
  on the next text post (or on the restore-time turn-ended check).
- The agent->slack post loop calls consumePendingEyes(slug) BEFORE
  posting any text reply, so the eyes message is gone in Slack by the
  time the human sees the new reply land — no flicker.
- Restore-time pill drop (the previous commit) also calls
  consumePendingEyes so a turn that ended without ever producing text
  doesn't orphan an eyes message in the channel.

Adds SlackClient.deleteMessage as a thin wrapper around chat.delete
(scope chat:write is already on the bot). 5 unit tests cover the
eyes-anchor persistence contract.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant