from __future__ import annotations from datetime import datetime from typing import Any from pydantic import BaseModel, ConfigDict, Field from app.core.agent_enums import ( AgentAssetContentType, AgentAssetDomain, AgentAssetStatus, AgentAssetType, AgentReviewStatus, ) class AgentAssetCreate(BaseModel): asset_type: AgentAssetType code: str = Field(min_length=1, max_length=100) name: str = Field(min_length=1, max_length=200) description: str = "" domain: AgentAssetDomain scenario_json: list[Any] = Field(default_factory=list) owner: str = Field(min_length=1, max_length=100) reviewer: str | None = Field(default=None, max_length=100) status: AgentAssetStatus = AgentAssetStatus.DRAFT config_json: dict[str, Any] = Field(default_factory=dict) class AgentAssetUpdate(BaseModel): name: str | None = Field(default=None, min_length=1, max_length=200) description: str | None = None domain: AgentAssetDomain | None = None scenario_json: list[Any] | None = None owner: str | None = Field(default=None, min_length=1, max_length=100) reviewer: str | None = Field(default=None, max_length=100) status: AgentAssetStatus | None = None current_version: str | None = Field(default=None, max_length=30) published_version: str | None = Field(default=None, max_length=30) working_version: str | None = Field(default=None, max_length=30) config_json: dict[str, Any] | None = None class AgentAssetVersionCreate(BaseModel): version: str = Field(min_length=1, max_length=30) content: Any content_type: AgentAssetContentType change_note: str | None = None created_by: str = Field(min_length=1, max_length=100) class RuleMarkdownUpdate(BaseModel): version: str = Field(min_length=1, max_length=30) content: str change_note: str | None = None created_by: str = Field(min_length=1, max_length=100) class AgentAssetReviewCreate(BaseModel): version: str = Field(min_length=1, max_length=30) reviewer: str = Field(min_length=1, max_length=100) review_status: AgentReviewStatus review_note: str | None = None class AgentAssetReviewRead(BaseModel): model_config = ConfigDict(from_attributes=True) id: str asset_id: str version: str reviewer: str review_status: str review_note: str | None reviewed_at: datetime | None created_at: datetime class AgentAssetOnlyOfficeConfigRead(BaseModel): documentServerUrl: str config: dict[str, Any] = Field(default_factory=dict) class AgentAssetOnlyOfficeCallbackRead(BaseModel): error: int = 0 class AgentAssetOnlyOfficeCallbackWrite(BaseModel): model_config = ConfigDict(extra="allow") status: int = Field(description="ONLYOFFICE 回调状态码。") url: str | None = Field(default=None, description="文档下载地址,状态为 2 或 6 时使用。") users: list[str] = Field(default_factory=list, description="当前编辑用户列表。") class AgentAssetRuleJsonWrite(BaseModel): payload: dict[str, Any] = Field(default_factory=dict) class AgentAssetRuleJsonRead(BaseModel): file_name: str rule_code: str name: str description: str = "" evaluator: str = "" ontology_signal: str | None = None flow_diagram_svg: str | None = None inputs: dict[str, Any] = Field(default_factory=dict) outcomes: dict[str, Any] = Field(default_factory=dict) payload: dict[str, Any] = Field(default_factory=dict) class AgentAssetRiskRuleGenerateRequest(BaseModel): business_domain: AgentAssetDomain = AgentAssetDomain.EXPENSE business_stage: str | None = Field( default="reimbursement", pattern="^(expense_application|reimbursement)$", max_length=40, ) expense_category: str | None = Field(default=None, max_length=40) rule_title: str | None = Field(default=None, max_length=80) risk_level: str | None = Field(default=None, pattern="^(low|medium|high|critical)$") natural_language: str = Field(min_length=8, max_length=2000) requires_attachment: bool = False class AgentAssetRiskRuleSampleCase(BaseModel): case_id: str | None = Field(default=None, max_length=60) name: str = Field(default="测试样例", min_length=1, max_length=80) values: dict[str, Any] = Field(default_factory=dict) expected_hit: bool = True expected_severity: str | None = Field(default=None, max_length=20) note: str | None = None class AgentAssetRiskRuleSampleTestRequest(BaseModel): version: str | None = Field(default=None, max_length=30) cases: list[AgentAssetRiskRuleSampleCase] = Field(default_factory=list) class AgentAssetRiskRuleScenarioTestRequest(BaseModel): version: str | None = Field(default=None, max_length=30) intent: str = Field(default="", max_length=1000) filters: dict[str, Any] = Field(default_factory=dict) class AgentAssetRiskRuleReportRequest(BaseModel): version: str | None = Field(default=None, max_length=30) confirm_passed: bool = True note: str | None = Field(default=None, max_length=1000) class AgentAssetRiskRuleSimulationAttachment(BaseModel): name: str = Field(default="", max_length=240) content_type: str | None = Field(default=None, max_length=120) size: int | None = Field(default=None, ge=0) note: str | None = Field(default=None, max_length=500) ocr_text: str | None = Field(default=None, max_length=20000) summary: str | None = Field(default=None, max_length=2000) document_type: str | None = Field(default=None, max_length=80) document_type_label: str | None = Field(default=None, max_length=120) scene_code: str | None = Field(default=None, max_length=80) scene_label: str | None = Field(default=None, max_length=120) avg_score: float | None = Field(default=None, ge=0.0, le=1.0) recognition_status: str | None = Field(default=None, max_length=40) document_fields: list[dict[str, Any]] = Field(default_factory=list) class AgentAssetRiskRuleSimulationRequest(BaseModel): version: str | None = Field(default=None, max_length=30) message: str = Field(default="", max_length=4000) field_values: dict[str, Any] = Field(default_factory=dict) attachments: list[AgentAssetRiskRuleSimulationAttachment] = Field(default_factory=list) class AgentAssetRiskRuleSimulationRead(BaseModel): version: str ready: bool = True stage: str = "executed" hit: bool severity: str = "none" severity_label: str = "未命中" summary: str blocking_reason: str = "" message: str = "" field_values: dict[str, Any] = Field(default_factory=dict) evidence: dict[str, Any] = Field(default_factory=dict) attachments: list[dict[str, Any]] = Field(default_factory=list) recognized_fields: list[dict[str, Any]] = Field(default_factory=list) missing_fields: list[dict[str, Any]] = Field(default_factory=list) recognition_summary: list[dict[str, Any]] = Field(default_factory=list) execution_mode: str = "risk_rule_simulation" created_at: datetime class AgentAssetRiskRuleReturnRequest(BaseModel): note: str = Field(min_length=1, max_length=1000) class AgentAssetRiskRuleEnabledUpdate(BaseModel): enabled: bool class AgentAssetRiskRuleLevelUpdate(BaseModel): risk_level: str = Field(pattern="^(low|medium|high|critical)$") class AgentAssetRiskRuleTestRunRead(BaseModel): model_config = ConfigDict(from_attributes=True) id: str asset_id: str version: str test_type: str status: str passed: bool summary: str input_json: dict[str, Any] = Field(default_factory=dict) result_json: dict[str, Any] = Field(default_factory=dict) created_by: str created_at: datetime class AgentAssetRiskRuleLatestTestSummary(BaseModel): version: str = "" sample: AgentAssetRiskRuleTestRunRead | None = None scenario: AgentAssetRiskRuleTestRunRead | None = None report: AgentAssetRiskRuleTestRunRead | None = None test_passed: bool = False class AgentAssetVersionTimelineItemRead(BaseModel): event_type: str version: str actor: str event_time: datetime title: str description: str = "" note: str | None = None source_version: str | None = None class AgentAssetSpreadsheetDiffCellRead(BaseModel): sheet_name: str cell: str change_type: str before_value: Any | None = None after_value: Any | None = None class AgentAssetSpreadsheetDiffSheetRead(BaseModel): sheet_name: str change_type: str class AgentAssetSpreadsheetChangeRecordRead(BaseModel): id: str actor: str changed_at: datetime summary: str sheet_changes: list[AgentAssetSpreadsheetDiffSheetRead] = Field(default_factory=list) cell_changes: list[AgentAssetSpreadsheetDiffCellRead] = Field(default_factory=list) changed_sheet_count: int = 0 changed_cell_count: int = 0 class AgentAssetVersionRead(BaseModel): model_config = ConfigDict(from_attributes=True) id: str asset_id: str version: str content: Any content_type: str change_note: str | None created_by: str created_at: datetime is_current: bool = False is_published: bool = False is_working: bool = False lifecycle_state: str = "history" class AgentAssetListItem(BaseModel): model_config = ConfigDict(from_attributes=True) id: str asset_type: str code: str name: str description: str domain: str scenario_json: list[Any] owner: str reviewer: str | None status: str current_version: str | None published_version: str | None working_version: str | None config_json: dict[str, Any] change_count: int = 0 modified_by: str | None = None published_by: str | None = None published_at: datetime | None = None created_at: datetime updated_at: datetime class AgentAssetRead(AgentAssetListItem): current_version_content: Any | None = None current_version_content_type: str | None = None current_version_change_note: str | None = None recent_versions: list[AgentAssetVersionRead] = Field(default_factory=list) latest_review: AgentAssetReviewRead | None = None latest_test_summary: AgentAssetRiskRuleLatestTestSummary | None = None