fix(chat): preserve plain-turn matching during settlement
Keep whitespace-normalized text matches for plain Agent rows, retain float timestamps for Gateway turn checkpoints, and test optional attachment suffix behavior rather than source spelling. Assisted-by: Hermes Agent:gpt-6-sol Assisted-by: Codex:gpt-6-luna
This commit is contained in:
1 parent
2262444806
commit
1f13717ca9
3 files changed
+25
-7
No files matched your search
+13
-1
@@ -1297,7 +1297,11 @@ def _run_gateway_chat_streaming(
|
|||||||
# role/content ordering instead of turn order.
|
# role/content ordering instead of turn order.
|
||||||
assistant_ts = now + 0.000001
|
assistant_ts = now + 0.000001
|
||||||
pending_source = getattr(s, "pending_user_source", None) or "webui"
|
pending_source = getattr(s, "pending_user_source", None) or "webui"
|
||||||
from api.streaming import _active_turn_authority, _materialize_active_turn_user
|
from api.streaming import (
|
||||||
|
_active_turn_authority,
|
||||||
|
_active_turn_token_matches,
|
||||||
|
_materialize_active_turn_user,
|
||||||
|
)
|
||||||
|
|
||||||
active_turn_identity = _active_turn_authority(s, stream_id, msg_text)
|
active_turn_identity = _active_turn_authority(s, stream_id, msg_text)
|
||||||
user_msg = _materialize_active_turn_user(
|
user_msg = _materialize_active_turn_user(
|
||||||
@@ -1373,6 +1377,14 @@ def _run_gateway_chat_streaming(
|
|||||||
if latest_text == msg_norm:
|
if latest_text == msg_norm:
|
||||||
display = display[:-1]
|
display = display[:-1]
|
||||||
s.messages = display + [user_msg, assistant_msg]
|
s.messages = display + [user_msg, assistant_msg]
|
||||||
|
if active_turn_identity.get("token"):
|
||||||
|
current_display_rows = [
|
||||||
|
message
|
||||||
|
for message in s.messages
|
||||||
|
if _active_turn_token_matches(message, active_turn_identity)
|
||||||
|
]
|
||||||
|
if len(current_display_rows) == 1:
|
||||||
|
current_display_rows[0]["timestamp"] = user_msg["timestamp"]
|
||||||
s.active_stream_id = None
|
s.active_stream_id = None
|
||||||
s.pending_user_message = None
|
s.pending_user_message = None
|
||||||
s.pending_attachments = None
|
s.pending_attachments = None
|
||||||
|
|||||||
@@ -2105,6 +2105,11 @@ def _active_turn_user_text_matches(message, expected_text):
|
|||||||
actual_text = content
|
actual_text = content
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
if (
|
||||||
|
isinstance(content, str)
|
||||||
|
and " ".join(actual_text.split()) == " ".join(expected_text.split())
|
||||||
|
):
|
||||||
|
return True
|
||||||
return _submitted_user_text_matches(actual_text, expected_text)
|
return _submitted_user_text_matches(actual_text, expected_text)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -41,12 +41,13 @@ class TestRootWorkspaceUnblocked:
|
|||||||
assert "'/etc'" in src or 'Path("/etc")' in src or "Path('/etc')" in src
|
assert "'/etc'" in src or 'Path("/etc")' in src or "Path('/etc')" in src
|
||||||
assert "'/proc'" in src or 'Path("/proc")' in src or "Path('/proc')" in src
|
assert "'/proc'" in src or 'Path("/proc")' in src or "Path('/proc')" in src
|
||||||
|
|
||||||
def test_split_guard_present(self):
|
def test_attached_files_suffix_is_optional(self):
|
||||||
src = read("api/streaming.py")
|
from api.models import _strip_attached_files_marker
|
||||||
assert "'\\n\\n[Attached files:' in msg_text" in src, (
|
|
||||||
"base_text split must guard against missing '[Attached files:' "
|
assert _strip_attached_files_marker("Plain message") == "Plain message"
|
||||||
"to avoid empty-string on plain messages"
|
assert _strip_attached_files_marker(
|
||||||
)
|
"Question\n\n[Attached files: photo.png]"
|
||||||
|
) == "Question"
|
||||||
|
|
||||||
|
|
||||||
# ── Group B: custom_providers visibility ─────────────────────────────────────
|
# ── Group B: custom_providers visibility ─────────────────────────────────────
|
||||||
|
|||||||
Reference in new issue
Block a user