refactor(cli): normalize note and avoid blank lines in prepend helper
Adopt the cleaner handling from PR #37080: coerce/strip the note and skip the extra newlines when the underlying message (or text part) is empty, while keeping the safer fail-open behavior for unknown shapes.
This commit is contained in:
parent
a26a12ad07
commit
c35ede789f
8
cli.py
8
cli.py
@ -2127,21 +2127,23 @@ def _prepend_note_to_message(message, note: str):
|
|||||||
sending a pasted image in the same turn.
|
sending a pasted image in the same turn.
|
||||||
|
|
||||||
Returns the message with ``note`` prepended:
|
Returns the message with ``note`` prepended:
|
||||||
* ``str`` → ``f"{note}\\n\\n{message}"``
|
* ``str`` → ``f"{note}\\n\\n{message}"`` (just ``note`` when empty)
|
||||||
* ``list`` → note folded into the first text part, or inserted as a new
|
* ``list`` → note folded into the first text part, or inserted as a new
|
||||||
leading ``{"type": "text"}`` part when there is no text part.
|
leading ``{"type": "text"}`` part when there is no text part.
|
||||||
Unknown shapes are returned unchanged (fail-open).
|
Unknown shapes are returned unchanged (fail-open).
|
||||||
"""
|
"""
|
||||||
|
note = str(note or "").strip()
|
||||||
if not note:
|
if not note:
|
||||||
return message
|
return message
|
||||||
if isinstance(message, str):
|
if isinstance(message, str):
|
||||||
return f"{note}\n\n{message}"
|
return f"{note}\n\n{message}" if message else note
|
||||||
if isinstance(message, list):
|
if isinstance(message, list):
|
||||||
parts = list(message)
|
parts = list(message)
|
||||||
for i, part in enumerate(parts):
|
for i, part in enumerate(parts):
|
||||||
if isinstance(part, dict) and part.get("type") == "text":
|
if isinstance(part, dict) and part.get("type") == "text":
|
||||||
merged = dict(part)
|
merged = dict(part)
|
||||||
merged["text"] = f"{note}\n\n{part.get('text', '')}"
|
text = merged.get("text", "")
|
||||||
|
merged["text"] = f"{note}\n\n{text}" if text else note
|
||||||
parts[i] = merged
|
parts[i] = merged
|
||||||
return parts
|
return parts
|
||||||
# No text part (image-only) — insert the note as a leading text block.
|
# No text part (image-only) — insert the note as a leading text block.
|
||||||
|
|||||||
@ -14,10 +14,30 @@ def test_string_message_gets_note_prepended():
|
|||||||
|
|
||||||
def test_empty_note_returns_message_unchanged():
|
def test_empty_note_returns_message_unchanged():
|
||||||
assert _prepend_note_to_message("hello", "") == "hello"
|
assert _prepend_note_to_message("hello", "") == "hello"
|
||||||
|
assert _prepend_note_to_message("hello", " ") == "hello"
|
||||||
parts = [{"type": "text", "text": "hi"}]
|
parts = [{"type": "text", "text": "hi"}]
|
||||||
assert _prepend_note_to_message(parts, "") == parts
|
assert _prepend_note_to_message(parts, "") == parts
|
||||||
|
|
||||||
|
|
||||||
|
def test_note_is_stripped():
|
||||||
|
assert _prepend_note_to_message("hello", " NOTE ") == "NOTE\n\nhello"
|
||||||
|
|
||||||
|
|
||||||
|
def test_empty_string_message_yields_just_note():
|
||||||
|
# No trailing blank lines when the user message is empty.
|
||||||
|
assert _prepend_note_to_message("", "NOTE") == "NOTE"
|
||||||
|
|
||||||
|
|
||||||
|
def test_empty_text_part_yields_just_note():
|
||||||
|
message = [
|
||||||
|
{"type": "text", "text": ""},
|
||||||
|
{"type": "image_url", "image_url": {"url": "x"}},
|
||||||
|
]
|
||||||
|
result = _prepend_note_to_message(message, "NOTE")
|
||||||
|
assert result[0]["text"] == "NOTE"
|
||||||
|
assert result[1]["type"] == "image_url"
|
||||||
|
|
||||||
|
|
||||||
def test_list_message_folds_note_into_first_text_part():
|
def test_list_message_folds_note_into_first_text_part():
|
||||||
message = [
|
message = [
|
||||||
{"type": "text", "text": "describe this"},
|
{"type": "text", "text": "describe this"},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user