""" PMFlow AI 服务 - Pydantic 请求/响应模型 对应 ai_service 各核心函数的输入输出。 """ from typing import List, Optional from pydantic import BaseModel, Field # ============================================================================ # 需求宪章 # ============================================================================ class CharterDraftResponse(BaseModel): """从信号生成的需求宪章草案""" title: str summary: str background: str objectives: List[str] scope: str success_metrics: List[str] risks: List[str] raw_content: Optional[str] = None # ============================================================================ # 任务拆解 # ============================================================================ class TaskWithSkillRequirement(BaseModel): """带技能要求的任务项""" task_name: str description: str type: str # frontend, backend, database, ai, devops estimated_hours: float required_skill_tag_ids: List[int] = Field(default_factory=list) required_skill_names: List[str] = Field(default_factory=list) priority: str = "medium" class TaskDecompositionResponse(BaseModel): """宪章拆解任务响应""" tasks: List[TaskWithSkillRequirement] total_estimated_hours: float detected_skills: List[str] # ============================================================================ # 人员推荐 # ============================================================================ class AssigneeRecommendation(BaseModel): """被推荐人""" user_id: str # UUID 或 int 的字符串形式 user_name: str match_score: float = Field(..., ge=0, le=100) reason: str current_workload: float proficiency_avg: float historical_performance: Optional[float] = None class AssigneeRecommendationResponse(BaseModel): """人员推荐响应""" recommendations: List[AssigneeRecommendation] total_count: int # ============================================================================ # 技能分数更新 # ============================================================================ class UserSkillScoreUpdate(BaseModel): """用户技能分数更新结果""" user_id: str skill_tag_id: str quality_score_delta: float efficiency_score_delta: float last_used_at: str class UpdateSkillScoresResponse(BaseModel): """更新技能分数响应""" updated_count: int updates: List[UserSkillScoreUpdate] # ============================================================================ # 认知对齐 # ============================================================================ class AlignmentScoreResponse(BaseModel): """认知对齐度评分响应""" user_id: str truth_node_id: str alignment_score: float = Field(..., ge=0, le=100) dimension_scores: Optional[dict] = None explanation: Optional[str] = None # ============================================================================ # 认知冲突 # ============================================================================ class CognitiveConflict(BaseModel): """认知冲突项""" conflict_type: str # e.g. definition, priority, scope description: str involved_user_ids: List[str] involved_user_names: List[str] severity: str # low, medium, high class CognitiveConflictsResponse(BaseModel): """认知冲突检测响应""" truth_node_id: str conflicts: List[CognitiveConflict] total_count: int # ============================================================================ # 模型需求评估 # ============================================================================ class ModelRequirementEvaluation(BaseModel): """需求与模型匹配度评估""" compatibility_score: float = Field(..., ge=0, le=100) cost_estimate_usd: Optional[float] = None cost_estimate_tokens_per_day: Optional[int] = None risk_hints: List[str] = Field(default_factory=list) recommendations: List[str] = Field(default_factory=list)