llm

package
v0.31.8 Latest Latest
Warning

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

Go to latest
Published: Apr 26, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FindClaudeCodeCLIPath added in v0.5.5

func FindClaudeCodeCLIPath() (string, error)

func WithSelectionMetadata added in v0.25.0

func WithSelectionMetadata(ctx context.Context, meta SelectionMetadata) context.Context

Types

type AnthropicClient

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

func NewAnthropicClient

func NewAnthropicClient(baseURL, apiKey, model string, maxTokens int) (*AnthropicClient, error)

func (*AnthropicClient) Ask

func (c *AnthropicClient) Ask(ctx context.Context, prompt string) (string, error)

func (*AnthropicClient) Chat

func (c *AnthropicClient) Chat(ctx context.Context, messages []ChatMessage, opts ChatOptions) (ChatResponse, error)

type ChatMessage

type ChatMessage struct {
	Role          string         `json:"role"` // system, user, assistant, tool
	Content       string         `json:"content"`
	ContentBlocks []ContentBlock `json:"content_blocks,omitempty"` // multimodal content (takes priority over Content when non-empty)
	ToolCalls     []ToolCall     `json:"tool_calls,omitempty"`
	ToolCallID    string         `json:"tool_call_id,omitempty"`
}

type ChatOptions

type ChatOptions struct {
	OnDelta func(text string) // SSE streaming callback (nil = no streaming)
	Tools   []ToolSchema
	// ToolChoice picks how the LLM selects tools. nil = provider default (auto).
	ToolChoice *ToolChoice
	// ResponseFormat constrains the response shape. nil = free-form text.
	ResponseFormat *ResponseFormat
	// ReasoningEffort is a provider-agnostic hint. Supported values are
	// none, minimal, low, medium, high.
	ReasoningEffort string
	// ThinkingBudget enables provider-native thinking when budgeted tokens are supported.
	ThinkingBudget int
	// ServiceTier controls provider-side latency tier when supported.
	ServiceTier string
}

type ChatResponse

type ChatResponse struct {
	Message    ChatMessage
	Usage      Usage
	StopReason string
}

type ClaudeCodeCLIClient added in v0.5.5

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

func NewClaudeCodeCLIClient added in v0.5.5

func NewClaudeCodeCLIClient(workDir, model string) (*ClaudeCodeCLIClient, error)

func (*ClaudeCodeCLIClient) Ask added in v0.5.5

func (c *ClaudeCodeCLIClient) Ask(ctx context.Context, prompt string) (string, error)

func (*ClaudeCodeCLIClient) Chat added in v0.5.5

func (c *ClaudeCodeCLIClient) Chat(ctx context.Context, messages []ChatMessage, opts ChatOptions) (ChatResponse, error)

type Client

type Client interface {
	Ask(ctx context.Context, prompt string) (string, error)
	Chat(ctx context.Context, messages []ChatMessage, opts ChatOptions) (ChatResponse, error)
}

func NewProvider

func NewProvider(opts ProviderOptions) (Client, error)

type ClientConfig

type ClientConfig struct {
	HTTPTimeout     time.Duration
	MaxTokens       int
	ReasoningEffort string
	ThinkingBudget  int
	ServiceTier     string
}

func DefaultClientConfig

func DefaultClientConfig() ClientConfig

type ContentBlock added in v0.14.0

type ContentBlock struct {
	Type      string `json:"type"`                 // "text", "image", "document"
	Text      string `json:"text,omitempty"`       // for type=text
	MediaType string `json:"media_type,omitempty"` // e.g. "image/png", "application/pdf"
	Data      string `json:"data,omitempty"`       // base64-encoded binary
}

ContentBlock represents a single block in a multimodal message. Type is "text", "image", or "document".

type FakeClient added in v0.25.0

type FakeClient struct {
	// Label identifies this client in assertions (e.g. "heavy", "light").
	Label string
	// AskResponse is returned from Ask; if empty, a default is synthesized.
	AskResponse string
	// ChatResponse is returned from Chat; if zero-valued, a default is
	// synthesized that echoes Label in the message content.
	ChatResponse ChatResponse
	// AskCalls counts invocations of Ask.
	AskCalls int
	// ChatCalls counts invocations of Chat.
	ChatCalls int
}

FakeClient is a minimal Client implementation for tests. Each call records its arguments and returns a canned response so that test code can assert which tier/role was resolved.

func (*FakeClient) Ask added in v0.25.0

func (f *FakeClient) Ask(_ context.Context, prompt string) (string, error)

Ask implements llm.Client.

