provider

package
v0.16.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 29, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultMaxStreamRetries    = 5
	DefaultMaxStreamRetryDelay = 30 * time.Second
)
View Source
const MaxToolCallsPerResponse = 1024

Variables

View Source
var (
	ErrInvalidToolCallArguments = errors.New("invalid tool call arguments")
	ErrDuplicateToolCallID      = errors.New("duplicate tool call id")
	ErrToolCallIdentityConflict = errors.New("provider tool call id/index binding conflicts")
	ErrMissingToolCallID        = errors.New("provider tool call is missing an id")
	ErrMissingTerminalEvent     = errors.New("provider stream ended without a terminal event")
	ErrMultipleTerminalEvents   = errors.New("provider stream returned multiple terminal events")
	ErrEventAfterTerminal       = errors.New("provider stream returned an event after termination")
	ErrTooManyProviderToolCalls = errors.New("provider response exceeds safe tool-call limit")
)
View Source
var ErrNoDriverForModel = errors.New("provider: no driver registered for model")

ErrNoDriverForModel is returned by a Resolver that has no Driver registered for the requested model name. agent.Build wraps it into a build error so an unservable model fails at construction rather than at the first model call.

View Source
var ErrNotImplemented = errors.New("provider driver not implemented")
View Source
var ErrNotStarted = errors.New("provider request was not started")

ErrNotStarted proves that a provider request was not issued.

View Source
var ErrStreamInterceptorProtocol = errors.New("provider stream interceptor protocol violation")

ErrStreamInterceptorProtocol reports an invalid interceptor implementation.

Functions

func IsRetryableError added in v0.13.0

func IsRetryableError(err error) bool

IsRetryableError recognizes typed transient provider failures and short transport interruptions. Context cancellation and deadlines are terminal.

func SuggestedRetryDelay added in v0.13.0

func SuggestedRetryDelay(err error) time.Duration

SuggestedRetryDelay returns a typed provider-requested retry delay.

func ValidateExtraBody added in v0.15.0

func ValidateExtraBody(body map[string]any) error

ValidateExtraBody accepts JSON-shaped provider wire fields only. Host callbacks, services, pointers, channels, and arbitrary structs must use the typed Request fields instead.

Types

type ClassifiedError added in v0.13.0

type ClassifiedError interface {
	error
	Category() ErrorKind
}

ClassifiedError exposes a provider-neutral failure category.

type ContextUsage added in v0.15.0

type ContextUsage struct {
	UsedTokens int `json:"usedTokens"`
	MaxTokens  int `json:"maxTokens,omitempty"`
}

ContextUsage reports non-billable provider context occupancy.

type ContextUsageObserver added in v0.15.0

type ContextUsageObserver func(ContextUsage)

type Driver

type Driver interface {
	Metadata() Metadata
	Stream(ctx context.Context, request Request) (Stream, error)
}

func Fallback

func Fallback(primary Driver, fallbacks ...Driver) Driver

Fallback returns a Driver that tries primary's Stream first and, when initiation fails, tries each fallback in order — model failover for provider outages that survive the driver's own retry policy. It never fails over mid-stream: once any driver returns a Stream, that stream is the run's. Stream identity reports the selected driver's identity, rather than the wrapper's primary metadata.

func ModelFallback added in v0.14.0

func ModelFallback(primary Driver, fallback Driver, fallbackModel string) Driver

ModelFallback returns a Driver that switches both driver and request model when the primary cannot open a stream. It never switches after a stream has been established.

func Resolve added in v0.14.0

func Resolve(resolver Resolver, providerName, model string) (Driver, error)

Resolve chooses a driver by model and, when providerName is non-empty, verifies or explicitly resolves the requested provider.

type Error added in v0.13.0

type Error struct {
	Provider   string
	Kind       ErrorKind
	Code       string
	StatusCode int
	Message    string
	RetryAfter time.Duration
}

Error is a provider-neutral failure classification. Provider adapters map wire-specific statuses and codes into Kind without string matching.

func NewHTTPError added in v0.13.0

func NewHTTPError(providerName string, statusCode int, message string) *Error

NewHTTPError maps a provider HTTP response to a generic failure category.

func (*Error) Category added in v0.13.0

func (e *Error) Category() ErrorKind

func (*Error) Error added in v0.13.0

func (e *Error) Error() string

func (*Error) RetryDelay added in v0.13.0

func (e *Error) RetryDelay() time.Duration

func (*Error) Retryable added in v0.13.0

func (e *Error) Retryable() bool

type ErrorKind added in v0.13.0

