Skip to content

A burst of messages opens one turn per message; there is no receive buffer #642

Closed

Description

@hsliuustc0106

Summary

Sending several short messages in a row opens one turn per message. The user types "把这个改一下", then "还有那个", then "顺便看下日志" within a few seconds and the Bot treats them as three separate tasks: it starts on the first, then the next message becomes a second queued turn, and the work restarts or is done twice. There is no receive buffer that collects a burst and hands it to the Bot as one turn.

The pending items are visible in the composer (one card per message, with trash/send), so the queue exists — it just does not coalesce.

What happens today

  1. Each message from the user (or from another Bot) is delivered as its own turn when the agent is idle, or queued as its own item when it is busy.
  2. Consecutive messages from the same sender have no debounce or merge window, so a typical "type two or three short lines" interaction costs two or three turns.
  3. When the agent is working, a second message is read at the next step boundary and a third one after that; the agent has to re-read and reconcile partial instructions.
  4. Bot-to-bot reports have the same shape and a separate issue (Bot-to-bot reports duplicate and pile up because cross-line delivery only goes through the parent chain #641) for duplication; this issue is about the missing buffer for a burst of messages, human or Bot.

Observed in this session (2026-10-21): several short user messages ("haole", "reorg一下", "这个是为什么") each opened a turn; a bot report was delivered twice while a turn was running.

Expected behaviour

  • A short receive window (e.g. 2-5 s) merges consecutive messages from the same sender into one turn, in order, with no loss.
  • While a turn is running, messages from one sender are collected and handed over together at the next boundary rather than one per boundary.
  • The queue shows the merged batch ("3 messages from the user → send together"), so the human can see what will be handed over.
  • Mixed senders are not merged into one turn; a human message must not be merged with a Bot report.

Options

A. Harness-side coalescing. In the turn queue, hold a new message for a short window when the agent is idle; merge with any message that arrives in that window from the same sender. When busy, merge same-sender messages at the step boundary.

B. Client-side debounce. The composer holds the send for the window while the user keeps typing; explicit send flushes immediately.

C. Manual batch. The queue groups pending items from one sender and offers "send all as one turn".

A is the honest fix; B alone does not help when messages come from Bots or from a different client. C is a useful complement for the queue UI.

Where

  • turn/delivery queue in the harness (turn start / step boundary)
  • core/src/host/turns.js — the Bot-side turn handling
  • core/src/client/ — composer and pending-item rendering

Acceptance

  • Three messages sent within the window from the same sender produce one turn whose input contains all three, in order.
  • No message is dropped, and an explicit "send now" bypasses the window.
  • Messages from different senders never end up in the same turn.
  • A burst sent while the agent is busy costs one turn, not one per message.

Gap with Grok Bot

This is the main behavioural gap noticed against Grok Bot: Grok Bot collects a burst of messages and handles them as one unit, while the Bot here opens a turn per message. The reference behaviour (window length, how a batch is shown before sending, how a busy agent receives it) should be pinned down before implementing, and used as the acceptance baseline.

Activity

  1. Birfy commented on Oct 22, 2026

    @Birfy
    Collaborator

    Triaged: the problem is clear, the wanted behaviour is not. Three answers and this becomes agent-ready.

    1. Window: how long is a burst — 1 s, 3 s, 5 s? And does it apply to Bot-to-Bot messages too, or only to the user's own messages?
    2. Shape: when messages coalesce, does the Bot see one merged message with each line's sender labelled, or only the newest with the earlier ones quoted under it?
    3. Acknowledgment: does a coalesced turn need one visible note ("read 3 messages as one"), or should nothing change in the chat?

    Acceptance I would write once answered: N messages inside the window produce one turn whose content contains all N lines in order, asserted in the bench; and a message arriving after the window still makes its own turn.

    Written-by: Triage

  2. added
    needs-infoWaiting for the reporter or a maintainer decision
    on Oct 22, 2026
  3. Birfy commented on Oct 22, 2026

    @Birfy
    Collaborator

    Design decision (owner, 2026-10-22: decide the design in the issue instead of asking). agent-ready, build exactly this.

    1. Window: 1500 ms, user messages only. Bot-to-Bot traffic already has its own queue and its own dedupe (Bot-to-bot reports duplicate and pile up because cross-line delivery only goes through the parent chain #641); a Bot must not delay another Bot's work behind a timer.
    2. Shape: one turn, all lines in order. The coalesced turn carries every line of the burst, in the order typed, each on its own line. No sender labels are needed for a single user, and no "read 3 messages as one" notice is shown in the chat — the composer cards already disappeared, and an extra notice is noise.
    3. Mechanism: one settle timer per Session. When a user message arrives and no turn is running, start a 1500 ms timer; every further user message in the window joins the pending text; when it fires, open one turn with the joined text. A message arriving while a turn is running still queues as its own item (that is a different problem and not this issue).
    4. Ordering is preserved, not sorted. The joined text is the lines as they arrived; if one arrives out of order the user's own order wins.

    Acceptance (bench, deterministic clock):

    • three messages 300 ms apart → one turn whose text contains all three lines in order;
    • a fourth message 2 s after the first → its own turn (two turns total);
    • one message alone → its own turn, unchanged, after the settle window;
    • a Bot-to-Bot message in the middle of a user burst is not held by the timer.

    Red without the change: the first case makes three turns (3 != 1).

    Scope: the host's delivery path (core/src/host/delivery.js / the queue that opens turns) + tests; no client change, no new setting, no i18n string.

    Written-by: Triage

  4. added
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    and removed
    needs-infoWaiting for the reporter or a maintainer decision
    questionFurther information is requested
    on Oct 22, 2026
  5. Birfy commented on Oct 22, 2026

    @Birfy
    Collaborator

    Claimed. Branch: feat/642-settle-window. Scope: host delivery path only (core/src/host/channel.js settle timer plus tests); no client change, no new setting, no i18n. Will implement the owner's design decision verbatim: 1500 ms window, user messages only, one turn per Session with all lines in arrival order, no labels and no notice, and a message arriving while a turn is running still queues on its own.

  6. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    agent-prPull request opened by an agent
    and removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 22, 2026
  7. removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    agent-prPull request opened by an agent
    on Oct 22, 2026
  8. added 2 commits that reference this issue on Oct 23, 2026
    a41f860
    f4e75d5
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

    area:automationScheduled tasks and automationenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions