feat: complete image console and add verified REST and MCP workflows

This commit is contained in:
2026-11-04 00:41:54 +08:00
parent 3140cd51d2
commit bef8af53ed
48 changed files with 5167 additions and 1176 deletions
+110
View File
@@ -0,0 +1,110 @@
"""请求 / 响应模型。"""
from __future__ import annotations
import re
from pydantic import BaseModel, Field, field_validator
from .config import PROFILE_RE
class ProviderIn(BaseModel):
id: str = Field(min_length=1, max_length=64)
name: str = Field(min_length=1, max_length=100)
adapter: str = Field(default="openai_compat")
base_url: str = Field(min_length=1)
api_key: str = ""
default_model: str = ""
enabled: bool = True
note: str = ""
@field_validator("id")
@classmethod
def check_id(cls, v: str) -> str:
v = v.strip()
if not PROFILE_RE.match(v):
raise ValueError("供应商 ID 只能包含字母数字下划线和短横线")
return v
@field_validator("adapter")
@classmethod
def check_adapter(cls, v: str) -> str:
if v not in ("openai_compat", "agnes"):
raise ValueError("不支持的适配器类型")
return v
@field_validator("base_url")
@classmethod
def check_base_url(cls, v: str) -> str:
v = v.strip().rstrip("/")
if not v.startswith("http://") and not v.startswith("https://"):
raise ValueError("Base URL 必须以 http:// 或 https:// 开头")
return v
class DiscoverIn(BaseModel):
"""手动填写 Base URL + Key 时的临时发现(供应商尚未保存)。"""
adapter: str = "openai_compat"
base_url: str = Field(min_length=1)
api_key: str = Field(min_length=1)
check_adapter = field_validator("adapter")(ProviderIn.check_adapter.__func__)
check_base_url = field_validator("base_url")(ProviderIn.check_base_url.__func__)
class ModelUpsertIn(BaseModel):
model_ids: list[str] = Field(default_factory=list)
enabled: bool = True
note: str = ""
class ModelPatchIn(BaseModel):
enabled: bool | None = None
note: str | None = None
class ModelBulkIn(BaseModel):
ids: list[str] = Field(default_factory=list)
enabled: bool
class GenerateIn(BaseModel):
provider_id: str = Field(min_length=1)
model: str = Field(min_length=1)
prompt: str = Field(min_length=1)
size: str = "1024x1024"
ratio: str = ""
n: int = Field(default=1, ge=1, le=4)
images: list[str] = Field(default_factory=list)
profile_name: str | None = None
@field_validator("size")
@classmethod
def check_size(cls, v: str) -> str:
v = v.strip().upper()
if v in ("1K", "2K", "3K", "4K"):
return v
match = re.fullmatch(r"([1-9]\d{0,4})[X×]([1-9]\d{0,4})", v)
if not match:
raise ValueError("尺寸必须为正整数 WxH 或 1K/2K/3K/4K")
return f"{int(match[1])}x{int(match[2])}"
@field_validator("profile_name")
@classmethod
def check_profile(cls, v: str | None) -> str | None:
if v is None or v == "":
return None
v = v.strip()
if not PROFILE_RE.match(v):
raise ValueError("profile_name 只能包含字母数字下划线和短横线")
return v
@field_validator("prompt")
@classmethod
def check_prompt(cls, v: str) -> str:
v = v.strip()
if not v:
raise ValueError("提示词不能为空")
return v