Help us shape the future of Go! Take the 2026 Go Developer Survey

provider

package
v0.23.2 Latest Latest
Warning

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

Go to latest
Published: Oct 25, 2026 License: Apache-2.0 Imports: 12 Imported by: 1

Documentation

Overview

Package provider is the kit a model adapter is built from: HTTP error classification, SSE framing, a cap on a streamed reply, Retry-After parsing, and the tool-result codec. The first-party adapters (model/anthropic, model/openai, model/gemini) use it, and a third-party adapter can too.

The agent core never imports this package. It holds adapter plumbing, not the contract a Model meets: that contract (agent.Model, agent.Stream, agent.NewStreamFunc, agent.Emit and the events, agent.APIError, agent.RateLimited and the error sentinels) stays in package agent.

Index

Constants

View Source
const DefaultMaxResponseBytes = 32 << 20

DefaultMaxResponseBytes is the most bytes of one streamed model reply an adapter reads unless it is configured otherwise (each adapter's WithMaxResponseBytes). MaxSSELine caps one line; this caps the whole reply, so a reply of many small lines cannot grow without limit either. A line is part of the reply, so a cap below MaxSSELine also bounds every line.

View Source
const MaxSSELine = 32 << 20

MaxSSELine is the longest SSE line NewSSEScanner reads. It is sized for the largest single event a model streams: a big tool-call arguments blob, or an image Gemini returns inline as base64, which runs to several megabytes.

Variables

This section is empty.

Functions

func ClassifyHTTPError

func ClassifyHTTPError(provider string, resp *http.Response) error

ClassifyHTTPError turns a non-2xx model response into the appropriate SDK error. It reads at most 64KB of the body and parses the provider's error object ({"error":{...}} from OpenAI, Anthropic, and Gemini) so the result carries the provider's message, type, and code, each (and the Body) cut to 8KB:

  • The account's quota or credit is used up (HTTP 402; an error type or code of insufficient_quota, billing_hard_limit_reached, billing_not_active, or billing_error; a Gemini quota violation whose quotaId is per day): an *agent.APIError wrapping agent.ErrQuotaExhausted, whatever the status, since no wait lifts it.
  • HTTP 429 otherwise: a *agent.RateLimited whose RetryAfter is the Retry-After header or, without one, Gemini's RetryInfo.retryDelay.
  • Anything else: an *agent.APIError with the status code.

It reads and closes resp.Body, so call it only on a response the adapter is abandoning (not one it will go on to stream). provider names the adapter for the wrapped message.

func ClassifyStreamError

func ClassifyStreamError(provider string, data []byte) error

ClassifyStreamError turns an error object a provider sends inside a 200 stream (an OpenAI or Gemini data line holding {"error":{...}}, an Anthropic "error" event) into an SDK error. With a numeric code (Gemini sends the HTTP status) it is classified as ClassifyHTTPError would a response with that status. Without one, an exhausted quota is an *agent.APIError wrapping agent.ErrQuotaExhausted, a rate limit (type or code rate_limit_error or rate_limit_exceeded) is a *agent.RateLimited, and anything else (overloaded, server_error) is an agent.ErrModel carrying the provider's message, which middleware.Retryable retries.

func EncodeToolResultOr

func EncodeToolResultOr(c ToolResultCodec, raw json.RawMessage) string

EncodeToolResultOr applies the codec to raw and returns the result. When the codec is nil it returns the canonical JSON string (the default behavior). When the codec returns an error it degrades to the same JSON string rather than failing the whole model request: the JSON form is always a correct payload, so a codec hiccup never drops a tool result. Adapters call this at the point where a ToolResult is serialized into a provider request.

func LimitResponse

func LimitResponse(body io.ReadCloser, max int64) io.ReadCloser

LimitResponse returns body limited to max bytes (DefaultMaxResponseBytes when max <= 0): once the reply has more, a read returns the bytes up to the limit and an error wrapping agent.ErrResponseTooLarge, which SSEReadError passes on. Closing the result closes body. Every adapter wraps its streamed reply with it, so the cap is enforced in one place.

func NewSSEScanner

func NewSSEScanner(body io.Reader) *bufio.Scanner

NewSSEScanner returns a bufio.Scanner over an SSE stream body with the default 64KB line cap raised to MaxSSELine. A single SSE line can carry a large tool-call arguments blob or inline image, and the 64KB default would fail the stream on it (the openai-go #368 lesson). The buffer grows only as a line needs it. Every adapter reads its event stream through this so the cap is fixed in exactly one place; pass the scanner's Err to SSEReadError. Over a body from LimitResponse, a reply that exceeds its cap ends the scan with that error before the cut-off last line is returned, so an adapter never decodes a line the cap truncated.

func ParseRetryAfter

func ParseRetryAfter(s string) time.Duration

ParseRetryAfter parses an HTTP Retry-After header value. It accepts either an integer number of seconds or an HTTP-date, and returns 0 if the value is absent, unparseable, negative, or already in the past. A number of seconds too large for a time.Duration saturates at the longest one rather than overflowing.

func SSEPayload

func SSEPayload(line string) (string, bool)

SSEPayload extracts the data payload from one raw SSE line. It reports ok=false for a line that is not `data:` framing (e.g. an `event:` line or a blank separator) or whose payload is empty, both of which callers skip; otherwise it returns the payload with the "data:" prefix stripped and surrounding whitespace trimmed. It does not interpret provider sentinels such as "[DONE]".

func SSEReadError

func SSEReadError(provider string, err error) error

SSEReadError wraps a failed read of a model's SSE stream (the Err of a NewSSEScanner scanner) as an agent.ErrModel. A line over MaxSSELine, or a reply over its LimitResponse cap, is agent.ErrResponseTooLarge, which the same request would hit again, so middleware.Retryable does not retry it; any other read failure (a connection cut partway through) is retried.

Types

type JSONToolResultCodec

type JSONToolResultCodec struct{}

JSONToolResultCodec is the default codec: it passes the canonical JSON through unchanged. It is equivalent to what an adapter does when no ToolResultCodec is configured.

func (JSONToolResultCodec) EncodeToolResult

func (JSONToolResultCodec) EncodeToolResult(raw json.RawMessage) (string, error)

EncodeToolResult returns the JSON bytes as a string, unchanged.

type ToolResultCodec

type ToolResultCodec interface {
	EncodeToolResult(raw json.RawMessage) (string, error)
}

ToolResultCodec renders a tool result's canonical JSON bytes into the string content that is sent to the model. The journal always stores the JSON form (see agent.Record.Result), so this only changes what the model reads: an adapter can hand the model a more token-efficient or better-comprehended encoding (for example GCF via github.com/bide-ai/bide/codec/gcf) without touching the durable record or the audit trail. Implementations must be pure and deterministic.

Jump to

Keyboard shortcuts

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