distill::teacher::TeacherClient
More...
Public Functions
|
Name |
|
init(self self, Optional config_path[Path] =None, Optional project_root[Path] =None) |
|
reset_budget(self self) |
|
generate(self self, Optional model_name[str] =None, messages messages =None, ** kwargs) |
|
generate_with_logprobs(self self, Optional model_name[str] =None, messages messages =None, ** kwargs) |
|
generate_with_cascade(self self, messages messages, domain domain ="encyclopedic", ** kwargs) |
|
total_cost(self self) |
|
budget_cap(self self) |
|
circuit_open(self self) |
|
call_count(self self) |
Protected Functions
|
Name |
| str |
_resolve_api_key(str endpoint_name, str api_type) |
|
_load_config(self self, config_path config_path) |
|
_get_or_create_backend(self self, str endpoint_name) |
|
_resolve_backend(self self, str model_name) |
| float |
_estimate_cost(self self, int prompt_tokens, int completion_tokens) |
|
_log_cost(self self, str model_name, int prompt_tokens, int completion_tokens, float cost) |
|
_log_error(self self, str error_type, Optional status_code[int], str detail) |
|
_load_budget_state(self self) |
|
_save_budget_state(self self) |
|
_check_circuit(self self) |
|
_check_budget(self self) |
| bool |
_is_retryable(self self, Exception exception) |
|
_call_api(self self, str model_name, messages messages, ** kwargs) |
Protected Attributes
Detailed Description
class distill::teacher::TeacherClient;
Multi-backend teacher API client.
Builds a backend registry from ``config/pipeline.yaml`` endpoints and
dispatches each ``generate()`` call to the correct backend based on the
model's endpoint ``apiType``.
Backends are constructed lazily on first use so that test code can inject
mock backends via ``client._backends`` without triggering real SDK imports.
Public Functions Documentation
function init
__init__(
self self,
Optional config_path[Path] =None,
Optional project_root[Path] =None
)
function reset_budget
reset_budget(
self self
)
Reset cumulative spend to zero and persist the change.
Used by the pipeline runner when the ``--reset-budget`` CLI flag
is passed.
function generate
generate(
self self,
Optional model_name[str] =None,
messages messages =None,
** kwargs
)
Generate a completion through the appropriate backend.
Args:
model_name: Model key from the ``models`` config block. If ``None``,
defaults to ``teacher.level1`` from pipeline.yaml.
messages: List of message dicts (OpenAI format).
**kwargs: Extra parameters forwarded to the backend.
Returns:
``_ResponseWrapper`` with ``.choices[0].message.content`` and ``.usage``.
function generate_with_logprobs
generate_with_logprobs(
self self,
Optional model_name[str] =None,
messages messages =None,
** kwargs
)
Generate with log-probabilities (OpenAI-compatible endpoints only).
Args:
model_name: Model key (defaults to ``teacher.level1``).
messages: List of message dicts.
**kwargs: Extra parameters.
Returns:
``_ResponseWrapper`` with logprobs data.
function generate_with_cascade
generate_with_cascade(
self self,
messages messages,
domain domain ="encyclopedic",
** kwargs
)
Generate a completion using the multi-teacher cascade.
Routes through ``TeacherCascade.execute()``: Level 1 always runs;
Level 2 is invoked only when Level 1 confidence is below threshold
and the best Level 2 teacher is selected from the benchmark table.
Args:
messages: List of message dicts (OpenAI format).
domain: Specialist niche name (e.g. ``"code"``, ``"medical"``).
Defaults to ``"encyclopedic"``.
**kwargs: Extra parameters forwarded to each teacher call.
Returns:
``_ResponseWrapper`` with ``.choices[0].message.content`` set to
the cascade's final content. The raw response payload is the
cascade result dict (for logging / inspection).
function total_cost
function budget_cap
function circuit_open
circuit_open(
self self
)
function call_count
Protected Functions Documentation
function _resolve_api_key
static str _resolve_api_key(
str endpoint_name,
str api_type
)
Resolve the API key for an endpoint.
Priority:
1. ``LITELLM_API_KEY`` env var (for LiteLLM proxy endpoints)
2. ``{ENDPOINT_NAME_UPPER}_API_KEY`` env var
3. ``{API_TYPE_UPPER}_API_KEY`` env var (e.g. ``ANTHROPIC_API_KEY``)
Raises:
TeacherConfigError: If no API key is found.
function _load_config
_load_config(
self self,
config_path config_path
)
function _get_or_create_backend
_get_or_create_backend(
self self,
str endpoint_name
)
Return (possibly creating) the backend instance for an endpoint.
Backends are created lazily so that tests may inject mocks into
``self._backends`` before any real SDK client is constructed.
function _resolve_backend
_resolve_backend(
self self,
str model_name
)
Look up the backend instance for a model name.
Args:
model_name: Key in the ``models`` config block (e.g. ``"deepseek-v4-fast"``).
Returns:
A ``TeacherBackend`` instance.
Raises:
TeacherConfigError: If the model or its endpoint is unknown.
function _estimate_cost
float _estimate_cost(
self self,
int prompt_tokens,
int completion_tokens
)
function _log_cost
_log_cost(
self self,
str model_name,
int prompt_tokens,
int completion_tokens,
float cost
)
function _log_error
_log_error(
self self,
str error_type,
Optional status_code[int],
str detail
)
function _load_budget_state
_load_budget_state(
self self
)
Load cumulative spend from ``artifacts/.budget_state.json``.
Budget state file format::
{
"cumulative_cost_usd": 1.234,
"budget_cap_usd": 5.0,
"last_updated": "2026-06-19T12:00:00+00:00",
"version": 1
}
If the file does not exist the budget starts at ``0.0``.
The budget state file can be edited manually — it is a soft
cost-control limit, not a security boundary (see T-04-01).
function _save_budget_state
_save_budget_state(
self self
)
Persist current cumulative spend to ``artifacts/.budget_state.json``.
Called after every successful API call that adds cost. Creates
parent directories if they do not exist.
function _check_circuit
_check_circuit(
self self
)
Gate API calls through a half-open circuit breaker.
**Closed:** calls proceed normally.
**Open:** calls are blocked for ``recovery_timeout`` seconds.
After the timeout elapses the circuit transitions to
*half-open* — the next call is allowed as a probe.
**Half-open:** a single probe call is permitted. If it succeeds
the circuit closes. If it fails the circuit re-opens
with a fresh recovery timer.
Raises:
CircuitBreakerOpenError: When the circuit is open and the
recovery timeout has not elapsed.
function _check_budget
_check_budget(
self self
)
Raise ``BudgetExceededError`` when cumulative spend hits the cap.
Budget enforcement reads the persisted total from disk on startup
(see ``_load_budget_state``), so the cap applies across runs.
function _is_retryable
bool _is_retryable(
self self,
Exception exception
)
function _call_api
_call_api(
self self,
str model_name,
messages messages,
** kwargs
)
Execute an API call through the correct backend with retry + circuit breaker.
Circuit breaker state machine:
* **Closed** → calls proceed; after ``failure_threshold`` consecutive
failures the circuit **opens** with a timestamp.
* **Open** → calls are blocked for ``recovery_timeout`` seconds.
* **Half-open** → one probe call is allowed. Success **closes** the
circuit. Failure **re-opens** it with a fresh recovery timer.
Args:
model_name: Key from the ``models`` config block.
messages: List of message dicts (OpenAI format).
**kwargs: Passed to ``backend.generate()`` (max_tokens, temperature, etc.).
Returns:
``_ResponseWrapper`` with ``.choices[0].message.content`` and ``.usage``.
Protected Attributes Documentation
variable _project_root
variable _config
variable _models
variable _default_max_tokens
variable _default_temperature
variable _max_retries
variable _backoff_base
variable _budget_cap
variable _max_consecutive_failures
_max_consecutive_failures;
variable _circuit_recovery_timeout
_circuit_recovery_timeout;
variable _endpoint_registry
variable _backends
variable _cascade
variable _total_cost
variable _budget_version
variable _call_count
variable _consecutive_failures
variable _circuit_open
variable _circuit_opened_at
variable _circuit_half_open
variable _cost_log_path
variable _error_log_path
variable _budget_state_path
Updated on 2026-07-25 at 22:56:57 +0000