Skip to content

models

The model gateway, price table and cost meter.

coalitionkit_models

The model provider gateway, media client, settings, price table and cost meter.

BudgetExhaustedError

Bases: RuntimeError

The Coalition's model budget is spent (protocol error budget_exhausted).

MediaInputError

Bases: ValueError

A media input is unusable (for example a WAV that is not mono 16-bit PCM).

MissingKeyError

Bases: SettingsError

A role needs an API key that is not set.

ProviderError

Bases: RuntimeError

A provider call failed for good: not retryable, or retries ran out.

SchemaValidationError

Bases: ProviderError

The reply did not match the response schema the caller asked for.

SettingsError

Bases: RuntimeError

The configuration is unusable. The message names variables, never their values.

TruncatedReply

Bases: ProviderError

The reply was cut off by the completion budget before any answer text came out.

Raised after one retry with a doubled budget also came back empty with finish_reason == "length" (reasoning tokens used the whole budget).

UnpricedModelError

Bases: LookupError

The price table has no entry for the model, so its cost cannot be metered.

Completer

Bases: Protocol

What callers (the Steward, the Gardener) need from the gateway.

FakeModel dataclass

A scripted transport for tests: replays responses (or raises exceptions) in order.

ModelGateway

aclose async
aclose() -> None

Close the transport's connections (a no-op for transports that hold none).

complete async
complete(
    role: Role,
    messages: Sequence[ChatMessage],
    *,
    coalition_id: str | None = None,
    participant: str = SYSTEM_PARTICIPANT,
    response_schema: type[BaseModel] | None = None,
    **opts: Any,
) -> Completion

One chat completion for a role.

The completion budget (the role setting, or max_completion_tokens) covers reasoning plus the answer; reasoning_effort defaults per role on Meta routes. An empty reply cut by finish_reason == "length" is retried once with double the budget, then raises TruncatedReply. response_schema (a pydantic model) asks for a strict JSON reply and validates it (SchemaValidationError); tools= passes OpenAI-style tools and the calls come back typed in Completion.tool_calls.

Raises BudgetExhaustedError before any request when the Coalition's budget is spent, and ProviderError when the call fails for good.

OpenAITransport

The real transport: the OpenAI SDK with its own retries switched off.

Transport

Bases: Protocol

Sends one request to one route. The retry policy lives in the gateway, not here.

MediaClient

generate_image async
generate_image(
    prompt: str,
    size: str = "1024x1024",
    *,
    coalition_id: str | None = None,
    participant: str = SYSTEM_PARTICIPANT,
) -> bytes

One generated image as bytes (the API returns WebP).

segment async
segment(
    image: bytes | str,
    phrase: str,
    *,
    include_confidence: bool = True,
    coalition_id: str | None = None,
    participant: str = SYSTEM_PARTICIPANT,
) -> list[Segment]

Segments of every instance of a short noun phrase in an image (bytes or URL).

transcribe async
transcribe(
    wav_bytes: bytes,
    mode: TranscribeMode = "PUSH_TO_TALK",
    *,
    language_bias: list[str] | None = None,
    keywords: list[str] | None = None,
    coalition_id: str | None = None,
    participant: str = SYSTEM_PARTICIPANT,
) -> Transcript

Transcribe a mono 16-bit PCM WAV (16 or 24 kHz). Validated before anything is sent.

CostMeter

check
check(coalition_id: str) -> None

Raise BudgetExhaustedError when the Coalition may not start another model call.

record
record(
    coalition_id: str,
    participant: str,
    model: str,
    *,
    prompt_tokens: int,
    completion_tokens: int,
    cached_tokens: int = 0,
    reasoning_tokens: int = 0,
) -> CostRecord

Price one response from its usage fields and add it to the totals.

reasoning_tokens are already inside completion_tokens (they bill at the output rate); they are kept on the record so reasoning cost can be reported.

record_media
record_media(
    coalition_id: str,
    participant: str,
    model: str,
    *,
    images: int = 0,
    audio_ms: int = 0,
) -> CostRecord

Price one media call (images generated or segmented, audio transcribed).

PriceTable

Bases: BaseModel

cost_micro_usd
cost_micro_usd(
    model: str,
    *,
    prompt_tokens: int,
    completion_tokens: int,
    cached_tokens: int = 0,
) -> int

Cost of one response in micro-USD, rounded up once over the whole response.

prompt_tokens includes the cached tokens, as in the OpenAI usage object.

media_cost_micro_usd
media_cost_micro_usd(
    model: str, *, images: int = 0, audio_ms: int = 0
) -> int

Cost of a media call in micro-USD: per image, or per audio hour rounded up.

Mask dataclass

The raw mask payload (everything after data=) and what it is.

SamParseError

Bases: ValueError

The SAM output does not follow the documented grammar.

BraveSearch

The Brave Search API. Needs COALITIONKIT_BRAVE_API_KEY.

DdgSearch

DuckDuckGo through ddgs: keyless. The library is synchronous, so it runs in a thread.

MetaSearch

The Meta endpoint's built-in web search tool, through the Responses API.

SearchRun dataclass

What one search did, for the activity line: the queries actually run and the cost.

Route

Where one role's calls go. Holds no secret; the key is looked up by name.

Settings

Bases: BaseSettings

steward_host property
steward_host: StewardProvider

The explicit provider, else Baseten; missing keys fail closed at use.

route
route(role: Role) -> Route

The model, endpoint and key name for a role.

media_route
media_route(model: str) -> Route

Media calls (images, SAM, transcription) always use the Meta endpoint and key.

api_key
api_key(route: Route) -> str

The key for a route. Raises MissingKeyError (naming the variable) when unset.

ToolCall dataclass

One tool call the model asked for.

arguments is the parsed JSON object. When the model sent empty, malformed or non-object arguments, arguments is None, error says why and raw_arguments keeps the text: the call is not executable and the caller must not run it (never an empty object).

status_error

status_error(status: int) -> openai.APIStatusError

An SDK status error for tests (httpx request and response are synthetic).

load_price_table

load_price_table(version: str | None = None) -> PriceTable

Load a table from the package. Without version the newest file wins.

parse_sam_output

parse_sam_output(text: str) -> list[Segment]

All segments of a SAM response text, in order, across frames.

make_search(
    settings: Settings, *, meter: CostMeter | None = None
) -> SearchProvider | None

The provider the settings name, or None when search is off.

load_settings

load_settings() -> Settings

Read settings from the environment. Errors name variables and never echo values.

validate_wav

validate_wav(data: bytes) -> WavInfo

Raise MediaInputError unless data is a mono 16-bit PCM WAV at 16 or 24 kHz, at most 10 minutes and 32 MB.