"""Pydantic request/response models for the inference registry API. All response models EXCLUDE actual auth_secret_ref values. Instead they show a status string: "configured" or "not_configured". Requirements: 3.6, 3.7 """ from __future__ import annotations from datetime import datetime from typing import Any, Literal from uuid import UUID from pydantic import BaseModel, Field, field_validator VALID_PROTOCOLS = ("ollama_native", "openai_chat", "specialist_http") # --------------------------------------------------------------------------- # Endpoint schemas # --------------------------------------------------------------------------- class EndpointCreate(BaseModel): """Request body for creating an inference endpoint.""" name: str = Field(..., min_length=1, max_length=255) protocol: Literal["ollama_native", "openai_chat", "specialist_http"] base_url: str = Field(..., min_length=1) auth_secret_ref: str | None = None auth_scheme: str = "bearer" default_headers: dict[str, str] = Field(default_factory=dict) health_path: str | None = None enabled: bool = True @field_validator("base_url") @classmethod def validate_url(cls, v: str) -> str: """Validate that base_url looks like a valid URL.""" if not v.startswith(("http://", "https://")): raise ValueError("base_url must start with http:// or https://") return v.rstrip("/") @field_validator("protocol") @classmethod def validate_protocol(cls, v: str) -> str: if v not in VALID_PROTOCOLS: raise ValueError(f"protocol must be one of {VALID_PROTOCOLS}") return v class EndpointUpdate(BaseModel): """Request body for updating an inference endpoint.""" name: str | None = None protocol: Literal["ollama_native", "openai_chat", "specialist_http"] | None = None base_url: str | None = None auth_secret_ref: str | None = Field(default=None) auth_scheme: str | None = None default_headers: dict[str, str] | None = None health_path: str | None = None enabled: bool | None = None @field_validator("base_url") @classmethod def validate_url(cls, v: str | None) -> str | None: if v is not None: if not v.startswith(("http://", "https://")): raise ValueError("base_url must start with http:// or https://") return v.rstrip("/") return v @field_validator("protocol") @classmethod def validate_protocol(cls, v: str | None) -> str | None: if v is not None and v not in VALID_PROTOCOLS: raise ValueError(f"protocol must be one of {VALID_PROTOCOLS}") return v class EndpointResponse(BaseModel): """Response model for an inference endpoint. NEVER includes auth_secret_ref value.""" id: UUID name: str protocol: str base_url: str auth_secret_status: str = "not_configured" # "configured" or "not_configured" auth_scheme: str = "bearer" default_headers: dict[str, str] = Field(default_factory=dict) health_path: str | None = None enabled: bool = True revision: int = 1 created_at: datetime | None = None updated_at: datetime | None = None last_probe: ProbeResponse | None = None capabilities: dict[str, Any] | None = None active_bindings: list[BindingResponse] | None = None class EndpointListResponse(BaseModel): """Response model for listing endpoints.""" id: UUID name: str protocol: str base_url: str auth_secret_status: str = "not_configured" enabled: bool = True revision: int = 1 created_at: datetime | None = None updated_at: datetime | None = None # --------------------------------------------------------------------------- # Deployment schemas # --------------------------------------------------------------------------- class DeploymentCreate(BaseModel): """Request body for creating a model deployment.""" endpoint_id: UUID served_model_name: str = Field(..., min_length=1) display_name: str = Field(..., min_length=1) capabilities: dict[str, Any] = Field(default_factory=dict) context_window: int | None = None max_output_tokens: int | None = None quantization: str | None = None runtime_metadata: dict[str, Any] = Field(default_factory=dict) enabled: bool = True class DeploymentResponse(BaseModel): """Response model for a model deployment.""" id: UUID endpoint_id: UUID served_model_name: str display_name: str capabilities: dict[str, Any] = Field(default_factory=dict) context_window: int | None = None max_output_tokens: int | None = None quantization: str | None = None runtime_metadata: dict[str, Any] = Field(default_factory=dict) enabled: bool = True revision: int = 1 # --------------------------------------------------------------------------- # Binding schemas # --------------------------------------------------------------------------- class BindingCreate(BaseModel): """Request body for creating an agent stage binding.""" agent_id: UUID stage: str = Field(..., min_length=1) model_deployment_id: UUID | None = None route_order: int = 0 routing_config: dict[str, Any] = Field(default_factory=dict) is_active: bool = True class BindingResponse(BaseModel): """Response model for an agent stage binding.""" id: UUID agent_id: UUID stage: str model_deployment_id: UUID | None = None route_order: int = 0 routing_config: dict[str, Any] = Field(default_factory=dict) is_active: bool = True revision: int = 1 # --------------------------------------------------------------------------- # Probe schemas # --------------------------------------------------------------------------- class ProbeResponse(BaseModel): """Response model for probe results.""" endpoint_id: UUID timestamp: datetime | None = None software_version: str | None = None probe_duration_ms: int = 0 health_success: bool = False health_detail: str = "" model_listing_success: bool | None = None json_schema_success: bool | None = None usage_success: bool | None = None seed_success: bool | None = None output_token_field_success: bool | None = None # --------------------------------------------------------------------------- # Egress confirmation schema # --------------------------------------------------------------------------- class EgressConfirmation(BaseModel): """Request body for confirming external endpoint egress enablement. Requires explicit confirmed=true flag. """ confirmed: bool = Field( ..., description="Must be explicitly set to true to confirm external egress enablement", ) @field_validator("confirmed") @classmethod def must_be_true(cls, v: bool) -> bool: if not v: raise ValueError("confirmed must be true to enable external egress") return v # --------------------------------------------------------------------------- # Structured output test schemas # --------------------------------------------------------------------------- class StructuredOutputTestRequest(BaseModel): """Request body for testing structured output on an endpoint.""" json_schema: dict[str, Any] = Field( default_factory=lambda: { "type": "object", "properties": {"status": {"type": "string"}}, "required": ["status"], } ) prompt: str = 'Respond with JSON: {"status": "ok"}' class StructuredOutputTestResponse(BaseModel): """Response for structured output test.""" success: bool structured_mode: str = "" content: str = "" parsed: dict[str, Any] | None = None schema_valid: bool = False latency_ms: int = 0 error: str | None = None