Files
2026-07-13 13:12:33 +08:00

224 lines
7.6 KiB
Python

from __future__ import annotations
from types import SimpleNamespace
from opensquilla.chat.history import transcript_entries_to_chat_messages
def test_transcript_entries_to_chat_messages_preserves_usage_and_artifacts() -> None:
entry = SimpleNamespace(
id=42,
message_id="m1",
role="assistant",
content=(
'{"text": "raw", "display_text": "shown", '
'"artifacts": [{"id": "art-a1"}]}'
),
created_at="now",
provenance_kind=None,
provenance_source_session_key=None,
provenance_source_tool=None,
turn_usage={"input_tokens": 1, "output_tokens": 2, "model": "openai/test"},
tool_calls=None,
)
messages = transcript_entries_to_chat_messages([entry])
assert messages[0]["id"] == "m1"
assert messages[0]["text"] == "shown"
assert messages[0]["transcript_id"] == 42
assert messages[0]["artifacts"][0]["id"] == "art-a1"
assert messages[0]["input_tokens"] == 1
assert messages[0]["output_tokens"] == 2
assert messages[0]["model"] == "openai/test"
assert "reasoning_content" not in messages[0]
def test_transcript_entries_to_chat_messages_rebuilds_artifact_thumbnail_url() -> None:
# A persisted assistant turn stores the public artifact payload, which carries
# the reconstructed thumbnail_url but not the internal has_thumbnail boolean.
entry = SimpleNamespace(
id=43,
message_id="m3",
role="assistant",
content=(
'{"text": "here is the chart", "artifacts": [{'
'"id": "art-bmYMIceM2Ddx3rkFM4BOmZ7A", "kind": "artifact_ref", '
'"name": "chart.png", "mime": "image/png", "size": 954199, '
'"session_id": "session-1", "source": "publish_artifact", '
'"created_at": "2026-06-13T00:00:00Z", "store": "artifacts", '
'"download_url": "/api/v1/artifacts/art-bmYMIceM2Ddx3rkFM4BOmZ7A", '
'"thumbnail_url": "/api/v1/artifacts/art-bmYMIceM2Ddx3rkFM4BOmZ7A?variant=thumb"'
'}]}'
),
created_at="now",
provenance_kind=None,
provenance_source_session_key=None,
provenance_source_tool=None,
turn_usage=None,
tool_calls=None,
)
messages = transcript_entries_to_chat_messages([entry])
artifact = messages[0]["artifacts"][0]
assert artifact["id"] == "art-bmYMIceM2Ddx3rkFM4BOmZ7A"
assert artifact["thumbnail_url"] == (
"/api/v1/artifacts/art-bmYMIceM2Ddx3rkFM4BOmZ7A?variant=thumb"
)
def test_transcript_entries_to_chat_messages_sanitizes_legacy_preflight_confirmation() -> None:
entry = SimpleNamespace(
id=43,
message_id="m2",
role="user",
content=(
"请帮我判断这份供应商续费材料:这个合同要不要签、拒绝还是谈判,并给我一份决策表。\n\n"
"合同摘录:\n"
"- 服务期:2026-07-01 到 2027-06-30\n\n"
"Confirmed request fields:\n"
"- audience: decision owner\n"
"- decision_question: 签不签合同\n\n"
"<!-- opensquilla:meta_preflight_confirmed=1 -->\n"
"<!-- opensquilla:meta_preflight_run_id=01KTCSELFVALID123 -->"
),
created_at="now",
provenance_kind=None,
provenance_source_session_key=None,
provenance_source_tool=None,
turn_usage=None,
tool_calls=None,
)
messages = transcript_entries_to_chat_messages([entry])
assert messages[0]["text"] == (
"请帮我判断这份供应商续费材料:这个合同要不要签、拒绝还是谈判,并给我一份决策表。\n\n"
"合同摘录:\n"
"- 服务期:2026-07-01 到 2027-06-30"
)
assert "Confirmed request fields" not in messages[0]["text"]
assert "opensquilla:meta_preflight" not in messages[0]["text"]
def test_transcript_entries_to_chat_messages_hides_marker_only_preflight_confirmation() -> None:
entry = SimpleNamespace(
id=45,
message_id="m4",
role="user",
content=(
"<!-- opensquilla:meta_preflight_confirmed=1 -->\n"
"<!-- opensquilla:meta_preflight_run_id=01KTCMARKERONLY -->"
),
created_at="now",
provenance_kind=None,
provenance_source_session_key=None,
provenance_source_tool=None,
turn_usage=None,
tool_calls=None,
)
messages = transcript_entries_to_chat_messages([entry])
assert messages[0]["text"] == ""
def _assistant_entry(**overrides: object) -> SimpleNamespace:
entry = SimpleNamespace(
id=7,
message_id="m2",
role="assistant",
content="final answer",
created_at="now",
provenance_kind=None,
provenance_source_session_key=None,
provenance_source_tool=None,
turn_usage=None,
tool_calls=None,
)
for key, value in overrides.items():
setattr(entry, key, value)
return entry
def test_transcript_entries_to_chat_messages_carries_assistant_reasoning() -> None:
entry = _assistant_entry(reasoning_content="Weighing both options first.")
messages = transcript_entries_to_chat_messages([entry])
assert messages[0]["reasoning_content"] == "Weighing both options first."
def test_transcript_entries_to_chat_messages_omits_blank_reasoning() -> None:
entry = _assistant_entry(reasoning_content=" ")
messages = transcript_entries_to_chat_messages([entry])
assert "reasoning_content" not in messages[0]
def test_transcript_entries_to_chat_messages_sanitizes_tool_call_preflight_payloads() -> None:
entry = SimpleNamespace(
id=44,
message_id="m3",
role="assistant",
content="done",
created_at="now",
provenance_kind=None,
provenance_source_session_key=None,
provenance_source_tool=None,
turn_usage=None,
tool_calls=[
{
"name": "meta_user_input",
"input": {
"clarify_skip_summary": {
"trigger_message": (
"请帮我判断这份供应商续费材料。\n\n"
"合同摘录:\n"
"- 价格:每月 $4,800\n\n"
"Confirmed request fields:\n"
"- audience: decision owner\n"
"- decision_question: 签不签合同\n\n"
"<!-- opensquilla:meta_preflight_confirmed=1 -->"
)
}
},
}
],
)
messages = transcript_entries_to_chat_messages([entry])
trigger = messages[0]["tool_calls"][0]["input"]["clarify_skip_summary"][
"trigger_message"
]
assert trigger == (
"请帮我判断这份供应商续费材料。\n\n"
"合同摘录:\n"
"- 价格:每月 $4,800"
)
assert "Confirmed request fields" not in trigger
def test_transcript_entries_to_chat_messages_keeps_plain_confirmed_fields_text() -> None:
entry = SimpleNamespace(
id=46,
message_id="m5",
role="assistant",
content="done",
created_at="now",
provenance_kind=None,
provenance_source_session_key=None,
provenance_source_tool=None,
turn_usage=None,
tool_calls=[{"text": "Confirmed request fields:\n- this is a visible note"}],
)
messages = transcript_entries_to_chat_messages([entry])
assert messages[0]["tool_calls"][0]["text"] == (
"Confirmed request fields:\n- this is a visible note"
)