Documentation
¶
Index ¶
- type APIFormat
- type Capabilities
- type ContextLimitField
- type ContextLimitValidationReason
- type ContextLimits
- type ContextLimitsValidationError
- type Effort
- type Model
- type ModelKey
- type ModelKeyField
- type ModelKeyValidationError
- type ModelKeyValidationReason
- type ModelOption
- func WithContextLimits(limits ContextLimits) ModelOption
- func WithImages() ModelOption
- func WithPromptCaching() ModelOption
- func WithSampling(s Sampling) ModelOption
- func WithStructuredOutput() ModelOption
- func WithStructuredOutputWithTools() ModelOption
- func WithThinking() ModelOption
- func WithThinkingDialect(d ThinkingDialect) ModelOption
- func WithTools() ModelOption
- type Origin
- type ProviderName
- type Sampling
- type ThinkingDialect
- type ValidationError
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type APIFormat ¶
type APIFormat string
APIFormat names the wire dialect a model endpoint speaks. It is an OPEN label: inference carries built-in constant names for the bundled codecs/routes, but the type is deliberately not a validation gate. Unknown values are allowed — a caller supplying explicit request/response/stream decoders and a Router can name any dialect it likes. Fail-closed validation of known provider/format pairs belongs in the llm module or consumer code, never here. Note there is no APIFormat.Valid(): the absence of a fail-closed gate is intentional.
const ( APIFormatOpenAI APIFormat = "openai" APIFormatAnthropic APIFormat = "anthropic" APIFormatGemini APIFormat = "gemini" // APIFormatOpenAIResponses names the OpenAI Responses API dialect // (POST /v1/responses), distinct from APIFormatOpenAI which names OpenAI // Chat Completions. APIFormatOpenAIResponses APIFormat = "openai-responses" // APIFormatBedrockConverse names Amazon Bedrock's model-neutral Converse // and ConverseStream APIs. APIFormatBedrockConverse APIFormat = "bedrock-converse" )
type Capabilities ¶
type Capabilities struct {
AcceptsImages bool
Tools bool
Thinking bool
StructuredOutput bool
StructuredOutputWithTools bool
// ThinkingDialect names which reasoning request shape this model accepts.
// It is meaningful only alongside Thinking, and its zero value means the
// catalogue has not described the model — see the ThinkingDialect doc for
// why that is not a default. A codec that can emit more than one thinking
// shape reads this instead of matching on the model name.
ThinkingDialect ThinkingDialect
// PromptCaching marks an endpoint that honors explicit cache_control
// breakpoints (Anthropic API, Bedrock-Anthropic). It is deliberately a
// per-model capability, not derived from the API format: a third-party
// server speaking the Anthropic dialect may instead cache prefixes
// automatically server-side (or reject the unknown field), so emission
// must be opt-in per endpoint. Codecs whose dialect has no request-side
// cache hints (OpenAI, Gemini implicit caching) ignore it.
PromptCaching bool
}
Capabilities is secret-free gating/informational data about a model: never serialized onto the wire, read locally (e.g. a TUI deciding whether to allow image attachments).
type ContextLimitField ¶
type ContextLimitField string
ContextLimitField identifies one ContextLimits field.
const ( ContextLimitFieldMaxInputTokens ContextLimitField = "MaxInputTokens" ContextLimitFieldMaxOutputTokens ContextLimitField = "MaxOutputTokens" )
type ContextLimitValidationReason ¶
type ContextLimitValidationReason string
ContextLimitValidationReason identifies why a context limit is invalid.
const ContextLimitValidationReasonExceedsWindow ContextLimitValidationReason = "exceeds WindowTokens"
type ContextLimits ¶
type ContextLimits struct {
WindowTokens content.TokenCount
MaxInputTokens content.TokenCount
MaxOutputTokens content.TokenCount
}
ContextLimits describes a model's known context capacity. Zero fields are explicitly unknown and are resolved by policy rather than guessed here.
func (ContextLimits) Validate ¶
func (l ContextLimits) Validate() error
Validate verifies relationships that can be established from known fields. Independent input and output maxima need not sum below the shared window; request admission accounts for their combined use.
type ContextLimitsValidationError ¶
type ContextLimitsValidationError struct {
Field ContextLimitField
Reason ContextLimitValidationReason
Value content.TokenCount
WindowTokens content.TokenCount
}
ContextLimitsValidationError reports a cap that contradicts a known shared context window.
func (*ContextLimitsValidationError) Error ¶
func (e *ContextLimitsValidationError) Error() string
type Effort ¶
type Effort string
Effort is dialect-neutral "how hard to think" intent. Each codec maps it to its wire mechanism (openaiapi → reasoning_effort; anthropicapi → adaptive thinking + effort). Zero value (EffortNone) means the model decides / thinking off.
type Model ¶
type Model struct {
Provider ProviderName
APIFormat APIFormat // which codec dialect speaks to this model (open label)
BaseURL string
Name string // provider-specific model id sent on the wire
Origin Origin // provenance; zero value = OriginCustom (fail-safe)
Caps Capabilities // local gating data, never sent on the wire
Limits ContextLimits // model context capacity; zero fields are unknown
Sampling Sampling // default sampling; per-call overrides live on Request.Override
}
Model is a secret-free model descriptor: which model, which wire dialect reaches it, where to reach it, its provenance, its local gating capabilities, and its default sampling. It deliberately omits the API key (a secret) and the system prompt (a per-agent concern) — those live on Request and the Authenticator, never on a Model. Call Validate at the trust boundary before use.
func CustomModel ¶
func CustomModel(p ProviderName, f APIFormat, baseURL, name string, opts ...ModelOption) Model
CustomModel builds a user-asserted Model: it forces the four wire-relevant fields — provider label, API format, endpoint, and model name — and leaves everything else at its fail-safe zero value (Origin OriginCustom, all Capabilities false, unknown ContextLimits, empty Sampling) unless an option opts in. The result is still subject to Validate before use.
func (Model) Clone ¶
Clone returns an independent Model value, including pointer- and slice-bearing sampling metadata.
func (Model) Key ¶
Key returns the model's stable provider namespace and provider model ID. Call ModelKey.Validate where a fully resolved identity is required.
func (Model) Validate ¶
Validate performs STRUCTURAL validation only, returning a typed validation error on the first rule violated. It is deliberately provider-policy-free: it never rejects an unknown Provider label, an unknown APIFormat label, or a provider/API-format pair. Fail-closed known-provider validation belongs in the llm module or a consumer composition root.
Rules:
- Name must be non-empty.
- StructuredOutputWithTools requires both Tools and StructuredOutput.
- ThinkingDialect must be a known dialect, and naming one requires Thinking.
- Known context limits must not contradict the shared context window.
- An empty BaseURL is allowed — it is a wildcard bound by the client at the trust boundary, not a claim.
- A non-empty BaseURL must be syntactically safe: https, or http only for a loopback host (127.0.0.1, ::1, or localhost), with a host present and no embedded userinfo.
OriginCustom models validate identically to catalog rows; the lower trust in a custom model's Caps is a downstream gating concern, not Validate's.
type ModelKey ¶
type ModelKey struct {
Provider ProviderName
Model string
}
ModelKey is the stable, secret-free identity of a resolved model. It contains only the provider namespace and provider model ID, so identity never depends on a mutable catalog, endpoint, or wire format.
type ModelKeyField ¶
type ModelKeyField string
ModelKeyField identifies a component of ModelKey.
const ( ModelKeyFieldProvider ModelKeyField = "Provider" ModelKeyFieldModel ModelKeyField = "Model" )
type ModelKeyValidationError ¶
type ModelKeyValidationError struct {
Field ModelKeyField
Reason ModelKeyValidationReason
}
ModelKeyValidationError reports an invalid ModelKey component.
func (*ModelKeyValidationError) Error ¶
func (e *ModelKeyValidationError) Error() string
type ModelKeyValidationReason ¶
type ModelKeyValidationReason string
ModelKeyValidationReason identifies why a ModelKey is invalid.
const ModelKeyValidationReasonEmpty ModelKeyValidationReason = "must not be empty"
type ModelOption ¶
type ModelOption func(*Model)
ModelOption mutates a Model built by CustomModel. Because CustomModel defaults every capability off (fail-safe), an option is the only way to opt one in.
func WithContextLimits ¶
func WithContextLimits(limits ContextLimits) ModelOption
WithContextLimits sets the model's advertised context capacity.
func WithImages ¶
func WithImages() ModelOption
WithImages marks the model as accepting image inputs.
func WithPromptCaching ¶
func WithPromptCaching() ModelOption
WithPromptCaching marks the endpoint as honoring explicit cache_control breakpoints (see Capabilities.PromptCaching).
func WithSampling ¶
func WithSampling(s Sampling) ModelOption
WithSampling sets the model's default sampling. The argument is deep-copied so the Model never aliases the caller's pointer/slice state.
func WithStructuredOutput ¶
func WithStructuredOutput() ModelOption
WithStructuredOutput marks the model as supporting native structured output.
func WithStructuredOutputWithTools ¶
func WithStructuredOutputWithTools() ModelOption
WithStructuredOutputWithTools marks the model as supporting native structured output in requests that also expose tools, including both prerequisite capabilities.
func WithThinking ¶
func WithThinking() ModelOption
WithThinking marks the model as supporting extended thinking WITHOUT saying which request shape it accepts. Prefer WithThinkingDialect: a codec that can emit more than one thinking shape fails closed on an undeclared dialect rather than guessing (see ThinkingDialect).
func WithThinkingDialect ¶
func WithThinkingDialect(d ThinkingDialect) ModelOption
WithThinkingDialect marks the model as supporting extended thinking and declares which request shape it accepts. Like WithStructuredOutputWithTools it sets its own prerequisite, so a caller cannot declare a dialect on a model that is not marked thinking-capable.
type Origin ¶
type Origin uint8
Origin is a model descriptor's provenance. The zero value is OriginCustom (fail-safe): a raw Model{} literal is treated as user-asserted, so gating stays conservative until proven curated.
type ProviderName ¶
type ProviderName string
ProviderName is an opaque label identifying the backend a model belongs to. It carries no provider policy. An empty value is a wildcard, not a claim.
type Sampling ¶
type Sampling struct {
Temperature *float64
TopP *float64
MaxTokens *int
Stop []string
Effort Effort
}
Sampling is dialect-neutral sampling intent. Each Codec maps it to its wire mechanism; the dialect-specific validity rules (e.g. Anthropic's Temperature==1.0 for thinking) live in the codec, not here.
type ThinkingDialect ¶
type ThinkingDialect string
ThinkingDialect names WHICH request shape a model accepts when reasoning is asked for. It is the companion of Capabilities.Thinking: the bool says the model can reason at all, the dialect says how the request has to spell it.
One bool cannot carry both, and the difference is not cosmetic. Measured against api.anthropic.com on 2026-08-13, from a single run of one encoder: claude-haiku-4-5 answers `{"type":"adaptive"}` with HTTP 400 "adaptive thinking is not supported on this model", and claude-sonnet-5 answers `{"type":"enabled","budget_tokens":N}` with HTTP 400 "\"thinking.type.enabled\" is not supported for this model. Use \"thinking.type.adaptive\" and \"output_config.effort\"". Both wrong answers are hard rejections, so a codec choosing from one boolean has no safe default.
It is deliberately a per-model capability rather than a per-format constant. The dialect a model accepts is server behaviour that changes with the model generation, not with the wire format: Anthropic's own API serves both spellings concurrently, and Bedrock Converse fronts the same models. It is also deliberately dialect-NEUTRAL vocabulary, like Effort — Gemini's thinkingConfig is a budget too, so "budget" describes a shape rather than one vendor's field name.
The zero value is UNDECLARED, not a default. A catalogue that does not describe a model's dialect has said nothing, and a codec must fail closed with a diagnostic naming the model rather than guess between two spellings it can prove one of to be a 400.
const ( // ThinkingDialectUnknown is the zero value: the model's dialect has not // been declared. It is not a synonym for either real dialect. ThinkingDialectUnknown ThinkingDialect = "" // ThinkingDialectAdaptive marks a model that decides its own reasoning // depth and takes a coarse effort level. Anthropic spells it // `thinking:{"type":"adaptive"}` plus `output_config.effort`. ThinkingDialectAdaptive ThinkingDialect = "adaptive" // ThinkingDialectBudget marks a model that takes an explicit reasoning // token budget. Anthropic spells it // `thinking:{"type":"enabled","budget_tokens":N}`, and rejects // `output_config.effort` on the same models. ThinkingDialectBudget ThinkingDialect = "budget" )
func (ThinkingDialect) Valid ¶
func (d ThinkingDialect) Valid() bool
Valid reports whether d is a known dialect. The empty value is valid here in the same sense Effort's is — it is a legal FIELD value meaning "unset" — and what a consumer does with an unset dialect is that consumer's rule, not Validate's.
type ValidationError ¶
ValidationError is a structurally invalid model or sampling value.
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string