func (*FakeClient) Chat added in v0.25.0

Chat implements llm.Client.

type GeminiNativeClient

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

func NewGeminiNativeClient

func NewGeminiNativeClient(baseURL, apiKey, model string) (*GeminiNativeClient, error)

func (*GeminiNativeClient) Ask

func (c *GeminiNativeClient) Ask(ctx context.Context, prompt string) (string, error)

func (*GeminiNativeClient) Chat

func (c *GeminiNativeClient) Chat(ctx context.Context, messages []ChatMessage, opts ChatOptions) (ChatResponse, error)

type ModelFetcher

type ModelFetcher interface {
	FetchModels(ctx context.Context, opts ProviderOptions) ([]string, error)
}

ModelFetcher resolves provider model ids via provider-specific live APIs.

func NewModelFetcher

func NewModelFetcher() ModelFetcher

type OpenAICodexClient

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

func NewOpenAICodexClient

func NewOpenAICodexClient(baseURL, model, authMode, oauthProvider, apiKey string) (*OpenAICodexClient, error)

func (*OpenAICodexClient) Ask

func (c *OpenAICodexClient) Ask(ctx context.Context, prompt string) (string, error)

func (*OpenAICodexClient) Chat

func (c *OpenAICodexClient) Chat(ctx context.Context, messages []ChatMessage, opts ChatOptions) (ChatResponse, error)

type OpenAICompatibleClient

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

OpenAICompatibleClient works with any OpenAI-compatible /chat/completions API (OpenAI, Azure OpenAI, etc.).

func NewGeminiClient

func NewGeminiClient(baseURL, apiKey, model string) (*OpenAICompatibleClient, error)

func NewOpenAIClient

func NewOpenAIClient(baseURL, apiKey, model string) (*OpenAICompatibleClient, error)

func (*OpenAICompatibleClient) Ask

func (c *OpenAICompatibleClient) Ask(ctx context.Context, prompt string) (string, error)

func (*OpenAICompatibleClient) Chat

type ProviderError

type ProviderError struct {
	Provider   string
	Operation  string
	StatusCode int
	Message    string
	Cause      error
}

ProviderError is a structured error for LLM provider failures.

func (*ProviderError) Error

func (e *ProviderError) Error() string

func (*ProviderError) Unwrap

func (e *ProviderError) Unwrap() error

type ProviderOptions

type ProviderOptions struct {
	Provider        string
	AuthMode        string
	OAuthProvider   string
	AuthConfig      auth.ProviderAuthConfig
	BaseURL         string
	WorkDir         string
	Model           string
	APIKey          string
	MaxTokens       int
	ReasoningEffort string
	ThinkingBudget  int
	ServiceTier     string
}

type ResponseFormat added in v0.31.0

type ResponseFormat struct {
	Type   ResponseFormatType
	Name   string
	Schema json.RawMessage
	Strict bool
}

ResponseFormat constrains the model output. Schema is required when Type == ResponseFormatJSONSchema. Strict enables provider-side strict validation (currently OpenAI-style only).

type ResponseFormatType added in v0.31.0

type ResponseFormatType string

ResponseFormatType enumerates the supported response shapes.

const (
	ResponseFormatText       ResponseFormatType = "text"
	ResponseFormatJSONObject ResponseFormatType = "json_object"
	ResponseFormatJSONSchema ResponseFormatType = "json_schema"
)

type Role added in v0.25.0

type Role string

Role identifies a semantic caller of the LLM layer. Role → Tier is a many-to-one mapping controlled by config; code references Role constants and never concrete tier names, so that reassigning a role to a different tier is a config-only change.

const (
	// RoleChatMain is the user-facing chat handler that streams responses
	// to the console/API.
	RoleChatMain Role = "chat_main"

	// RoleContextCompactor runs background transcript compaction and
	// compaction-memory extraction. Light by default.
	RoleContextCompactor Role = "context_compactor"

	// RoleMemoryHook runs per-turn memory maintenance (daily log append,
	// explicit "remember ..." hot path). Light by default.
	RoleMemoryHook Role = "memory_hook"

	// RoleReflectionMemory was the nightly knowledge-base compilation
	// role. The KB system was removed in ID-001; this role is kept in
	// the enumeration for backward-compatible config parsing but no
	// production code resolves it anymore.
	RoleReflectionMemory Role = "reflection_memory"

	// RoleReflectionKB runs nightly KB cleanup. Currently non-LLM, reserved
	// for future use.
	RoleReflectionKB Role = "reflection_kb"

	// RolePulseDecider is the pulse watchdog classifier. Light by default.
	RolePulseDecider Role = "pulse_decider"

	// RoleAgentRuntimeDefault is the default executor role for agent runtime agents
	// that do not declare a tier explicitly. Standard by default.
	RoleAgentRuntimeDefault Role = "agentruntime_default"

	// RoleAgentRuntimePlanner is reserved for planner-style agents that benefit
	// from heavy reasoning.
	RoleAgentRuntimePlanner Role = "agentruntime_planner"
)

