167 lines
4.4 KiB
Python
167 lines
4.4 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
|
|
# -------- Provider --------
|
|
|
|
class ProviderCreate(BaseModel):
|
|
code: str = Field(min_length=1, max_length=64)
|
|
name: str = Field(min_length=1, max_length=64)
|
|
vendor: str = Field(default="openai", pattern=r"^(openai|azure|anthropic|custom)$")
|
|
api_base: str = Field(min_length=1, max_length=255)
|
|
api_key: str | None = None
|
|
description: str | None = None
|
|
status: str = Field(default="ACTIVE", pattern=r"^(ACTIVE|DISABLED)$")
|
|
|
|
|
|
class ProviderUpdate(BaseModel):
|
|
name: str | None = None
|
|
vendor: str | None = Field(default=None, pattern=r"^(openai|azure|anthropic|custom)$")
|
|
api_base: str | None = None
|
|
# 留空 / undefined 不改;空串清空
|
|
api_key: str | None = None
|
|
description: str | None = None
|
|
status: str | None = Field(default=None, pattern=r"^(ACTIVE|DISABLED)$")
|
|
|
|
|
|
class ProviderRead(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
code: str
|
|
name: str
|
|
vendor: str
|
|
api_base: str
|
|
api_key_mask: str = ""
|
|
has_api_key: bool = False
|
|
description: str | None = None
|
|
status: str
|
|
|
|
|
|
# -------- Model --------
|
|
|
|
class ModelCreate(BaseModel):
|
|
provider_id: int
|
|
model: str = Field(min_length=1, max_length=128)
|
|
name: str = Field(min_length=1, max_length=128)
|
|
description: str | None = None
|
|
max_context: int = Field(default=8192, ge=1024, le=2_000_000)
|
|
price_input_per_1k: float = Field(default=0.0, ge=0)
|
|
price_output_per_1k: float = Field(default=0.0, ge=0)
|
|
status: str = Field(default="ACTIVE", pattern=r"^(ACTIVE|DISABLED)$")
|
|
|
|
|
|
class ModelUpdate(BaseModel):
|
|
name: str | None = None
|
|
description: str | None = None
|
|
max_context: int | None = Field(default=None, ge=1024, le=2_000_000)
|
|
price_input_per_1k: float | None = Field(default=None, ge=0)
|
|
price_output_per_1k: float | None = Field(default=None, ge=0)
|
|
status: str | None = Field(default=None, pattern=r"^(ACTIVE|DISABLED)$")
|
|
|
|
|
|
class ModelRead(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
provider_id: int
|
|
provider_code: str | None = None
|
|
provider_name: str | None = None
|
|
model: str
|
|
name: str
|
|
description: str | None = None
|
|
max_context: int
|
|
price_input_per_1k: float
|
|
price_output_per_1k: float
|
|
status: str
|
|
|
|
|
|
# -------- Routing --------
|
|
|
|
class RuleBase(BaseModel):
|
|
name: str = Field(min_length=1, max_length=128)
|
|
priority: int = Field(default=100, ge=0, le=10000)
|
|
conditions: dict | None = None
|
|
model_id: int
|
|
enabled: bool = True
|
|
description: str | None = None
|
|
|
|
|
|
class RuleCreate(RuleBase):
|
|
pass
|
|
|
|
|
|
class RuleUpdate(BaseModel):
|
|
name: str | None = None
|
|
priority: int | None = Field(default=None, ge=0, le=10000)
|
|
conditions: dict | None = None
|
|
model_id: int | None = None
|
|
enabled: bool | None = None
|
|
description: str | None = None
|
|
|
|
|
|
class RuleRead(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
name: str
|
|
priority: int
|
|
conditions: dict | None = None
|
|
model_id: int
|
|
model_label: str | None = None # "provider/model"
|
|
enabled: bool
|
|
description: str | None = None
|
|
|
|
|
|
# -------- Chat / Usage --------
|
|
|
|
class ChatRequest(BaseModel):
|
|
"""面向任务执行器 / playground 的统一请求。
|
|
|
|
- 若 `model` 指定(形如 "provider_code/model"),跳过路由
|
|
- 否则 `conditions` 走路由命中
|
|
"""
|
|
|
|
messages: list[dict]
|
|
model: str | None = None
|
|
conditions: dict | None = None
|
|
temperature: float | None = Field(default=None, ge=0, le=2)
|
|
max_tokens: int | None = Field(default=None, ge=1)
|
|
stream: bool = False # 目前仅 false
|
|
source: str = Field(default="playground", max_length=16)
|
|
|
|
|
|
class ChatResponse(BaseModel):
|
|
provider: str
|
|
model: str
|
|
content: str
|
|
prompt_tokens: int
|
|
completion_tokens: int
|
|
total_tokens: int
|
|
cost_usd: float
|
|
cost_ms: int
|
|
|
|
|
|
class UsageRead(BaseModel):
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
id: int
|
|
provider_id: int | None = None
|
|
provider_code: str | None = None
|
|
model_id: int | None = None
|
|
model: str | None = None
|
|
operator_id: int | None = None
|
|
operator_name: str | None = None
|
|
source: str
|
|
prompt_tokens: int
|
|
completion_tokens: int
|
|
total_tokens: int
|
|
cost_usd: float
|
|
result: str
|
|
message: str | None = None
|
|
cost_ms: int
|
|
created_at: datetime | None = None
|