from __future__ import annotations from datetime import datetime, timezone from typing import Any, Literal from pydantic import BaseModel, Field LearningSignalType = Literal[ "preference", "workflow", "decomposition", "tool_success", "correction", ] class SessionRetrospective(BaseModel): retrospective_id: str | None = None user_id: str conversation_id: str request_message_id: str | None = None response_message_id: str | None = None query_text: str final_response: str | None = None summary: str task_type: str | None = None execution_mode: str | None = None primary_agent: str | None = None verification_status: str | None = None verification_summary: str | None = None used_skill_names: list[str] = Field(default_factory=list) evidence_refs: list[dict[str, Any]] = Field(default_factory=list) task_refs: list[dict[str, Any]] = Field(default_factory=list) event_refs: list[dict[str, Any]] = Field(default_factory=list) context_snapshot: dict[str, Any] = Field(default_factory=dict) learning_signals: list["LearningSignal"] = Field(default_factory=list) pattern_candidates: list["PatternCandidate"] = Field(default_factory=list) skill_candidates: list["SkillCandidate"] = Field(default_factory=list) learning_decision: "LearningDecision | None" = None outcome: Literal["completed", "partial", "failed"] = "completed" captured_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) class LearningSignal(BaseModel): signal_type: LearningSignalType confidence: float = 0.0 evidence_refs: list[dict[str, Any]] = Field(default_factory=list) explanation: str | None = None payload: dict[str, Any] = Field(default_factory=dict) class PatternCandidate(BaseModel): pattern_id: str pattern_type: str description: str confidence: float = 0.0 evidence_refs: list[dict[str, Any]] = Field(default_factory=list) class SkillCandidate(BaseModel): candidate_id: str name: str summary: str candidate_type: Literal["workflow_skill", "preference_skill", "decomposition_skill"] = "workflow_skill" source_pattern_ids: list[str] = Field(default_factory=list) confidence: float = 0.0 evidence_refs: list[dict[str, Any]] = Field(default_factory=list) recommended_status: Literal["candidate", "shadow"] = "candidate" class LearningDecision(BaseModel): decision: Literal["reinforce_memory", "create_candidate", "promote_skill", "defer", "reject"] explanation: str evidence_refs: list[dict[str, Any]] = Field(default_factory=list) metadata: dict[str, Any] = Field(default_factory=dict)