Documentation
¶
Index ¶
- func FindClaudeCodeCLIPath() (string, error)
- func WithSelectionMetadata(ctx context.Context, meta SelectionMetadata) context.Context
- type AnthropicClient
- type ChatMessage
- type ChatOptions
- type ChatResponse
- type ClaudeCodeCLIClient
- type Client
- type ClientConfig
- type ContentBlock
- type FakeClient
- type GeminiNativeClient
- type ModelFetcher
- type OpenAICodexClient
- type OpenAICompatibleClient
- type ProviderError
- type ProviderOptions
- type ResponseFormat
- type ResponseFormatType
- type Role
- type Router
- type RouterConfig
- type SelectionMetadata
- type Tier
- type TierEntry
- type TierRecommendation
- type TierResolution
- type ToolCall
- type ToolChoice
- type ToolChoiceMode
- type ToolFunctionSchema
- type ToolSchema
- type Usage
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FindClaudeCodeCLIPath ¶ added in v0.5.5
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) 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"`
// ReasoningContent is provider-specific payload metadata for tool-calling
// requests. Kimi requires it on assistant messages that include tool calls.
ReasoningContent string `json:"reasoning_content,omitempty"`
}
type ChatOptions ¶
type ChatOptions struct {
OnDelta func(text string) // SSE streaming callback (nil = no streaming)
// OnReasoningDelta receives provider-native chain-of-thought / thinking
// deltas as they stream. Called only when the provider exposes a
// distinct reasoning channel (kimi reasoning_content, anthropic
// thinking_delta, openai responses reasoning summary). nil = ignore.
// OnDelta governs whether streaming is requested; reasoning deltas only
// fire when streaming is active.
OnReasoningDelta func(text string)
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) 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
// LastChatOptions records the most recent Chat options.
LastChatOptions ChatOptions
}
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) Chat ¶ added in v0.25.0
func (f *FakeClient) Chat(_ context.Context, _ []ChatMessage, opts ChatOptions) (ChatResponse, error)
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) 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) 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) Chat ¶
func (c *OpenAICompatibleClient) Chat(ctx context.Context, messages []ChatMessage, opts ChatOptions) (ChatResponse, error)
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 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" // RoleSessionCleanup analyzes compact session metadata and transcript // snippets for user-reviewed archive/delete cleanup suggestions. RoleSessionCleanup Role = "session_cleanup" // 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
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
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
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
type TierEntry ¶ added in v0.25.0
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 TierRecommendation ¶ added in v0.31.119
type TierRecommendation struct {
TaskType string `json:"task_type"`
RecommendedTier Tier `json:"recommended_tier"`
Reason string `json:"reason"`
Confidence float64 `json:"confidence"`
ShouldPrompt bool `json:"should_prompt"`
}
func RecommendTierForTask ¶ added in v0.31.119
func RecommendTierForTask(message string) TierRecommendation
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 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"`
}
Source Files
¶
- anthropic.go
- ask.go
- claude_code_cli.go
- errors.go
- gemini_native.go
- gemini_native_chat.go
- gemini_native_convert.go
- http_utils.go
- model_lister.go
- openai_codex_client.go
- openai_compat_client.go
- provider.go
- role.go
- router.go
- router_fake.go
- selection_context.go
- tier.go
- tier_recommendation.go
- tool_json.go
- transport.go
- validation.go