Model providers¶
A model provider is a boundary Brama depends on but does not own. This page carries the provider side of the integration contract: how an existing model bearer is registered as a caller, where the adapter boundary sits, what a catalog entry is allowed to declare, and the provider integration's own identity, reliability, compatibility and removal rules.
Register an existing model bearer¶
Reading a bearer from Skarbiec does not register it as a Brama caller. On the
Skarbiec owner host,
python3 scripts/provision-model-consumer.py probierz --model codex/gpt-5.6-sol
registers the existing probierz-model-router#token value with the
authority for that exact route and audience probierz. It does not
rotate the stored bearer or restart Brama. Repeat --model for
additional exact routes; existing model grants are retained.
The command prints the grant expiry. Running it again renews the same bearer registration. A grant with another audience, a workload key, or non-model capabilities is refused, and that grant is left exactly as it was. Supplying the optional workload public-key path also provisions the caller's separate one-use acquisition grant, as before.
Brama reads this registration through token introspection, so the registered bearer must still meet the request-signing and subscription-ownership requirements. An HTTP 401 means authentication did not succeed; it is not proof that the selected model ran.
Adapter boundary¶
subscription_dispatch owns provider-neutral eligibility and bounded
selection. providers owns external protocol adapters. An adapter
owns:
- endpoint and trusted-host policy;
- credential extraction and provider authorization shape;
- request and response translation;
- model discovery and capability declaration;
- completion, cancellation and response decoding;
- provider-specific error classification and telemetry;
- compatibility and disable/removal behavior.
Core HTTP handlers never construct raw provider requests. Protocol adapters are shared only when their wire behavior is genuinely compatible; provider identity and endpoint policy remain explicit.
POST /v1/chat/completions accepts OpenAI-compatible
tool_choice. OpenAI Chat providers receive it unchanged; the
Responses, Anthropic, and Google adapters translate a named function choice
into their native forced-tool shape. See
HTTP API for the request surface.
Capability declaration¶
Every catalog entry distinguishes:
- executable versus unsupported protocol;
- text and image input modalities;
- tool calling;
- reasoning metadata;
- context and output limits;
- input, output, cache-read, and cache-write price metadata;
- direct capability configured versus agent subscription available.
Catalog metadata is untrusted advisory data. A model is not executable merely because models.dev lists it; Brama must have a supported protocol, trusted endpoint, and correct capability. The catalog contract is on models.dev catalog.
Outcome¶
Execute one provider-neutral ModelRequest and return one normalized
ModelResponse without exposing provider credentials or raw SDK types
to the caller.
Configuration and identity¶
- direct capabilities use key
provider:<slugged-provider>; - account and agent credentials use internal subscription ID and resource
provider:<provider>:<subscription>; - account API keys are written through the local Skarbiec boundary and selected only by the verified Wisent account that owns them;
- endpoint overrides are namespaced by provider and accept HTTPS approved hosts or explicit loopback only;
- only the credential named for the selected route is used: an ambient proxy setting, a redirect, a host metadata identity, and a credential belonging to another provider are never read;
- credentials are redeemed immediately before each attempt.
The alias being served names exactly one destination route, so an attempt reaches exactly one provider. When that provider refuses, the refusal is what the caller receives.
Reliability¶
- a provider attempt finishes when the provider answers or refuses, or its connection fails; Brama does not stop it because of elapsed time;
- buffered provider response bodies are read whole before UTF-8 or JSON parsing;
- selector and credential attempts are bounded by
CORE.md; - only authentication, quota, and rate-limit exhaustion move to another credential for the same route;
- permanent authentication failure appends a retirement marker;
- a malformed or permanent provider result stops replay and returns a normalized failure to the caller;
- provider status and body are treated as untrusted; response handling follows the core resource contract.
Compatibility¶
Brama supports the buffered and streaming shapes implemented by its protocol
adapters, not every feature exposed by a provider SDK. Batch
APIs, files, assistants, fine-tuning, and provider control planes are
unsupported. Provider-only corrections may remain compatible when the
normalized contract is unchanged; schema, behavior, or error changes visible to
callers follow RELEASE.md.
Disable and removal¶
Remove the provider capability mapping and its alias entries, stop advertising
its executable routes, revoke the exact direct or subscription capability, and
retain journal evidence according to policy. An alias entry is removed with
DELETE /v1/admin/routes carrying {"alias"}, which
answers with ok and the whole registry document; if the file on
disk still carries fields from an older shape, bring it forward first with
brama routes migrate.
An alias left declared with no serving destination reports state
no_route, and a completion naming it answers
503 alias_unserviceable with that state and route in
details. Removing one provider must not prevent unrelated direct
routes, local detection, version, or MCP startup.