aidial_adapter_openai/utils/chat_completion_response.py (37 lines of code) (raw):
from typing import Any, Iterable, Literal, Self
from aidial_sdk.utils.merge_chunks import merge_chat_completion_chunks
from pydantic import BaseModel
class ChatCompletionResponse(BaseModel):
message_key: Literal["delta", "message"]
resp: dict = {}
@property
def usage(self) -> Any | None:
return self.resp.get("usage")
@property
def is_empty(self) -> bool:
return self.resp == {}
@property
def finish_reasons(self) -> Iterable[Any]:
for choice in self.resp.get("choices") or []:
if (reason := choice.get("finish_reason")) is not None:
yield reason
@property
def has_finish_reason(self) -> bool:
return len(list(self.finish_reasons)) > 0
@property
def messages(self) -> Iterable[Any]:
for choice in self.resp.get("choices") or []:
if (message := choice.get(self.message_key)) is not None:
yield message
@property
def has_messages(self) -> bool:
return len(list(self.messages)) > 0
class ChatCompletionBlock(ChatCompletionResponse):
def __init__(self, **kwargs):
super().__init__(message_key="message", **kwargs)
class ChatCompletionStreamingChunk(ChatCompletionResponse):
def __init__(self, **kwargs):
super().__init__(message_key="delta", **kwargs)
def merge(self, chunk: dict) -> Self:
self.resp = merge_chat_completion_chunks(self.resp, chunk)
return self