The flow
Reserving before the call stops a workspace from starting more work than its balance allows, then you release the estimate and consume the real cost once you know it.Check access first
isModelGranted() reflects the workspace’s plan. assertCanConsume() throws Ai\Domain\Exceptions\InsufficientCreditsException or Billing\Domain\Exceptions\UsageLimitException, which the exception middleware turns into a 403.
Resolve a service
Bill the usage
TextCompletionResponse::$cost, so you rarely compute it yourself.
Always pass the
Model. The billing service uses it to decide whether credits apply at all: when the workspace brings its own provider key, nothing is charged.Cost calculation
Use the calculator when you bill something the core doesn’t price for you.CostCalculator::estimate($model) returns the model’s configured multiplier as a rough pre-flight number, and CostCalculator::calculate($amount, $model, $opt) converts real usage into credits using the installation’s configured rates. The optional bitmask selects a rate variant, such as CostCalculator::INPUT, CostCalculator::OUTPUT, CostCalculator::IMAGE, CostCalculator::QUALITY_HD and the SIZE_* constants.
Streaming chat
MessageServiceInterface::generateMessage() returns a generator of stream parts. Fold them as they arrive, and take the cost from the usage part:
Which models exist
The model registry holds every service and model the installation knows about, including admin customizations:option.embeddings.model, where one exists.