Files
AIOA/ai-service/app/models.py
T
selfrelease 57c8a26147 feat: LLM多阶段交互式Schema生成 + UI布局优化
- AI Service: 多阶段对话模型(理解→澄清→生成→校验→确认),支持对话历史和当前Schema上下文
- Backend: 适配多阶段AI模型,Gateway/Service/Controller传递history和currentSchema
- Frontend: AiDesignerChat组件重写,支持阶段徽章、快速回复、Schema校验展示
- Frontend: 表单/流程设计器布局优化,AI助手和Schema预览作为独立列
- Frontend: 流程设计器元数据和模式选择器合并为一行
- Keycloak: 自定义登录主题(中文化)
- 修复CSS媒体查询括号平衡问题
2026-07-19 09:36:42 +08:00

146 lines
5.0 KiB
Python

from datetime import datetime
from enum import StrEnum
from pydantic import BaseModel, ConfigDict, Field, model_validator
class LeaveType(StrEnum):
PERSONAL = "PERSONAL"
SICK = "SICK"
ANNUAL = "ANNUAL"
class LeaveDraftSuggestionRequest(BaseModel):
text: str = Field(min_length=1, max_length=2000)
timezone: str = Field(default="Asia/Shanghai", min_length=1, max_length=64)
now: datetime | None = None
class LeaveDraftSuggestion(BaseModel):
type: LeaveType | None = None
startsAt: datetime | None = None
endsAt: datetime | None = None
reason: str | None = Field(default=None, max_length=2000)
assumptions: list[str] = Field(default_factory=list, max_length=10)
needsClarification: list[str] = Field(default_factory=list, max_length=10)
@model_validator(mode="after")
def validate_time_range(self) -> "LeaveDraftSuggestion":
if self.startsAt is not None and self.endsAt is not None:
if self.startsAt.tzinfo is None or self.endsAt.tzinfo is None:
raise ValueError("startsAt and endsAt must include timezone offsets")
if self.endsAt <= self.startsAt:
raise ValueError("endsAt must be later than startsAt")
if self.reason is not None:
normalized = self.reason.strip()
self.reason = normalized or None
return self
class LeaveDraftSuggestionResponse(BaseModel):
suggestion: LeaveDraftSuggestion
model: str
requiresUserConfirmation: bool = True
class LeaveProgressContext(BaseModel):
model_config = ConfigDict(extra="forbid")
requestId: str
type: LeaveType
status: str
startsAt: datetime
endsAt: datetime
activeTaskNames: list[str] = Field(default_factory=list, max_length=20)
completedTaskNames: list[str] = Field(default_factory=list, max_length=50)
processEnded: bool
timelineEventTypes: list[str] = Field(default_factory=list, max_length=50)
class LeaveProgressAnswerRequest(BaseModel):
question: str = Field(min_length=1, max_length=2000)
timezone: str = Field(min_length=1, max_length=64)
context: LeaveProgressContext
class LeaveProgressAnswerResponse(BaseModel):
answer: str = Field(min_length=1, max_length=2000)
model: str
# ── AI 对话式设计助手(多阶段交互) ──────────────────────────────────
class DesignerStage(StrEnum):
UNDERSTANDING = "UNDERSTANDING"
CLARIFYING = "CLARIFYING"
GENERATING = "GENERATING"
VALIDATING = "VALIDATING"
CONFIRMING = "CONFIRMING"
class DesignerFieldType(StrEnum):
TEXT = "text"
TEXT_AREA = "textArea"
SELECT = "select"
DATE_TIME = "dateTime"
NUMBER = "number"
class DesignerFormField(BaseModel):
key: str = Field(min_length=1, max_length=64)
label: str = Field(min_length=1, max_length=100)
control: DesignerFieldType
required: bool = False
placeholder: str | None = Field(default=None, max_length=200)
options: list[str] | None = Field(default=None, max_length=20)
helperText: str | None = Field(default=None, max_length=200)
class DesignerProcessStep(BaseModel):
name: str = Field(min_length=1, max_length=100)
assigneeVariable: str = Field(min_length=1, max_length=64)
class DesignerProcessSuggestion(BaseModel):
mode: str = Field(default="SERIAL", max_length=20)
steps: list[DesignerProcessStep] = Field(default_factory=list, max_length=10)
conditionThresholdDays: float | None = None
class SchemaValidationIssue(BaseModel):
field: str = Field(min_length=1, max_length=100)
issue: str = Field(min_length=1, max_length=300)
severity: str = Field(default="WARNING", max_length=20)
class DesignerSuggestion(BaseModel):
stage: DesignerStage = DesignerStage.UNDERSTANDING
formTitle: str | None = Field(default=None, max_length=100)
formKey: str | None = Field(default=None, max_length=64)
fields: list[DesignerFormField] = Field(default_factory=list, max_length=30)
process: DesignerProcessSuggestion | None = None
summary: str = Field(default="", max_length=500)
understanding: str = Field(default="", max_length=800)
assumptions: list[str] = Field(default_factory=list, max_length=10)
needsClarification: list[str] = Field(default_factory=list, max_length=10)
validationIssues: list[SchemaValidationIssue] = Field(default_factory=list, max_length=20)
schemaReady: bool = False
class ChatTurn(BaseModel):
role: str = Field(min_length=1, max_length=20)
content: str = Field(min_length=1, max_length=4000)
class DesignerSuggestionRequest(BaseModel):
message: str = Field(min_length=1, max_length=2000)
history: list[ChatTurn] = Field(default_factory=list, max_length=20)
currentSchema: str | None = Field(default=None, max_length=8000)
timezone: str = Field(default="Asia/Shanghai", min_length=1, max_length=64)
class DesignerSuggestionResponse(BaseModel):
suggestion: DesignerSuggestion
model: str
requiresUserConfirmation: bool = True