ProviderRegistry

org.llm4s.llmconnect.spi.ProviderRegistry
See theProviderRegistry companion object
@Stable
final class ProviderRegistry

The set of providers this build can resolve.

A registry is an immutable value, not a mutable global: withProvider and withModule return a new registry, and an application that wants a different set constructs one with ProviderRegistry.of and passes it in. Core code resolves a registry through a using clause, so the default is ProviderRegistry.default — every provider on the classpath — unless the caller supplies another.

llm4s-core ships no provider: every one comes from a provider module (llm4s-openai, llm4s-anthropic, llm4s-gemini, llm4s-ollama, llm4s-openai-compatible, llm4s-voyage, or a third party's), found through its META-INF/services entry. Where discovery cannot run - a shaded fat jar whose services files were merged away - ProviderRegistry.ofModules builds the registry from the modules named explicitly.

Chat and embedding providers are held in separate namespaces, because the two sets overlap without either containing the other - OpenAI and Ollama supply both, Voyage only embeddings, Anthropic only chat. The same id may therefore appear in both, and does: ollama names a chat client and an embedding provider that share nothing but a base URL.

Lookup is by ProviderId and never throws: an id nothing handles produces a Left naming the ids that are registered, which is the difference between a usable error and "provider openai not registered".

Value parameters

descriptors

the registered chat providers, in registration order.

embeddingDescriptors

the registered embedding providers, in registration order.

report

how this registry came to hold them; see ProviderRegistryReport.

Attributes

Companion
object
Graph
Supertypes
class Object
trait Matchable
class Any

Members list

Value members

Concrete methods

def canonicalEmbeddingId(raw: String): ProviderId

canonicalId over the embedding providers, which have their own aliases.

canonicalId over the embedding providers, which have their own aliases.

Attributes

def canonicalId(raw: String): ProviderId

Folds an alias onto the id that owns it, leaving unknown strings alone.

Folds an alias onto the id that owns it, leaving unknown strings alone.

"google" becomes "gemini" because the Gemini descriptor (llm4s-gemini) declares that alias. An id no provider claims is returned canonicalised but unchanged — parsing config must not depend on what happens to be on the classpath; only resolution does.

Attributes

def embeddingIds: Seq[String]

Registered embedding provider ids in canonical spelling, sorted.

Registered embedding provider ids in canonical spelling, sorted.

Attributes

def find(id: ProviderId): Option[ProviderDescriptor]

The registered descriptor for id, if any. Does not consider aliases.

The registered descriptor for id, if any. Does not consider aliases.

Attributes

The registered embedding descriptor for id, if any. Does not consider aliases.

The registered embedding descriptor for id, if any. Does not consider aliases.

Attributes

The registered descriptor for id, or an error naming what is registered.

The registered descriptor for id, or an error naming what is registered.

Attributes

def ids: Seq[String]

Registered chat provider ids in canonical spelling, sorted.

Registered chat provider ids in canonical spelling, sorted.

Attributes

def resolve(id: ProviderId, configPath: Option[String]): Result[ProviderDescriptor]

The registered descriptor for id, or an error naming what is registered.

The registered descriptor for id, or an error naming what is registered.

The error carries the discovery summary as well as the registered ids, because the two most common causes of a missing provider are invisible otherwise: a dependency that was never added, and a fat jar whose META-INF/services entries were dropped or overwritten during shading.

Value parameters

configPath

where the id came from, e.g. "llm4s.providers.my-bedrock.provider". Included in the error so the user knows which entry to fix.

Attributes

def resolveEmbedding(id: ProviderId, configPath: Option[String]): Result[EmbeddingProviderDescriptor]

The registered embedding descriptor for id, or an error naming what is registered.

The registered embedding descriptor for id, or an error naming what is registered.

The error names the '''embedding''' providers specifically. A user who set EMBEDDING_MODEL=anthropic/... needs to be told that Anthropic supplies no embedding provider, not handed the chat list and left to infer it.

Value parameters

configPath

where the id came from, e.g. "llm4s.embeddings.model".

Attributes

override def toString: String

Returns a string representation of the object.

Returns a string representation of the object.

The default representation is platform dependent.

Attributes

Returns

a string representation of the object.

Definition Classes
Any

This registry plus descriptor; a later registration of the same id wins.

This registry plus descriptor; a later registration of the same id wins.

Attributes

This registry plus every provider module supplies, of either kind.

This registry plus every provider module supplies, of either kind.

Attributes

This registry plus descriptor; a later registration of the same id wins.

This registry plus descriptor; a later registration of the same id wins.

This is the escape hatch for a classpath where discovery cannot work — a shaded fat jar, most often. The discovery report is carried through unchanged, so the diagnostics still say what the scan saw.

Attributes