func AllRoles added in v0.25.0

func AllRoles() []Role

AllRoles returns the exhaustive list of roles in canonical order. Used for config validation and defaulting.

func ParseRole added in v0.25.0

func ParseRole(raw string) (Role, bool)

ParseRole parses a role name (case-insensitive, trimmed). Returns the zero value and false when the role is unknown.

func ParseRoleOrKeep added in v0.25.0

func ParseRoleOrKeep(role Role) Role

func (Role) String added in v0.25.0

func (r Role) String() string

String returns the canonical string form of the role.

func (Role) Valid added in v0.25.0

func (r Role) Valid() bool

Valid reports whether r is one of the known role constants.

type Router added in v0.25.0

type Router interface {
	// ClientFor returns the client for the given role, applying the
	// configured Role→Tier mapping. Unknown roles fall back to DefaultTier.
	ClientFor(role Role) (Client, TierResolution, error)

	// ClientForTier returns the client for an explicitly requested tier.
	// This is used by callers that already know the tier (e.g. a sub-agent
	// task has set an explicit tier override).
	ClientForTier(tier Tier) (Client, TierResolution, error)

	// DefaultTier reports the tier used when a role has no explicit mapping.
	DefaultTier() Tier

	// TierForRole reports which tier the given role resolves to without
	// fetching the client. Returns DefaultTier when the role is not mapped.
	TierForRole(role Role) Tier
}

Router resolves (Role | Tier) to a concrete llm.Client.

The intended usage pattern is: construct exactly one Router at server startup with three pre-wrapped tier clients; hand it to every subsystem (chat, pulse, reflection, agent runtime, compaction); callers ask for a client by Role and remain oblivious to which tier or model actually served them.

func NewFakeRouter added in v0.25.0

func NewFakeRouter(defaultTier Tier, roleDefaults map[Role]Tier) (Router, map[Tier]*FakeClient, error)

NewFakeRouter builds a Router backed by FakeClients, one per tier. Each tier gets a FakeClient labelled with the tier name. Useful in tests that need to assert which tier was used for which call.

func NewRouter added in v0.25.0

func NewRouter(cfg RouterConfig) (Router, error)

NewRouter validates the config and returns a Router ready to serve clients. Returns an error if any required tier is missing or if RoleDefaults references an unknown tier.

type RouterConfig added in v0.25.0

type RouterConfig struct {
	// Tiers maps tier → client binding. All three tiers (heavy/standard/light)
	// should be present for production use; NewRouter will error if any is
	// missing, although the backing clients may be identical when the caller
	// wants a single model everywhere (legacy mode).
	Tiers map[Tier]TierEntry

	// DefaultTier is used when a role has no explicit mapping. Must be one
	// of the tiers present in Tiers.
	DefaultTier Tier

	// RoleDefaults maps role → tier. Roles not present here fall back to
	// DefaultTier. An unknown role in the map is silently ignored — the
	// Router validates only the tier side.
	RoleDefaults map[Role]Tier
}

RouterConfig is the input to NewRouter. The caller is responsible for constructing and (optionally) wrapping the clients for each tier before handing them to the router; this keeps the llm package free of a dependency on internal/usage.

type SelectionMetadata added in v0.25.0

type SelectionMetadata struct {
	Role      Role
	Tier      Tier
	Provider  string
	Model     string
	Source    string
	SessionID string
	RunID     string
	AgentName string
	FlowID    string
	StepID    string
}

func SelectionMetadataFromContext added in v0.25.0

func SelectionMetadataFromContext(ctx context.Context) (SelectionMetadata, bool)

type Tier added in v0.25.0

type Tier string

Tier identifies a named LLM configuration bundle (provider+model+knobs). Three tiers are supported so that callers can target a class of model (heavy reasoning / standard / fast-light) without knowing the concrete provider or model name at the call site.

