tool_events.py 1.1 KB

1234567891011121314151617181920212223242526272829303132333435
  1. """SSE 事件推送 —— 工具调用追踪器与 SSE 消息编解码."""
  2. from __future__ import annotations
  3. import json
  4. import time
  5. from dataclasses import dataclass
  6. from typing import Any, Callable, Dict, List, Optional
  7. @dataclass
  8. class ToolEvent:
  9. ts_ms: int
  10. type: str
  11. payload: Dict[str, Any]
  12. class ToolCallTracker:
  13. def __init__(self, sink: Optional[Callable[[Dict[str, Any]], None]] = None) -> None:
  14. self._events: List[ToolEvent] = []
  15. self._sink = sink
  16. def emit(self, type: str, payload: Dict[str, Any]) -> None:
  17. ev = ToolEvent(ts_ms=int(time.time() * 1000), type=type, payload=dict(payload or {}))
  18. self._events.append(ev)
  19. if self._sink:
  20. self._sink(self.to_wire(ev))
  21. def to_wire(self, ev: ToolEvent) -> Dict[str, Any]:
  22. return {"type": ev.type, "ts_ms": ev.ts_ms, **(ev.payload or {})}
  23. def snapshot(self) -> List[Dict[str, Any]]:
  24. return [self.to_wire(e) for e in self._events]
  25. def sse_pack(event: Dict[str, Any]) -> str:
  26. return "data: " + json.dumps(event, ensure_ascii=False, default=str) + "\n\n"