Skip to content

fix(slack-bot): stop intermediate agent narration leaking into final response#1672

Closed
cisco-erilutz wants to merge 1 commit into
prebuild/hotfix-cnoe-agent-utils-anthropic-bedrockfrom
fix/slack-bot-thinking-text-leak
Closed

fix(slack-bot): stop intermediate agent narration leaking into final response#1672
cisco-erilutz wants to merge 1 commit into
prebuild/hotfix-cnoe-agent-utils-anthropic-bedrockfrom
fix/slack-bot-thinking-text-leak

Conversation

@cisco-erilutz
Copy link
Copy Markdown
Collaborator

Summary

Stacked on top of #1609 (the Anthropic Bedrock client switch). That switch surfaced a latent bug in the Slack bot's response reconstruction: intermediate agent narration ("Now let me search…", "I notice the pagination is returning the same data…") leaks into the final Slack message body, in front of the real answer.

Root cause

The Slack bot rebuilds the final answer from the AG-UI SSE event stream (integrations/slack_bot/utils/ai.py), not from the AIMessage directly. The ChatBedrockConverseChatAnthropicBedrock change altered which intermediate text reaches the bot as TEXT_MESSAGE_CONTENT deltas — the Anthropic client emits per-step narration tokens that the converse path did not surface. That exposed two flaws:

  1. TEXT_MESSAGE_CONTENT arriving while a tool was active (stream already open in todo/plan mode) was streamed live via appendStream, so every narration segment was written straight into the message body.
  2. accumulated_text (which was never reset during a run) was used as a final-answer fallback, so the entire concatenated transcript could surface at finalization and on the RUN_ERROR recovery path.

Fix

  • Never stream text to the message body mid-run.
  • Text emitted while a tool is active is treated as discardable narration — it only feeds the typing indicator.
  • Text emitted when no tool is active is buffered and cleared on the next TOOL_CALL_START, so only the text after the last tool call (the real answer) is rendered at finalization.
  • Removed the accumulated_text buffer entirely; finalization and error recovery now use the single answer buffer.

Tests

  • Added a regression test for narration emitted while a tool is active (the previous between-tools test didn't cover that path).
  • Full integrations/slack_bot suite passes (179 tests).

🤖 Generated with Claude Code

…response

[GAI]

The Slack bot reconstructs the final answer from the AG-UI SSE event stream.
Two paths could leak intermediate "Let me…" narration into the message body
once the LLM client began emitting inter-step text deltas:

- TEXT_MESSAGE_CONTENT that arrived while a tool was active was streamed live
  via appendStream, so every narration segment was written to the body.
- accumulated_text (never reset) was used as a final-answer fallback, so it
  could surface the entire concatenated transcript at finalization and on the
  RUN_ERROR recovery path.

Now text is never streamed to the body mid-run. Text emitted while a tool is
active is treated as discardable narration (it only feeds the typing
indicator); text emitted when no tool is active is buffered and cleared on the
next tool start, so only the text after the last tool call — the real answer —
is rendered. The accumulated_text buffer is removed entirely; finalization and
error recovery both use that single buffer.

Add a regression test covering narration emitted while a tool is active (the
case the previous between-tools test did not exercise).
@cisco-erilutz
Copy link
Copy Markdown
Collaborator Author

Superseded by #1675 (moved to a prebuild/ branch so prebuild slack-bot images get published for testing). Same commit, same base.

@cisco-erilutz cisco-erilutz deleted the fix/slack-bot-thinking-text-leak branch June 1, 2026 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants