CredentialEndpoint

sealed interface CredentialEndpoint

Where a user's key should be sent, and what the service built from it should say about itself.

A value rather than a service: the application states which endpoint speaks for a provider, and the platform builds the client, so nothing here names a type from com.embabel.agent.spi. That is the point - CredentialLlmServiceFactory is the other way round, and requires a package the documentation asks application code not to depend on.

The case is the wire protocol, because that is what decides which client can talk to the endpoint. Everything that varies within a protocol is a field.

Adding a provider therefore does not mean adding a case, and cannot: the interface is sealed, so only this module can. Nearly every provider speaks one of the protocols below, and reaching it is a CredentialEndpointResolver returning OpenAiCompatible or Anthropic with your base URL - no framework change, no new type.

A case earns its place only when a protocol needs a client this framework does not have, and whoever adds one has to add that client too. Sealed so that the two stay together: an open hierarchy would let an application define a case nothing here can build, and it would fail at runtime with a key already in hand. Until such a protocol is shipped, reach it by registering a CredentialLlmServiceFactory and building the service yourself, accepting the SPI dependency that carries.

Inheritors

Types

Link copied to clipboard
data class Anthropic constructor(val provider: String, val baseUrl: String? = null, val pricingModel: <Error class: unknown class> = PricingModel.ALL_YOU_CAN_EAT, val knowledgeCutoffDate: LocalDate? = null) : CredentialEndpoint

Anthropic's own protocol, for Anthropic and anything fronting it.

Link copied to clipboard
data class OpenAiCompatible constructor(val provider: String, val baseUrl: String?, val pricingModel: <Error class: unknown class> = PricingModel.ALL_YOU_CAN_EAT, val knowledgeCutoffDate: LocalDate? = null) : CredentialEndpoint

The OpenAI wire protocol, which most providers now speak: OpenAI itself, DeepSeek, Mistral, Gemini and Atlas Cloud all reach the platform this way, as does the average self-hosted gateway.

Properties

Link copied to clipboard
abstract val baseUrl: String?

Base URL to talk to, or null for the protocol's default host.

Link copied to clipboard

Null unless you know it for the model the role named. The name comes from configuration and may be one this framework version has never heard of, so a cutoff stated here would be a guess, and it reaches the LLM as a prompt contribution.

Link copied to clipboard
abstract val pricingModel: <Error class: unknown class>

Defaults to PricingModel.ALL_YOU_CAN_EAT - zero - because a BYOK call is billed to the user's own key rather than to the deployment, so charging it to the deployment's cost accounting would be wrong in the one direction that matters. Set it only if you are reselling the call and do want it counted.

Link copied to clipboard
abstract val provider: String

Provider name the built service reports, which is what cost accounting and metadata lookups key on. Usually the same name the credential carries, but it need not be: a credential holds whatever spelling the application stored, and this is the framework's own.