Skip to content

Agent conversations: build the sender's side from delivered messages so both threads always match #4788

Description

@brsbl

Summary

PR #4772 shows agent-to-agent conversations on both threads. The receiving thread renders each delivered message as "Message from " with its answer as "Reply to ". The sending thread renders "Message to " / "Reply from ", but it builds those chips by parsing bb thread tell commands in its own timeline. Any message delivered with that thread as sender that its agent did not send with a bb thread tell shell command appears on the receiver's side only, so the two timelines can disagree.

Proposal: build the sender's view from the receiver's records (every delivered message whose senderThreadId is this thread) instead of from command text. The two sides then match by construction.

Versions and environment

Steps to reproduce

With PR #4772 checked out and pnpm dev running, in a shell with the dev CLI (pnpm bb:dev):

  1. Create two threads, A ("Release manager") and B ("Calendar worker"), in the same project.
  2. Send B a message attributed to A without A's agent running a command:
    BB_THREAD_ID=<A> pnpm -s bb:dev thread tell <B> "Is the cache TTL the cause? One short sentence."
  3. Wait for B to answer, then open both threads in the app.

Also reproduces when A's agent sends with a form the parser doesn't recognize. Examples: an unusual shell wrapper, --message-file pointing at a file (the chip renders without text), or any SDK/API send that sets senderThreadId.

Expected vs actual

  • Expected: B shows "Message from A" + "Reply to A", and A shows the matching "Message to B" + "Reply from B".
  • Actual: B shows "Message from A" + "Reply to A". A shows nothing for that exchange. During QA for Tell agents to answer other agents with bb thread tell #4772, B showed 5 messages from A while A's timeline showed 1, the only one its agent had sent itself.

When A's agent does send with bb thread tell, both sides match. Verified with four agent-driven rounds: 4 sent, 4 received.

Evidence

Proposed approach

  1. Server: add a read route, with SDK and CLI parity per AGENTS.md, that returns messages delivered with senderThreadId = <thread>. Each entry carries the recipient thread, message text, request status, delivered-at time, the recipient turn id, and that turn's final assistant text once the turn settles. This likely needs an indexed sender column, or a small table written at send time, rather than JSON scans over thread_events.
  2. App: render the sender's "Message to" / "Reply from" chips from that route, placed in the sender's timeline by delivery time. Drop the command parsing and the text/time reply heuristic. The receiver side stays as in Tell agents to answer other agents with bb thread tell #4772.
  3. Decide: whether bb thread tell command rows stay visible in the sender's work summary once the chips no longer depend on them.

What I ruled out

Suggested priority and effort

Medium priority, medium effort. Agent-driven sends, the common case, already match after #4772. The mismatch hits manual or SDK sends and unusual command forms, and nothing is lost: the receiver still has the full record.

Related: #4772
BB-Thread-ID: thr_4u5mgu9qe7

AGENT GENERATED

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    threadsTurns, timeline, messaging, forksuiApp shell, sidebar, composer, rendering

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions