Documentation
¶
Overview ¶
Package a1 is a thin, opinionated layer over the official Anthropic Go SDK for the calls amberpixels apps actually make: plain-text completions and schema-constrained JSON extraction.
It is deliberately not a framework. The SDK stays visible (models are plain id strings, schemas are plain maps) — a1 only owns the glue every app kept rewriting:
- usage metering: every billed call reports Meta (model, tokens, duration) through one gate — by default the grep-able "💥 tokens burned" log line
- stop-reason handling: refusal and max_tokens truncation become typed errors instead of silently wrong text
- response assembly: text blocks are concatenated (answers have been observed split across blocks or followed by empty ones)
- retry: transient empty/truncated/garbled responses — a failure class the SDK's transport retries don't cover — are retried when Request.Attempts allows; API errors are never retried here (the SDK already does that)
Index ¶
- Constants
- Variables
- func Cost(model string, inputTokens, outputTokens int64) float64
- func Enum(description string, values ...string) map[string]any
- func Obj(props map[string]any, required ...string) map[string]any
- func Prop(description string) map[string]any
- func SupportsAdaptiveThinking(model string) bool
- type Budget
- type Client
- type Meta
- type Meter
- type Option
- type Request
Constants ¶
const DefaultMaxTokens = 4096
DefaultMaxTokens bounds a completion when Request.MaxTokens is unset.
Variables ¶
var ( // ErrRefused: the model (or a safety classifier) declined the request — // stop_reason "refusal". Not retryable; retrying the same prompt refuses // again. ErrRefused = errors.New("a1: request refused") // ErrTruncated: the response hit MaxTokens before finishing — stop_reason // "max_tokens". Retryable (a rerun usually stays in budget), but a // persistent truncation means MaxTokens is too low for the task. ErrTruncated = errors.New("a1: response truncated (max_tokens)") // ErrEmpty: the response carried no text. Observed rarely in bulk runs; // retryable. ErrEmpty = errors.New("a1: empty response") )
Typed outcomes of a completed API call. API/transport errors from the SDK are returned as-is (see the SDK's typed error values for those).
Functions ¶
func Cost ¶ added in v0.0.2
Cost estimates the USD list-price cost of one call. It is an estimate for budgeting/metering (no batch or cache discounts), not a billing statement.
func Obj ¶
Obj builds an object schema from its properties. required lists the mandatory property names; when omitted, every property is required (the common case — and structured outputs reject optional-by-absence anyway). additionalProperties is always false, as structured outputs require.
func SupportsAdaptiveThinking ¶
SupportsAdaptiveThinking reports whether a model accepts the adaptive thinking config. Haiku-tier and pre-4.x models reject it.
Types ¶
type Budget ¶ added in v0.0.2
Budget declares a spend policy in code: a default plus the operator-tunable range. Configuration can customize the value within [Min, Max]; anything else — unset, zero, negative, out of range — resolves to Default. Unlimited is deliberately not expressible: a missing or bogus config value must never disable a spend guard.
The unit is whatever the declaring app counts in (USD/day is the common case); Budget only owns the clamping semantics, not the counting.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client wraps the Anthropic SDK client with metering.
type Meta ¶
type Meta struct {
Model string
StopReason string
InputTokens int64
OutputTokens int64
// CostUSD is the estimated list-price cost of the call (see Cost).
CostUSD float64
Duration time.Duration
}
Meta is the usage/latency record of one billed API call.
func JSON ¶
func JSON[T any](ctx context.Context, c *Client, req Request, schema map[string]any) (*T, Meta, error)
JSON runs one schema-constrained completion (structured outputs) and unmarshals the response into T. The schema is a plain JSON-schema map — build it with Obj/Prop/Enum or by hand; keep property descriptions rich, they steer the model as much as the prompt does.
type Meter ¶
Meter observes every billed call (including failed attempts that still returned a response). task is Request.Task.
type Option ¶
type Option func(*config)
Option configures a Client.
func WithMeter ¶
WithMeter replaces the default metering log line with a custom observer (e.g. the app's own logger, or a metrics counter).
func WithSDKOptions ¶
func WithSDKOptions(opts ...option.RequestOption) Option
WithSDKOptions appends raw SDK request options to the underlying client — base URL overrides, custom HTTP clients, extra headers.
type Request ¶
type Request struct {
// Task names the call site for metering/logs (e.g. "geo-guess",
// "compose-message").
Task string
// Model is the Anthropic model id. Required.
Model string
// System is the system prompt; empty means none.
System string
// Prompt is the user message.
Prompt string
// MaxTokens bounds the completion; 0 means DefaultMaxTokens.
MaxTokens int64
// Thinking enables adaptive thinking on models that support it (it is
// silently skipped on models that don't, e.g. Haiku 4.5).
Thinking bool
// Attempts is how many times a transient content failure (empty,
// truncated, or unparseable response) is tried before giving up.
// 0 or 1 means no retry. API/transport errors are never retried here.
Attempts int
}
Request describes one completion call. Model is a plain Anthropic model id (e.g. "claude-haiku-4-5" or an anthropic.ModelClaude* constant).