Documentation
¶
Overview ¶
Package llm is a minimal, provider-agnostic Go interface for streaming LLM completions with tool calling. Built-in providers cover the Anthropic Messages API and OpenAI-compatible Chat Completions APIs (OpenAI, Groq, Together, vLLM, OpenRouter, Ollama, and similar).
Two patterns of use:
- Streaming events: range over LLM.Stream to react to deltas in real time.
- One-shot completion: call Complete to drain the stream and receive the final assistant message.
Cancellation propagates through context.Context. Provider errors surface through the iterator's error return as *APIError wrapping a sentinel (ErrAuth, ErrRateLimit, ErrInvalidRequest, ErrProvider).
pi-llm-go does not execute tools. It declares tool schemas on requests and surfaces ToolCallBlocks on responses. The companion pi-agent-go module adds the execution loop.
Index ¶
- Variables
- func Accumulate(events iter.Seq2[StreamEvent, error]) iter.Seq2[*Message, error]
- func SentinelForStatus(status int) error
- type APIError
- type Block
- type EventMessageEnd
- type EventMessageStart
- type EventTextDelta
- type EventTextEnd
- type EventTextStart
- type EventThinkingDelta
- type EventThinkingEnd
- type EventThinkingStart
- type EventToolCallDelta
- type EventToolCallEnd
- type EventToolCallStart
- type LLM
- type Message
- type Request
- type Role
- type StopReason
- type StreamEvent
- type TextBlock
- type ThinkingBlock
- type ThinkingConfig
- type Tool
- type ToolCallBlock
- type ToolResultBlock
- type Usage
Constants ¶
This section is empty.
Variables ¶
var ( ErrAuth = errors.New("llm: authentication failed") ErrRateLimit = errors.New("llm: rate limited") ErrInvalidRequest = errors.New("llm: invalid request") ErrProvider = errors.New("llm: provider error") )
Sentinel errors. Wrap via APIError or return directly. Use errors.Is to branch on them in caller retry / fallback logic.
Functions ¶
func Accumulate ¶
Accumulate folds a stream of events into a stream of progressively-built messages. Each yield emits a snapshot of the assistant message as it stands after the most recent event. The final yielded value (when err is nil) is the fully-assembled assistant message.
Callers that only want the final message should prefer Complete. Use Accumulate when intermediate snapshots are useful (e.g. driving a UI that renders each delta against a complete message tree rather than against individual deltas).
Each snapshot is an independent value — internal slices and strings are copied on emit so callers can retain previous snapshots without aliasing.
func SentinelForStatus ¶
SentinelForStatus maps an HTTP status code to the matching sentinel error. Used by provider implementations when constructing APIError.
Types ¶
type APIError ¶
APIError wraps a non-2xx HTTP response from a provider. The Inner field is one of the sentinel errors above so that errors.Is works through the wrapping. Status and Body let callers inspect the raw failure (e.g. to parse a structured provider error payload).
type Block ¶
type Block interface {
// contains filtered or unexported methods
}
Block is the sealed sum type for message content. Concrete implementations are TextBlock, ThinkingBlock, ToolCallBlock, and ToolResultBlock — all defined in this package. The unexported marker method keeps the set closed: provider converters need exhaustive type-switches to serialize content correctly, so new block types must be added inside the package.
type EventMessageEnd ¶
type EventMessageEnd struct {
StopReason StopReason
Usage Usage
}
EventMessageEnd is the terminal event. It carries the normalized stop reason and the final usage tally.
type EventMessageStart ¶
type EventMessageStart struct {
Model string
}
EventMessageStart is emitted once at the start of an assistant turn, before any block events.
type EventTextDelta ¶
EventTextDelta appends Delta to the text in the block at BlockIndex.
type EventTextEnd ¶
type EventTextEnd struct {
BlockIndex int
}
EventTextEnd marks the end of the TextBlock at BlockIndex.
type EventTextStart ¶
type EventTextStart struct {
BlockIndex int
}
EventTextStart marks the beginning of a TextBlock.
type EventThinkingDelta ¶
EventThinkingDelta appends Delta to the thinking block at BlockIndex.
type EventThinkingEnd ¶
EventThinkingEnd marks the end of the ThinkingBlock. Signature is the opaque provider-supplied token to round-trip on follow-up messages.
type EventThinkingStart ¶
type EventThinkingStart struct {
BlockIndex int
}
EventThinkingStart marks the beginning of a ThinkingBlock.
type EventToolCallDelta ¶
EventToolCallDelta delivers a fragment of the streaming JSON arguments. Callers that need the assembled arguments should wait for EventToolCallEnd rather than accumulate Delta bytes themselves (provider JSON delta framing is not guaranteed to be at value boundaries).
type EventToolCallEnd ¶
type EventToolCallEnd struct {
BlockIndex int
Arguments json.RawMessage
}
EventToolCallEnd marks the end of a ToolCallBlock and carries the assembled arguments.
type EventToolCallStart ¶
EventToolCallStart marks the beginning of a ToolCallBlock. ID and Name are available immediately; arguments stream as deltas and are emitted in fully assembled form on EventToolCallEnd.
type LLM ¶
LLM is the provider-agnostic streaming interface. Anthropic and OpenAI providers implement this; third-party providers may do the same to plug into Complete and Accumulate.
Implementations must:
- Honor cancellation of ctx by terminating the underlying HTTP request and yielding (nil, ctx.Err()) from the iterator.
- Surface HTTP errors as *APIError values via the iterator's error half.
- Emit events in the order documented on StreamEvent.
type Message ¶
type Message struct {
Role Role
Content []Block
Usage Usage
StopReason StopReason
Model string
}
Message is one turn in the transcript. Content holds a sequence of blocks — the model emits assistant messages with mixed text / thinking / tool-call content; the caller sends user messages with text and tool messages with tool-result content.
Usage, StopReason, and Model are populated on assistant messages produced by Complete or Accumulate; they are zero on user / tool messages and on messages sent into Stream.
func Complete ¶
Complete drains a streaming completion and returns the final assistant message. It is equivalent to iterating Stream and folding each event into a Message via Accumulate.
Returns the partial message and a wrapped error if the stream terminates early; the partial may be useful for debugging or replay.
type Request ¶
type Request struct {
Model string
System string
Messages []Message
Tools []Tool
Temperature *float64
MaxTokens int
Thinking *ThinkingConfig
StopReasons []string
}
Request is the common payload for a completion. Provider-specific tunables that have no portable meaning live on the provider's own Options struct (passed to its constructor), not here.
Temperature is a pointer so the zero value can be distinguished from "unset"; callers that want temperature=0 must set *Temperature to 0.
type Role ¶
type Role string
Role enumerates message roles in a transcript. RoleTool messages carry tool results back to the model and may hold only ToolResultBlock content.
type StopReason ¶
type StopReason string
StopReason is the normalized reason a model stopped generating. Provider-specific stop reasons map to one of these; unmappable values surface as errors rather than leaking provider strings.
const ( StopReasonEnd StopReason = "end" // natural end of turn StopReasonMaxTokens StopReason = "max_tokens" // hit MaxTokens cap StopReasonToolUse StopReason = "tool_use" // model requested tool calls StopReasonStop StopReason = "stop" // matched a stop sequence )
type StreamEvent ¶
type StreamEvent interface {
// contains filtered or unexported methods
}
StreamEvent is the sealed sum type emitted during a streaming completion. Errors flow through the iterator's error half rather than as event values, so consumers do not need an EventError variant.
Event order for one assistant turn:
EventMessageStart ( EventTextStart, EventTextDelta*, EventTextEnd | EventThinkingStart, EventThinkingDelta*, EventThinkingEnd | EventToolCallStart, EventToolCallDelta*, EventToolCallEnd )* EventMessageEnd
BlockIndex on per-block events is the position of the block inside the emitted message's Content slice — it lets consumers route deltas when rendering or reconstructing incrementally.
type ThinkingBlock ¶
ThinkingBlock holds an extended-thinking segment emitted by reasoning models. Signature is an opaque provider-supplied token that must be preserved and replayed for multi-turn thinking continuity (Anthropic).
type ThinkingConfig ¶
type ThinkingConfig struct {
// BudgetTokens is the maximum number of thinking tokens the model may
// emit before producing the final response. Required when ThinkingConfig
// is non-nil. Provider minimums apply (Anthropic: 1024).
//
// IMPORTANT: Anthropic requires Request.MaxTokens > BudgetTokens because
// thinking tokens are counted against max_tokens. A common safe choice
// is MaxTokens == BudgetTokens * 2, giving roughly equal budget to the
// reasoning trace and the visible answer.
BudgetTokens int
}
ThinkingConfig enables extended thinking on supported models. Honored by the Anthropic provider. Ignored by the OpenAI-compatible provider in v1.
type Tool ¶
type Tool struct {
Name string
Description string
InputSchema json.RawMessage
}
Tool is the wire-level declaration of a callable function exposed to the model. pi-llm-go does not execute tools — it surfaces ToolCallBlocks on the response and accepts ToolResultBlocks in follow-up messages. Execution lives in pi-agent-go.
InputSchema is a JSON Schema document describing the tool's expected input. Both Anthropic and OpenAI accept JSON Schema draft-07; the schema is forwarded to the provider as-is, so the caller is responsible for dialect choice.
type ToolCallBlock ¶
type ToolCallBlock struct {
ID string
Name string
Arguments json.RawMessage
}
ToolCallBlock represents a tool invocation requested by the model. Arguments is the raw JSON object the model emitted, matching the tool's declared InputSchema. The agent layer validates and dispatches.
type ToolResultBlock ¶
ToolResultBlock carries the result of a tool invocation back to the model. ToolCallID matches the ID on the originating ToolCallBlock.
type Usage ¶
type Usage struct {
InputTokens int
OutputTokens int
CacheReadTokens int
CacheWriteTokens int
TotalTokens int
}
Usage records token accounting returned by a provider for a single completion request. Cache fields are zero when the provider doesn't bill or report cache reads/writes separately.
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
azure_openai
command
azure_openai: stream a completion from Azure OpenAI / Azure AI Services.
|
azure_openai: stream a completion from Azure OpenAI / Azure AI Services. |
|
multi_turn
command
multi_turn: build up a conversation across several Complete() calls.
|
multi_turn: build up a conversation across several Complete() calls. |
|
openai_responses
command
openai_responses: stream from the OpenAI Responses API (/v1/responses).
|
openai_responses: stream from the OpenAI Responses API (/v1/responses). |
|
streaming
command
Streaming example: prints assistant text to stdout as it streams.
|
Streaming example: prints assistant text to stdout as it streams. |
|
thinking
command
thinking: demonstrates Anthropic's extended thinking via pi-llm-go.
|
thinking: demonstrates Anthropic's extended thinking via pi-llm-go. |
|
tool_calling
command
Tool-calling example: registers a get_current_time tool and runs a hand-rolled loop until the model issues no more tool calls.
|
Tool-calling example: registers a get_current_time tool and runs a hand-rolled loop until the model issues no more tool calls. |
|
internal
|
|
|
sse
Package sse parses Server-Sent Events frames from an io.Reader.
|
Package sse parses Server-Sent Events frames from an io.Reader. |
|
providers
|
|
|
anthropic
Package anthropic is the Anthropic Messages provider for pi-llm-go.
|
Package anthropic is the Anthropic Messages provider for pi-llm-go. |
|
openai
Package openai is the OpenAI-compatible Chat Completions provider for pi-llm-go.
|
Package openai is the OpenAI-compatible Chat Completions provider for pi-llm-go. |
|
openai_responses
Package openai_responses is the OpenAI Responses API (/v1/responses) provider for pi-llm-go.
|
Package openai_responses is the OpenAI Responses API (/v1/responses) provider for pi-llm-go. |