test_openai_stream_parser.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. from agent_lab.domain.events import ToolCallEvent
  2. from agent_lab.infrastructure.openai_compatible import ChatCompletionStreamParser
  3. def test_parser_emits_content_usage_and_tool_event():
  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": {
  24. "tool_calls": [
  25. {
  26. "index": 0,
  27. "id": "call_1",
  28. "type": "function",
  29. "function": {
  30. "name": "handoff_note",
  31. "arguments": '{"message":"',
  32. },
  33. }
  34. ]
  35. },
  36. "finish_reason": None,
  37. }
  38. ]
  39. }
  40. )
  41. )
  42. items.extend(
  43. parser.feed(
  44. {
  45. "choices": [
  46. {
  47. "delta": {
  48. "tool_calls": [
  49. {
  50. "index": 0,
  51. "function": {"arguments": 'from model"}'},
  52. }
  53. ]
  54. },
  55. "finish_reason": "tool_calls",
  56. }
  57. ],
  58. "usage": {
  59. "prompt_tokens": 10,
  60. "completion_tokens": 3,
  61. "total_tokens": 13,
  62. "prompt_tokens_details": {"cached_tokens": 4},
  63. },
  64. }
  65. )
  66. )
  67. assert [item.content for item in items if item.kind == "message_delta"] == ["hello"]
  68. events = [item.event for item in items if item.kind == "event"]
  69. assert events == [
  70. ToolCallEvent(
  71. id="call_1",
  72. name="handoff_note",
  73. arguments={"message": "from model"},
  74. raw_arguments='{"message":"from model"}',
  75. )
  76. ]
  77. usage = [item.usage for item in items if item.kind == "usage"][0]
  78. assert usage.total_tokens == 13
  79. assert usage.cached_tokens == 4