astera-customerAI / runtime /schemas.py
G-ACE's picture
Deploy current Customer AI runtime 9f9b14b9aede20b7fd34c06fb2d255db93748013
9e95393 verified
Raw History Blame Contribute Delete
4.81 kB
from __future__ import annotations
from enum import Enum
from typing import Any, Literal
from pydantic import BaseModel, Field
class RoleName(str, Enum):
CONSTRUCTIVE = "constructive"
ADVERSARIAL = "adversarial"
EVIDENCE_BOUND = "evidence_bound"
class FollowUpKind(str, Enum):
"""Cross-turn relationship between the current message and prior needs."""
CONTINUE = "continue"
CLARIFICATION = "clarification"
CONDITION_CHANGE = "condition_change"
CORRECTION = "correction"
NEW_NEED = "new_need"
class NeedLifecycle(str, Enum):
ACTIVE = "active"
RESOLVED = "resolved"
UNRESOLVED = "unresolved"
REOPENED = "reopened"
DEFERRED = "deferred"
class NeedTask(BaseModel):
task_id: str
stable_need_id: str | None = None
parent_need_id: str | None = None
text: str
intent: str
required_facts: list[str] = Field(default_factory=list)
completion_condition: str
priority: Literal["primary", "secondary"] = "primary"
response_shape: Literal["direct", "procedure", "comparison", "troubleshooting"] = "direct"
required_user_inputs: list[str] = Field(default_factory=list)
actionability_required: bool = False
condition_signature: str = ""
class GroundedFact(BaseModel):
fact_id: str
value: str
source_id: str
authority: Literal["canonical", "current", "live"]
freshness: str | None = None
public: bool = True
legacy: bool = False
undecided: bool = False
source_ids: list[str] = Field(default_factory=list)
conditions: list[str] = Field(default_factory=list)
exceptions: list[str] = Field(default_factory=list)
relations: list[str] = Field(default_factory=list)
knowledge_key: str | None = None
domain: str | None = None
topic: str | None = None
canonical_key: str | None = None
condition_signature: str = ""
conflict_group: str | None = None
valid_from: str | None = None
valid_to: str | None = None
lifecycle_status: Literal["active", "superseded", "expired", "withdrawn"] = "active"
volatile: bool = False
generation_id: str | None = None
fact_version: str | None = None
class TaskResolution(BaseModel):
task_id: str
public_text: str = ""
evidence_ids: list[str] = Field(default_factory=list)
conditions: list[str] = Field(default_factory=list)
exceptions: list[str] = Field(default_factory=list)
action_steps: list[str] = Field(default_factory=list)
unresolved_reason: str | None = None
@property
def resolved(self) -> bool:
return bool(self.public_text.strip()) and self.unresolved_reason is None
class SharedRolePacket(BaseModel):
request_id: str
session_id: str
turn_id: str
user_message: str
normalized_need: str
audience: str
tasks: list[NeedTask]
user_conditions: dict[str, Any] = Field(default_factory=dict)
language_hints: dict[str, Any] = Field(default_factory=dict)
facts: list[GroundedFact] = Field(default_factory=list)
unresolved_items: list[str] = Field(default_factory=list)
repair_targets: list[str] = Field(default_factory=list)
forbidden_claims: list[str] = Field(default_factory=list)
legacy_exclusions: list[str] = Field(default_factory=list)
completion_conditions: list[str] = Field(default_factory=list)
class RoleResult(BaseModel):
role: RoleName
claims: list[str] = Field(default_factory=list)
evidence_ids: list[str] = Field(default_factory=list)
risks: list[str] = Field(default_factory=list)
uncertainties: list[str] = Field(default_factory=list)
missing_needs: list[str] = Field(default_factory=list)
contradictions: list[str] = Field(default_factory=list)
task_resolutions: list[TaskResolution] = Field(default_factory=list)
proposed_resolution: str = Field(default="", description="Legacy migration field; never use as the sole final response source.")
completion_state: Literal["complete", "partial", "blocked"] = "partial"
class ResolutionMode(str, Enum):
RESOLVED = "resolved"
NEEDS_USER_INPUT = "needs_user_input"
SAFE_PARTIAL = "safe_partial"
BLOCKED_CURRENT_FACT = "blocked_current_fact"
SAFETY_BLOCKED = "safety_blocked"
RUNTIME_FAILURE = "runtime_failure"
class FinalResponse(BaseModel):
request_id: str
session_id: str
turn_id: str
answer: str | None
answered_task_ids: list[str]
unresolved_task_ids: list[str]
evidence_ids: list[str]
resolution_score: float
passed: bool
resolution_mode: ResolutionMode
clarification_questions: list[str] = Field(default_factory=list)
failure_class: Literal["coverage_defect", "grounding_conflict", "safety_rejection", "runtime_failure"] | None = None
violations: list[str] = Field(default_factory=list)