初始化提交

This commit is contained in:
chenxin committed 2026-08-21 16:00:13 +08:00
commit 887c1f449e
963 files changed
+166869

No files matched your search

+323
View File
@@ -0,0 +1,323 @@
"""司命台管理 API schema(api-spec §19)。
九枢健康度聚合 / 朱批待办 / 起居注审计 + 五组治理对象 CRUD。
枚举取值见契约字典 §5.5 / §5.7 / §5.9 / §5.10 / §5.11–§5.14 / §11 / §13。
"""
from datetime import datetime
from typing import Any, Literal
from pydantic import BaseModel, ConfigDict, Field
# —— §19.1 九枢健康度聚合 ——
class PivotHealthSummary(BaseModel):
pivot: str = Field(description="九枢标识(契约字典 §5.9)。")
name: str = Field(description="枢中文名。")
module: str = Field(description="工程模块名。")
health: str = Field(description="健康状态:void / breathing / steady / cracked(§5.10)。")
summary: str = Field(description="人类可读的一句话态势;cracked 须给出原因。")
updated_at: str | None = Field(default=None, description="最近更新时间。")
class PivotHealthReport(BaseModel):
overall: str = Field(description="九枢聚合健康度;存在任一 cracked 则为 cracked。")
alerts: int = Field(description="cracked 枢计数。")
pivots: list[PivotHealthSummary] = Field(
description="九枢全集,缺数据枢 health=void,不得省略。"
)
# —— §19.2 朱批待办 ——
class PendingApproval(BaseModel):
confirmation_id: str = Field(
description="确认 ID,用于 /safety/confirmations/{id}/approve|deny。"
)
character_id: str | None = Field(default=None, description="所属人物 ID。")
tool: str = Field(description="待裁定工具名。")
risk_level: str = Field(description="风险等级(§5.5)。")
permission_policy: str = Field(description="权限策略(§5.6)。")
action_summary: str = Field(description="动作摘要。")
input_summary: str | None = Field(default=None, description="输入摘要,不得含明文密钥。")
possible_impact: str | None = Field(default=None, description="可能影响。")
reason: str | None = Field(default=None, description="裁定原因。")
created_at: str | None = Field(default=None, description="创建时间。")
# —— §19.3 起居注审计 ——
class AuditEntry(BaseModel):
audit_id: str = Field(description="审计事件 ID。")
pivot: str = Field(description="九枢标识。")
actor: str = Field(description="发起者:user / system / tool(§13.2)。")
action: str = Field(description="动作。")
subject: str | None = Field(default=None, description="动作对象。")
decision: str = Field(description="裁定结果:auto / approved / denied / blocked(§13.3)。")
risk_level: str | None = Field(default=None, description="风险等级。")
summary: str = Field(description="人类可读一句话摘要。")
trace_id: str | None = Field(default=None, description="链路追踪 ID。")
created_at: str | None = Field(default=None, description="创建时间。")
# —— §19.4 太一枢 · 目标 ——
class GoalNode(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: str
character_id: str | None = None
title: str
description: str
level: str = Field(description="目标层级(§5.11)。")
type: str = Field(
default="session",
description="目标类型(§5.15):mission/relationship/skill/knowledge/maintenance/exploration",
)
status: str = Field(description="目标状态(§5.12)。")
priority: int
progress: float = Field(default=0.0, ge=0.0, le=1.0, description="完成度 0~1。")
constraints: list[str]
parent_id: str | None = None
success_criteria: list[str]
updated_at: str | None = None
class CreateGoalRequest(BaseModel):
title: str = Field(max_length=300)
description: str = Field(default="", max_length=2000)
level: str = Field(description="目标层级(§5.11)。")
type: str = Field(default="session", description="目标类型(§5.15)。")
priority: int = Field(default=50, ge=0, le=100)
character_id: str | None = Field(default=None, description="归属于哪个人物。")
constraints: list[str] = Field(default_factory=list)
parent_id: str | None = None
success_criteria: list[str] = Field(default_factory=list)
class UpdateGoalRequest(BaseModel):
title: str | None = Field(default=None, max_length=300)
description: str | None = Field(default=None, max_length=2000)
status: str | None = Field(default=None, description="目标状态(§5.12)。")
type: str | None = Field(default=None, description="目标类型(§5.15)。")
priority: int | None = Field(default=None, ge=0, le=100)
progress: float | None = Field(default=None, ge=0.0, le=1.0)
constraints: list[str] | None = None
# —— §19.4 烛照枢 · 感知通道 ——
class PerceptionChannelResponse(BaseModel):
model_config = ConfigDict(from_attributes=True)
channel: str
name: str
description: str
enabled: bool
consent_status: str = Field(description="授权状态(§5.7)。")
privacy_level: str = Field(description="隐私等级(§5.4)。")
risk_level: str = Field(description="风险等级(§5.5)。")
last_active_at: str | None = None
class CreatePerceptionChannelRequest(BaseModel):
channel: str = Field(max_length=80, description="通道标识;默认六类,可自定义。")
name: str = Field(max_length=120)
description: str = Field(default="", max_length=2000)
risk_level: str = Field(default="L2")
class UpdatePerceptionChannelRequest(BaseModel):
enabled: bool | None = None
consent_status: str | None = Field(default=None, description="授权状态(§5.7)。")
privacy_level: str | None = Field(default=None, description="隐私等级(§5.4)。")
# —— §19.4 河图枢 · 世界实体 ——
class WorldEntityResponse(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: str
type: str = Field(description="实体类型(§11.1)。")
name: str
attributes: dict[str, str]
state_type: str = Field(description="状态类型(§11.2)。")
confidence: float
sources: list[str]
updated_at: str | None = None
class CreateWorldEntityRequest(BaseModel):
type: str = Field(description="实体类型(§11.1)。")
name: str = Field(max_length=200)
attributes: dict[str, str] = Field(default_factory=dict)
state_type: str = Field(default="inference", description="状态类型(§11.2)。")
confidence: float = Field(default=0.5, ge=0.0, le=1.0)
sources: list[str] = Field(default_factory=list)
class UpdateWorldEntityRequest(BaseModel):
name: str | None = Field(default=None, max_length=200)
state_type: str | None = Field(default=None, description="状态类型(§11.2)。")
confidence: float | None = Field(default=None, ge=0.0, le=1.0)
# —— §19.4 洛书枢 · 计划 ——
class PlanSummaryResponse(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: str
goal_id: str
title: str
status: str = Field(description="计划状态(§5.13)。")
assumptions: list[str]
risks: list[str]
required_tools: list[str]
success_criteria: list[str]
step_count: int
completed_steps: int
updated_at: str | None = None
class CreatePlanRequest(BaseModel):
title: str = Field(max_length=300)
goal_id: str | None = None
assumptions: list[str] = Field(default_factory=list)
risks: list[str] = Field(default_factory=list)
class UpdatePlanRequest(BaseModel):
status: str | None = Field(default=None, description="计划状态(§5.13)。")
assumptions: list[str] | None = None
risks: list[str] | None = None
# —— §19.4 天工阁枢 · 角色在岗 ——
class AgentRosterResponse(BaseModel):
model_config = ConfigDict(from_attributes=True)
role: str
name: str
responsibility: str
enabled: bool
presence: str = Field(description="在岗呈现态(派生自最近活跃时间):idle / active。")
last_active_at: str | None = None
class CreateAgentRequest(BaseModel):
role: str = Field(max_length=80, description="角色标识;默认九角色,可自定义。")
name: str = Field(max_length=120)
responsibility: str = Field(default="", max_length=2000)
class UpdateAgentRequest(BaseModel):
enabled: bool | None = None
# —— §19.5 链路追踪 ——
class TraceItem(BaseModel):
kind: Literal["event", "audit", "idempotency"] = Field(
description="记录来源:运行事件 / 安全审计 / 请求幂等。"
)
id: str = Field(description="记录主键。")
created_at: datetime = Field(description="发生时间(前端按此排序展示)。")
source_label: str = Field(description="人类可读来源(如「运行事件 / message.completed」)。")
summary: str = Field(description="一句话摘要。")
detail: dict[str, Any] = Field(
default_factory=dict,
description="原始字段(payload / decision / path 等),供详情展开。",
)
class TraceDetail(BaseModel):
trace_id: str = Field(description="被查询的链路追踪 ID。")
character_ids: list[str] = Field(
default_factory=list, description="该链路涉及的人物去重列表(由 events / audits 聚合)。"
)
run_ids: list[str] = Field(
default_factory=list, description="该链路涉及的 run 去重列表(由 events 聚合)。"
)
session_ids: list[str] = Field(
default_factory=list,
description="该链路涉及的对话(chat session)去重列表(由 runs 聚合)。",
)
items: list[TraceItem] = Field(
default_factory=list, description="按 created_at 升序的时间线条目。"
)
class TraceSummary(BaseModel):
trace_id: str = Field(description="链路追踪 ID。")
last_seen: datetime = Field(description="该链路最近一次活动时间。")
character_ids: list[str] = Field(default_factory=list, description="涉及的人物去重列表。")
session_ids: list[str] = Field(default_factory=list, description="涉及的对话去重列表。")
event_count: int = Field(default=0, description="运行事件数。")
audit_count: int = Field(default=0, description="安全审计数。")
idempotency_count: int = Field(default=0, description="请求幂等数。")
class TraceListResponse(BaseModel):
items: list[TraceSummary] = Field(description="按 last_seen 倒序的链路概览。")
total: int = Field(description="distinct trace 总数(未截断)。")
# —— §8 司命台 · 起居注时间河(辰正 time.* 事件)——
class TimeEventResponse(BaseModel):
"""辰正 time.* 事件(起居注时间河条目)。"""
id: str = Field(description="事件 ID。")
type: str = Field(description="事件类型(time.* 前缀,如 time.reunion / time.sentiment)。")
payload: dict[str, Any] = Field(default_factory=dict, description="事件 payload(已解析)。")
run_id: str | None = Field(default=None, description="所属 run ID(可空)。")
character_id: str | None = Field(default=None, description="所属人物 ID(可空)。")
sensitivity: str = Field(default="low", description="敏感度(§5.4)。")
created_at: str = Field(description="发生时间(ISO 字符串)。")
class TimeEventListResponse(BaseModel):
items: list[TimeEventResponse] = Field(description="按 created_at 倒序的事件列表。")
total: int = Field(description="source='time_sense' 的事件总数(未截断)。")
# —— §19.6 用户管理 ——
class AdminUserResponse(BaseModel):
"""管理员视角的用户信息。"""
model_config = ConfigDict(from_attributes=True)
id: str
username: str
email: str
is_active: bool
is_admin: bool
created_at: datetime
updated_at: datetime | None = None
class AdminCreateUserRequest(BaseModel):
username: str = Field(min_length=1, description="用户名。")
email: str = Field(min_length=1, description="邮箱。")
password: str = Field(min_length=6, description="密码(>=6 字符)。")
is_admin: bool = Field(default=False, description="是否管理员。")
class AdminUpdateUserRequest(BaseModel):
is_active: bool | None = Field(default=None, description="是否启用。")
is_admin: bool | None = Field(default=None, description="是否管理员。")