fix(orchestrator): Skip blank subagent opening messages - #5456
Open
mwolson wants to merge 2 commits into
Open
Conversation
A provider-native subagent could open its child thread with an empty or whitespace-only user message, which renders as an empty bubble under the "Sent by another agent" label. The Claude adapter emitted the opening prompt whenever the subagent was new, and a task_progress frame can register a subagent before any frame carries its prompt, so the message was emitted with the "" default and never rewritten when the real prompt arrived on a later task_started. A shared hasSubagentPromptText guard now gates every subagent opening message. The Claude adapter emits it the first time the task prompt actually has text rather than on first registration, so a late prompt still opens the child thread exactly once. Codex's existing length check becomes trim-aware, and Cursor and ACP pick up the same guard.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Carried from another PR
fix(orchestration): Preserve Claude subagent attribution after settle—carried for #5388 claude-postsettle-attribution.
Review it there, not here.
fix(orchestrator): Skip blank subagent opening messages— this PR.Summary
whitespace-only user message under the "Sent by another agent" label.
Claude's opening message the first time the task prompt has real text rather
than on first registration.
t3code/codex-turn-mapping.Problem and Fix
promptis whitespace-only still produced a child user message. The Agent tool accepts it,task_startedcarries it, and the emission site had no emptiness guard, so the web timeline rendered an empty bubble.hasSubagentPromptTexttrims before deciding. EverymakeSubagentConversationArtifactscaller withrole: "user"goes through it (Claude, Codex, Cursor, ACP).task_progressframe can register a Claude subagent before any prompt-bearing frame. Registration fell back toprompt: input.prompt ?? "", and the opening message was tied to first registration, so it was emitted as""and never rewritten when a latertask_startedsupplied the real prompt.hasSubagentPromptText(task.prompt) && !hasSubagentPromptText(priorTask?.prompt), so a late prompt still opens the child exactly once and a prompt change from one non-empty value to another does not re-emit.input.prompt.length > 0, which still admits whitespace. Cursor and ACP had no guard.Validation
claude_subagent_empty_promptcovers both routes (whitespace Agent prompt andtask_progressbeforetask_started). Confirmed fail before the emission fix and pass after.OrchestratorReplayFixtures.integration/.contract,ClaudeReplayFixtures.integration,CodexReplayFixtures.integration): 89 tests, 1 skipped.SubagentProjection): 274 tests.vp check: passed.vp run typecheck: passed all 15 packages.prompt: " "and a child thread with no user message; a sibling ordinary-prompt child held exactly one:promptmessage. Zero trim-empty user-role projection messages in the isolated DB.Checklist
Note
Low Risk
Server-side projection-only change with a narrow guard; low risk to auth, data, or core runtime paths.
Overview
Subagent child threads no longer get an opening user message when the task prompt is empty or whitespace-only, avoiding empty “Sent by another agent” bubbles in the timeline.
A shared
hasSubagentPromptText(trim-aware) gatesmakeSubagentConversationArtifactsfor user-role opening messages across provider adapters. In this diff, ACP only emitsmessage.updated/turn_item.updatedfor the:promptitem whenupdate.prompthas real text after trim.Related adapter behavior (same PR): Claude defers the opening message until the first frame with non-empty prompt (not first registration); Codex drops a raw length check in favor of the shared helper; Cursor and ACP gain the same guard.
Reviewed by Cursor Bugbot for commit 0e1b4fe. Bugbot is set up for automated code reviews on this repo. Configure here.