feat: initial commit
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Pydantic schemas for data_modules outputs.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from pydantic import BaseModel, Field, ValidationError, ConfigDict
|
||||
|
||||
|
||||
class EntityAppeared(BaseModel):
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
id: str
|
||||
type: str
|
||||
mentions: List[str] = Field(default_factory=list)
|
||||
confidence: float = 1.0
|
||||
|
||||
|
||||
class EntityNew(BaseModel):
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
suggested_id: str
|
||||
name: str
|
||||
type: str
|
||||
tier: str = "装饰"
|
||||
|
||||
|
||||
class StateChange(BaseModel):
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
entity_id: str
|
||||
field: str
|
||||
old: Optional[str] = None
|
||||
new: str
|
||||
reason: Optional[str] = None
|
||||
|
||||
|
||||
class RelationshipNew(BaseModel):
|
||||
model_config = ConfigDict(extra="allow", populate_by_name=True)
|
||||
|
||||
from_entity: str = Field(alias="from")
|
||||
to_entity: str = Field(alias="to")
|
||||
type: str
|
||||
description: Optional[str] = None
|
||||
chapter: Optional[int] = None
|
||||
|
||||
|
||||
class UncertainCandidate(BaseModel):
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
type: str
|
||||
id: str
|
||||
|
||||
|
||||
class UncertainMention(BaseModel):
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
mention: str
|
||||
candidates: List[UncertainCandidate] = Field(default_factory=list)
|
||||
confidence: float = 0.0
|
||||
adopted: Optional[str] = None
|
||||
|
||||
|
||||
class DataAgentOutput(BaseModel):
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
entities_appeared: List[EntityAppeared] = Field(default_factory=list)
|
||||
entities_new: List[EntityNew] = Field(default_factory=list)
|
||||
state_changes: List[StateChange] = Field(default_factory=list)
|
||||
relationships_new: List[RelationshipNew] = Field(default_factory=list)
|
||||
scenes_chunked: int = 0
|
||||
uncertain: List[UncertainMention] = Field(default_factory=list)
|
||||
warnings: List[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
class ErrorSchema(BaseModel):
|
||||
model_config = ConfigDict(extra="allow")
|
||||
|
||||
code: str
|
||||
message: str
|
||||
suggestion: Optional[str] = None
|
||||
details: Optional[Dict[str, Any]] = None
|
||||
|
||||
|
||||
def validate_data_agent_output(payload: Dict[str, Any]) -> DataAgentOutput:
|
||||
return DataAgentOutput.model_validate(payload)
|
||||
|
||||
|
||||
def format_validation_error(exc: ValidationError) -> Dict[str, Any]:
|
||||
return {
|
||||
"code": "SCHEMA_VALIDATION_FAILED",
|
||||
"message": "数据结构校验失败",
|
||||
"details": {"errors": exc.errors()},
|
||||
"suggestion": "请检查 data-agent 输出字段是否完整且类型正确",
|
||||
}
|
||||
|
||||
|
||||
def normalize_data_agent_output(payload: Dict[str, Any]) -> Dict[str, Any]:
|
||||
if not isinstance(payload, dict):
|
||||
return {}
|
||||
|
||||
def _ensure_list(key: str):
|
||||
value = payload.get(key)
|
||||
if value is None:
|
||||
payload[key] = []
|
||||
elif isinstance(value, list):
|
||||
return
|
||||
else:
|
||||
payload[key] = [value]
|
||||
|
||||
for key in [
|
||||
"entities_appeared",
|
||||
"entities_new",
|
||||
"state_changes",
|
||||
"relationships_new",
|
||||
"uncertain",
|
||||
"warnings",
|
||||
]:
|
||||
_ensure_list(key)
|
||||
|
||||
payload.setdefault("scenes_chunked", 0)
|
||||
return payload
|
||||
Reference in New Issue
Block a user