mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-10 22:38:40 +03:00
66 lines
1.8 KiB
Python
66 lines
1.8 KiB
Python
"""Shared characterization cases for live and persisted WebUI projection."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
from nanobot.webui.transcript import replay_transcript_to_ui_messages
|
|
|
|
_FIXTURE_PATH = (
|
|
Path(__file__).parents[2]
|
|
/ "webui"
|
|
/ "src"
|
|
/ "tests"
|
|
/ "fixtures"
|
|
/ "live-replay-event-projection.json"
|
|
)
|
|
_SEMANTIC_MESSAGE_FIELDS = (
|
|
"role",
|
|
"content",
|
|
"kind",
|
|
"traces",
|
|
"toolEvents",
|
|
"fileEdits",
|
|
"images",
|
|
"media",
|
|
"cliApps",
|
|
"mcpPresets",
|
|
"sessionMentions",
|
|
"reasoning",
|
|
"latencyMs",
|
|
"source",
|
|
"turnId",
|
|
"turnPhase",
|
|
"turnSeq",
|
|
)
|
|
|
|
|
|
def _normalize_projection(messages: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
|
segment_aliases: dict[str, str] = {}
|
|
normalized: list[dict[str, Any]] = []
|
|
for message in messages:
|
|
row = {
|
|
field: message[field]
|
|
for field in _SEMANTIC_MESSAGE_FIELDS
|
|
if field in message and message[field] is not None
|
|
}
|
|
segment_id = message.get("activitySegmentId")
|
|
if isinstance(segment_id, str) and segment_id:
|
|
row["activitySegmentId"] = segment_aliases.setdefault(
|
|
segment_id,
|
|
f"segment-{len(segment_aliases) + 1}",
|
|
)
|
|
normalized.append(row)
|
|
return normalized
|
|
|
|
|
|
def test_replay_matches_shared_live_projection_before_canonical_revision_migration() -> None:
|
|
"""Lock the known-equivalent subset without defining the future snapshot protocol."""
|
|
fixture = json.loads(_FIXTURE_PATH.read_text(encoding="utf-8"))
|
|
|
|
for case in fixture["cases"]:
|
|
actual = replay_transcript_to_ui_messages(case["transcript"])
|
|
assert _normalize_projection(actual) == case["expected"], case["name"]
|