|
import json |
|
|
|
from dataclasses import dataclass, asdict, field, is_dataclass |
|
from typing import Any, Dict, Literal, Optional, List, Set, Union |
|
from enum import Enum |
|
import uuid |
|
|
|
|
|
def generate_event_id() -> str: |
|
return str(uuid.uuid4()) |
|
|
|
|
|
class Voices(str, Enum): |
|
Alloy = "alloy" |
|
Echo = "echo" |
|
Fable = "fable" |
|
Nova = "nova" |
|
Nova_2 = "nova_2" |
|
Nova_3 = "nova_3" |
|
Nova_4 = "nova_4" |
|
Nova_5 = "nova_5" |
|
Onyx = "onyx" |
|
Shimmer = "shimmer" |
|
|
|
class AudioFormats(str, Enum): |
|
PCM16 = "pcm16" |
|
G711_ULAW = "g711_ulaw" |
|
G711_ALAW = "g711_alaw" |
|
|
|
class ItemType(str, Enum): |
|
Message = "message" |
|
FunctionCall = "function_call" |
|
FunctionCallOutput = "function_call_output" |
|
|
|
class MessageRole(str, Enum): |
|
System = "system" |
|
User = "user" |
|
Assistant = "assistant" |
|
|
|
class ContentType(str, Enum): |
|
InputText = "input_text" |
|
InputAudio = "input_audio" |
|
Text = "text" |
|
Audio = "audio" |
|
|
|
@dataclass |
|
class FunctionToolChoice: |
|
name: str |
|
type: str = "function" |
|
|
|
|
|
ToolChoice = Union[str, FunctionToolChoice] |
|
|
|
@dataclass |
|
class RealtimeError: |
|
type: str |
|
message: str |
|
code: Optional[str] = None |
|
param: Optional[str] = None |
|
event_id: Optional[str] = None |
|
|
|
@dataclass |
|
class InputAudioTranscription: |
|
model: str = "whisper-1" |
|
|
|
@dataclass |
|
class ServerVADUpdateParams: |
|
threshold: Optional[float] = None |
|
prefix_padding_ms: Optional[int] = None |
|
silence_duration_ms: Optional[int] = None |
|
type: str = "server_vad" |
|
@dataclass |
|
class Session: |
|
id: str |
|
model: str |
|
expires_at: int |
|
object: str = "realtime.session" |
|
modalities: Set[str] = field(default_factory=lambda: {"text", "audio"}) |
|
instructions: Optional[str] = None |
|
voice: Voices = Voices.Alloy |
|
turn_detection: Optional[ServerVADUpdateParams] = None |
|
input_audio_format: AudioFormats = AudioFormats.PCM16 |
|
output_audio_format: AudioFormats = AudioFormats.PCM16 |
|
input_audio_transcription: Optional[InputAudioTranscription] = None |
|
tools: List[Dict[str, Union[str, Any]]] = field(default_factory=list) |
|
tool_choice: Literal["auto", "none", "required"] = "auto" |
|
temperature: float = 0.8 |
|
max_response_output_tokens: Union[int, Literal["inf"]] = "inf" |
|
|
|
|
|
@dataclass |
|
class SessionUpdateParams: |
|
model: Optional[str] = None |
|
modalities: Optional[Set[str]] = None |
|
instructions: Optional[str] = None |
|
voice: Optional[Voices] = None |
|
turn_detection: Optional[ServerVADUpdateParams] = None |
|
input_audio_format: Optional[AudioFormats] = None |
|
output_audio_format: Optional[AudioFormats] = None |
|
input_audio_transcription: Optional[InputAudioTranscription] = None |
|
tools: Optional[List[Dict[str, Union[str, any]]]] = None |
|
tool_choice: Optional[ToolChoice] = None |
|
temperature: Optional[float] = None |
|
max_response_output_tokens: Optional[Union[int, str]] = None |
|
|
|
|
|
|
|
@dataclass |
|
class SystemMessageItemParam: |
|
content: List[dict] |
|
id: Optional[str] = None |
|
status: Optional[str] = None |
|
type: str = "message" |
|
role: str = "system" |
|
|
|
@dataclass |
|
class UserMessageItemParam: |
|
content: List[dict] |
|
id: Optional[str] = None |
|
status: Optional[str] = None |
|
type: str = "message" |
|
role: str = "user" |
|
|
|
@dataclass |
|
class AssistantMessageItemParam: |
|
content: List[dict] |
|
id: Optional[str] = None |
|
status: Optional[str] = None |
|
type: str = "message" |
|
role: str = "assistant" |
|
|
|
@dataclass |
|
class FunctionCallItemParam: |
|
name: str |
|
call_id: str |
|
arguments: str |
|
type: str = "function_call" |
|
id: Optional[str] = None |
|
status: Optional[str] = None |
|
|
|
@dataclass |
|
class FunctionCallOutputItemParam: |
|
call_id: str |
|
output: str |
|
id: Optional[str] = None |
|
type: str = "function_call_output" |
|
|
|
|
|
ItemParam = Union[ |
|
SystemMessageItemParam, |
|
UserMessageItemParam, |
|
AssistantMessageItemParam, |
|
FunctionCallItemParam, |
|
FunctionCallOutputItemParam |
|
] |
|
|
|
|
|
|
|
|
|
class EventType(str, Enum): |
|
SESSION_UPDATE = "session.update" |
|
INPUT_AUDIO_BUFFER_APPEND = "input_audio_buffer.append" |
|
INPUT_AUDIO_BUFFER_COMMIT = "input_audio_buffer.commit" |
|
INPUT_AUDIO_BUFFER_CLEAR = "input_audio_buffer.clear" |
|
UPDATE_CONVERSATION_CONFIG = "update_conversation_config" |
|
ITEM_CREATE = "conversation.item.create" |
|
ITEM_TRUNCATE = "conversation.item.truncate" |
|
ITEM_DELETE = "conversation.item.delete" |
|
RESPONSE_CREATE = "response.create" |
|
RESPONSE_CANCEL = "response.cancel" |
|
|
|
ERROR = "error" |
|
SESSION_CREATED = "session.created" |
|
SESSION_UPDATED = "session.updated" |
|
|
|
INPUT_AUDIO_BUFFER_COMMITTED = "input_audio_buffer.committed" |
|
INPUT_AUDIO_BUFFER_CLEARED = "input_audio_buffer.cleared" |
|
INPUT_AUDIO_BUFFER_SPEECH_STARTED = "input_audio_buffer.speech_started" |
|
INPUT_AUDIO_BUFFER_SPEECH_STOPPED = "input_audio_buffer.speech_stopped" |
|
|
|
ITEM_CREATED = "conversation.item.created" |
|
ITEM_DELETED = "conversation.item.deleted" |
|
ITEM_TRUNCATED = "conversation.item.truncated" |
|
ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED = "conversation.item.input_audio_transcription.completed" |
|
ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED = "conversation.item.input_audio_transcription.failed" |
|
|
|
RESPONSE_CREATED = "response.created" |
|
RESPONSE_CANCELLED = "response.cancelled" |
|
RESPONSE_DONE = "response.done" |
|
RESPONSE_OUTPUT_ITEM_ADDED = "response.output_item.added" |
|
RESPONSE_OUTPUT_ITEM_DONE = "response.output_item.done" |
|
RESPONSE_CONTENT_PART_ADDED = "response.content_part.added" |
|
RESPONSE_CONTENT_PART_DONE = "response.content_part.done" |
|
RESPONSE_TEXT_DELTA = "response.text.delta" |
|
RESPONSE_TEXT_DONE = "response.text.done" |
|
RESPONSE_AUDIO_TRANSCRIPT_DELTA = "response.audio_transcript.delta" |
|
RESPONSE_AUDIO_TRANSCRIPT_DONE = "response.audio_transcript.done" |
|
RESPONSE_AUDIO_DELTA = "response.audio.delta" |
|
RESPONSE_AUDIO_DONE = "response.audio.done" |
|
RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA = "response.function_call_arguments.delta" |
|
RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE = "response.function_call_arguments.done" |
|
RATE_LIMITS_UPDATED = "rate_limits.updated" |
|
|
|
|
|
@dataclass |
|
class ServerToClientMessage: |
|
event_id: str |
|
|
|
|
|
@dataclass |
|
class ErrorMessage(ServerToClientMessage): |
|
error: RealtimeError |
|
type: str = EventType.ERROR |
|
|
|
|
|
@dataclass |
|
class SessionCreated(ServerToClientMessage): |
|
session: Session |
|
type: str = EventType.SESSION_CREATED |
|
|
|
|
|
@dataclass |
|
class SessionUpdated(ServerToClientMessage): |
|
session: Session |
|
type: str = EventType.SESSION_UPDATED |
|
|
|
|
|
@dataclass |
|
class InputAudioBufferCommitted(ServerToClientMessage): |
|
item_id: str |
|
type: str = EventType.INPUT_AUDIO_BUFFER_COMMITTED |
|
previous_item_id: Optional[str] = None |
|
|
|
|
|
@dataclass |
|
class InputAudioBufferCleared(ServerToClientMessage): |
|
type: str = EventType.INPUT_AUDIO_BUFFER_CLEARED |
|
|
|
|
|
@dataclass |
|
class InputAudioBufferSpeechStarted(ServerToClientMessage): |
|
audio_start_ms: int |
|
item_id: str |
|
type: str = EventType.INPUT_AUDIO_BUFFER_SPEECH_STARTED |
|
|
|
|
|
@dataclass |
|
class InputAudioBufferSpeechStopped(ServerToClientMessage): |
|
audio_end_ms: int |
|
type: str = EventType.INPUT_AUDIO_BUFFER_SPEECH_STOPPED |
|
item_id: Optional[str] = None |
|
|
|
|
|
@dataclass |
|
class ItemCreated(ServerToClientMessage): |
|
item: ItemParam |
|
type: str = EventType.ITEM_CREATED |
|
previous_item_id: Optional[str] = None |
|
|
|
|
|
@dataclass |
|
class ItemTruncated(ServerToClientMessage): |
|
item_id: str |
|
content_index: int |
|
audio_end_ms: int |
|
type: str = EventType.ITEM_TRUNCATED |
|
|
|
|
|
@dataclass |
|
class ItemDeleted(ServerToClientMessage): |
|
item_id: str |
|
type: str = EventType.ITEM_DELETED |
|
|
|
|
|
|
|
|
|
|
|
|
|
ResponseStatus = Union[str, Literal["in_progress", "completed", "cancelled", "incomplete", "failed"]] |
|
|
|
|
|
@dataclass |
|
class ResponseCancelledDetails: |
|
reason: str |
|
type: str = "cancelled" |
|
|
|
@dataclass |
|
class ResponseIncompleteDetails: |
|
reason: str |
|
type: str = "incomplete" |
|
|
|
@dataclass |
|
class ResponseError: |
|
type: str |
|
message: str |
|
code: Optional[str] = None |
|
|
|
@dataclass |
|
class ResponseFailedDetails: |
|
error: ResponseError |
|
type: str = "failed" |
|
|
|
|
|
ResponseStatusDetails = Union[ResponseCancelledDetails, ResponseIncompleteDetails, ResponseFailedDetails] |
|
|
|
|
|
@dataclass |
|
class InputTokenDetails: |
|
cached_tokens: int |
|
text_tokens: int |
|
audio_tokens: int |
|
|
|
@dataclass |
|
class OutputTokenDetails: |
|
text_tokens: int |
|
audio_tokens: int |
|
|
|
@dataclass |
|
class Usage: |
|
total_tokens: int |
|
input_tokens: int |
|
output_tokens: int |
|
input_token_details: InputTokenDetails |
|
output_token_details: OutputTokenDetails |
|
|
|
|
|
@dataclass |
|
class Response: |
|
id: str |
|
output: List[ItemParam] = field(default_factory=list) |
|
object: str = "realtime.response" |
|
status: ResponseStatus = "in_progress" |
|
status_details: Optional[ResponseStatusDetails] = None |
|
usage: Optional[Usage] = None |
|
metadata: Optional[Dict[str, Any]] = None |
|
|
|
|
|
|
|
@dataclass |
|
class ResponseCreated(ServerToClientMessage): |
|
response: Response |
|
type: str = EventType.RESPONSE_CREATED |
|
|
|
|
|
@dataclass |
|
class ResponseDone(ServerToClientMessage): |
|
response: Response |
|
type: str = EventType.RESPONSE_DONE |
|
|
|
|
|
@dataclass |
|
class ResponseTextDelta(ServerToClientMessage): |
|
response_id: str |
|
item_id: str |
|
output_index: int |
|
content_index: int |
|
delta: str |
|
type: str = EventType.RESPONSE_TEXT_DELTA |
|
|
|
|
|
@dataclass |
|
class ResponseTextDone(ServerToClientMessage): |
|
response_id: str |
|
item_id: str |
|
output_index: int |
|
content_index: int |
|
text: str |
|
type: str = EventType.RESPONSE_TEXT_DONE |
|
|
|
|
|
@dataclass |
|
class ResponseAudioTranscriptDelta(ServerToClientMessage): |
|
response_id: str |
|
item_id: str |
|
output_index: int |
|
content_index: int |
|
delta: str |
|
type: str = EventType.RESPONSE_AUDIO_TRANSCRIPT_DELTA |
|
|
|
|
|
@dataclass |
|
class ResponseAudioTranscriptDone(ServerToClientMessage): |
|
response_id: str |
|
item_id: str |
|
output_index: int |
|
content_index: int |
|
transcript: str |
|
type: str = EventType.RESPONSE_AUDIO_TRANSCRIPT_DONE |
|
|
|
|
|
@dataclass |
|
class ResponseAudioDelta(ServerToClientMessage): |
|
response_id: str |
|
item_id: str |
|
output_index: int |
|
content_index: int |
|
delta: str |
|
type: str = EventType.RESPONSE_AUDIO_DELTA |
|
|
|
|
|
@dataclass |
|
class ResponseAudioDone(ServerToClientMessage): |
|
response_id: str |
|
item_id: str |
|
output_index: int |
|
content_index: int |
|
type: str = EventType.RESPONSE_AUDIO_DONE |
|
|
|
|
|
@dataclass |
|
class ResponseFunctionCallArgumentsDelta(ServerToClientMessage): |
|
response_id: str |
|
item_id: str |
|
output_index: int |
|
call_id: str |
|
delta: str |
|
type: str = EventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA |
|
|
|
|
|
@dataclass |
|
class ResponseFunctionCallArgumentsDone(ServerToClientMessage): |
|
response_id: str |
|
item_id: str |
|
output_index: int |
|
call_id: str |
|
name: str |
|
arguments: str |
|
type: str = EventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE |
|
|
|
|
|
@dataclass |
|
class RateLimitDetails: |
|
name: str |
|
limit: int |
|
remaining: int |
|
reset_seconds: float |
|
|
|
@dataclass |
|
class RateLimitsUpdated(ServerToClientMessage): |
|
rate_limits: List[RateLimitDetails] |
|
type: str = EventType.RATE_LIMITS_UPDATED |
|
|
|
|
|
@dataclass |
|
class ResponseOutputItemAdded(ServerToClientMessage): |
|
response_id: str |
|
output_index: int |
|
item: Union[ItemParam, None] |
|
type: str = EventType.RESPONSE_OUTPUT_ITEM_ADDED |
|
|
|
@dataclass |
|
class ResponseContentPartAdded(ServerToClientMessage): |
|
response_id: str |
|
item_id: str |
|
output_index: int |
|
content_index: int |
|
part: Union[ItemParam, None] |
|
content: Union[ItemParam, None] = None |
|
type: str = EventType.RESPONSE_CONTENT_PART_ADDED |
|
|
|
@dataclass |
|
class ResponseContentPartDone(ServerToClientMessage): |
|
response_id: str |
|
item_id: str |
|
output_index: int |
|
content_index: int |
|
part: Union[ItemParam, None] |
|
content: Union[ItemParam, None] = None |
|
type: str = EventType.RESPONSE_CONTENT_PART_ADDED |
|
|
|
@dataclass |
|
class ResponseOutputItemDone(ServerToClientMessage): |
|
response_id: str |
|
output_index: int |
|
item: Union[ItemParam, None] |
|
type: str = EventType.RESPONSE_OUTPUT_ITEM_DONE |
|
|
|
@dataclass |
|
class ItemInputAudioTranscriptionCompleted(ServerToClientMessage): |
|
item_id: str |
|
content_index: int |
|
transcript: str |
|
type: str = EventType.ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED |
|
|
|
@dataclass |
|
class ItemInputAudioTranscriptionFailed(ServerToClientMessage): |
|
item_id: str |
|
content_index: int |
|
error: ResponseError |
|
type: str = EventType.ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED |
|
|
|
|
|
ServerToClientMessages = Union[ |
|
ErrorMessage, |
|
SessionCreated, |
|
SessionUpdated, |
|
InputAudioBufferCommitted, |
|
InputAudioBufferCleared, |
|
InputAudioBufferSpeechStarted, |
|
InputAudioBufferSpeechStopped, |
|
ItemCreated, |
|
ItemTruncated, |
|
ItemDeleted, |
|
ResponseCreated, |
|
ResponseDone, |
|
ResponseTextDelta, |
|
ResponseTextDone, |
|
ResponseAudioTranscriptDelta, |
|
ResponseAudioTranscriptDone, |
|
ResponseAudioDelta, |
|
ResponseAudioDone, |
|
ResponseFunctionCallArgumentsDelta, |
|
ResponseFunctionCallArgumentsDone, |
|
RateLimitsUpdated, |
|
ResponseOutputItemAdded, |
|
ResponseContentPartAdded, |
|
ResponseContentPartDone, |
|
ResponseOutputItemDone, |
|
ItemInputAudioTranscriptionCompleted, |
|
ItemInputAudioTranscriptionFailed |
|
] |
|
|
|
|
|
|
|
|
|
@dataclass |
|
class ClientToServerMessage: |
|
event_id: str = field(default_factory=generate_event_id) |
|
|
|
|
|
@dataclass |
|
class InputAudioBufferAppend(ClientToServerMessage): |
|
audio: Optional[str] = field(default=None) |
|
type: str = EventType.INPUT_AUDIO_BUFFER_APPEND |
|
|
|
@dataclass |
|
class InputAudioBufferCommit(ClientToServerMessage): |
|
type: str = EventType.INPUT_AUDIO_BUFFER_COMMIT |
|
|
|
|
|
@dataclass |
|
class InputAudioBufferClear(ClientToServerMessage): |
|
type: str = EventType.INPUT_AUDIO_BUFFER_CLEAR |
|
|
|
|
|
@dataclass |
|
class ItemCreate(ClientToServerMessage): |
|
item: Optional[ItemParam] = field(default=None) |
|
type: str = EventType.ITEM_CREATE |
|
previous_item_id: Optional[str] = None |
|
|
|
|
|
@dataclass |
|
class ItemTruncate(ClientToServerMessage): |
|
item_id: Optional[str] = field(default=None) |
|
content_index: Optional[int] = field(default=None) |
|
audio_end_ms: Optional[int] = field(default=None) |
|
type: str = EventType.ITEM_TRUNCATE |
|
|
|
|
|
@dataclass |
|
class ItemDelete(ClientToServerMessage): |
|
item_id: Optional[str] = field(default=None) |
|
type: str = EventType.ITEM_DELETE |
|
|
|
@dataclass |
|
class ResponseCreateParams: |
|
commit: bool = True |
|
cancel_previous: bool = True |
|
append_input_items: Optional[List[ItemParam]] = None |
|
input_items: Optional[List[ItemParam]] = None |
|
modalities: Optional[Set[str]] = None |
|
instructions: Optional[str] = None |
|
voice: Optional[Voices] = None |
|
output_audio_format: Optional[AudioFormats] = None |
|
tools: Optional[List[Dict[str, Any]]] = None |
|
tool_choice: Optional[ToolChoice] = None |
|
temperature: Optional[float] = None |
|
max_response_output_tokens: Optional[Union[int, str]] = None |
|
|
|
|
|
@dataclass |
|
class ResponseCreate(ClientToServerMessage): |
|
type: str = EventType.RESPONSE_CREATE |
|
response: Optional[ResponseCreateParams] = None |
|
|
|
|
|
@dataclass |
|
class ResponseCancel(ClientToServerMessage): |
|
type: str = EventType.RESPONSE_CANCEL |
|
|
|
DEFAULT_CONVERSATION = "default" |
|
|
|
@dataclass |
|
class UpdateConversationConfig(ClientToServerMessage): |
|
type: str = EventType.UPDATE_CONVERSATION_CONFIG |
|
label: str = DEFAULT_CONVERSATION |
|
subscribe_to_user_audio: Optional[bool] = None |
|
voice: Optional[Voices] = None |
|
system_message: Optional[str] = None |
|
temperature: Optional[float] = None |
|
max_tokens: Optional[int] = None |
|
tools: Optional[List[dict]] = None |
|
tool_choice: Optional[ToolChoice] = None |
|
disable_audio: Optional[bool] = None |
|
output_audio_format: Optional[AudioFormats] = None |
|
|
|
|
|
@dataclass |
|
class SessionUpdate(ClientToServerMessage): |
|
session: Optional[SessionUpdateParams] = field(default=None) |
|
type: str = EventType.SESSION_UPDATE |
|
|
|
|
|
|
|
ClientToServerMessages = Union[ |
|
InputAudioBufferAppend, |
|
InputAudioBufferCommit, |
|
InputAudioBufferClear, |
|
ItemCreate, |
|
ItemTruncate, |
|
ItemDelete, |
|
ResponseCreate, |
|
ResponseCancel, |
|
UpdateConversationConfig, |
|
SessionUpdate |
|
] |
|
|
|
def from_dict(data_class, data): |
|
"""Recursively convert a dictionary to a dataclass instance.""" |
|
if is_dataclass(data_class): |
|
fieldtypes = {f.name: f.type for f in data_class.__dataclass_fields__.values()} |
|
|
|
valid_data = {f: data[f] for f in fieldtypes if f in data} |
|
return data_class(**{f: from_dict(fieldtypes[f], valid_data[f]) for f in valid_data}) |
|
elif isinstance(data, list): |
|
return [from_dict(data_class.__args__[0], item) for item in data] |
|
else: |
|
return data |
|
|
|
def parse_client_message(unparsed_string: str) -> ClientToServerMessage: |
|
data = json.loads(unparsed_string) |
|
|
|
|
|
if data["type"] == EventType.INPUT_AUDIO_BUFFER_APPEND: |
|
return from_dict(InputAudioBufferAppend, data) |
|
elif data["type"] == EventType.INPUT_AUDIO_BUFFER_COMMIT: |
|
return from_dict(InputAudioBufferCommit, data) |
|
elif data["type"] == EventType.INPUT_AUDIO_BUFFER_CLEAR: |
|
return from_dict(InputAudioBufferClear, data) |
|
elif data["type"] == EventType.ITEM_CREATE: |
|
return from_dict(ItemCreate, data) |
|
elif data["type"] == EventType.ITEM_TRUNCATE: |
|
return from_dict(ItemTruncate, data) |
|
elif data["type"] == EventType.ITEM_DELETE: |
|
return from_dict(ItemDelete, data) |
|
elif data["type"] == EventType.RESPONSE_CREATE: |
|
return from_dict(ResponseCreate, data) |
|
elif data["type"] == EventType.RESPONSE_CANCEL: |
|
return from_dict(ResponseCancel, data) |
|
elif data["type"] == EventType.UPDATE_CONVERSATION_CONFIG: |
|
return from_dict(UpdateConversationConfig, data) |
|
elif data["type"] == EventType.SESSION_UPDATE: |
|
return from_dict(SessionUpdate, data) |
|
|
|
raise ValueError(f"Unknown message type: {data['type']}") |
|
|
|
|
|
|
|
|
|
|
|
def parse_server_message(unparsed_string: str) -> ServerToClientMessage: |
|
data = json.loads(unparsed_string) |
|
|
|
|
|
if data["type"] == EventType.ERROR: |
|
return from_dict(ErrorMessage, data) |
|
elif data["type"] == EventType.SESSION_CREATED: |
|
return from_dict(SessionCreated, data) |
|
elif data["type"] == EventType.SESSION_UPDATED: |
|
return from_dict(SessionUpdated, data) |
|
elif data["type"] == EventType.INPUT_AUDIO_BUFFER_COMMITTED: |
|
return from_dict(InputAudioBufferCommitted, data) |
|
elif data["type"] == EventType.INPUT_AUDIO_BUFFER_CLEARED: |
|
return from_dict(InputAudioBufferCleared, data) |
|
elif data["type"] == EventType.INPUT_AUDIO_BUFFER_SPEECH_STARTED: |
|
return from_dict(InputAudioBufferSpeechStarted, data) |
|
elif data["type"] == EventType.INPUT_AUDIO_BUFFER_SPEECH_STOPPED: |
|
return from_dict(InputAudioBufferSpeechStopped, data) |
|
elif data["type"] == EventType.ITEM_CREATED: |
|
return from_dict(ItemCreated, data) |
|
elif data["type"] == EventType.ITEM_TRUNCATED: |
|
return from_dict(ItemTruncated, data) |
|
elif data["type"] == EventType.ITEM_DELETED: |
|
return from_dict(ItemDeleted, data) |
|
elif data["type"] == EventType.RESPONSE_CREATED: |
|
return from_dict(ResponseCreated, data) |
|
elif data["type"] == EventType.RESPONSE_DONE: |
|
return from_dict(ResponseDone, data) |
|
elif data["type"] == EventType.RESPONSE_TEXT_DELTA: |
|
return from_dict(ResponseTextDelta, data) |
|
elif data["type"] == EventType.RESPONSE_TEXT_DONE: |
|
return from_dict(ResponseTextDone, data) |
|
elif data["type"] == EventType.RESPONSE_AUDIO_TRANSCRIPT_DELTA: |
|
return from_dict(ResponseAudioTranscriptDelta, data) |
|
elif data["type"] == EventType.RESPONSE_AUDIO_TRANSCRIPT_DONE: |
|
return from_dict(ResponseAudioTranscriptDone, data) |
|
elif data["type"] == EventType.RESPONSE_AUDIO_DELTA: |
|
return from_dict(ResponseAudioDelta, data) |
|
elif data["type"] == EventType.RESPONSE_AUDIO_DONE: |
|
return from_dict(ResponseAudioDone, data) |
|
elif data["type"] == EventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DELTA: |
|
return from_dict(ResponseFunctionCallArgumentsDelta, data) |
|
elif data["type"] == EventType.RESPONSE_FUNCTION_CALL_ARGUMENTS_DONE: |
|
return from_dict(ResponseFunctionCallArgumentsDone, data) |
|
elif data["type"] == EventType.RATE_LIMITS_UPDATED: |
|
return from_dict(RateLimitsUpdated, data) |
|
elif data["type"] == EventType.RESPONSE_OUTPUT_ITEM_ADDED: |
|
return from_dict(ResponseOutputItemAdded, data) |
|
elif data["type"] == EventType.RESPONSE_CONTENT_PART_ADDED: |
|
return from_dict(ResponseContentPartAdded, data) |
|
elif data["type"] == EventType.RESPONSE_CONTENT_PART_DONE: |
|
return from_dict(ResponseContentPartDone, data) |
|
elif data["type"] == EventType.RESPONSE_OUTPUT_ITEM_DONE: |
|
return from_dict(ResponseOutputItemDone, data) |
|
elif data["type"] == EventType.ITEM_INPUT_AUDIO_TRANSCRIPTION_COMPLETED: |
|
return from_dict(ItemInputAudioTranscriptionCompleted, data) |
|
elif data["type"] == EventType.ITEM_INPUT_AUDIO_TRANSCRIPTION_FAILED: |
|
return from_dict(ItemInputAudioTranscriptionFailed, data) |
|
|
|
raise ValueError(f"Unknown message type: {data['type']}") |
|
|
|
def to_json(obj: Union[ClientToServerMessage, ServerToClientMessage]) -> str: |
|
|
|
return json.dumps(asdict(obj, dict_factory=lambda x: {k: v for (k, v) in x if v is not None})) |