"""OpenAI-compatible request and response models.""" from typing import Any, Dict, List, Literal, Optional, Union from pydantic import BaseModel, Field # ============================================================================ # Chat Completions Models # ============================================================================ class ChatMessage(BaseModel): """A chat message in the conversation.""" role: Literal["system", "user", "assistant", "function", "tool", "developer"] content: Optional[str] = None name: Optional[str] = None function_call: Optional[Dict[str, Any]] = None tool_calls: Optional[List[Dict[str, Any]]] = None class FunctionCall(BaseModel): """Function call specification.""" name: str arguments: str class ToolCall(BaseModel): """Tool call specification.""" id: str type: Literal["function"] function: FunctionCall class ChatCompletionRequest(BaseModel): """OpenAI chat completion request.""" model: str messages: List[ChatMessage] temperature: Optional[float] = Field(default=1.0, ge=0, le=2) top_p: Optional[float] = Field(default=1.0, ge=0, le=1) n: Optional[int] = Field(default=1, ge=1) stream: Optional[bool] = False stop: Optional[Union[str, List[str]]] = None max_tokens: Optional[int] = Field(default=None, ge=1) presence_penalty: Optional[float] = Field(default=0, ge=-2, le=2) frequency_penalty: Optional[float] = Field(default=0, ge=-2, le=2) logit_bias: Optional[Dict[str, float]] = None user: Optional[str] = None functions: Optional[List[Dict[str, Any]]] = None function_call: Optional[Union[str, Dict[str, str]]] = None tools: Optional[List[Dict[str, Any]]] = None tool_choice: Optional[Union[str, Dict[str, Any]]] = None class ChatCompletionChoice(BaseModel): """A single chat completion choice.""" index: int message: ChatMessage finish_reason: Optional[str] = None logprobs: Optional[Dict[str, Any]] = None class ChatCompletionUsage(BaseModel): """Token usage information.""" prompt_tokens: int completion_tokens: int total_tokens: int class ChatCompletionResponse(BaseModel): """OpenAI chat completion response.""" id: str object: Literal["chat.completion"] = "chat.completion" created: int model: str choices: List[ChatCompletionChoice] usage: ChatCompletionUsage system_fingerprint: Optional[str] = None class ChatCompletionChunkDelta(BaseModel): """Delta content in streaming response.""" role: Optional[str] = None content: Optional[str] = None function_call: Optional[Dict[str, Any]] = None tool_calls: Optional[List[Dict[str, Any]]] = None class ChatCompletionChunkChoice(BaseModel): """A single streaming chunk choice.""" index: int delta: ChatCompletionChunkDelta finish_reason: Optional[str] = None logprobs: Optional[Dict[str, Any]] = None class ChatCompletionChunk(BaseModel): """OpenAI streaming chat completion chunk.""" id: str object: Literal["chat.completion.chunk"] = "chat.completion.chunk" created: int model: str choices: List[ChatCompletionChunkChoice] system_fingerprint: Optional[str] = None # ============================================================================ # Completions Models (Legacy) # ============================================================================ class CompletionRequest(BaseModel): """OpenAI completion request (legacy).""" model: str prompt: Union[str, List[str], List[int], List[List[int]]] suffix: Optional[str] = None max_tokens: Optional[int] = Field(default=16, ge=1) temperature: Optional[float] = Field(default=1.0, ge=0, le=2) top_p: Optional[float] = Field(default=1.0, ge=0, le=1) n: Optional[int] = Field(default=1, ge=1) stream: Optional[bool] = False logprobs: Optional[int] = Field(default=None, ge=0, le=5) echo: Optional[bool] = False stop: Optional[Union[str, List[str]]] = None presence_penalty: Optional[float] = Field(default=0, ge=-2, le=2) frequency_penalty: Optional[float] = Field(default=0, ge=-2, le=2) best_of: Optional[int] = Field(default=1, ge=1) logit_bias: Optional[Dict[str, float]] = None user: Optional[str] = None class CompletionChoice(BaseModel): """A single completion choice.""" text: str index: int logprobs: Optional[Dict[str, Any]] = None finish_reason: Optional[str] = None class CompletionResponse(BaseModel): """OpenAI completion response.""" id: str object: Literal["text_completion"] = "text_completion" created: int model: str choices: List[CompletionChoice] usage: ChatCompletionUsage # ============================================================================ # Embeddings Models # ============================================================================ class EmbeddingRequest(BaseModel): """OpenAI embedding request.""" model: str input: Union[str, List[str], List[int], List[List[int]]] encoding_format: Optional[Literal["float", "base64"]] = "float" dimensions: Optional[int] = None user: Optional[str] = None class EmbeddingData(BaseModel): """A single embedding result.""" object: Literal["embedding"] = "embedding" embedding: List[float] index: int class EmbeddingUsage(BaseModel): """Token usage for embeddings.""" prompt_tokens: int total_tokens: int class EmbeddingResponse(BaseModel): """OpenAI embedding response.""" object: Literal["list"] = "list" data: List[EmbeddingData] model: str usage: EmbeddingUsage # ============================================================================ # Models List # ============================================================================ class ModelInfo(BaseModel): """Information about a single model.""" id: str object: Literal["model"] = "model" created: int owned_by: str class ModelsResponse(BaseModel): """List of available models.""" object: Literal["list"] = "list" data: List[ModelInfo] # ============================================================================ # Error Models # ============================================================================ class ErrorDetail(BaseModel): """Error detail information.""" message: str type: str param: Optional[str] = None code: Optional[str] = None class ErrorResponse(BaseModel): """OpenAI error response.""" error: ErrorDetail