Code / services/llm_provider_service/api_models.py

services/llm_provider_service/api_models.py

View this file on Codeberg


  1
  """API request/response models for LLM Provider Service.


  2
  


  3
  This module contains LPS-internal models only.


  4
  Shared HTTP contracts are in common_core.api_models.llm_provider


  5
  """


  6
  


  7
  from __future__ import annotations


  8
  


  9
  from datetime import date


  10
  from typing import Any


  11
  


  12
  from pydantic import BaseModel, Field


  13
  


  14
  


  15
  class LlamaCppRuntimeStatus(BaseModel):


  16
      """Configured and observed llama.cpp server identity."""


  17
  


  18
      reachable: bool


  19
      configured_model: str


  20
      loaded_model: str | None = None


  21
      model_path: str | None = None


  22
      model_matches_configured: bool | None = None


  23
      context_size: int | None = None


  24
      total_slots: int | None = None


  25
      thinking_enabled: bool | None = None


  26
      generation_defaults: dict[str, str | int | float | bool | None] = Field(default_factory=dict)


  27
      error_type: str | None = None


  28
  


  29
  


  30
  class LLMProviderStatus(BaseModel):


  31
      """Model for LLM provider status."""


  32
  


  33
      name: str


  34
      enabled: bool


  35
      available: bool


  36
      circuit_breaker_state: str  # "closed", "open", "half_open"


  37
      default_model: str | None = None


  38
      last_success: str | None = None


  39
      last_failure: str | None = None


  40
      failure_count: int = 0


  41
      average_response_time_ms: float | None = None


  42
      runtime: LlamaCppRuntimeStatus | None = None


  43
  


  44
  


  45
  class LLMProviderListResponse(BaseModel):


  46
      """Response model for listing LLM providers."""


  47
  


  48
      providers: list[LLMProviderStatus]


  49
      default_provider: str


  50
      selection_strategy: str


  51
      total_requests_today: int = 0


  52
      total_cost_today: float = 0.0


  53
  


  54
  


  55
  class HealthCheckResponse(BaseModel):


  56
      """Health check response model."""


  57
  


  58
      status: str = Field(description="Service status")


  59
      service: str = Field(description="Service name")


  60
      version: str = Field(description="Service version")


  61
      dependencies: dict[str, dict[str, Any]] = Field(


  62
          default_factory=dict, description="Status of service dependencies"


  63
      )


  64
  


  65
  


  66
  class UsageSummaryResponse(BaseModel):


  67
      """Usage summary response model."""


  68
  


  69
      period: str = Field(description="Time period for summary")


  70
      total_requests: int = Field(description="Total requests in period")


  71
      successful_requests: int = Field(description="Successful requests")


  72
      failed_requests: int = Field(description="Failed requests")


  73
      total_tokens: dict[str, int] = Field(description="Total tokens by type")


  74
      total_cost: float = Field(description="Total cost in USD")


  75
      provider_breakdown: dict[str, dict[str, Any]] = Field(description="Usage breakdown by provider")


  76
  


  77
  


  78
  class ModelInfoResponse(BaseModel):


  79
      """Model information for API exposure.


  80
  


  81
      Subset of ModelConfig fields relevant for external clients.


  82
      Internal manifest fields (parameter compatibility flags, etc.) are excluded.


  83
      """


  84
  


  85
      model_id: str = Field(description="Provider-specific model identifier")


  86
      provider: str = Field(description="Provider hosting this model")


  87
      display_name: str = Field(description="Human-readable model name")


  88
      model_family: str = Field(description="Model family identifier")


  89
      max_tokens: int = Field(description="Maximum output tokens supported")


  90
      context_window: int = Field(description="Total context window size")


  91
      supports_streaming: bool = Field(description="Supports streaming responses")


  92
      capabilities: dict[str, bool] = Field(description="Model capabilities")


  93
      cost_per_1k_input_tokens: float | None = Field(


  94
          default=None, description="Cost per 1000 input tokens in USD"


  95
      )


  96
      cost_per_1k_output_tokens: float | None = Field(


  97
          default=None, description="Cost per 1000 output tokens in USD"


  98
      )


  99
      is_deprecated: bool = Field(description="Model is deprecated")


  100
      release_date: date | None = Field(default=None, description="Model release date")


  101
      recommended_for: list[str] = Field(description="Use cases this model excels at")


  102
  


  103
  


  104
  class ModelManifestResponse(BaseModel):


  105
      """Response model for model manifest endpoint.


  106
  


  107
      Returns all available models grouped by provider.


  108
      """


  109
  


  110
      providers: dict[str, list[ModelInfoResponse]] = Field(


  111
          description="Models grouped by provider name"


  112
      )


  113
      total_models: int = Field(description="Total number of models across all providers")