|
6 | 6 |
|
7 | 7 | import litellm |
8 | 8 | from litellm import acompletion |
| 9 | +from litellm.types.utils import ModelResponse, Choices |
| 10 | +from litellm.litellm_core_utils.streaming_handler import CustomStreamWrapper |
9 | 11 |
|
10 | 12 | from eval_protocol.dataset_logger import default_logger |
11 | 13 | from eval_protocol.models import EvaluationRow, Message |
@@ -65,14 +67,18 @@ async def process_row(row: EvaluationRow) -> EvaluationRow: |
65 | 67 | if request_params.get("stream") is True: |
66 | 68 | chunks = [] |
67 | 69 | stream = await acompletion(**request_params) |
| 70 | + |
| 71 | + assert isinstance(stream, CustomStreamWrapper), "Stream should be a CustomStreamWrapper" |
| 72 | + |
68 | 73 | async for chunk in stream: # pyright: ignore[reportGeneralTypeIssues] |
69 | 74 | chunks.append(chunk) |
70 | 75 | response = litellm.stream_chunk_builder(chunks, messages_payload) |
71 | 76 | else: |
72 | 77 | response = await acompletion(**request_params) |
73 | 78 |
|
74 | | - if response is None: |
75 | | - raise ValueError("Response is None") |
| 79 | + assert response is not None, "Response is None" |
| 80 | + assert isinstance(response, ModelResponse), "Response should be ModelResponse" |
| 81 | + assert isinstance(response.choices[0], Choices), "Response choice should be a Choices" |
76 | 82 |
|
77 | 83 | assistant_content = response.choices[0].message.content or "" |
78 | 84 | tool_calls = response.choices[0].message.tool_calls if response.choices[0].message.tool_calls else None |
@@ -115,10 +121,12 @@ async def process_row(row: EvaluationRow) -> EvaluationRow: |
115 | 121 | tool_calls=converted_tool_calls, |
116 | 122 | ) |
117 | 123 | ] |
118 | | - row.execution_metadata.usage = CompletionUsage( |
119 | | - prompt_tokens=response.usage.prompt_tokens, |
120 | | - completion_tokens=response.usage.completion_tokens, |
121 | | - total_tokens=response.usage.total_tokens, |
| 124 | + row.execution_metadata.usage = ( |
| 125 | + CompletionUsage( # Note: LiteLLM sets usage dynamically via setattr(), not as a typed field |
| 126 | + prompt_tokens=response.usage.prompt_tokens, # pyright: ignore[reportAttributeAccessIssue] |
| 127 | + completion_tokens=response.usage.completion_tokens, # pyright: ignore[reportAttributeAccessIssue] |
| 128 | + total_tokens=response.usage.total_tokens, # pyright: ignore[reportAttributeAccessIssue] |
| 129 | + ) |
122 | 130 | ) |
123 | 131 |
|
124 | 132 | row.messages = messages |
|
0 commit comments