type ErrorKind string
const (
	ErrorUnknown        ErrorKind = "unknown"
	ErrorAuthentication ErrorKind = "authentication"
	ErrorPermission     ErrorKind = "permission"
	ErrorInvalidRequest ErrorKind = "invalid_request"
	ErrorNotFound       ErrorKind = "not_found"
	ErrorRateLimit      ErrorKind = "rate_limit"
	ErrorServer         ErrorKind = "server"
	ErrorStream         ErrorKind = "stream"
)

func ErrorKindOf added in v0.13.0

func ErrorKindOf(err error) ErrorKind

ErrorKindOf returns a typed provider failure category through wrapped errors.

type Event

type Event struct {
	Kind      EventKind `json:"kind"`
	Text      string    `json:"text,omitempty"`
	TextPhase TextPhase `json:"textPhase,omitempty"`
	Thinking  string    `json:"thinking,omitempty"`
	// Signature carries the opaque thinking-block signature emitted alongside
	// reasoning (Anthropic signature_delta). It is associated with the
	// current thinking block and accumulated by NormalizeEvents.
	Signature string `json:"signature,omitempty"`
	// RedactedThinking carries the opaque payload of a redacted_thinking
	// block delivered whole by the provider.
	RedactedThinking string            `json:"redactedThinking,omitempty"`
	ToolCall         *message.ToolCall `json:"toolCall,omitempty"`
	ToolCallDelta    *ToolCallDelta    `json:"toolCallDelta,omitempty"`
	Usage            Usage             `json:"usage,omitempty"`
	StopReason       StopReason        `json:"stopReason,omitempty"`
	// ProviderState carries an opaque provider-owned turn payload that must be
	// replayed verbatim on a later request.
	ProviderState json.RawMessage  `json:"providerState,omitempty"`
	Response      ResponseMetadata `json:"response,omitempty"`
	Err           error            `json:"-"`
}

type EventKind

type EventKind string
const (
	EventTextDelta     EventKind = "text_delta"
	EventThinkingDelta EventKind = "thinking_delta"
	EventToolCallDelta EventKind = "tool_call_delta"
	EventToolCall      EventKind = "tool_call"
	EventDone          EventKind = "done"
	EventError         EventKind = "error"
)

type IdentifiedStream added in v0.14.0

type IdentifiedStream interface {
	Stream
	Identity() StreamIdentity
}

IdentifiedStream is optionally implemented by streams returned from composite drivers such as failover wrappers.

type Metadata

type Metadata struct {
	Name    string   `json:"name"`
	Models  []string `json:"models,omitempty"`
	Version string   `json:"version,omitempty"`
}

type NamedResolver added in v0.14.0

type NamedResolver interface {
	Resolver
	DriverFor(providerName, model string) (Driver, error)
}

NamedResolver resolves an explicit provider/model pair. Resolver implementations may expose it when model names are not globally unique.

type NormalizedResponse

type NormalizedResponse struct {
	Content  []message.ContentPart `json:"content,omitempty"`
	Text     string                `json:"text,omitempty"`
	Thinking string                `json:"thinking,omitempty"`
	// Signature is the opaque thinking-block signature accumulated from
	// signature_delta events; empty for providers that do not sign reasoning.
	Signature string `json:"signature,omitempty"`
	// RedactedThinking is the opaque payload of a redacted_thinking block, if
	// the provider emitted one.
	RedactedThinking string             `json:"redactedThinking,omitempty"`
	ToolCalls        []message.ToolCall `json:"toolCalls,omitempty"`
	Usage            Usage              `json:"usage,omitempty"`
	StopReason       StopReason         `json:"stopReason,omitempty"`
	ProviderState    json.RawMessage    `json:"providerState,omitempty"`
	Response         ResponseMetadata   `json:"response,omitempty"`
}

func NormalizeEvents

func NormalizeEvents(events []Event) (NormalizedResponse, error)

NormalizeEvents folds one complete provider stream and requires exactly one terminal event at the end.

func NormalizePartialEvents added in v0.15.0

func NormalizePartialEvents(events []Event) (NormalizedResponse, error)

NormalizePartialEvents folds events already observed from an interrupted stream. A terminal event is optional, but if present it must still be unique and last.

type PartialStreamError added in v0.16.0

type PartialStreamError struct {
	Cause error
}

PartialStreamError reports a receive or terminal failure after valid output was delivered. Reopening the stream would duplicate an ambiguous effect.

func (*PartialStreamError) Error added in v0.16.0

func (failure *PartialStreamError) Error() string

func (*PartialStreamError) Retryable added in v0.16.0

func (*PartialStreamError) Retryable() bool

Retryable always returns false because partial output is an unsafe replay boundary regardless of the underlying transport classification.

func (*PartialStreamError) Unwrap added in v0.16.0

