Interface IBowireAiProviderFactory
- Namespace
- Kuestenlogik.Bowire.Ai
- Assembly
- Kuestenlogik.Bowire.Ai.dll
Plugin seam for AI provider connectors. Each provider package
(Kuestenlogik.Bowire.Ai.OpenAi / .Anthropic /
.Mcp) registers exactly one implementation against the
DI container. The core Kuestenlogik.Bowire.Ai package
ships only the Ollama / LM Studio factory and the seam itself
— embedded hosts pay only for the providers they install.
public interface IBowireAiProviderFactory
Remarks
Why a factory, not a direct service registration. The active provider is a runtime pick from the Settings UI (#63), not a compile-time choice. The runtime needs to (a) hold every available factory and (b) build a fresh Microsoft.Extensions.AI.IChatClient when the user swaps providers without restarting the host. The factory shape lets each provider package own its own credential reading, endpoint defaults, and disposable lifetime contract.
Factory selection contract. BowireAiRuntime
iterates registered factories in DI order and picks the first whose
Matches(string) accepts the configured provider id. Each
provider package's AddBowireAi* extension registers the
factory as a transient (default) or singleton (if it caches HTTP
clients itself); either lifetime works because the runtime only
asks for Build(BowireAiOptions) on hot-swap.
Methods
Build(BowireAiOptions)
Build the active Microsoft.Extensions.AI.IChatClient for these options.
Returns (null, null) when the provider id matches but
the options are incomplete (missing API key, missing endpoint)
— the runtime surfaces this as a 503 with a "configure me"
message rather than throwing. The second tuple item is the
inner socket-owning disposable; the runtime calls
Dispose() on it during hot-swap and
shutdown so a Settings-UI save doesn't leak the HTTP pool.
May be the same instance as the client when there's no
separate inner — that's fine, the runtime treats double-dispose
as a no-op.
(IChatClient? Client, IDisposable? Inner) Build(BowireAiOptions opts)
Parameters
optsBowireAiOptions
Returns
- (IChatClient Client, IDisposable Inner)
Matches(string)
True when this factory handles the configured
ProviderId. Compared
case-insensitively in implementations. A single factory MAY
match multiple ids when they share an SDK shape — the OpenAI
factory matches both openai and openrouter
because they speak the same wire format.
bool Matches(string providerId)
Parameters
providerIdstring