minijev-snake / code /minijev /types.py
markuz89's picture
MiniJEV v2 model export
026f63e verified
Raw History Blame Contribute Delete
1.98 kB
"""Task-agnostic decision interfaces.
MiniJEV always answers the same kind of request::
DecisionRequest(state=..., question="...", choices=["a", "b", ...]) -> Decision
`state` is opaque to the core: each environment/task plugin knows how to turn
its states into tensors (see `minijev.tasks.Task`). Choices are plain strings,
so the number and the meaning of choices are *inputs*, not model constants.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Sequence
State = Any # task-specific (SnakeState, str, dict, ...)
@dataclass
class DecisionRequest:
state: State
question: str
choices: Sequence[str]
@dataclass
class Decision:
choice: str
index: int
confidence: float # calibrated probability of `choice`
scores: dict[str, float] # calibrated probability per choice
logits: list[float] = field(default_factory=list)
embedding: list[float] | None = None # optional shared state representation
raw_scores: dict[str, float] | None = None # softmax(logits), before temperature calibration
temperature: float = 1.0
@property
def distribution(self) -> dict[str, float]:
return self.scores
@property
def raw_confidence(self) -> float:
return self.raw_scores[self.choice] if self.raw_scores else self.confidence
def to_dict(self) -> dict:
d = {"choice": self.choice, "confidence": round(self.confidence, 4),
"distribution": {k: round(v, 4) for k, v in self.scores.items()}}
if self.raw_scores is not None:
d["raw_distribution"] = {k: round(v, 4) for k, v in self.raw_scores.items()}
if self.embedding is not None:
d["embedding"] = self.embedding
return d
@dataclass
class BooleanDecision:
answer: bool
confidence: float # calibrated probability of `answer`
p_yes: float
raw_p_yes: float
def __bool__(self) -> bool:
return self.answer