hjjjj 5487450f34 feat: 实现审核系统核心功能与UI优化
- 新增审核卡片和确认卡片模型,支持Agent推送审核任务和用户确认
- 实现审核卡片API服务,支持创建、更新、批准、驳回等操作
- 扩展审核维度配置,新增角色一致性、剧情连贯性等维度
- 优化前端审核配置页面,修复API路径错误和状态枚举问题
- 改进剧集创作平台布局,新增左侧边栏用于剧集管理和上下文查看
- 增强Skill管理,支持从审核系统跳转创建/编辑Skill
- 修复episodes.json数据问题,清理聊天历史记录
- 更新Agent提示词,明确Skill引用加载流程
- 统一前端主题配置,优化整体UI体验
2026-01-30 18:32:48 +08:00

247 lines
10 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.

"""
Review System Data Models
审核系统数据模型 - 用于配置和执行内容审核
"""
from pydantic import BaseModel, Field
from typing import Dict, List, Optional, Any
from datetime import datetime
from enum import Enum
# ============================================
# 枚举类型
# ============================================
class SeverityLevel(str, Enum):
"""严重程度"""
low = "low"
medium = "medium"
high = "high"
class DimensionType(str, Enum):
"""审核维度类型"""
consistency = "consistency" # 一致性审核
character_consistency = "character_consistency" # 角色一致性审核
quality = "quality" # 质量审核
pacing = "pacing" # 节奏审核
dialogue = "dialogue" # 对话审核
dialogue_quality = "dialogue_quality" # 对话质量审核
character = "character" # 人物审核
plot = "plot" # 剧情审核
plot_coherence = "plot_coherence" # 剧情连贯性审核
emotional_depth = "emotional_depth" # 情感深度审核
thematic_strength = "thematic_strength" # 主题强度审核
custom = "custom" # 自定义审核
class IssueType(str, Enum):
"""问题类型"""
inconsistency = "inconsistency" # 不一致
grammar = "grammar" # 语法错误
logic_error = "logic_error" # 逻辑错误
pacing_issue = "pacing_issue" # 节奏问题
character_ooc = "character_ooc" # 人物性格崩坏
plot_hole = "plot_hole" # 剧情漏洞
weak_dialogue = "weak_dialogue" # 对话薄弱
description_issue = "description_issue" # 描述问题
custom = "custom" # 自定义问题
# ============================================
# 嵌套模型
# ============================================
class Location(BaseModel):
"""位置信息 - 精确定位问题所在位置"""
episode: int = Field(..., description="集数")
scene: Optional[int] = Field(None, description="场景编号")
line: Optional[int] = Field(None, description="行号")
context: Optional[str] = Field(None, description="上下文片段")
class DimensionConfig(BaseModel):
"""维度配置 - 单个审核维度的配置"""
enabled: bool = Field(True, description="是否启用该维度")
strictness: float = Field(0.7, ge=0.0, le=1.0, description="严格程度 0-1")
custom_rules: List[str] = Field(default_factory=list, description="该维度的自定义规则ID列表")
weight: float = Field(1.0, ge=0.0, le=2.0, description="权重,用于计算总分")
class CustomRule(BaseModel):
"""自定义规则"""
id: str = Field(..., description="规则ID")
name: str = Field(..., description="规则名称")
description: str = Field("", description="规则描述")
trigger_condition: str = Field(..., description="触发条件(自然语言描述)")
dimension: DimensionType = Field(..., description="所属维度")
severity: SeverityLevel = Field(SeverityLevel.medium, description="默认严重程度")
enabled: bool = Field(True, description="是否启用")
created_at: datetime = Field(default_factory=datetime.now)
updated_at: datetime = Field(default_factory=datetime.now)
class ReviewIssue(BaseModel):
"""审核问题 - 具体的审核发现"""
id: str = Field(..., description="问题ID")
type: IssueType = Field(..., description="问题类型")
dimension: DimensionType = Field(..., description="所属维度")
severity: SeverityLevel = Field(..., description="严重程度")
location: Location = Field(..., description="问题位置")
description: str = Field(..., description="问题描述")
suggestion: str = Field("", description="修改建议")
rule_id: Optional[str] = Field(None, description="触发的自定义规则ID如果有")
class DimensionScore(BaseModel):
"""维度分数"""
dimension: DimensionType = Field(..., description="维度")
score: float = Field(..., ge=0.0, le=100.0, description="分数 0-100")
passed: bool = Field(..., description="是否通过")
issue_count: int = Field(0, ge=0, description="问题数量")
issues: List[ReviewIssue] = Field(default_factory=list, description="问题列表")
# ============================================
# 核心模型
# ============================================
class ReviewConfig(BaseModel):
"""审核配置 - 项目的审核设置"""
enabled_review_skills: List[str] = Field(
default_factory=lambda: ["consistency_checker"],
description="启用的审核Skill ID列表"
)
overall_strictness: float = Field(0.7, ge=0.0, le=1.0, description="整体严格程度 0-1")
dimension_settings: Dict[DimensionType, DimensionConfig] = Field(
default_factory=dict,
description="各维度配置"
)
custom_rules: List[CustomRule] = Field(default_factory=list, description="自定义规则列表")
auto_fix_enabled: bool = Field(False, description="是否启用自动修复")
pass_threshold: float = Field(75.0, ge=0.0, le=100.0, description="通过阈值")
class Config:
use_enum_values = False
class ReviewResult(BaseModel):
"""审核结果 - 单集审核的完整结果"""
id: str = Field(..., description="审核结果ID")
episode_id: str = Field(..., description="剧集ID")
episode_number: int = Field(..., description="集数")
project_id: str = Field(..., description="项目ID")
# 整体结果
overall_score: float = Field(..., ge=0.0, le=100.0, description="总分 0-100")
passed: bool = Field(..., description="是否通过审核")
passed_dimensions: int = Field(0, ge=0, description="通过的维度数")
total_dimensions: int = Field(0, ge=0, description="总维度数")
# 维度分数
dimension_scores: List[DimensionScore] = Field(
default_factory=list,
description="各维度分数"
)
# 所有问题
issues: List[ReviewIssue] = Field(
default_factory=list,
description="所有问题(按严重程度排序)"
)
# 统计
issue_count: int = Field(0, ge=0, description="总问题数")
high_severity_count: int = Field(0, ge=0, description="高严重度问题数")
medium_severity_count: int = Field(0, ge=0, description="中严重度问题数")
low_severity_count: int = Field(0, ge=0, description="低严重度问题数")
# 元数据
reviewed_at: datetime = Field(default_factory=datetime.now, description="审核时间")
review_duration: Optional[float] = Field(None, description="审核耗时(秒)")
reviewer_version: str = Field("1.0.0", description="审核器版本")
def calculate_statistics(self):
"""计算统计信息"""
self.issue_count = len(self.issues)
self.high_severity_count = sum(1 for i in self.issues if i.severity == SeverityLevel.high)
self.medium_severity_count = sum(1 for i in self.issues if i.severity == SeverityLevel.medium)
self.low_severity_count = sum(1 for i in self.issues if i.severity == SeverityLevel.low)
self.passed_dimensions = sum(1 for ds in self.dimension_scores if ds.passed)
self.total_dimensions = len(self.dimension_scores)
# ============================================
# 请求/响应模型
# ============================================
class ReviewConfigUpdate(BaseModel):
"""更新审核配置请求"""
enabled_review_skills: Optional[List[str]] = None
overall_strictness: Optional[float] = Field(None, ge=0.0, le=1.0)
dimension_settings: Optional[Dict[DimensionType, DimensionConfig]] = None
custom_rules: Optional[List[CustomRule]] = None
auto_fix_enabled: Optional[bool] = None
pass_threshold: Optional[float] = Field(None, ge=0.0, le=100.0)
# 前端兼容字段 - 使用 Dict[str, Any] 避免前向引用问题
preset: Optional[str] = Field(None, description="预设模式: draft|standard|strict|custom")
dimensions: Optional[Dict[str, Any]] = Field(None, description="前端维度配置格式")
customRules: Optional[List[Dict[str, Any]]] = Field(None, description="前端自定义规则格式")
class ReviewRequest(BaseModel):
"""执行审核请求"""
episode_number: int = Field(..., ge=1, description="集数")
dimensions: Optional[List[DimensionType]] = Field(None, description="指定要审核的维度(可选)")
force_rereview: bool = Field(False, description="是否强制重新审核")
class ReviewResponse(BaseModel):
"""审核响应"""
success: bool
review_result: Optional[ReviewResult] = None
message: str = ""
episode_id: Optional[str] = None
class DimensionInfo(BaseModel):
"""维度信息 - 用于返回可用维度"""
id: DimensionType = Field(..., description="维度ID")
name: str = Field(..., description="维度名称")
description: str = Field(..., description="维度描述")
default_strictness: float = Field(0.7, ge=0.0, le=1.0, description="默认严格程度")
supported_skill_ids: List[str] = Field(default_factory=list, description="支持该维度的Skill ID列表")
class CustomRuleCreate(BaseModel):
"""创建自定义规则请求"""
name: str = Field(..., description="规则名称")
description: str = Field("", description="规则描述")
trigger_condition: str = Field(..., description="触发条件")
dimension: Optional[DimensionType] = Field(None, description="所属维度")
severity: SeverityLevel = Field(SeverityLevel.medium, description="严重程度")
category: Optional[str] = Field(None, description="分类(前端使用)")
class CustomRuleUpdate(BaseModel):
"""更新自定义规则请求"""
name: Optional[str] = None
description: Optional[str] = None
trigger_condition: Optional[str] = None
dimension: Optional[DimensionType] = None
severity: Optional[SeverityLevel] = None
enabled: Optional[bool] = None
category: Optional[str] = None
class ReviewPreset(BaseModel):
"""审核预设 - 预设的审核配置"""
id: str = Field(..., description="预设ID")
name: str = Field(..., description="预设名称")
description: str = Field(..., description="预设描述")
config: ReviewConfig = Field(..., description="审核配置")
category: str = Field("general", description="预设分类")