Files
2026-08-21 16:00:13 +08:00

198 lines
9.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""司命台治理对象模型(九枢治理视图,api-spec §19.4)。
目标(太一)/ 感知通道(烛照)/ 世界实体(河图)/ 计划(洛书)/ 天工阁角色
为可增长的开放集合;生成偏好(模型网关 §4.3)为本地单用户单行配置。
这些对象当前由司命台治理视图维护,对应枢的自动运行时暂未启用(见
docs/operations/capability-matrix.md §8)。
"""
from datetime import datetime
from sqlalchemy import (
Boolean,
DateTime,
Float,
ForeignKey,
Integer,
String,
Text,
)
from sqlalchemy.orm import Mapped, mapped_column
from app.core.config import settings
from app.core.ids import new_goal_id, new_plan_id, new_world_entity_id
from app.core.time import utc_now
from app.db.base import Base
class Goal(Base):
"""太一枢目标节点(契约字典 §5.11 / §5.12)。"""
__tablename__ = "goals"
def __init__(self, **kwargs: object) -> None:
# Python 端默认值:mapped_column(default=...) 仅在 ORM flush 时生效,
# __init__ 覆盖使测试在不侵入 session 时就能验证默认值。
kwargs.setdefault("type", "session")
kwargs.setdefault("progress", 0.0)
super().__init__(**kwargs)
id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_goal_id)
character_id: Mapped[str | None] = mapped_column(
String(80), ForeignKey("characters.id"), nullable=True, index=True
)
title: Mapped[str] = mapped_column(String(300), nullable=False)
description: Mapped[str] = mapped_column(Text, nullable=False, default="")
level: Mapped[str] = mapped_column(String(40), nullable=False, default="task", index=True)
type: Mapped[str] = mapped_column(String(40), nullable=False, default="session")
status: Mapped[str] = mapped_column(String(40), nullable=False, default="pending", index=True)
priority: Mapped[int] = mapped_column(Integer, nullable=False, default=50)
progress: Mapped[float] = mapped_column(Float, nullable=False, default=0.0)
constraints_json: Mapped[str] = mapped_column(Text, nullable=False, default="[]")
parent_id: Mapped[str | None] = mapped_column(String(80), ForeignKey("goals.id"), nullable=True)
success_criteria_json: Mapped[str] = mapped_column(Text, nullable=False, default="[]")
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=utc_now, onupdate=utc_now
)
class PerceptionChannel(Base):
"""烛照枢感知通道授权(契约字典 §5.7 频道级)。channel 为主键,默认六类可自定义。"""
__tablename__ = "perception_channels"
channel: Mapped[str] = mapped_column(String(80), primary_key=True)
name: Mapped[str] = mapped_column(String(120), nullable=False)
description: Mapped[str] = mapped_column(Text, nullable=False, default="")
enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
consent_status: Mapped[str] = mapped_column(String(40), nullable=False, default="unknown")
privacy_level: Mapped[str] = mapped_column(String(40), nullable=False, default="normal")
risk_level: Mapped[str] = mapped_column(String(20), nullable=False, default="L2")
last_active_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=utc_now, onupdate=utc_now
)
class WorldEntity(Base):
"""河图枢世界实体(契约字典 §11.1 / §11.2)。"""
__tablename__ = "world_entities"
id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_world_entity_id)
type: Mapped[str] = mapped_column(String(40), nullable=False, default="concept", index=True)
name: Mapped[str] = mapped_column(String(200), nullable=False)
attributes_json: Mapped[str] = mapped_column(Text, nullable=False, default="{}")
state_type: Mapped[str] = mapped_column(String(40), nullable=False, default="inference")
confidence: Mapped[float] = mapped_column(Float, nullable=False, default=0.5)
sources_json: Mapped[str] = mapped_column(Text, nullable=False, default="[]")
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=utc_now, onupdate=utc_now
)
class Plan(Base):
"""洛书枢计划(契约字典 §5.13)。goal_id 关联太一枢目标,可空。"""
__tablename__ = "plans"
id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_plan_id)
goal_id: Mapped[str | None] = mapped_column(String(80), ForeignKey("goals.id"), index=True)
title: Mapped[str] = mapped_column(String(300), nullable=False)
status: Mapped[str] = mapped_column(String(40), nullable=False, default="draft", index=True)
assumptions_json: Mapped[str] = mapped_column(Text, nullable=False, default="[]")
risks_json: Mapped[str] = mapped_column(Text, nullable=False, default="[]")
required_tools_json: Mapped[str] = mapped_column(Text, nullable=False, default="[]")
success_criteria_json: Mapped[str] = mapped_column(Text, nullable=False, default="[]")
step_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
completed_steps: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=utc_now, onupdate=utc_now
)
class AgentRosterEntry(Base):
"""天工阁枢九角色在岗(契约字典 §5.14)。role 为主键,默认九角色可自定义。"""
__tablename__ = "agent_roster"
role: Mapped[str] = mapped_column(String(80), primary_key=True)
name: Mapped[str] = mapped_column(String(120), nullable=False)
responsibility: Mapped[str] = mapped_column(Text, nullable=False, default="")
enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
last_active_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=utc_now, onupdate=utc_now
)
class GenerationPreferences(Base):
"""生成参数偏好(模型网关 §4.3)。本地单用户单行,按 owner_scope 固定。"""
__tablename__ = "generation_preferences"
owner_scope: Mapped[str] = mapped_column(
String(80), primary_key=True, default=settings.default_owner_scope
)
default_model_hint: Mapped[str] = mapped_column(String(120), nullable=False)
temperature: Mapped[float] = mapped_column(Float, nullable=False, default=0.7)
top_p: Mapped[float] = mapped_column(Float, nullable=False, default=1.0)
max_output_tokens: Mapped[int] = mapped_column(Integer, nullable=False, default=4096)
streaming: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=utc_now, onupdate=utc_now
)
class ToolPolicy(Base):
"""百工枢工具策略治理(api-spec §15 / §16)。
工具的风险/权限策略持久化层;``name`` 为主键。builtin 工具启动时由种子 upsert
(``source=builtin``),自定义工具经 API 注册(``source=custom``)。司命决策器
(SafetyGovernor)从本表加载覆盖策略;``/tools`` 与 ``/safety/policies`` 两组 API
共享本表——前者返回完整元数据,后者只返回策略子集。
"""
__tablename__ = "tool_policies"
name: Mapped[str] = mapped_column(String(80), primary_key=True)
description: Mapped[str] = mapped_column(Text, nullable=False, default="")
risk_level: Mapped[str] = mapped_column(String(20), nullable=False, default="L2")
permission_policy: Mapped[str] = mapped_column(String(20), nullable=False, default="ask")
side_effect: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
audit_required: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
source: Mapped[str] = mapped_column(String(20), nullable=False, default="custom")
enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=utc_now, onupdate=utc_now
)
class ModelEndpointOverride(Base):
"""模型网关 endpoint 运行时覆盖(DB 优先于 .env / yaml,api-spec §4.4)。
每个 (logical_model_name, endpoint_name) 一行;字段非空才覆盖同名 endpoint 配置,
None = 不覆盖、回退 yaml/env。base_url/api_key 经 resolved_* 优先 endpoint 字段生效,
故 DB 写入后即「DB 优先 env」。本地单用户边界下 API key 明文存储,GET 脱敏不回值。
"""
__tablename__ = "model_endpoint_overrides"
logical_model_name: Mapped[str] = mapped_column(String(120), primary_key=True)
endpoint_name: Mapped[str] = mapped_column(String(120), primary_key=True)
base_url: Mapped[str | None] = mapped_column(String(500))
api_key: Mapped[str | None] = mapped_column(String(500))
status: Mapped[str | None] = mapped_column(String(40))
weight: Mapped[int | None] = mapped_column(Integer)
priority: Mapped[int | None] = mapped_column(Integer)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=utc_now, onupdate=utc_now
)