| """Pydantic data types shared across the routing agent. |
| |
| These types are the stable boundary between the (unknown) scoring harness and |
| the rest of the system. `Task` tolerantly accepts several historically-common |
| field name variants so that `adapter.py` can stay thin; every other module |
| only ever sees the normalized shape. |
| """ |
|
|
| from __future__ import annotations |
|
|
| from typing import Any |
|
|
| from pydantic import BaseModel, ConfigDict, Field, model_validator |
|
|
| |
| _PROMPT_ALIASES = ("prompt", "input", "question", "text") |
|
|
|
|
| class Task(BaseModel): |
| """A single unit of work to route and solve. |
| |
| `prompt` is populated from whichever of `prompt`/`input`/`question`/`text` |
| is present in the source payload (first match wins). `type` is an optional |
| harness-supplied hint; when absent the classifier infers it. |
| """ |
|
|
| model_config = ConfigDict(extra="allow") |
|
|
| id: str |
| prompt: str |
| type: str | None = None |
| metadata: dict[str, Any] = Field(default_factory=dict) |
|
|
| @model_validator(mode="before") |
| @classmethod |
| def _populate_prompt_from_aliases(cls, data: Any) -> Any: |
| if not isinstance(data, dict): |
| return data |
| if data.get("prompt"): |
| return data |
| normalized = dict(data) |
| for alias in _PROMPT_ALIASES: |
| value = data.get(alias) |
| if isinstance(value, str) and value.strip(): |
| normalized["prompt"] = value |
| break |
| return normalized |
|
|
|
|
| class RouteDecision(BaseModel): |
| """Records which tier/model resolved a task, for logging and eval analysis.""" |
|
|
| tier: int |
| model: str | None = None |
| task_type: str |
| confident: bool = True |
| retried: bool = False |
| escalated: bool = False |
|
|
|
|
| class Result(BaseModel): |
| """The output for a single task plus routing metadata (never serialized to |
| the harness-facing results.json — adapter strips metadata before writing). |
| """ |
|
|
| id: str |
| output: str |
| route: RouteDecision | None = None |
|
|
|
|
| class CallRecord(BaseModel): |
| """A single Fireworks API call, as recorded by the TokenLedger.""" |
|
|
| model: str |
| prompt_tokens: int |
| completion_tokens: int |
| cached_tokens: int = 0 |
| latency_ms: float = 0.0 |
| route: str = "" |
| retry: bool = False |
|
|
| @property |
| def total_tokens(self) -> int: |
| return self.prompt_tokens + self.completion_tokens |
|
|