test_openai_stream_parser.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. from agent_lab.domain.events import ToolCallEvent
  2. from agent_lab.infrastructure.openai_compatible import ChatCompletionStreamParser
  3. def test_parser_emits_visible_content_usage_and_text_protocol_events():
  4. parser = ChatCompletionStreamParser()
  5. items = []
  6. items.extend(
  7. parser.feed(
  8. {
  9. "choices": [
  10. {
  11. "delta": {"content": "hello"},
  12. "finish_reason": None,
  13. }
  14. ]
  15. }
  16. )
  17. )
  18. items.extend(
  19. parser.feed(
  20. {
  21. "choices": [
  22. {
  23. "delta": {"content": "\n<agent_"},
  24. "finish_reason": None,
  25. }
  26. ]
  27. }
  28. )
  29. )
  30. items.extend(
  31. parser.feed(
  32. {
  33. "choices": [
  34. {
  35. "delta": {
  36. "content": "events>\nhandoff_note\nmock_search\n</agent_events>"
  37. },
  38. "finish_reason": "stop",
  39. }
  40. ],
  41. "usage": {
  42. "prompt_tokens": 10,
  43. "completion_tokens": 3,
  44. "total_tokens": 13,
  45. "prompt_tokens_details": {"cached_tokens": 4},
  46. },
  47. }
  48. )
  49. )
  50. assert [item.content for item in items if item.kind == "message_delta"] == [
  51. "hello",
  52. "\n",
  53. ]
  54. events = [item.event for item in items if item.kind == "event"]
  55. assert events == [
  56. ToolCallEvent(
  57. id="event_1",
  58. name="handoff_note",
  59. arguments={},
  60. raw_arguments="{}",
  61. ),
  62. ToolCallEvent(
  63. id="event_2",
  64. name="mock_search",
  65. arguments={},
  66. raw_arguments="{}",
  67. )
  68. ]
  69. usage = [item.usage for item in items if item.kind == "usage"][0]
  70. assert usage.total_tokens == 13
  71. assert usage.cached_tokens == 4