func (failure *PartialStreamError) Unwrap() error

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry resolves a model name to a registered Driver by indexing each Driver's Metadata().Models. Register every Driver a deployment can route to, then hand the Registry to agent.Build as the Resolver; the Build for an agent whose Model is served by driver X selects X, and an agent on a model served by driver Y selects Y. When two drivers declare the same model name, the last registration wins.

Registry is safe for concurrent Driver lookups; concurrent Register calls are serialized. The expected pattern is to register all drivers at startup and then only resolve.

func NewRegistry

func NewRegistry(drivers ...Driver) *Registry

NewRegistry builds a Registry pre-populated with the given drivers, each indexed by the model names it declares in Metadata().Models.

func (*Registry) Driver

func (r *Registry) Driver(model string) (Driver, error)

Driver returns the Driver registered for model, or ErrNoDriverForModel when no registered Driver declares it.

func (*Registry) DriverFor added in v0.14.0

func (r *Registry) DriverFor(providerName, model string) (Driver, error)

DriverFor returns the driver registered for the exact provider/model pair.

func (*Registry) Register

func (r *Registry) Register(d Driver)

Register indexes d under every model name in d.Metadata().Models. A nil driver is ignored, and a driver that declares no models is indexed under no key, so it matches no lookup. The byModel map is allocated lazily, so a zero-value Registry (&Registry{} or var r Registry) is safe to Register into without NewRegistry.

type Request

type Request struct {
	Model             string                   `json:"model"`
	OperationID       string                   `json:"-"`
	Messages          []message.Message        `json:"messages"`
	Temperature       float64                  `json:"temperature,omitempty"`
	TopP              float64                  `json:"topP,omitempty"`
	MaxTokens         int                      `json:"maxTokens,omitempty"`
	Tools             []message.ToolDefinition `json:"tools,omitempty"`
	Metadata          map[string]string        `json:"metadata,omitempty"`
	StopSequences     []string                 `json:"stopSequences,omitempty"`
	ThinkingBudget    int                      `json:"thinkingBudget,omitempty"`
	ResponseFormat    *ResponseFormat          `json:"responseFormat,omitempty"`
	PromptCacheKey    string                   `json:"promptCacheKey,omitempty"`
	ServiceTier       string                   `json:"serviceTier,omitempty"`
	ParallelToolCalls *bool                    `json:"parallelToolCalls,omitempty"`
	ContextUsage      ContextUsageObserver     `json:"-"`
	// ExtraBody contains provider wire fields, not process objects.
	// godoc-allow-any
	ExtraBody map[string]any `json:"extraBody,omitempty"`
}

type Resolver

type Resolver interface {
	Driver(model string) (Driver, error)
}

Resolver maps a model name to the Driver that serves it. agent.Build calls Resolver.Driver(spec.Model) once per materialized agent, so each agent can run on a different model — and, when drivers from different vendors are registered, a different provider — while sharing a single Build path.

A Driver already takes the model name per request (Request.Model), so a single Driver serves many model names on its own. The Resolver only adds the cross-vendor dimension: picking which Driver a given model name belongs to.

Spec anchor: docs/adr/ADR-018-self-sufficient-agent-layer.md §"Per-agent model and provider selection".

func Single

func Single(d Driver) Resolver

Single returns a Resolver that always yields d, ignoring the model name. It is the trivial single-provider case: every agent shares one Driver and only the model name (Request.Model) varies per call. A deployment that never needs cross-vendor routing passes Single(driver) wherever a Resolver is required.

type ResponseFormat

type ResponseFormat struct {
	Type   string              `json:"type"`
	Name   string              `json:"name,omitempty"`
	Strict bool                `json:"strict,omitempty"`
	Schema *message.JSONSchema `json:"schema,omitempty"`
}

type ResponseMetadata added in v0.15.0

type ResponseMetadata = message.ResponseMetadata

type RetryDelayConfigurable added in v0.13.0

type RetryDelayConfigurable interface {
	SetMaxRetryDelay(time.Duration)
}

RetryDelayConfigurable is implemented by drivers whose provider-suggested retry delay can be capped by host policy.

type RetryDelayError added in v0.13.0

type RetryDelayError interface {
	error
	RetryDelay() time.Duration
}

RetryDelayError carries a provider-requested minimum delay.

type RetryObservable added in v0.13.0

type RetryObservable interface {
	SetRetryObserver(RetryObserver)
}

RetryObservable is implemented by drivers that expose SDK retry progress.

type RetryObserver added in v0.13.0

type RetryObserver func(RetryProgress) error

RetryObserver receives each approved retry before its backoff. Returning an error vetoes that retry.

type RetryProgress added in v0.13.0

type RetryProgress struct {
	Attempt int
	Max     int
	Delay   time.Duration
	Cause   error
}

RetryProgress describes a provider connection retry before backoff starts.

type RetryableError added in v0.13.0

type RetryableError interface {
	error
	Retryable() bool
}

