Repository navigation
Python: Treat a single string passed to Message as one text content - #9327
Conversation
Message(role, contents) iterated contents directly. A bare string is
itself a sequence of strings, and the contents type hint accepts it, so
Message("user", "Hello") produced one text content per character, which
Chat Completions then sent as one user message per character. Wrap a
bare string in a list so it becomes a single text content, the same as
Message("user", ["Hello"]).
|
/review |
There was a problem hiding this comment.
MAF Automated Review — Iteration 1
Result: No findings
Scope: full PR (1 commit(s)): 55e431ec6065
Model: gpt-5.6-sol
Overview
The change narrowly normalizes a bare string into one content item before the existing parser runs, while leaving None, lists, mixed content, metadata, and serialization paths unchanged. The new positional, keyword, and empty-string tests cover the corrected contract, and existing list and serialization tests constrain regressions. No publishable Critical, High, or Medium issue was established.
Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
No publishable findings remained after source verification for this scope.
|
Aditya Kumar (@Aditya-XR) The current PR template requires an AI Assistance disclosure. Please state whether material AI assistance was used and, if it was, briefly identify the assisted areas. |
Review feedback: keep all content-shape parsing in the existing helper instead of normalizing at the Message constructor. _parse_content_list now treats a bare string as one text item, and Message.__init__ calls it unchanged. Adds a helper-level test next to the existing ones.
|
Thanks, I've added the AI Assistance section to the description. Yes, this was AI-assisted: I used Claude Code as an assistant to help find the bug and draft the fix, tests, issue and PR description. The final review was mine: I went through every change and the test results myself before submitting, and I'm happy to answer any questions about it. |
Motivation & Context
Message("user", "Hello")creates one text content per character, becauseMessage.__init__iteratescontentsand astris itself a sequence of strings. Thecontentstype hint accepts a bare string, the docstring says strings are converted to text content, and the repository's own hosted-workflows sample uses this form. With Chat Completions, each character is then sent as a separate user message.Description & Review Guide
What are the major changes?
_parse_content_listwraps a bare string in a list before iterating, so it becomes a single text content, the same asMessage("user", ["Hello"]).Message.__init__already handscontentsto this helper, so the constructor itself is unchanged:The docstrings of
Message.__init__and_parse_content_listnow say a single string is treated as one text item. New tests intest_types.pycover a bare string passed toMessagepositionally and by keyword, an empty string (one empty text content, as with[""]), and a bare string passed straight to_parse_content_list. They fail without the change: a 19-character string produces 19 contents, and""produces none.What is the impact of these changes?
For the repro in the linked issue,
Message("user", "Write a slogan.")now has one text content, and Chat Completions receives one user message instead of 15. Lists,Noneand every other input are unchanged, andMessage.__init__is the helper's only caller. The sample and the 27 test call sites that pass a bare string now get the message they intended.What do you want reviewers to focus on?
I kept the
contentstype hint as it is, sincestralready satisfiesSequence[str]; I can spell outstr | Sequence[...]if you'd like it explicit. A singleContentor dict passed without a list is still not accepted, as before. Those aren't sequences of items, so type checkers already flag them, and a singleContentraises aTypeError.Related Issue
Fixes #9326
AI Assistance
AI assistance details: I used Claude Code as an assistant to help find the bug and to draft the fix, the tests, the linked issue and this description. I did the final review myself: I read and understood every change, checked the repro and test results, and made the final decisions on what to submit.
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.