const (
	// TierHeavy is for high-reasoning work: planning, complex code changes,
	// architectural decisions, long-context synthesis.
	TierHeavy Tier = "heavy"
	// TierStandard is the general-purpose default used for chat and most
	// agent runtime work.
	TierStandard Tier = "standard"
	// TierLight is for fast, cheap operations: summarization, classification,
	// memory hooks, pulse deciders, reflection compaction.
	TierLight Tier = "light"
)

func AllTiers added in v0.25.0

func AllTiers() []Tier

AllTiers returns the full set of supported tiers in canonical order.

func ParseTier added in v0.25.0

func ParseTier(raw string) (Tier, error)

ParseTier parses a tier name, returning an error for unknown values. Empty input is treated as an error so that callers can distinguish "unset" (use default) from "explicit but invalid".

func ParseTierOrKeep added in v0.25.0

func ParseTierOrKeep(tier Tier) Tier

func (Tier) String added in v0.25.0

func (t Tier) String() string

String returns the canonical string form of the tier.

func (Tier) Valid added in v0.25.0

func (t Tier) Valid() bool

Valid reports whether t is one of the known tier constants.

type TierEntry added in v0.25.0

type TierEntry struct {
	Client   Client
	Provider string
	Model    string
}

TierEntry is one tier's concrete binding: the client to use and the provider/model labels that identify it (for logs and usage tracking).

type TierResolution added in v0.25.0

type TierResolution struct {
	// Tier is the tier that was selected.
	Tier Tier
	// Role is the role the caller asked for; zero value when the caller
	// asked for a tier directly via ClientForTier.
	Role Role
	// Provider is the provider identifier backing the selected tier
	// (e.g. "anthropic", "openai", "gemini-native").
	Provider string
	// Model is the concrete model name backing the selected tier.
	Model string
	// Source describes why this tier was picked. One of:
	// "role" (role→tier map), "default" (fell back to DefaultTier),
	// "explicit" (ClientForTier was called).
	Source string
}

TierResolution describes how a Router resolved a request for a client. It is returned alongside the Client so that callers can log or emit events that tell the user exactly which tier and model served the call.

type ToolCall

type ToolCall struct {
	ID        string `json:"id"`
	Name      string `json:"name"`
	Arguments string `json:"arguments"`
	// ThoughtSignature is provider-specific metadata used by Gemini Native
	// to preserve tool-calling context across turns.
	ThoughtSignature string `json:"thought_signature,omitempty"`
}

type ToolChoice added in v0.31.0

type ToolChoice struct {
	Mode ToolChoiceMode
	Name string
}

ToolChoice expresses how the LLM should pick (or be forced to pick) a tool. nil means "no preference" — equivalent to ToolChoiceAuto for providers that require a value. Mode == ToolChoiceModeSpecific requires Name.

func ToolChoiceAuto added in v0.31.0

func ToolChoiceAuto() *ToolChoice

ToolChoiceAuto returns the default "auto" choice.

func ToolChoiceNone added in v0.31.0

func ToolChoiceNone() *ToolChoice

ToolChoiceNone forbids tool calls.

func ToolChoiceRequired added in v0.31.0

func ToolChoiceRequired() *ToolChoice

ToolChoiceRequired forces *some* tool call.

func ToolChoiceSpecific added in v0.31.0

func ToolChoiceSpecific(name string) *ToolChoice

ToolChoiceSpecific forces calling a specific tool by name.

func (*ToolChoice) String added in v0.31.0

func (tc *ToolChoice) String() string

String returns a short label for logging.

type ToolChoiceMode added in v0.31.0

type ToolChoiceMode string

ToolChoiceMode enumerates the provider-agnostic tool selection modes.

const (
	ToolChoiceModeAuto     ToolChoiceMode = "auto"
	ToolChoiceModeNone     ToolChoiceMode = "none"
	ToolChoiceModeRequired ToolChoiceMode = "required"
	ToolChoiceModeSpecific ToolChoiceMode = "specific"
)

type ToolFunctionSchema

type ToolFunctionSchema struct {
	Name        string          `json:"name"`
	Description string          `json:"description"`
	Parameters  json.RawMessage `json:"parameters,omitempty"`
}

type ToolSchema

type ToolSchema struct {
	Type     string             `json:"type"`
	Function ToolFunctionSchema `json:"function"`
}

type Usage

type Usage struct {
	InputTokens      int `json:"input_tokens"`
	OutputTokens     int `json:"output_tokens"`
	CachedTokens     int `json:"cached_tokens,omitempty"`
	CacheReadTokens  int `json:"cache_read_tokens,omitempty"`
	CacheWriteTokens int `json:"cache_write_tokens,omitempty"`
}

Jump to

Keyboard shortcuts

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