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

opts BowireAiOptions

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

providerId string

Returns

bool