- Client providers use
IClientProviderfor configuration-driven creation of chat, speech-to-text, and text-to-speech clients. IClientProviderandIClientFactoryare the canonical provider/factory APIs; do not add chat-only compatibility abstractions.- Resolve section-bound
IClientFactoryinstances throughClientFactoryResolver; do not register or depend on an unbound singletonIClientFactory. - Provider-created clients should expose the bound provider options through
GetService(typeof(object), "options")and typed options requests. AddClientsregisters keyedIClientFactory(for sections with directapikey) and keyedIChatClient(for sections withmodelid) by full configuration section path. Alternate lookup keys are registered in priority order (first wins): configuredidattribute, then generated aliases: lowercase path, dotted path (:→.), dotted lowercase path, last path segment, last path segment lowercase. There is no separateAddChatClients— all registration flows throughAddClients.IChatClientregistrations useConfigurableChatClientfor auto-reload; on every configuration reload, the inner client is recreated via the heldIClientFactory, which applies defaults throughDefaultsApplyingClientFactory— there is no separate defaults wrapping at the registration level.- Keyed
IClientFactoryregistrations inAddClientsareDefaultsApplyingClientFactory(ConfigurationBoundClientFactory(...))singletons; theConfigurationBoundClientFactoryre-resolves the provider on everyCreate*Clientcall to reflect configuration changes including provider switches — no reload required for factory-created clients. ConfigurableChatClientholds anIClientFactoryreference (notIClientFactoryResolver); the public resolver-based constructors wrap the resolver inConfigurationBoundClientFactoryfor backwards compatibility.