Files
KiloStar/kilostar/core/postgres_database/model/individual.py
T
zhaoxi 8f1398c591 feat: 人设模板系统、节点调度标签、pydantic-settings收敛、错误处理增强
新增persona_template表和CRUD API,BaseIndividualModel增加node_affinity和template_origin_id字段,
WorkerCluster支持多集群Ray资源调度,环境变量收敛到pydantic-settings统一校验,
数据库异常转换为结构化BusinessError/RetryableError,系统节点支持custom_system_prompt。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-04 06:07:46 +00:00

146 lines
5.3 KiB
Python

# Copyright 2026 zhaoxi826
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from enum import Enum
from typing import List, Optional, Dict, Any
from sqlalchemy import String, Text, text, ForeignKey, Enum as SAEnum
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import Mapped, mapped_column, relationship
from .base import BaseDataModel
class ModalityType(str, Enum):
TEXT = "text"
VISION = "vision"
AUDIO = "audio"
MULTIMODAL = "multimodal"
# ==========================================
# 1. 通用基类表 (身份中心)
# ==========================================
class BaseIndividualModel(BaseDataModel):
__tablename__ = "base_individual"
agent_id: Mapped[str] = mapped_column(String(64), primary_key=True)
agent_name: Mapped[str] = mapped_column(String(100), index=True, nullable=False)
description: Mapped[str] = mapped_column(Text, nullable=False)
system_prompt: Mapped[Optional[str]] = mapped_column(Text)
provider_title: Mapped[str] = mapped_column(String(50))
model_id: Mapped[str] = mapped_column(String(100))
owner_id: Mapped[str] = mapped_column(String(64), index=True)
agent_type: Mapped[str] = mapped_column(String(32))
node_affinity: Mapped[str] = mapped_column(String(32), nullable=False, default="cpu")
template_origin_id: Mapped[Optional[str]] = mapped_column(
ForeignKey("persona_template.template_id", ondelete="SET NULL"),
nullable=True,
index=True,
)
__mapper_args__ = {"polymorphic_on": "agent_type", "polymorphic_identity": "base"}
# ==========================================
# 2. 专家子个体 (技能与复杂工作流)
# ==========================================
class SpecialistIndividualModel(BaseIndividualModel):
__tablename__ = "specialist_individual"
agent_id: Mapped[str] = mapped_column(
ForeignKey("base_individual.agent_id", ondelete="CASCADE"), primary_key=True
)
bound_skill: Mapped[Optional[Dict[str, Any]]] = mapped_column(JSONB)
workspace: Mapped[Optional[List[str]]] = mapped_column(JSONB)
tools: Mapped[Optional[List[str]]] = mapped_column(
JSONB, default=list, server_default=text("'[]'::jsonb")
)
# 逻辑关联:作为管理者,管理下属个体
sub_ordinary_agents: Mapped[List["OrdinaryIndividualModel"]] = relationship(
back_populates="manager",
cascade="all, delete-orphan",
foreign_keys="[OrdinaryIndividualModel.manager_id]",
)
sub_special_agents: Mapped[List["SpecialIndividualModel"]] = relationship(
back_populates="manager",
cascade="all, delete-orphan",
foreign_keys="[SpecialIndividualModel.manager_id]",
)
__mapper_args__ = {
"polymorphic_identity": "specialist",
}
# ==========================================
# 3. 基础子个体 (普通微调模型)
# ==========================================
class OrdinaryIndividualModel(BaseIndividualModel):
__tablename__ = "ordinary_individual"
agent_id: Mapped[str] = mapped_column(
ForeignKey("base_individual.agent_id", ondelete="CASCADE"), primary_key=True
)
finetuned_from: Mapped[Optional[str]] = mapped_column(String(100))
tools: Mapped[Optional[List[str]]] = mapped_column(
JSONB, default=list, server_default=text("'[]'::jsonb")
)
# 【修复1】:必须显式定义物理外键
manager_id: Mapped[Optional[str]] = mapped_column(
ForeignKey("specialist_individual.agent_id", ondelete="SET NULL")
)
# 逻辑关联:指向上级专家
manager: Mapped[Optional["SpecialistIndividualModel"]] = relationship(
back_populates="sub_ordinary_agents",
foreign_keys=[manager_id], # 显式指定使用 manager_id 解析关系
)
__mapper_args__ = {
"polymorphic_identity": "ordinary",
}
# ==========================================
# 4. 特殊子个体 (多模态)
# ==========================================
class SpecialIndividualModel(BaseIndividualModel):
__tablename__ = "special_individual"
agent_id: Mapped[str] = mapped_column(
ForeignKey("base_individual.agent_id", ondelete="CASCADE"), primary_key=True
)
modality_type: Mapped[ModalityType] = mapped_column(
SAEnum(ModalityType),
default=ModalityType.MULTIMODAL,
)
multimodal_config: Mapped[Optional[Dict[str, Any]]] = mapped_column(JSONB)
# 【修复1】:添加缺失的物理外键
manager_id: Mapped[Optional[str]] = mapped_column(
ForeignKey("specialist_individual.agent_id", ondelete="SET NULL")
)
# 【修复2】:修正 back_populates 指向正确的变量名
manager: Mapped[Optional["SpecialistIndividualModel"]] = relationship(
back_populates="sub_special_agents", foreign_keys=[manager_id]
)
__mapper_args__ = {
"polymorphic_identity": "special",
}