Skip to Content
TroubleshootingAgents talk over each other

Two Agents Talk Over Each Other

Symptom

Two voices speak at the same time, or spoken updates interleave mid-sentence, when more than one agent is active against the same Autonomy session.

Why

Autonomy serializes spoken output through one speech queue per attached session — a single lock that each voiceover_transport_announce call acquires before speaking and holds for the real audio lifetime, not just an estimated duration. Overlap happens for one of two reasons:

  1. An agent bypassed the queue. Only voiceover_transport_announce acquires the session’s speech slot. speak_text, raw say, or osascript calls speak immediately, on top of whatever Autonomy is already saying.
  2. Agents aren’t identified. Without a registered agentId and spokenName, announcements fall back to a generic “Autonomy agent” prefix, so even correctly serialized speech is hard to attribute to the right agent — and it’s easy to assume two overlapping calls are a queue bug when they’re actually just unlabeled.

This was a real, fixed defect (tracked as autonomy-r0r23): the speech slot now spans the actual audio playback, and is released even if the requesting client disconnects mid-call, so a dropped connection can’t leave the lane stuck or let the next message speak over an unfinished one.

Keep agent-to-agent development coordination (build status, handoffs between coding agents) out of the user’s spoken accessibility lane entirely. That’s a separate channel’s job — the spoken lane is for the user, not for agents talking to each other.

Fix

Register each agent’s identity once per session, before it speaks

a7y-cli tools call voiceover_transport_session_policy \ --args '{"agentId":"claude","spokenName":"Claude"}'
a7y-cli tools call voiceover_transport_session_policy \ --args '{"agentId":"codex","spokenName":"Codex"}'

Announce through the same tool from every agent

Pass each agent’s own agentId so the response is attributed and serialized correctly:

a7y-cli tools call voiceover_transport_announce \ --args '{"message":"Tests passed.","agentId":"claude"}'

Leave queue at its default (true) — don’t disable it to “speed things up.” Disabling the queue is what reintroduces overlap.

Verify

Check the response’s action.speaker.spokenName and spokenPrefix — each agent’s messages should carry its own name (rendered as "<Name> says: …"), not the generic default. Fire two announcements back to back from different agents and confirm the second one’s speechQueue.mode reads serialized_session_queue and that it doesn’t start speaking until the first finishes, rather than interleaving.

If a single agent’s own updates are the ones going unheard rather than overlapping, see Spoken updates are not heard. If calls are being dropped outright rather than overlapping, see The daemon closes a request.

Last updated on