Files
ai-video-fullstack/backend/schemas.py
Xin Wang 809b634420 Enhance AssistantConfig and pipeline for FastGPT integration
- Add new fields in AssistantConfig for FastGPT connection details, including `fastgpt_api_url`, `fastgpt_api_key`, and `fastgpt_app_id`.
- Update the pipeline to utilize the new FastGPT configuration, ensuring proper integration with external services.
- Introduce type handling for different assistant types, including support for realtime modes and external brain management.
- Refactor frontend components to include hints for FastGPT configuration inputs, improving user guidance during setup.
2026-06-16 16:55:51 +08:00

129 lines
4.0 KiB
Python

"""面向前端的请求/响应 DTO。与 DB 模型解耦,**响应里的 key 一律打码**。
模型资源 DTO 字段对齐前端 ComponentsModelsPage 的 ModelResource:
JSON 用 camelCase(modelId/interfaceType/apiUrl/apiKey),Python 内部用 snake_case,
靠 Pydantic alias 自动互转。FastAPI 响应默认 by_alias=True,所以出参也是 camelCase。
"""
from __future__ import annotations
from typing import Any, Literal
from pydantic import BaseModel, ConfigDict, Field, model_validator
from pydantic.alias_generators import to_camel
RuntimeMode = Literal["pipeline", "realtime"]
ModelType = Literal["LLM", "ASR", "TTS", "Realtime", "Embedding"]
AssistantType = Literal["prompt", "workflow", "dify", "fastgpt", "opencode"]
# 外部应用类型:其 config.apiKey 是该助手私有密钥,读时打码 / 写时哨兵
EXTERNAL_TYPES = {"dify", "fastgpt", "opencode"}
# 支持 realtime(语音到语音)的类型;外部托管大脑只能走 cascade。
# 与 services.brains 各 BrainSpec.supported_runtime_modes 对齐(此处独立声明,
# 避免 HTTP schema 层为做校验而引入 pipecat 重依赖)。
REALTIME_CAPABLE_TYPES = {"prompt", "workflow"}
class CamelModel(BaseModel):
"""JSON camelCase ↔ Python snake_case。protected_namespaces 关掉以允许 model_id。"""
model_config = ConfigDict(
alias_generator=to_camel,
populate_by_name=True,
protected_namespaces=(),
)
# 各 type 允许的瘦字段(其余字段写入时清零,防止跨类型脏数据)
ALLOWED_FIELDS: dict[str, set[str]] = {
"prompt": {"prompt"},
"workflow": {"graph"},
"dify": {"api_url", "api_key"},
"fastgpt": {"app_id", "api_url", "api_key"},
"opencode": {"prompt", "api_url", "api_key"},
}
# ---------- 助手(单表 STI:瘦类型真列 + workflow 图 JSON 列) ----------
class AssistantUpsert(CamelModel):
name: str
type: AssistantType = "prompt"
runtime_mode: RuntimeMode = "pipeline"
greeting: str = ""
enable_interrupt: bool = True
model_resource_ids: dict[ModelType, str] = Field(default_factory=dict)
knowledge_base_id: str | None = None
# 瘦类型专属(真列);按 type 取用,无关字段写入时清零
prompt: str = ""
api_url: str = ""
api_key: str = "" # 写时:占位符/空 → 保留旧(哨兵)
app_id: str = ""
# workflow 专属:图
graph: dict[str, Any] = Field(default_factory=dict)
@model_validator(mode="after")
def _strip_irrelevant_fields(self):
allowed = ALLOWED_FIELDS[self.type]
for field in ("prompt", "api_url", "api_key", "app_id"):
if field not in allowed:
setattr(self, field, "")
if "graph" not in allowed:
self.graph = {}
# 外部托管大脑只能 cascade,拦住不兼容的 realtime
if self.runtime_mode == "realtime" and self.type not in REALTIME_CAPABLE_TYPES:
raise ValueError(f"类型 {self.type} 不支持 realtime 运行模式")
return self
class AssistantOut(AssistantUpsert):
id: str
updated_at: str | None = None
# ---------- 知识库 ----------
class KnowledgeBaseUpsert(CamelModel):
name: str
description: str = ""
embedding_model_resource_id: str | None = None
class KnowledgeBaseOut(KnowledgeBaseUpsert):
id: str
status: str = "active"
updated_at: str | None = None
# ---------- 接口定义驱动的统一模型资源 ----------
class InterfaceDefinitionOut(CamelModel):
interface_type: str
name: str
capability: ModelType
field_schema: dict[str, Any]
enabled: bool
version: int
class ModelResourceUpsert(CamelModel):
name: str
interface_type: str
values: dict[str, Any] = Field(default_factory=dict)
secrets: dict[str, Any] = Field(default_factory=dict)
enabled: bool = True
is_default: bool = False
class ModelResourceOut(ModelResourceUpsert):
id: str
capability: ModelType
updated_at: str | None = None
class ModelResourceTestResult(CamelModel):
ok: bool
latency_ms: int | None = None
message: str
detail: str = ""