Skip to content

fix(engine): use user role for sub-agent completion runtime message#2057

Open
h3c-hexin wants to merge 1 commit into
Hmbown:mainfrom
h3c-hexin:fix/subagent-completion-user-role
Open

fix(engine): use user role for sub-agent completion runtime message#2057
h3c-hexin wants to merge 1 commit into
Hmbown:mainfrom
h3c-hexin:fix/subagent-completion-user-role

Conversation

@h3c-hexin
Copy link
Copy Markdown
Contributor

Problem

subagent_completion_runtime_message builds the sub-agent completion hand-off that gets appended into the parent turn with role: "system". That message is injected mid-conversation (not at the front).

Some OpenAI-compatible backends apply a strict chat template that requires any system message to be messages[0]. The clearest case is vLLM serving Qwen3 — its chat template raises:

System message must be at the beginning

vLLM returns this as a 400 BadRequest, which fails the request that carries the sub-agent result back to the parent. The whole sub-agent hand-off breaks on these backends.

Fix

Switch the role of this single internal runtime message from system to user.

The "this is an internal runtime event, not user input" framing is already carried by the visibility="internal" tag and the surrounding instruction text, so the role itself carries no semantic weight to the model here — it only determines chat-template placement. Using user keeps the message valid mid-conversation on strict templates while reading identically to lenient ones (Anthropic / OpenAI proper).

Scope

  • One-line behavior change in subagent_completion_runtime_message, plus a rationale comment.
  • Updates the colocated unit test (subagent_completion_handoff_is_internal_user_message) to pin the new role.
  • No trust-boundary surface touched (no auth / sandbox / publishing / prompts).

Test

cargo test -p codewhale-tui --bins subagent_completion_handoff

🤖 Generated with Claude Code

The sub-agent completion hand-off injected into the parent turn used
role "system". Some OpenAI-compatible backends apply a strict chat
template (e.g. vLLM serving Qwen3) that requires any system message to
be messages[0]; a system message appended mid-conversation makes the
template raise "System message must be at the beginning", returned as a
400 BadRequest that breaks the entire sub-agent hand-off in the parent
turn.

Switch the role to "user". The internal-event framing is already carried
by the `visibility="internal"` tag and the surrounding text, so the role
change costs no semantics — it only removes the template incompatibility.
Updates the colocated unit test to pin the new role.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request changes the role of subagent completion runtime messages from 'system' to 'user' in crates/tui/src/core/engine/turn_loop.rs. This modification addresses compatibility issues with OpenAI-compatible backends, such as vLLM serving Qwen3, which require system messages to be positioned at the start of a conversation. Corresponding unit tests were updated to reflect this change. I have no feedback to provide.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant