from __future__ import annotations from datetime import datetime from typing import Any from pydantic import BaseModel, Field, model_validator CALCULATOR_PATTERN = "^(text_token_tiered_v1|image_per_output_v1|image_input_output_tiered_v1|video_pixel_token_v1)$" class ModelPricingRuleBase(BaseModel): provider: str = Field(default="volcengine", max_length=32) model_name: str = Field(..., min_length=1, max_length=128) model_category: str = Field(..., pattern="^(text|image|video)$") billing_mode: str = Field(..., pattern="^(text_token_tiered|image_per_output|image_input_output_tiered|video_token_rate)$") calculator_version: str = Field(..., pattern=CALCULATOR_PATTERN) version_code: str = Field(..., min_length=1, max_length=64) effective_from: datetime effective_to: datetime | None = None currency: str = Field(default="CNY", min_length=3, max_length=8) rule_schema_version: int = Field(default=1, ge=1, le=100) rule_json: dict[str, Any] source_url: str | None = None source_updated_at: datetime | None = None remark: str | None = None @model_validator(mode="after") def validate_time_range(self): if self.effective_to and self.effective_to <= self.effective_from: raise ValueError("effective_to 必须晚于 effective_from") return self class ModelPricingRuleCreate(ModelPricingRuleBase): pass class ModelPricingRuleUpdate(BaseModel): provider: str | None = Field(None, max_length=32) model_name: str | None = Field(None, min_length=1, max_length=128) model_category: str | None = Field(None, pattern="^(text|image|video)$") billing_mode: str | None = Field(None, pattern="^(text_token_tiered|image_per_output|image_input_output_tiered|video_token_rate)$") calculator_version: str | None = Field(None, pattern=CALCULATOR_PATTERN) version_code: str | None = Field(None, min_length=1, max_length=64) effective_from: datetime | None = None effective_to: datetime | None = None currency: str | None = Field(None, min_length=3, max_length=8) rule_schema_version: int | None = Field(None, ge=1, le=100) rule_json: dict[str, Any] | None = None source_url: str | None = None source_updated_at: datetime | None = None remark: str | None = None class ModelPricingRuleOut(ModelPricingRuleBase): id: str publish_status: str rule_content_hash: str referenced_count: int = 0 created_by: str | None = None updated_by: str | None = None created_at: datetime | None = None updated_at: datetime | None = None class ModelPricingRuleListOut(BaseModel): items: list[ModelPricingRuleOut] total: int class ModelPricingPreviewRequest(BaseModel): billing_mode: str calculator_version: str = Field(..., pattern=CALCULATOR_PATTERN) rule_json: dict[str, Any] usage: dict[str, Any] currency: str = "CNY" class ModelPricingPreviewOut(BaseModel): amount: str currency: str is_estimated: bool selected_rate: str | None = None usage_source: str breakdown: dict[str, Any]