Skip to content

slack bridge: attribute inbound human messages with the sender's name#141

Merged
langwatch-agent merged 1 commit into
mainfrom
ai-pulse/slack-inbound-author
Jul 9, 2026
Merged

slack bridge: attribute inbound human messages with the sender's name#141
langwatch-agent merged 1 commit into
mainfrom
ai-pulse/slack-inbound-author

Conversation

@langwatch-agent

Copy link
Copy Markdown
Contributor

Problem

When a person types in an agent's Slack channel, the bridge relays the text into the agent's tmux session with no author attached, so the agent cannot tell who is steering it. Agent-to-agent posts happen to self-label with a From <Agent>: line (a convention in each agent's prompt), and bot posts are dropped upstream, so only human messages hit this gap, and they are exactly the ones with no attribution. The Slack sender id was already on the event; it was just never surfaced.

This came up when an agent could not tell whether it was talking to one teammate or another, and defaulted to a stale identity from its environment.

Fix

  • routeSlackMessage carries event.user on the deliver decision (kept pure; the id just passes through).
  • SlackClient.resolveUserName resolves the id to a display name via users.info. users:read is already in the app manifest, so no scope change is needed.
  • The bridge caches the name per user id and prefixes the relayed prompt with From <name> (Slack): before pasting. If the lookup fails, it falls back to the unprefixed text, so delivery is never blocked.

Only human messages reach this path (bot posts are ignored before it), so an agent's own From <Agent>: line is never double-labeled.

Tests

  • New unit coverage: routeSlackMessage carries the sender id, and prefixAuthor labels a message / no-ops when no name resolves.
  • Full non-e2e suite green (273/273). tsc --noEmit clean.
  • The e2e-tmux real-tmux tests fail in this sandbox (2/4), but they fail identically on a pristine checkout of main with no changes, they drive the kanban send broadcast path this PR does not touch, and their own comment notes they need interactive tmux rendering. Unrelated to this change.

🤖 Generated with Claude Code

Human messages relayed from Slack into an agent's tmux session arrived with
no author, so the agent could not tell who was steering it (agent-to-agent
posts self-label with a "From <Agent>:" line, but a person typing in the
channel does not, and bot posts are dropped before this path). The Slack
sender id was available on the event but never surfaced.

- routeSlackMessage now carries event.user on the deliver decision.
- SlackClient.resolveUserName looks up a display name (users:read is already
  in the app manifest); the bridge caches it per user id.
- The bridge prefixes the relayed prompt with "From <name> (Slack):" before
  pasting it, falling back to the unprefixed text if the lookup fails.

Only human messages reach this path, so an agent's own "From <Agent>:" line is
never double-labeled. Added unit coverage for the carried sender id and the
prefix helper.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@langwatch-agent langwatch-agent added the ai-pulse Opened by the ai-pulse agent (shared langwatch-agent bot identity) label Jul 8, 2026

@drewdrewthis drewdrewthis left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@langwatch-agent langwatch-agent merged commit 1927029 into main Jul 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-pulse Opened by the ai-pulse agent (shared langwatch-agent bot identity)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants