maxOutputTokens and $request->timeoutSeconds, * - check $cancel between streamed chunks, * - throw ProviderException with an accurate `dispatched` flag, * - never include credentials in results or exception messages. */ interface ModelAdapter { public function id(): string; /** * Declared capabilities. Every adapter declares all keys; the contract tests check them. * streaming deltas are delivered through $onDelta as they arrive * max_output_tokens hard ceiling the adapter enforces * simulated true for offline stand-ins: their answers must be labelled as simulated * in the UI, diagnostics and evaluation reports * usage "reported": token counts come from the provider's response; * "simulated": computed locally (mock only) * cancellation "between_chunks": $cancel is checked between streamed chunks and the * upstream request is aborted; "none": runs to completion * * @return array{streaming: bool, max_output_tokens: int, simulated: bool, usage: string, cancellation: string} */ public function capabilities(): array; /** * @param callable(string): void|null $onDelta Receives text chunks as they arrive. * @throws ProviderException */ public function complete(ModelRequest $request, CancellationToken $cancel, ?callable $onDelta = null): ModelResult; }