How it works
ProviderInterface is the core contract (getName, getIdentifier, configure, chatCompletion, complete, embeddings, testConnection, and capability checks). Optional features are opt-in capability interfaces — VisionCapableInterface, StreamingCapableInterface, ToolCapableInterface, DocumentCapableInterface — detected by instanceof, while embeddings remain a core method. AbstractProvider supplies shared behavior and every shipped adapter extends it.
Registration is attribute-driven: a class marked #[AsLlmProvider(priority: N)] in the Netresearch\NrLlm\ namespace is auto-tagged nr_llm.provider by ProviderCompilerPass at container-compile time (ADR-022). Providers are kept private; nothing resolves them by class name — access is via LlmServiceManager, resolved by the identifier returned from getIdentifier(). Priority is an ordering hint only. Third-party providers outside the namespace keep the legacy Services.yaml tag path.
The three tiers are Extbase entities over tx_nrllm_provider, tx_nrllm_model, and tx_nrllm_configuration. A Configuration references a Model, which references a Provider that owns the connection (endpoint_url, adapter_type, timeout, max_retries, and api_key stored as a vault UUID). Calls run through a middleware pipeline (ADR-026) ordered by tag priority: Guardrail (115), Telemetry (110), Idempotency (105), Cache (100), Budget (75), Fallback (50), Usage (25), CircuitBreaker (20).
FallbackMiddleware runs the primary configuration; on a retryable failure it walks the configuration's FallbackChain of sibling configuration identifiers, skipping not-found and inactive ones, until one succeeds or the chain is exhausted (FallbackChainExhaustedException). Retryable is ProviderConnectionException, a 429 ProviderResponseException, or CircuitOpenException. AbstractProvider::getHttpClient() authenticates through nr-vault's HTTP client (vault->http()->withAuthentication(identifier, placement, options)); api-key-less providers such as Ollama use the raw factory client behind an explicit SSRF host check.
Netresearch\NrLlm\Provider\Contract\ProviderInterface
Core provider contract every adapter implements — name, identifier, configure, chatCompletion, complete, embeddings, testConnection, capability checks.
Netresearch\NrLlm\Provider\AbstractProvider
Shared base for the seven adapters; stores apiKeyIdentifier and builds the vault-authenticated HTTP client in getHttpClient().
Netresearch\NrLlm\Attribute\AsLlmProvider
#[AsLlmProvider(priority)] marker; ProviderCompilerPass auto-tags it nr_llm.provider so no Services.yaml entry is needed.
Netresearch\NrLlm\Domain\DTO\FallbackChain
Immutable, normalized ordered list of LlmConfiguration identifiers to try when the primary fails; shallow (a fallback's own chain is ignored).
Netresearch\NrLlm\Provider\Middleware\FallbackMiddleware
Runtime enforcer (tag priority 50): retries the chain on retryable errors, skips inactive/missing configs, throws FallbackChainExhaustedException when all fail.
Netresearch\NrVault\Service\VaultServiceInterface
Resolves the stored UUID identifier to the real secret and injects it at send time; keeps plaintext keys out of nr-llm's code and database.