feat: 多平台 Coding Plan 统一管理系统初始实现
- 支持 MiniMax/OpenAI/Google Gemini/智谱/Kimi 五个平台 - 插件化 Provider 架构,自动发现注册 - 多维度 QuotaRule 额度追踪(固定间隔/自然周期/API同步/手动) - OpenAI + Anthropic 兼容 API 代理,SSE 流式转发 - Model 路由表 + 额度耗尽自动 fallback - 多媒体任务队列(图片/语音/视频) - Vue3 + Tailwind 单文件 Web 仪表盘 - Docker 一键部署 Made-with: Cursor
This commit is contained in:
+165
@@ -0,0 +1,165 @@
|
||||
"""Pydantic 数据模型 -- API 请求/响应 + 数据库行映射"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
# ── 枚举 ──────────────────────────────────────────────
|
||||
|
||||
class RefreshType(str, Enum):
|
||||
FIXED_INTERVAL = "fixed_interval"
|
||||
CALENDAR_CYCLE = "calendar_cycle"
|
||||
MANUAL = "manual"
|
||||
API_SYNC = "api_sync"
|
||||
|
||||
|
||||
class TaskStatus(str, Enum):
|
||||
PENDING = "pending"
|
||||
RUNNING = "running"
|
||||
COMPLETED = "completed"
|
||||
FAILED = "failed"
|
||||
CANCELLED = "cancelled"
|
||||
|
||||
|
||||
# ── Plan ──────────────────────────────────────────────
|
||||
|
||||
class PlanBase(BaseModel):
|
||||
name: str
|
||||
provider_name: str
|
||||
api_base: str = ""
|
||||
plan_type: str = "coding"
|
||||
supported_models: list[str] = Field(default_factory=list)
|
||||
extra_headers: dict[str, str] = Field(default_factory=dict)
|
||||
extra_config: dict[str, Any] = Field(default_factory=dict)
|
||||
enabled: bool = True
|
||||
|
||||
|
||||
class PlanCreate(PlanBase):
|
||||
api_key: str = ""
|
||||
|
||||
|
||||
class PlanUpdate(BaseModel):
|
||||
name: str | None = None
|
||||
api_key: str | None = None
|
||||
api_base: str | None = None
|
||||
plan_type: str | None = None
|
||||
supported_models: list[str] | None = None
|
||||
extra_headers: dict[str, str] | None = None
|
||||
extra_config: dict[str, Any] | None = None
|
||||
enabled: bool | None = None
|
||||
|
||||
|
||||
class PlanOut(PlanBase):
|
||||
id: str
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
# ── QuotaRule ─────────────────────────────────────────
|
||||
|
||||
class QuotaRuleBase(BaseModel):
|
||||
rule_name: str
|
||||
quota_total: int
|
||||
quota_unit: str = "requests"
|
||||
refresh_type: RefreshType = RefreshType.CALENDAR_CYCLE
|
||||
interval_hours: float | None = None
|
||||
calendar_unit: str | None = None
|
||||
calendar_anchor: dict[str, Any] | None = None
|
||||
enabled: bool = True
|
||||
|
||||
|
||||
class QuotaRuleCreate(QuotaRuleBase):
|
||||
plan_id: str
|
||||
|
||||
|
||||
class QuotaRuleUpdate(BaseModel):
|
||||
rule_name: str | None = None
|
||||
quota_total: int | None = None
|
||||
quota_unit: str | None = None
|
||||
refresh_type: RefreshType | None = None
|
||||
interval_hours: float | None = None
|
||||
calendar_unit: str | None = None
|
||||
calendar_anchor: dict[str, Any] | None = None
|
||||
enabled: bool | None = None
|
||||
|
||||
|
||||
class QuotaRuleOut(QuotaRuleBase):
|
||||
id: str
|
||||
plan_id: str
|
||||
quota_used: int = 0
|
||||
last_refresh_at: datetime | None = None
|
||||
next_refresh_at: datetime | None = None
|
||||
|
||||
|
||||
# ── QuotaSnapshot ─────────────────────────────────────
|
||||
|
||||
class QuotaSnapshotOut(BaseModel):
|
||||
id: str
|
||||
rule_id: str
|
||||
quota_used: int
|
||||
quota_remaining: int
|
||||
checked_at: datetime
|
||||
|
||||
|
||||
# ── Model Route ───────────────────────────────────────
|
||||
|
||||
class ModelRouteBase(BaseModel):
|
||||
model_name: str
|
||||
plan_id: str
|
||||
priority: int = 0
|
||||
|
||||
|
||||
class ModelRouteOut(ModelRouteBase):
|
||||
id: str
|
||||
|
||||
|
||||
# ── Task Queue ────────────────────────────────────────
|
||||
|
||||
class TaskCreate(BaseModel):
|
||||
plan_id: str | None = None
|
||||
task_type: str
|
||||
request_payload: dict[str, Any] = Field(default_factory=dict)
|
||||
priority: int = 0
|
||||
max_retries: int = 3
|
||||
callback_url: str | None = None
|
||||
|
||||
|
||||
class TaskOut(BaseModel):
|
||||
id: str
|
||||
plan_id: str | None
|
||||
task_type: str
|
||||
status: TaskStatus
|
||||
request_payload: dict[str, Any]
|
||||
response_payload: dict[str, Any] | None = None
|
||||
result_file_path: str | None = None
|
||||
result_mime_type: str | None = None
|
||||
priority: int
|
||||
retry_count: int
|
||||
max_retries: int
|
||||
callback_url: str | None = None
|
||||
created_at: datetime
|
||||
started_at: datetime | None = None
|
||||
completed_at: datetime | None = None
|
||||
|
||||
|
||||
# ── 聚合视图 ──────────────────────────────────────────
|
||||
|
||||
class PlanWithRules(PlanOut):
|
||||
"""Plan + 所有 QuotaRule 的聚合返回"""
|
||||
quota_rules: list[QuotaRuleOut] = Field(default_factory=list)
|
||||
|
||||
|
||||
class DashboardPlan(BaseModel):
|
||||
"""仪表盘用的精简视图"""
|
||||
id: str
|
||||
name: str
|
||||
provider_name: str
|
||||
plan_type: str
|
||||
enabled: bool
|
||||
quota_rules: list[QuotaRuleOut]
|
||||
all_available: bool = True # 所有 Rule 均有余量
|
||||
Reference in New Issue
Block a user