fix: keep assistant-only stream deltas on current turn
This commit is contained in:
committed by
nesquena-hermes
parent
34726c3356
commit
048f1fa24e
@@ -1516,6 +1516,33 @@ def _merge_display_messages_after_agent_result(previous_display, previous_contex
|
||||
merged = previous_display[:]
|
||||
seen = {_message_identity(m) for m in merged}
|
||||
current_user_key = _message_identity({'role': 'user', 'content': msg_text})
|
||||
current_user_in_candidates = any(
|
||||
_message_identity(m) == current_user_key for m in candidates
|
||||
)
|
||||
current_user_already_checkpointed = bool(
|
||||
merged and _message_identity(merged[-1]) == current_user_key
|
||||
)
|
||||
if (
|
||||
current_user_key is not None
|
||||
and not current_user_in_candidates
|
||||
and not current_user_already_checkpointed
|
||||
and any(
|
||||
isinstance(m, dict) and m.get('role') in ('assistant', 'tool')
|
||||
for m in candidates
|
||||
)
|
||||
):
|
||||
# Some provider retry/fallback paths can return an assistant/tool delta
|
||||
# without echoing the current user turn. In deferred session-save mode
|
||||
# the prompt exists only in pending_user_message, so appending that delta
|
||||
# directly would make the assistant bubble appear attached to the prior
|
||||
# exchange and then clear the pending prompt. Materialize the current
|
||||
# turn at the transcript boundary before the assistant/tool response.
|
||||
current_user_msg = {'role': 'user', 'content': msg_text}
|
||||
insert_at = 0
|
||||
while insert_at < len(candidates) and _is_context_compression_marker(candidates[insert_at]):
|
||||
insert_at += 1
|
||||
candidates = candidates[:insert_at] + [current_user_msg] + candidates[insert_at:]
|
||||
|
||||
for msg in candidates:
|
||||
key = _message_identity(msg)
|
||||
if (
|
||||
|
||||
BIN
docs/pr-media/1787/issue-1787-transcript-order.png
Normal file
BIN
docs/pr-media/1787/issue-1787-transcript-order.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
@@ -130,3 +130,30 @@ def test_eager_checkpointed_user_is_not_duplicated_after_agent_result():
|
||||
msg_text="repeat me",
|
||||
)
|
||||
assert [m["role"] for m in merged] == ["user", "assistant"]
|
||||
|
||||
|
||||
def test_deferred_turn_is_materialized_when_agent_returns_assistant_only_delta():
|
||||
merged = streaming._merge_display_messages_after_agent_result(
|
||||
previous_display=[
|
||||
{"role": "user", "content": "older prompt"},
|
||||
{"role": "assistant", "content": "older answer"},
|
||||
],
|
||||
previous_context=[
|
||||
{"role": "user", "content": "older prompt"},
|
||||
{"role": "assistant", "content": "older answer"},
|
||||
],
|
||||
result_messages=[
|
||||
{"role": "user", "content": "older prompt"},
|
||||
{"role": "assistant", "content": "older answer"},
|
||||
{"role": "assistant", "content": "current answer"},
|
||||
],
|
||||
msg_text="latest prompt",
|
||||
)
|
||||
|
||||
assert [m["role"] for m in merged] == [
|
||||
"user",
|
||||
"assistant",
|
||||
"user",
|
||||
"assistant",
|
||||
]
|
||||
assert [m["content"] for m in merged[-2:]] == ["latest prompt", "current answer"]
|
||||
|
||||
Reference in New Issue
Block a user