llm

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Aug 17, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package llm wraps a chat model for the two places sieve needs one: captioning canvas regions that yielded nothing to the scene-graph parse, and running the benchmark's question sets.

It is deliberately thin. The value it adds over calling a provider's SDK directly is in the parts that are easy to get wrong and that both callers need: refusal handling, a per-job spend ceiling, and usage accounting exact enough to put in a benchmark table.

Two providers, one shape

Anthropic is the default. Setting a base URL switches to the OpenAI chat completions shape, which is what almost every other provider speaks -- Groq, OpenRouter, Together, vLLM, Ollama and the rest -- so a user can point sieve at whichever model they already pay for, or at a local one.

That matters beyond convenience. The benchmark sends a page's full HTML with every question, which on the default model costs real money per site; being able to run it against a free or self-hosted model is the difference between a benchmark anyone can reproduce and one only its author ever runs.

Index

Constants

View Source
const DefaultModel = "claude-opus-5"

DefaultModel is the model used unless the caller names another.

Variables

View Source
var ErrBudgetExhausted = errors.New("model budget for this job is exhausted")

ErrBudgetExhausted is returned when a job's token ceiling is reached. Vision is the most expensive step in the pipeline by an order of magnitude, so the ceiling is a hard stop rather than a warning.

View Source
var ErrNoCredentials = errors.New(
	"no model credentials found\n" +
		"  Anthropic: set ANTHROPIC_API_KEY, or run `ant auth login`.\n" +
		"  Any other provider: set LLM_BASE_URL, LLM_API_KEY and LLM_MODEL.\n" +
		"    Most providers expose an OpenAI-compatible endpoint, e.g.\n" +
		"    LLM_BASE_URL=https://api.groq.com/openai/v1\n" +
		"  Only the vision and benchmark paths need this; distillation does not.")

ErrNoCredentials is returned when no API key is configured. It explains what to do rather than surfacing a 401 from three layers down.

Functions

func HasCredentials

func HasCredentials(explicit string) bool

HasCredentials reports whether anything is configured to authenticate with. It is a pre-flight check so a long distillation does not run to completion and then fail on its last step.

Types

type Client

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

Client is a budgeted wrapper around one provider's chat endpoint.

func New

func New(opts Options) (*Client, error)

New builds a client. The API key is resolved from the options, then from ANTHROPIC_API_KEY; when neither is set the SDK's own credential chain is left to find a stored profile, and only a call will reveal whether it succeeded.

func (*Client) Ask

func (c *Client) Ask(ctx context.Context, system string, blocks []ContentBlock) (*Result, error)

Ask sends a single-turn request and returns the text response.

system may be empty. blocks is the user turn's content, which lets callers mix text and images without this package knowing anything about either.

func (*Client) Model

func (c *Client) Model() string

Model reports which model this client calls.

func (*Client) Usage

func (c *Client) Usage() Usage

Usage reports the running total.

type ContentBlock

type ContentBlock struct {
	Text string
	// MediaType and B64 are set instead of Text for an image.
	MediaType string
	B64       string
}

ContentBlock is a piece of a user turn: either text or an image.

It is deliberately this package's own type rather than a provider's. Callers build a request once and it goes to whichever provider is configured; making it an alias for one SDK's union would have put that SDK in the signature of every caller and made a second provider impossible to add without changing all of them.

func ImageBlock

func ImageBlock(mediaType string, b64 string) ContentBlock

ImageBlock builds an image content block from base64-encoded bytes.

func TextBlock

func TextBlock(s string) ContentBlock

TextBlock is a convenience for building a user turn.

func (ContentBlock) IsImage

func (b ContentBlock) IsImage() bool

IsImage reports whether this block carries an image.

type Options

type Options struct {
	APIKey string
	Model  string
	// BaseURL selects an OpenAI-compatible provider. Empty means Anthropic.
	//
	// Resolved from LLM_BASE_URL when unset, so a user can switch provider
	// without every caller growing a flag.
	BaseURL string
	// MaxTokens bounds a single response.
	MaxTokens int64
	// Effort trades thoroughness against cost: low, medium, high, xhigh, max.
	// Empty leaves the API default.
	Effort string
	// Budget caps total tokens across the client's lifetime. Zero means no cap.
	Budget int64
	// Timeout bounds one request.
	Timeout time.Duration
}

Options configures a client.

type Result

type Result struct {
	Text  string
	Usage Usage
	// Refused is true when the model's safety classifiers declined the request.
	// This is a successful HTTP response, not an error, and it has to be
	// checked before reading Text.
	Refused bool
	// RefusalCategory is the policy category, when the API supplies one.
	RefusalCategory string
	// Latency is wall clock for the call.
	Latency time.Duration
	// StopReason is the raw stop reason, for the benchmark report.
	StopReason string
}

Result is one completed call.

type Usage

type Usage struct {
	InputTokens      int64 `json:"input_tokens"`
	OutputTokens     int64 `json:"output_tokens"`
	CacheReadTokens  int64 `json:"cache_read_input_tokens,omitempty"`
	CacheWriteTokens int64 `json:"cache_creation_input_tokens,omitempty"`
	Calls            int   `json:"calls"`
}

Usage is what a call actually cost. These numbers come from the API's own accounting, not from an estimate, which is why the benchmark can report them as measurements.

func (*Usage) Add

func (u *Usage) Add(o Usage)

Add accumulates another call's usage.

func (Usage) Total

func (u Usage) Total() int64

Total is every input token the call was charged for, cached or not.

Jump to

Keyboard shortcuts

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