Documentation
¶
Index ¶
- Variables
- func ApplyModelMemory(cfg *config.Config)
- func ClaudeListModels() ([]string, error)
- func CodexListModels() ([]string, error)
- func ContextTokensForRAM(cfg config.AgentConfig, ramGB float64) int
- func ContextTokensForWeights(weightBytes int64, ramGB float64) int
- func CopilotListModels() ([]string, error)
- func IsLocalRunner(cfg config.AgentConfig) bool
- func LMStudioListInstalled() ([]string, error)
- func MLXListInstalled() ([]string, error)
- func OllamaInstalledWithSizes() (map[string]int64, error)
- func OllamaListInstalled() ([]string, error)
- func OllamaModelSizeBytes(model string) int64
- func OpenCodeListModels() ([]string, error)
- func Ping(provider, model string) error
- func ProviderReachable(provider string) error
- func ResolveSkills(systemPrompt string, skillNames []string, loader *skills.Loader) string
- func UnloadFor(ctx context.Context, cfg config.AgentConfig) error
- type BudgetRunner
- type ClaudeRunner
- type CodexRunner
- type CompletionRequest
- type ConvMessage
- type CopilotRunner
- type LLMRunner
- type LMStudioRunner
- type LocalModel
- type MLXRunner
- type MockRunner
- type OllamaRunner
- type OpenCodeRunner
- type RateLimitError
- type SkillRunner
- type Token
- type TokenUsage
- type Unloader
Constants ¶
This section is empty.
Variables ¶
var ClaudeModels = []string{
"sonnet",
"opus",
"haiku",
}
ClaudeModels lists available Claude model aliases accepted by the CLI --model flag.
var CodexModels = []string{
"gpt-5.5",
"gpt-5.4",
"gpt-5.4-mini",
"gpt-5.3-codex",
"gpt-5.2-codex",
"gpt-5.2",
"gpt-5.1-codex-max",
"gpt-5.1-codex-mini",
}
CodexModels lists known Codex-compatible model names.
var CopilotModels = []string{
"claude-sonnet-4.6",
"claude-sonnet-4.5",
"claude-haiku-4.5",
"claude-opus-4.8",
"claude-opus-4.7",
"claude-opus-4.6",
"claude-opus-4.5",
"gpt-5.5",
"gpt-5.4",
"gpt-5.4-mini",
"gpt-5.3-codex",
"gpt-5.2-codex",
"gpt-5.2",
"gpt-5-mini",
"gpt-4.1",
}
CopilotModels is the curated fallback list of model IDs accepted by `copilot --model`. Mirrors the entries shown by the interactive `/model` picker. Kept in sync manually; the CLI does not expose a discovery command.
var ErrRateLimited = errors.New("rate limited")
ErrRateLimited is the sentinel returned (wrapped) by all runners when the underlying LLM provider rejects a request because of rate limiting, quota exhaustion, or session usage caps. Callers can detect any flavour with errors.Is(err, runner.ErrRateLimited) and stop the pipeline immediately — continuing would just burn more retries against the same exhausted limit.
var OllamaPopularModels = []string{
"kimi-k2.5:cloud",
"qwen2.5-coder:latest",
"deepseek-coder-v2:latest",
"codellama:latest",
"llama3.2:latest",
"mistral:latest",
"phi4:latest",
"gemma3:latest",
}
OllamaPopularModels is a curated list of models useful for coding tasks.
var OpenCodeAvailableModels = []string{
"qwen2.5-coder:3b",
"qwen2.5-coder:latest",
"llama3.2:latest",
"deepseek-coder-v2:latest",
"opencode/big-pickle",
"opencode/gpt-5-nano",
}
OpenCodeAvailableModels is a fallback list used when the CLI is unavailable.
Functions ¶
func ApplyModelMemory ¶
ApplyModelMemory fills each agent's MaxContextTokens from the global ModelMemory setting. An explicit per-agent MaxContextTokens always wins and is left untouched. When ModelMemory is disabled (Mode "" or "off") nothing changes.
In "context" mode the configured token limit is applied verbatim to every agent. In "ram" mode the limit is derived per agent from its model via ContextTokensForRAM.
func ClaudeListModels ¶
ClaudeListModels returns the known Claude model aliases.
func CodexListModels ¶
CodexListModels returns available models by merging the currently configured model from ~/.codex/config.toml with the known models list. No API keys or network calls required.
func ContextTokensForRAM ¶
func ContextTokensForRAM(cfg config.AgentConfig, ramGB float64) int
ContextTokensForRAM estimates the largest context window (in tokens) that the agent's model can run within ramGB gigabytes of memory. It prefers real model metadata (Ollama reports the on-disk weight size) and falls back to a heuristic when metadata is unavailable (LM Studio / oMLX). The result is clamped to a sane range and rounded down to a multiple of 1024.
The conversion is intentionally approximate: an exact figure depends on the model's layer count, head dimensions and KV quantisation, which are not generally exposed by the local backends. Under-estimating is the safe failure mode, so the heuristic errs low.
func ContextTokensForWeights ¶
ContextTokensForWeights estimates the largest context window (in tokens) a model of the given weight size can run within ramGB gigabytes of memory. It is the network-free core of ContextTokensForRAM, exposed so callers that already know a model's weight size (e.g. a UI listing several models) can compute estimates without re-fetching metadata per keystroke. weightBytes <= 0 falls back to the default estimate. The result is clamped and rounded down to a multiple of 1024.
func CopilotListModels ¶
CopilotListModels returns the models the local Copilot CLI accepts. It prefers CLI-reported models when a future release exposes them, otherwise falls back to CopilotModels with the user's currently configured model (from ~/.copilot/settings.json) moved to the front.
func IsLocalRunner ¶
func IsLocalRunner(cfg config.AgentConfig) bool
IsLocalRunner returns true when the runner uses a local model (opencode with local Ollama model, or direct ollama runner). Local runners have no API cost so fix-attempt limits should not apply.
func LMStudioListInstalled ¶
LMStudioListInstalled returns model IDs available in the running LM Studio server. It prefers the native /api/v0/models endpoint (which reports each model's load state, so loaded models are listed first) and falls back to the OpenAI-compatible /v1/models endpoint.
func MLXListInstalled ¶
MLXListInstalled returns model IDs reported by the running oMLX server.
func OllamaInstalledWithSizes ¶
OllamaInstalledWithSizes returns installed Ollama models paired with their on-disk weight size in bytes, from a single /api/tags call.
func OllamaListInstalled ¶
OllamaListInstalled returns model names available in the local Ollama instance.
func OllamaModelSizeBytes ¶
OllamaModelSizeBytes returns the on-disk size (≈ weight size) of an installed model as reported by /api/tags, or 0 when unavailable. Ollama matches model names loosely (an empty tag means ":latest"), so both the exact name and a ":latest" variant are considered.
func OpenCodeListModels ¶
OpenCodeListModels returns available models from the OpenCode CLI.
func Ping ¶
Ping performs a lightweight reachability check for the given provider and model. For CLI providers it verifies the binary exists; for Ollama it also checks the model is available.
func ProviderReachable ¶
ProviderReachable performs a lightweight check that the given provider's backend is usable: the CLI binary is in PATH, or the local HTTP server responds. It deliberately does NOT verify a specific model so the result can be cached up-front (e.g. to gray out unavailable providers in the setup UI). Returns nil when reachable, otherwise a descriptive error.
func ResolveSkills ¶
ResolveSkills loads skill content and appends it to the system prompt. Returns the enriched system prompt. If loader is nil or no skills match, the original prompt is returned unchanged.
Types ¶
type BudgetRunner ¶
type BudgetRunner struct {
// contains filtered or unexported fields
}
BudgetRunner wraps an LLMRunner and truncates message content to stay within a token budget. Used for cloud runners where tokens have cost.
func (*BudgetRunner) Complete ¶
func (r *BudgetRunner) Complete(ctx context.Context, req CompletionRequest) (<-chan Token, error)
type ClaudeRunner ¶
ClaudeRunner executes the Claude CLI (claude) as an LLM backend.
func (ClaudeRunner) Complete ¶
func (r ClaudeRunner) Complete(ctx context.Context, req CompletionRequest) (<-chan Token, error)
Complete implements LLMRunner by streaming the Claude CLI output incrementally. Uses `--output-format stream-json --verbose` so the TUI shows progress live instead of a single burst at the end of generation.
type CodexRunner ¶
CodexRunner executes the OpenAI Codex CLI as an LLM backend. Uses `codex --quiet` for non-interactive text output.
func (CodexRunner) Complete ¶
func (r CodexRunner) Complete(ctx context.Context, req CompletionRequest) (<-chan Token, error)
Complete implements LLMRunner by running the Codex CLI with the given prompt. Stdout is streamed incrementally so the TUI shows progress live instead of a single burst at the end of generation.
type CompletionRequest ¶
type CompletionRequest struct {
SystemPrompt string
Skills []string
Messages []ConvMessage
Model string
}
CompletionRequest describes what to send to the LLM.
type ConvMessage ¶
ConvMessage is a single turn in a conversation.
type CopilotRunner ¶
CopilotRunner executes the GitHub Copilot CLI (`copilot`) as an LLM backend. Uses `copilot -p <prompt>` for non-interactive prompt mode with `--allow-all-tools` so the CLI does not pause on tool-permission prompts.
func (CopilotRunner) Complete ¶
func (r CopilotRunner) Complete(ctx context.Context, req CompletionRequest) (<-chan Token, error)
Complete implements LLMRunner by running the Copilot CLI with the given prompt. Stdout is streamed incrementally so the TUI shows progress live.
type LLMRunner ¶
type LLMRunner interface {
Complete(ctx context.Context, req CompletionRequest) (<-chan Token, error)
}
LLMRunner is the common interface for all LLM backends.
func New ¶
func New(cfg config.AgentConfig, skillLoader *skills.Loader, promptLanguage string) (LLMRunner, error)
New creates an LLMRunner from agent config. skillLoader may be nil — skills will be silently skipped. promptLanguage is accepted for backwards compatibility but ignored: all agents always reply in English regardless of the user's language.
type LMStudioRunner ¶
LMStudioRunner calls the LM Studio OpenAI-compatible REST API directly. The local model receives the prompt verbatim and is expected to return plain text (no agentic loop, no tool use).
func NewLMStudioRunner ¶
func NewLMStudioRunner(model string) *LMStudioRunner
func (*LMStudioRunner) Complete ¶
func (r *LMStudioRunner) Complete(ctx context.Context, req CompletionRequest) (<-chan Token, error)
func (*LMStudioRunner) Unload ¶
func (r *LMStudioRunner) Unload(ctx context.Context, model string) error
Unload evicts the given model from LM Studio via the `lms` CLI (`lms unload <model>`). LM Studio's REST API has no documented unload endpoint, so this shells out best-effort: if the `lms` CLI is not on PATH the call is a no-op and returns nil.
type LocalModel ¶
type LocalModel struct {
Runner string // "ollama" | "lmstudio" | "mlx"
Model string
WeightBytes int64 // 0 when the backend does not report a size (heuristic used)
}
LocalModel describes a locally-hosted model discovered on one of the local backends, with its weight size when the backend reports it.
func ListLocalModels ¶
func ListLocalModels() []LocalModel
ListLocalModels enumerates models currently available across the local backends (Ollama, LM Studio, oMLX). Unreachable backends are skipped silently so the result reflects whatever is up right now. Ollama entries include their on-disk weight size; LM Studio and oMLX entries leave WeightBytes at 0 because those servers do not report a reliable size.
type MLXRunner ¶
MLXRunner calls the oMLX OpenAI-compatible REST API directly. The local model receives the prompt verbatim and is expected to return plain text (no agentic loop, no tool use).
func NewMLXRunner ¶
func (*MLXRunner) Unload ¶
Unload is a best-effort no-op for oMLX: the server exposes no documented model-eviction endpoint, so DECSR cannot force an unload. It is defined to satisfy the Unloader interface; callers treat a nil return as "unload attempted". oMLX typically holds a single model and swaps it on the next request anyway.
type MockRunner ¶
type MockRunner struct {
Responses []string
MockUsage *TokenUsage // if set, attached to the Done token of each response
// Requests captures every CompletionRequest passed to Complete, in order.
// Useful for asserting on prompt construction in tests.
Requests []CompletionRequest
// contains filtered or unexported fields
}
MockRunner returns pre-programmed responses for testing.
func (*MockRunner) Complete ¶
func (m *MockRunner) Complete(_ context.Context, req CompletionRequest) (<-chan Token, error)
func (*MockRunner) Reset ¶
func (m *MockRunner) Reset()
Reset resets the response index so the mock can be reused.
type OllamaRunner ¶
type OllamaRunner struct {
Model string
BaseURL string
// NumCtx, when > 0, sets Ollama's num_ctx option so the model loads with a
// bounded context window. This is the primary lever for capping a local
// model's RAM use (the KV cache grows with the context window).
NumCtx int
}
OllamaRunner calls the Ollama REST API directly (/api/chat) instead of shelling out through the Claude Code CLI.
func NewOllamaRunner ¶
func NewOllamaRunner(model string) *OllamaRunner
func (*OllamaRunner) Complete ¶
func (r *OllamaRunner) Complete(ctx context.Context, req CompletionRequest) (<-chan Token, error)
func (*OllamaRunner) Unload ¶
func (r *OllamaRunner) Unload(ctx context.Context, model string) error
Unload asks Ollama to evict the given model from memory immediately by issuing an empty /api/generate request with keep_alive=0. Best-effort: a nil return means the request was accepted, not that eviction is guaranteed.
type OpenCodeRunner ¶
OpenCodeRunner executes the OpenCode CLI in non-interactive mode as an LLM backend. Uses `opencode run` with --format json for structured output.
func (OpenCodeRunner) Complete ¶
func (r OpenCodeRunner) Complete(ctx context.Context, req CompletionRequest) (<-chan Token, error)
Complete implements LLMRunner by running the OpenCode CLI with `opencode run`.
type RateLimitError ¶
RateLimitError carries provider-specific context about a rate-limit hit while still satisfying errors.Is(err, ErrRateLimited).
func ClassifyRateLimit ¶
func ClassifyRateLimit(provider string, fragments ...string) *RateLimitError
ClassifyRateLimit returns a non-nil *RateLimitError when any of the given text fragments contains a known rate-limit marker. Returns nil otherwise.
func (*RateLimitError) Error ¶
func (e *RateLimitError) Error() string
func (*RateLimitError) Is ¶
func (e *RateLimitError) Is(target error) bool
type SkillRunner ¶
type SkillRunner struct {
// contains filtered or unexported fields
}
SkillRunner wraps an LLMRunner and injects skill content into system prompts. Agent responses are always English; the user-language directive has been removed to keep agent output uniform across locales.
func (*SkillRunner) Complete ¶
func (r *SkillRunner) Complete(ctx context.Context, req CompletionRequest) (<-chan Token, error)
type Token ¶
type Token struct {
Text string
// Reasoning is display-only chain-of-thought from reasoning models. It is
// shown live in the UI but NOT included in the returned/parsed result.
Reasoning string
Done bool
Error error
Usage *TokenUsage // non-nil only on the Done token
}
Token is a single streaming chunk from an LLM.
type TokenUsage ¶
TokenUsage holds token counts for a single LLM completion. Estimated is true when the count was derived from a heuristic (chars÷4) rather than actual API data.