Python: preserve message roles in ClaudeAgent._format_prompt - #7895
Open
Praveen Kumar Mittal (mittalpk) wants to merge 1 commit into
Open
Python: preserve message roles in ClaudeAgent._format_prompt#7895Praveen Kumar Mittal (mittalpk) wants to merge 1 commit into
Praveen Kumar Mittal (mittalpk) wants to merge 1 commit into
Conversation
_format_prompt() joined every message's text with no role information, so in multi-agent orchestration (SequentialBuilder/ConcurrentBuilder) Claude couldn't tell its own prior turns apart from another agent's turns or the user's actual instruction. The Claude Agent SDK's streaming-input protocol only accepts user-role turns (it generates its own assistant turns), so per-message roles can't be sent on the wire. Instead, when the input is more than a single plain user turn, each message is now prefixed with its role as text (e.g. "[assistant]: ...") so Claude can still tell the turns apart. The common single-user-turn case is left unchanged.
Praveen Kumar Mittal (mittalpk)
deployed
to
github-app-auth
August 26, 2026 21:00 — with
GitHub Actions
Active
Praveen Kumar Mittal (mittalpk)
deployed
to
github-app-auth
August 26, 2026 21:00 — with
GitHub Actions
Active
Praveen Kumar Mittal (mittalpk)
deployed
to
github-app-auth
August 26, 2026 21:00 — with
GitHub Actions
Active
Praveen Kumar Mittal (mittalpk)
deployed
to
github-app-auth
August 26, 2026 21:00 — with
GitHub Actions
Active
Member
|
Please use the standard PR template Praveen Kumar Mittal (@mittalpk) |
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.
Fixes #7894.
ClaudeAgent._format_prompt()joined every message's text together with no role information at all, so a multi-agent orchestration (SequentialBuilder/ConcurrentBuilder) that hands an agent the accumulated conversation — including other agents' and the user's turns — loses all of that structure by the time Claude sees it. Everything reads as one undifferentiated blob sent as a singleuser-role turn.I originally proposed sending real per-message roles through the SDK's async-iterable
query()input (see the issue discussion), but testing that against the actual CLI showed the streaming-input protocol rejects any role other thanuseroutright (Error: Expected message role 'user', got 'assistant') — it generates its own assistant turns and won't accept synthetic ones. So the fix here instead labels each message with its role as visible text ([user]: .../[assistant]: ...) when there's more than a single plain user turn, so Claude can still tell who said what. The common single-user-message case is left exactly as it was, to avoid changing behavior for the overwhelming majority of calls.Verification:
git stashisolation).packages/claude/tests/suite passes (72 tests).ruff check/ruff format --checkclean on both changed files.mypyon the changed file shows the same 2 pre-existing, unrelated errors present on a cleanmaincheckout (confirmed viagit stash) — nothing introduced by this change.