ProviderConfigSpec

org.llm4s.llmconnect.spi.ProviderConfigSpec
See theProviderConfigSpec companion object
@Stable
final case class ProviderConfigSpec

The shape of a provider's llm4s.providers.<name> section: which fields it requires, which provider-specific keys it accepts, and what to tell the user when one is missing.

This replaces the per-provider NamedProviderValidator implementations that llm4s-core used to hold, one object per provider in a shared file. A provider now declares its own requirements, and a single generic validator turns that declaration into the same error messages as before.

== Why defaults live here rather than in HOCON == Chat-provider config is keyed by the user's ''instance'' name (llm4s.providers.my-openai.baseUrl), so a reference.conf fragment shipped by a provider module cannot express "the default baseUrl for anything whose provider = "openai"" — it does not know the instance name. defaultBaseUrl is therefore code, and is the single source for a provider's default endpoint. The same holds for the defaults of extras.

== Provider-specific keys == The built-in fields (ProviderConfigSpec.BuiltinKeys) are shared by every provider. Anything else a provider needs - a cloud region, a project id - is declared in extras rather than smuggled through a built-in field (#1215):

val configSpec = ProviderConfigSpec(
 extras = Seq(
   ProviderConfigKey.required("project", "the GCP project ID that owns your Vertex AI resources"),
   ProviderConfigKey.optional("location", "the GCP region", default = Some("us-central1"))
 )
)

Value parameters

apiKeyEnv

the variables the provider's module binds to its vendor's shared key, llm4s.credentials.<id>.apiKey, highest precedence first - e.g. Seq("OPENAI_API_KEY"), or Gemini's Seq("GOOGLE_API_KEY", "GEMINI_API_KEY"). Named in the missing-apiKey error. This is a declaration for the message only: the binding itself is a line in the module's reference.conf, and the module's round-trip spec proves the two agree. Empty when the module binds no variable; the error then names llm4s.credentials.<id>.apiKey itself.

authExtras

the keys this provider reads from a section's auth block besides the identity token (identityTokenFile / identityToken, which core reads itself). Non-empty means the provider supports workload-identity authentication, and a section with an auth block then needs no apiKey; required and default keys are validated as for extras.

baseUrlEnv

the conventional environment variable for baseUrl, if the provider has one. The missing-baseUrl message then shows the binding that reads it (baseUrl = ${?VAR}); None means no variable is suggested.

baseUrlExample

example shown when a required baseUrl is missing.

defaultBaseUrl

base URL used when the section omits one.

extras

the provider-specific keys this section accepts.

keylessWhen

a provider-specific key and the value of it that selects an authentication needing no API key - Azure OpenAI's authentication = "entra-id" (#2274). A section that sets that value is validated without an apiKey, does not take the vendor's shared key, and may not set one of its own. The key must be one of extras; the value is compared ignoring case and surrounding blanks. None, the default, when every section of the provider needs a key. == The API key == A section's key is its own apiKey when it sets one, and otherwise the vendor's shared llm4s.credentials.<id>.apiKey - keyed by provider id, which a reference.conf ''can'' know, unlike the instance name. So with OPENAI_API_KEY set, a section needs only provider and model; a section for a second account sets apiKey itself.

requiresApiKey

the section must carry a non-empty apiKey.

requiresBaseUrl

the section must carry a non-empty baseUrl; set this only when there is no defaultBaseUrl.

Attributes

Companion
object
Graph
Supertypes
trait Serializable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all

Members list

Value members

Concrete methods

def extra(name: String): Option[ProviderConfigKey]

The declared provider-specific key called name, if any.

The declared provider-specific key called name, if any.

Attributes

def withApiKeyEnv(apiKeyEnv: Seq[String]): ProviderConfigSpec
def withBaseUrlEnv(baseUrlEnv: String): ProviderConfigSpec
def withBaseUrlEnv(baseUrlEnv: Option[String]): ProviderConfigSpec
def withBaseUrlExample(baseUrlExample: String): ProviderConfigSpec
def withDefaultBaseUrl(defaultBaseUrl: String): ProviderConfigSpec
def withDefaultBaseUrl(defaultBaseUrl: Option[String]): ProviderConfigSpec
def withKeylessWhen(key: String, value: String): ProviderConfigSpec
def withKeylessWhen(keylessWhen: Option[(String, String)]): ProviderConfigSpec
def withRequiresApiKey(requiresApiKey: Boolean): ProviderConfigSpec
def withRequiresBaseUrl(requiresBaseUrl: Boolean): ProviderConfigSpec

Inherited methods

def productElementNames: Iterator[String]

Attributes

Inherited from:
Product
def productIterator: Iterator[Any]

Attributes

Inherited from:
Product