RetryableError marks a provider failure that is safe to retry from the last completed turn checkpoint.

type SliceStream

type SliceStream struct {
	// contains filtered or unexported fields
}

func NewSliceStream

func NewSliceStream(events []Event) *SliceStream

func (*SliceStream) Close

func (s *SliceStream) Close() error

func (*SliceStream) Recv

func (s *SliceStream) Recv() (Event, error)

type StopReason

type StopReason string
const (
	StopReasonUnknown       StopReason = "unknown"
	StopReasonComplete      StopReason = "complete"
	StopReasonToolUse       StopReason = "tool_use"
	StopReasonLength        StopReason = "length"
	StopReasonContentFilter StopReason = "content_filter"
	StopReasonMaxTurns      StopReason = "max_turns"
	StopReasonAborted       StopReason = "aborted"
	StopReasonError         StopReason = "error"
)

type Stream

type Stream interface {
	Recv() (Event, error)
	Close() error
}

func OpenRetryingStream added in v0.13.0

func OpenRetryingStream(ctx context.Context, open func() (Stream, error), options StreamRetryOptions) (Stream, error)

OpenRetryingStream retries stream-open and pre-emission receive failures. Once valid output has been emitted, every failure is returned as a PartialStreamError and the stream is never reopened.

type StreamIdentity added in v0.14.0

type StreamIdentity struct {
	Provider Metadata
	Model    string
}

StreamIdentity identifies the provider and model that opened a stream. Composite drivers attach this to the returned stream so callers can attribute the actual selected backend rather than the wrapper's metadata.

type StreamInterceptor added in v0.16.0

type StreamInterceptor interface {
	Stream(context.Context, Driver, Request) (Stream, error)
}

StreamInterceptor surrounds one provider request. It may call the supplied Driver zero or one time and must pass the Request through unchanged.

func ChainStreamInterceptors added in v0.16.0

func ChainStreamInterceptors(interceptors ...StreamInterceptor) StreamInterceptor

ChainStreamInterceptors composes interceptors outermost-first. Nil entries are ignored; an empty chain returns nil.

type StreamInterceptorFunc added in v0.16.0

type StreamInterceptorFunc func(context.Context, Driver, Request) (Stream, error)

StreamInterceptorFunc adapts a function to StreamInterceptor.

func (StreamInterceptorFunc) Stream added in v0.16.0

func (f StreamInterceptorFunc) Stream(ctx context.Context, next Driver, request Request) (Stream, error)

Stream delegates to f.

type StreamInterceptorProtocolError added in v0.16.0

type StreamInterceptorProtocolError struct {
	Index int
	Err   error
}

StreamInterceptorProtocolError identifies the interceptor stage that broke the zero-or-one-call or immutable-request contract.

func (*StreamInterceptorProtocolError) Error added in v0.16.0

func (failure *StreamInterceptorProtocolError) Error() string

func (*StreamInterceptorProtocolError) Unwrap added in v0.16.0

func (failure *StreamInterceptorProtocolError) Unwrap() []error

type StreamRetryOptions added in v0.13.0

type StreamRetryOptions struct {
	Max         int
	Delay       func(int) time.Duration
	MaxDelay    time.Duration
	ShouldRetry func(RetryProgress) bool
	Observer    RetryObserver
}

StreamRetryOptions configures retries before a stream emits any content.

type TextPhase

type TextPhase string

TextPhase identifies the semantic phase of streamed assistant text.

const (
	// TextPhaseCommentary is intermediate commentary emitted before the answer.
	TextPhaseCommentary TextPhase = "commentary"
	// TextPhaseFinalAnswer is assistant text intended as the final answer.
	TextPhaseFinalAnswer TextPhase = "final_answer"
)

type ToolCallDelta

type ToolCallDelta struct {
	Index          *int   `json:"index,omitempty"`
	ID             string `json:"id,omitempty"`
	Name           string `json:"name,omitempty"`
	ArgumentsDelta string `json:"argumentsDelta,omitempty"`
}

type Usage

type Usage struct {
	InputTokens                   int  `json:"inputTokens,omitempty"`
	CachedInputTokens             int  `json:"cachedInputTokens,omitempty"`
	CachedInputTokensReported     bool `json:"cachedInputTokensReported,omitempty"`
	CacheWriteInputTokens         int  `json:"cacheWriteInputTokens,omitempty"`
	CacheWriteInputTokensReported bool `json:"cacheWriteInputTokensReported,omitempty"`
	OutputTokens                  int  `json:"outputTokens,omitempty"`
	ReasoningTokens               int  `json:"reasoningTokens,omitempty"`
	TotalTokens                   int  `json:"totalTokens,omitempty"`
}

func (Usage) Add

func (u Usage) Add(v Usage) Usage

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL