dheraingoud's picture
feat: sync upstream commits up to f17c92bc
a1bab2d
Raw
History Blame Contribute Delete
3.61 kB
"""Provider-neutral reasoning intent."""
from __future__ import annotations
from dataclasses import dataclass
from enum import StrEnum
class ReasoningControl(StrEnum):
"""Whether a request explicitly controls reasoning computation."""
DEFAULT = "default"
OFF = "off"
ON = "on"
class ReasoningEffort(StrEnum):
"""Named reasoning effort understood at the FCC application boundary."""
MINIMAL = "minimal"
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
XHIGH = "xhigh"
MAX = "max"
@property
def budget_tokens(self) -> int:
"""Return FCC's numeric token budget for this effort."""
return _EFFORT_BUDGET_TOKENS[self]
_EFFORT_BUDGET_TOKENS = {
ReasoningEffort.MINIMAL: 512,
ReasoningEffort.LOW: 512,
ReasoningEffort.MEDIUM: 1_024,
ReasoningEffort.HIGH: 2_048,
ReasoningEffort.XHIGH: 4_096,
ReasoningEffort.MAX: 8_192,
}
@dataclass(frozen=True, slots=True)
class ReasoningPolicy:
"""Resolved client and configuration intent passed to one provider.
``control`` and ``effort`` remain independent because clients may set an
overall effort while separately disabling extended thinking. Providers
translate the representable subset without changing the original intent.
"""
control: ReasoningControl = ReasoningControl.DEFAULT
effort: ReasoningEffort | None = None
budget_tokens: int | None = None
def __post_init__(self) -> None:
if self.budget_tokens is not None and (
not isinstance(self.budget_tokens, int)
or isinstance(self.budget_tokens, bool)
or self.budget_tokens <= 0
):
raise ValueError("Reasoning budget must be a positive integer.")
if self.budget_tokens is not None and self.control is not ReasoningControl.ON:
raise ValueError("A reasoning budget requires reasoning control to be on.")
@classmethod
def provider_default(cls) -> "ReasoningPolicy":
"""Leave reasoning computation to the provider."""
return cls()
@classmethod
def off(cls) -> "ReasoningPolicy":
"""Explicitly disable reasoning computation and output."""
return cls(control=ReasoningControl.OFF)
@classmethod
def on(
cls,
*,
effort: ReasoningEffort | None = None,
budget_tokens: int | None = None,
) -> "ReasoningPolicy":
"""Explicitly enable reasoning with optional client controls."""
return cls(
control=ReasoningControl.ON,
effort=effort,
budget_tokens=budget_tokens,
)
@property
def output_enabled(self) -> bool:
"""Return whether provider reasoning may be exposed to the client."""
return self.control is not ReasoningControl.OFF
@property
def requests_reasoning(self) -> bool:
"""Return whether the request explicitly asks the provider to reason."""
return self.control is not ReasoningControl.OFF and (
self.control is ReasoningControl.ON
or self.effort is not None
or self.budget_tokens is not None
)
@property
def numeric_budget_tokens(self) -> int | None:
"""Express this intent as an exact or FCC-mapped numeric budget."""
if self.control is ReasoningControl.OFF:
return None
if self.budget_tokens is not None:
return self.budget_tokens
if self.effort is None:
return None
return self.effort.budget_tokens
DEFAULT_REASONING_POLICY = ReasoningPolicy.provider_default()