Files
wyndham-ARR/tests/test_agent_events.py
2026-07-29 16:38:05 +08:00

184 lines
6.7 KiB
Python

from __future__ import annotations
import unittest
from agent_integration.client import OpenAgentEvent
from agent_integration.events import AgentStreamNormalizer
class AgentStreamNormalizerTests(unittest.TestCase):
def test_live_langgraph_shape_exposes_only_visible_answer(self):
normalizer = AgentStreamNormalizer()
raw_events = [
OpenAgentEvent(
event="metadata",
data={"run_id": "run-001", "thread_id": "internal-thread"},
event_id="1",
),
OpenAgentEvent(
event="values",
data={
"messages": [{"type": "human", "content": "hello"}],
"thread_data": {"workspace_path": "/internal/secret/path"},
},
),
OpenAgentEvent(
event="messages",
data=[
{
"type": "AIMessageChunk",
"content": "",
"additional_kwargs": {"reasoning_content": "INTERNAL_REASONING"},
},
{"langgraph_node": "model"},
],
),
OpenAgentEvent(
event="messages",
data=[
{"type": "AIMessageChunk", "content": "INTERNAL_TITLE"},
{"langgraph_node": "TitleMiddleware.after_model", "tags": ["middleware:title"]},
],
),
OpenAgentEvent(
event="messages",
data=[
{"type": "AIMessageChunk", "content": "连接"},
{"langgraph_node": "model"},
],
event_id="2",
),
OpenAgentEvent(
event="messages",
data=[
{"type": "AIMessageChunk", "content": "成功"},
{"langgraph_node": "model"},
],
event_id="3",
),
OpenAgentEvent(
event="messages",
data=[
{
"type": "ai",
"content": "连接成功",
"additional_kwargs": {"reasoning_content": "INTERNAL_REASONING"},
},
{"langgraph_node": "model"},
],
),
OpenAgentEvent(
event="values",
data={
"messages": [
{"type": "human", "content": "hello"},
{
"type": "ai",
"content": "连接成功",
"additional_kwargs": {"reasoning_content": "INTERNAL_REASONING"},
},
],
"thread_data": {"workspace_path": "/internal/secret/path"},
},
),
OpenAgentEvent(
event="error",
data={
"code": "open_agent_final_content_missing",
"message": "Open agent run completed without final content",
"retryable": True,
"run_id": "run-001",
"request_id": "request-001",
"internal_trace": "DO_NOT_EXPOSE",
},
),
OpenAgentEvent(event="end", data=None, event_id="4"),
]
public_events = []
for event in raw_events:
public_events.extend(normalizer.feed(event))
public_events.extend(normalizer.finish())
self.assertEqual(
[event.event for event in public_events],
[
"run.started",
"message.delta",
"message.delta",
"message.completed",
"run.warning",
"run.end",
],
)
self.assertEqual(public_events[0].data, {"run_id": "run-001"})
self.assertEqual(public_events[1].data, {"content": "连接"})
self.assertEqual(public_events[2].data, {"content": "成功"})
self.assertEqual(
public_events[3].data,
{"content": "连接成功", "streamed": True},
)
self.assertEqual(public_events[4].event, "run.warning")
self.assertEqual(public_events[5].data["status"], "completed_with_warning")
self.assertFalse(normalizer.fatal_error)
self.assertEqual(normalizer.final_content, "连接成功")
rendered = repr([event.to_dict() for event in public_events])
self.assertNotIn("INTERNAL_REASONING", rendered)
self.assertNotIn("INTERNAL_TITLE", rendered)
self.assertNotIn("secret/path", rendered)
self.assertNotIn("DO_NOT_EXPOSE", rendered)
def test_final_content_missing_without_visible_content_is_fatal(self):
normalizer = AgentStreamNormalizer()
normalizer.feed(
OpenAgentEvent(
event="error",
data={
"code": "open_agent_final_content_missing",
"message": "missing",
"retryable": True,
},
)
)
public_events = normalizer.feed(OpenAgentEvent(event="end", data=None))
self.assertTrue(normalizer.fatal_error)
self.assertEqual([event.event for event in public_events], ["run.error", "run.end"])
self.assertEqual(public_events[-1].data["status"], "failed")
def test_values_final_message_is_fallback_when_no_deltas_arrive(self):
normalizer = AgentStreamNormalizer()
normalizer.feed(
OpenAgentEvent(
event="values",
data={"messages": [{"type": "ai", "content": "完整答案"}]},
)
)
public_events = normalizer.finish()
self.assertEqual(public_events[0].event, "message.completed")
self.assertEqual(
public_events[0].data,
{"content": "完整答案", "streamed": False},
)
self.assertFalse(normalizer.fatal_error)
def test_documented_message_delta_shape_remains_supported(self):
normalizer = AgentStreamNormalizer()
public_events = normalizer.feed(
OpenAgentEvent(event="message.delta", data={"content": ""})
)
normalizer.feed(
OpenAgentEvent(event="run.completed", data={"status": "completed"})
)
public_events.extend(normalizer.finish())
self.assertEqual(public_events[0].data, {"content": ""})
self.assertEqual(public_events[1].data, {"content": "", "streamed": True})
self.assertEqual(public_events[2].data["status"], "completed")
if __name__ == "__main__":
unittest.main(verbosity=2)