Spaces:
Sleeping
Sleeping
| """Output types produced by ACE roles.""" | |
| from __future__ import annotations | |
| from typing import Any, Dict, List, Optional | |
| from pydantic import BaseModel, ConfigDict, Field, model_validator | |
| from .skillbook import UpdateBatch | |
| class AgentOutput(BaseModel): | |
| """Output from the Agent role containing reasoning and answer.""" | |
| model_config = ConfigDict(arbitrary_types_allowed=True) | |
| reasoning: str = Field(..., description="Step-by-step reasoning process") | |
| final_answer: str = Field(..., description="The final answer to the question") | |
| skill_ids: List[str] = Field( | |
| default_factory=list, description="IDs of strategies cited in reasoning" | |
| ) | |
| raw: Dict[str, Any] = Field( | |
| default_factory=dict, description="Raw LLM response data" | |
| ) | |
| trace_context: Optional[Any] = Field( | |
| default=None, | |
| exclude=True, | |
| description="Pre-built TraceContext from integration (bypasses auto-detection)", | |
| ) | |
| class ExtractedLearning(BaseModel): | |
| """A single learning extracted by the Reflector from task execution.""" | |
| learning: str = Field(..., description="The extracted learning or insight") | |
| evidence: str = Field( | |
| default="", | |
| description=( | |
| "Specific traces/items where this pattern was observed. " | |
| "Cite task IDs or item indices, e.g. 'task_2, task_16, task_29'." | |
| ), | |
| ) | |
| justification: str = Field( | |
| default="", | |
| description=( | |
| "Why this is worth remembering: how many traces exhibited this pattern, " | |
| "whether it's recurring or a one-off, and why it generalizes beyond these examples." | |
| ), | |
| ) | |
| class ReflectorOutput(BaseModel): | |
| """Output from the Reflector role containing pure analysis. | |
| Reflector reports what it found; downstream (SkillManager) decides how | |
| to act. No tagging fields, no prescriptive output. | |
| """ | |
| model_config = ConfigDict(arbitrary_types_allowed=True) | |
| reasoning: str = Field(..., description="Overall reasoning about the outcome") | |
| error_identification: str = Field( | |
| default="", description="Description of what went wrong (if applicable)" | |
| ) | |
| root_cause_analysis: str = Field( | |
| default="", description="Analysis of why errors occurred" | |
| ) | |
| correct_approach: str = Field( | |
| ..., description="What the correct approach should be" | |
| ) | |
| key_insight: str = Field( | |
| ..., description="The main lesson learned from this iteration" | |
| ) | |
| raw: Dict[str, Any] = Field( | |
| default_factory=dict, description="Raw LLM response data" | |
| ) | |
| class SkillManagerOutput(BaseModel): | |
| """Output from the SkillManager role containing skillbook update operations. | |
| Accepts both nested ``{"update": {"reasoning": ..., "operations": [...]}}`` | |
| and the flat shape the LLM actually returns: | |
| ``{"reasoning": ..., "operations": [...]}``. | |
| """ | |
| model_config = ConfigDict(arbitrary_types_allowed=True) | |
| update: UpdateBatch = Field( | |
| ..., description="Batch of update operations to apply to skillbook" | |
| ) | |
| raw: Dict[str, Any] = Field( | |
| default_factory=dict, description="Raw LLM response data" | |
| ) | |
| def _accept_flat_shape(cls, data: Any) -> Any: | |
| """If the LLM returns {reasoning, operations, ...} without an 'update' | |
| wrapper, nest it automatically so Pydantic can validate.""" | |
| if isinstance(data, dict) and "update" not in data and "operations" in data: | |
| reasoning = data.pop("reasoning", "") | |
| operations = data.pop("operations", []) | |
| data["update"] = UpdateBatch.from_json( | |
| {"reasoning": reasoning, "operations": operations} | |
| ) | |
| return data | |