simplify HomeFormatter to pass-through — frontend handles entity tag parsing

This commit is contained in:
2026-03-12 00:10:38 +01:00
parent 617a17db40
commit f80bdfa8f7
2 changed files with 26 additions and 165 deletions

View File

@@ -7,7 +7,6 @@ import pytest
from app.core.output_formatter import HomeFormatter, FloatingFormatter
from app.schemas import (
WsFloatingDomain,
WsStreamBlock,
WsStreamEnd,
WsStreamStart,
WsStreamText,
@@ -49,8 +48,8 @@ async def test_home_formatter_plain_text():
@pytest.mark.asyncio
async def test_home_formatter_entity_tag_single_id():
"""A <project>[id]</project> tag emits a WsStreamBlock with entity + ids."""
async def test_home_formatter_entity_tags_passed_through():
"""Entity tags are streamed as-is — the frontend parses them."""
req_id = "req-2"
events = [
("token", "Here is your project:\n<project>[abc-123]</project>\nAll good."),
@@ -59,39 +58,15 @@ async def test_home_formatter_entity_tag_single_id():
formatter = HomeFormatter(request_id=req_id)
frames = await collect(formatter, _stream(*events))
block_frames = [f for f in frames if isinstance(f, WsStreamBlock)]
assert len(block_frames) == 1
assert block_frames[0].block_type == "entity_ref"
assert block_frames[0].data["entity"] == "projects"
assert block_frames[0].data["ids"] == ["abc-123"]
# Surrounding text is streamed
text = "".join(f.chunk for f in frames if isinstance(f, WsStreamText))
assert "<project>[abc-123]</project>" in text
assert "Here is your project:" in text
assert "All good." in text
# The raw tag itself should NOT appear in streamed text
assert "<project>" not in text
@pytest.mark.asyncio
async def test_home_formatter_entity_tag_multiple_ids():
async def test_home_formatter_multiple_tags_passed_through():
req_id = "req-3"
events = [
("token", "Pending:\n<task>[id-1,id-2,id-3]</task>"),
("mutations", []),
]
formatter = HomeFormatter(request_id=req_id)
frames = await collect(formatter, _stream(*events))
block_frames = [f for f in frames if isinstance(f, WsStreamBlock)]
assert len(block_frames) == 1
assert block_frames[0].data["entity"] == "tasks"
assert block_frames[0].data["ids"] == ["id-1", "id-2", "id-3"]
@pytest.mark.asyncio
async def test_home_formatter_multiple_entity_tags():
req_id = "req-4"
events = [
("token", "<project>[p1]</project>\nText\n<task>[t1,t2]</task>"),
("mutations", []),
@@ -99,34 +74,15 @@ async def test_home_formatter_multiple_entity_tags():
formatter = HomeFormatter(request_id=req_id)
frames = await collect(formatter, _stream(*events))
block_frames = [f for f in frames if isinstance(f, WsStreamBlock)]
assert len(block_frames) == 2
entities = {b.data["entity"] for b in block_frames}
assert entities == {"projects", "tasks"}
@pytest.mark.asyncio
async def test_home_formatter_tag_split_across_tokens():
"""Entity tag arrives across two token chunks — still detected."""
req_id = "req-5"
events = [
("token", "See: <project>[abc-"),
("token", "123]</project> done"),
("mutations", []),
]
formatter = HomeFormatter(request_id=req_id)
frames = await collect(formatter, _stream(*events))
block_frames = [f for f in frames if isinstance(f, WsStreamBlock)]
assert len(block_frames) == 1
assert block_frames[0].data["entity"] == "projects"
assert block_frames[0].data["ids"] == ["abc-123"]
text = "".join(f.chunk for f in frames if isinstance(f, WsStreamText))
assert "<project>[p1]</project>" in text
assert "<task>[t1,t2]</task>" in text
@pytest.mark.asyncio
async def test_home_formatter_tool_end_ignored():
"""tool_end events no longer produce blocks — only entity tags do."""
req_id = "req-6"
"""tool_end events are silently ignored by HomeFormatter."""
req_id = "req-4"
events = [
("tool_end", {"name": "task_agent", "result": "3 tasks"}),
("token", "No tags here."),
@@ -135,13 +91,13 @@ async def test_home_formatter_tool_end_ignored():
formatter = HomeFormatter(request_id=req_id)
frames = await collect(formatter, _stream(*events))
block_frames = [f for f in frames if isinstance(f, WsStreamBlock)]
assert len(block_frames) == 0
text = "".join(f.chunk for f in frames if isinstance(f, WsStreamText))
assert text == "No tags here."
@pytest.mark.asyncio
async def test_home_formatter_mutations_in_stream_end():
req_id = "req-7"
req_id = "req-5"
muts = [{"action": "insert", "table": "tasks", "data": {"id": "t1"}}]
events = [
("token", "Done"),
@@ -159,7 +115,7 @@ async def test_home_formatter_mutations_in_stream_end():
@pytest.mark.asyncio
async def test_home_formatter_frame_order():
"""stream_start is first, stream_end is last."""
req_id = "req-8"
req_id = "req-6"
formatter = HomeFormatter(request_id=req_id)
frames = await collect(formatter, _stream(("token", "Hi"), ("mutations", [])))
assert isinstance(frames[0], WsStreamStart)
@@ -203,8 +159,8 @@ async def test_floating_formatter_text_only():
@pytest.mark.asyncio
async def test_floating_formatter_no_block_frames():
"""FloatingFormatter must never emit WsStreamBlock."""
async def test_floating_formatter_no_entity_tags():
"""FloatingFormatter never emits entity tag blocks."""
req_id = "pop-3"
formatter = FloatingFormatter(request_id=req_id)
events = [
@@ -213,7 +169,9 @@ async def test_floating_formatter_no_block_frames():
("mutations", []),
]
frames = await collect(formatter, _stream(*events))
assert not any(isinstance(f, WsStreamBlock) for f in frames)
# Only expected frame types
for f in frames:
assert isinstance(f, (WsFloatingDomain, WsStreamStart, WsStreamText, WsStreamEnd))
@pytest.mark.asyncio