Help us shape the future of Go! Take the 2026 Go Developer Survey

axconfig

package
v0.50.0 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: MIT Imports: 33 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// ApprovalRulesFileName is the name shared by user and project rule files.
	ApprovalRulesFileName = "approval-rules.yaml"
	// DefaultApprovalRulesPrefixTokens is the number of shell tokens captured by
	// a chat "always allow" answer when the setting is not configured.
	DefaultApprovalRulesPrefixTokens = 2
)
View Source
const (
	// DefaultBudgetScope is the scope used when a budget limit is enabled but
	// no scope is configured.
	DefaultBudgetScope = "turn"
	// DefaultBudgetEstimate controls provider usage estimation for a budget.
	DefaultBudgetEstimate = "auto"
	// DefaultBudgetEstimateFactor is the multiplier applied by the estimator.
	DefaultBudgetEstimateFactor = 1.0
	// DefaultBudgetNoticeRatio is the chat reminder threshold.
	DefaultBudgetNoticeRatio = 0.8
)
View Source
const (
	ChatHistoryScopeProject = "project"
	ChatHistoryScopeAll     = "all"
)

ChatHistoryScope* are the values chat.history_scope accepts: project | all.

View Source
const (
	ChatThemeAuto  = "auto"
	ChatThemeDark  = "dark"
	ChatThemeLight = "light"
)

ChatTheme* are the values chat.theme (and SUGA_THEME) accept: auto | dark | light.

View Source
const (
	DefaultFoldEvery = 0
	DefaultFoldKeep  = 5
	// DefaultFoldAt is the size trigger of folding: a request view estimated at
	// more than this share of the compaction threshold starts folding
	// (docs/design/2026-10-21-fold-by-size-design.md). It defaults to 0 (off):
	// two real comparisons (design 0.4) showed smaller requests but no clear
	// net gain once the cache rebuilds were counted; 0.5 is the tested value.
	DefaultFoldAt = 0
)

History folding defaults (docs/design/2026-10-12-history-folding-design.md). Folding is off by default since 2026-10-12: rebuilding the prefix after each fold was about a third of the uncached input in the P5 retest (see docs/research/2026-10-11-suag-vs-omp-loop-analysis.md), and runs compare more directly with omp without it. context.fold_every: 10 turns it on.

View Source
const (
	DefaultGCRetentionInteractive    = 180 * 24 * time.Hour
	DefaultGCRetentionNonInteractive = 30 * 24 * time.Hour
)

Garbage-collection retention (data governance P3, design 0.3 会话来源). `suga data gc --retention` removes sessions by class instead of by one age: a session an interactive chat created is kept for the interactive period, one a non-interactive entry point created (run, ACP, sub-agent) for the shorter one. A period of 0 keeps its class forever.

View Source
const (
	DefaultIdleAfter    = 15 * time.Minute
	DefaultIdleMinRatio = 0.65
)

Chat idle consolidation defaults (design D6/Q1).

View Source
const (
	// DefaultImageHistoryTurns is how many recent assistant steps keep their
	// pictures whole when history folding is off (images.history_turns).
	DefaultImageHistoryTurns = 3
	// DefaultImageRequestCount is the number of pictures one request may carry
	// (images.max_request_count).
	DefaultImageRequestCount = 8
	// DefaultImageRequestBytes is the encoded-size budget of the pictures of one
	// request (images.max_request_bytes), below the ~32MB a single Claude request
	// allows.
	DefaultImageRequestBytes = 20 << 20
	// DefaultImageMaxSide is the long side view_image scales a picture down to
	// (images.max_side).
	DefaultImageMaxSide = 1568
)

Image input limits (design 0.3, "历史裁剪与成本" and "安全上限"): the byte budget of one request, how many pictures it may carry, how much history keeps its pictures, and the long side view_image scales to.

View Source
const (
	LanguageAuto = string(i18n.SettingAuto)
	LanguageZH   = string(i18n.SettingZH)
	LanguageEN   = string(i18n.SettingEN)
)

Language* are the canonical values of the top-level language setting. The alias table and the resolved language live in internal/i18n; the configuration layer only stores and reports the normalized setting, so `config get language` answers the same thing on every machine (auto included).

View Source
const (
	LogLevelDebug = "debug"
	LogLevelInfo  = "info"
	LogLevelWarn  = "warn"
	LogLevelError = "error"

	// LogStderrAuto keeps the historical behavior: the records also reach stderr
	// while debug mode is on (SUGA_DEBUG or log.level: debug).
	LogStderrAuto   = "auto"
	LogStderrAlways = "always"
	LogStderrNever  = "never"

	// DefaultLogMaxSize is the size one log file may reach before it rotates
	// (log.max_size).
	DefaultLogMaxSize = 10 << 20
	// DefaultLogKeep is how many rotated log files are kept (log.keep); 0 keeps
	// every rotated file.
	DefaultLogKeep = 5
	// LogFileOff is the log.file value that turns the log file off.
	LogFileOff = "off"
)

Log levels, stderr modes and defaults of the process logger (see internal/wiring/logging.go). The vocabulary lives here so `suga config set` and the runtime reader cannot drift apart.

View Source
const (
	ProviderTypeOpenAI    = "openai"
	ProviderTypeAnthropic = "anthropic"
	// ProviderTypeOpenAIResponses is the OpenAI Responses API
	// (POST {base_url}/responses), see llm.ResponsesProvider.
	ProviderTypeOpenAIResponses = "openai-responses"
)

Provider protocol types accepted in providers.<id>.type.

View Source
const (
	ToolsApprovalAsk         = "ask"
	ToolsApprovalAuto        = "auto"
	ChatAgentProgressSummary = "summary"
	ChatAgentProgressFull    = "full"
	ChatAgentProgressOff     = "off"
	MemoryWriteAuto          = "auto"  // memory.write: writes take effect directly (default)
	MemoryWriteOff           = "off"   // memory.write: the memory tool is read-only
	MemoryTaintedAsk         = "ask"   // memory.write_tainted: tainted sessions ask (default; run refuses)
	MemoryTaintedDeny        = "deny"  // memory.write_tainted: tainted sessions never write
	MemoryTaintedAllow       = "allow" // memory.write_tainted: tainted sessions write without asking
)

Shared values are also consumed by the runtime readers. Keeping the enum vocabulary here prevents config set from accepting values that runtime wiring would reject.

View Source
const (
	// DefaultSnapshotMaxFileBytes is the largest before-image retained for one call.
	DefaultSnapshotMaxFileBytes int64 = 16 << 20
	// DefaultSnapshotMaxSessionBytes bounds before-images in one session.
	DefaultSnapshotMaxSessionBytes int64 = 256 << 20
	// DefaultSnapshotMaxGlobalBytes bounds before-images below the sessions root.
	DefaultSnapshotMaxGlobalBytes int64 = 1 << 30
	DefaultSnapshotKeepTurns            = 20
	DefaultSnapshotKeepDays             = 7
	SnapshotOnErrorDeny                 = "deny"
	SnapshotOnErrorContinue             = "continue"
)
View Source
const (
	// DefaultSpillMaxBytes is the logical byte budget of all spill files
	// (tools.spill.max_bytes); 0 means no quota, manual gc only.
	DefaultSpillMaxBytes int64 = 1 << 30
	// DefaultSpillMaxAge is the age at which a spill file is reported as
	// removable (tools.spill.max_age); nothing is deleted automatically.
	DefaultSpillMaxAge = 90 * 24 * time.Hour
	// DefaultSpillCompressAfter is how old an idle spill file must be before
	// `gc --compress-spill` compresses it (tools.spill.compress_after).
	DefaultSpillCompressAfter = 7 * 24 * time.Hour
	// DefaultSpillKeepDays is tools.spill.keep_days; 0 keeps the max_age rule only.
	DefaultSpillKeepDays = 0
	// SpillCompressionGzip is the supported compression (tools.spill.compression).
	SpillCompressionGzip = "gzip"
	// SpillCompressionOff turns the compression pass off.
	SpillCompressionOff = "off"
	// SpillOnQuotaRefuse is the supported quota policy (tools.spill.on_quota): a
	// new output over the quota is refused and the output layer keeps head and
	// tail, instead of dropping older outputs silently.
	SpillOnQuotaRefuse = "refuse"
)

Spill policy defaults and the accepted values (design: Spill 配额、压缩与透明 读取). tools.max_output_bytes and tools.max_spill_bytes keep their meaning; tools.spill.* governs the files below $SUGA_HOME/sessions/**/outputs.

View Source
const (
	ThinkingStyleBudget   = "budget"   // {"type": "enabled", "budget_tokens": N} + interleaved beta
	ThinkingStyleAdaptive = "adaptive" // {"type": "adaptive"} + output_config.effort
	ThinkingStyleNone     = "none"     // never send thinking parameters
)

Thinking styles accepted in providers.<id>.thinking_style and providers.<id>.models.<key>.thinking_style. They pin the protocol shape of extended thinking instead of guessing it from the model name.

View Source
const (
	DefaultRequestTimeout        = llm.DefaultRequestTimeout
	DefaultResponseHeaderTimeout = llm.DefaultResponseHeaderTimeout
)

Default model request timeouts: the llm package's defaults, repeated so the config layer can resolve an unset key on its own.

View Source
const DefaultChatCodeMaxLines = 40

DefaultChatCodeMaxLines is how many lines of one code block chat shows before it folds the rest (chat.code_max_lines) when the key is not set.

View Source
const DefaultChatDiffLines = 20

DefaultChatDiffLines is how many lines one diff preview in chat shows (chat.diff_lines) when the key is not set.

View Source
const DefaultContextWindow = 128000

DefaultContextWindow is used when the model is unknown and no providers.<id>.models.<model>.context_window is set. 128k is the smallest window among current mainstream chat models, so a client computing "used/size" never under-reports pressure by assuming a larger window than the model really has.

View Source
const DefaultMaxSteps = 240

DefaultMaxSteps is the per-turn step limit of the main agent when neither max_steps nor SUGA_MAX_STEPS is set.

View Source
const DefaultRuleFileName = "AGENTS.md"

DefaultRuleFileName is the project rule file read at every directory level when rules.file is unset.

View Source
const DefaultRunDeadlineEnv = ""

DefaultRunDeadlineEnv is the disabled default of run.deadline_env.

View Source
const (
	// DefaultSessionMessageMaxHops is the automatic-reply depth at which a
	// received session message no longer starts a turn of its own.
	DefaultSessionMessageMaxHops = 3
)

The session_message tool (design 2026-10-21 session_message D2/D3): whether a model may list and message the other chat sessions of the same SUGA_HOME, and how deep the automatic replies between two sessions may go.

View Source
const DeprecatedConfigRemoval = "v0.41.0"

DeprecatedConfigRemoval is the release the removed configuration key alias (store.tool_body_inline_bytes) stopped being read in.

View Source
const RunDeadlineEnvKey = "run.deadline_env"

run.deadline_env: the name of the environment variable that carries the job deadline of this run as RFC3339 (gofer injects GOFER_JOB_DEADLINE). Empty or unset = disabled: no deadline hint is ever attached. The deadline itself is read from the process environment at every model request, so it works for run, chat and ACP alike.

Variables

View Source
var DefaultAgentSettings = AgentSettings{Enabled: true, MaxSteps: 30, MaxTokens: 400_000, Timeout: 10 * time.Minute}

DefaultAgentSettings are the agents.* defaults.

LogLevels lists the accepted log.level values.

View Source
var ThinkingLevels = []string{"off", "minimal", "low", "medium", "high", "xhigh", "max", "auto"}

ThinkingLevels are the accepted thinking levels (--thinking, providers.<id>.thinking, providers.<id>.models.<key>.thinking), the same names omp uses. "auto" (or unset) leaves the provider's default.

ThinkingStyles are the accepted thinking styles; see ParseThinkingStyle.

Functions

func AnyVisionModel

func AnyVisionModel(providers map[string]ProviderConfig, settings ModelSettings) bool

AnyVisionModel reports whether the configuration contains at least one model that accepts images (design 0.3, "ACP(第二期)修正"): the ACP initialize answer is sent before any session or runtime exists, so the declaration can only look at configuration, never at the model of a later turn; a prompt that turns out to run a text-only model degrades to a text note instead. The whole offline catalog is consulted, so a switchable or fallback model counts even when the main one cannot see.

func BuildProvider

func BuildProvider(spec ModelSpec) (llm.Provider, error)

BuildProvider constructs the llm provider for one resolved model. The provider Name is the configured provider id so trace/stats record it.

func BuildProviderWithProxy

func BuildProviderWithProxy(spec ModelSpec, proxy netproxy.ProxyFunc) (llm.Provider, error)

BuildProviderWithProxy additionally pins the global network.proxy selector on the provider's HTTP clients: a matched host goes through the proxy, every other host connects directly. A nil selector keeps the default transport, which follows the environment proxies.

func ChatAgentProgress

func ChatAgentProgress() (string, error)

ChatAgentProgress reads chat.agent_progress. Summary is the default so a busy group of sub-agents does not fill the terminal with one line per tool call.

func ChatAskOutsideDirs

func ChatAskOutsideDirs() bool

ChatAskOutsideDirs reports whether an interactive chat asks the person to authorize a directory a file tool wants to reach outside the workspace and the session's added directories (chat.ask_outside_dirs, on by default). It takes the same values as chat.markdown. The question is asked on the terminal, so run, ACP and a chat without a terminal keep refusing such a call as before.

func ChatCodeHighlightEnabled

func ChatCodeHighlightEnabled() bool

ChatCodeHighlightEnabled reports whether chat colors a fenced code block by the language its fence names (chat.code_highlight, on by default). It takes the same values as chat.markdown; an unknown language, a non-terminal output or NO_COLOR keeps the plain text anyway.

func ChatCodeMaxLines

func ChatCodeMaxLines() (int, error)

ChatCodeMaxLines reads chat.code_max_lines: how many lines of one code block chat shows before it folds the rest and names :code. 0 shows the block whole.

func ChatDiffEnabled

func ChatDiffEnabled() bool

ChatDiffEnabled reports whether chat shows what a file tool call changed (chat.diff, on by default): the unified diff under the tool result, the pending diff before an approval question and the :diff command. It takes the same values as chat.markdown. run, ACP and stream-json are not affected - ACP builds its own diff for its client either way.

func ChatDiffLines

func ChatDiffLines() (int, error)

ChatDiffLines reads chat.diff_lines: how many lines one diff preview shows (the :diff command always shows the whole change). A value below 1 or something that is not a whole number is an error rather than a silently changed or ignored limit.

func ChatHighlightInputEnabled

func ChatHighlightInputEnabled() bool

ChatHighlightInputEnabled reports whether chat paints a background behind the line the person submitted at the prompt, and behind messages delivered from elsewhere (chat.highlight_input, on by default). It takes the same values as chat.markdown; a non-terminal output or NO_COLOR turns the background off.

func ChatHistoryEnabled

func ChatHistoryEnabled() bool

ChatHistoryEnabled reports whether locally typed chat lines are persisted.

func ChatHistoryScope

func ChatHistoryScope() (string, error)

ChatHistoryScope reads chat.history_scope: project (the default) makes the Up/Down history only recall lines typed in the current project; all keeps the old behaviour, where the current project comes first and the other projects' lines follow once its lines are exhausted.

func ChatHistorySize

func ChatHistorySize() (int, error)

ChatHistorySize returns the maximum number of persisted chat lines.

func ChatMarkdownEnabled

func ChatMarkdownEnabled() bool

ChatMarkdownEnabled reports whether chat renders the model's markdown in the terminal (chat.markdown, on by default). The key accepts a bool or a string; "off"/"false" turn the rendering off and show the exact model text instead.

func ChatNotifyAfter

func ChatNotifyAfter() (time.Duration, error)

ChatNotifyAfter reads the minimum turn duration before a completion notice.

func ChatNotifyMode

func ChatNotifyMode() (string, error)

ChatNotifyMode selects terminal notifications: auto, bell, osc9 or off.

func ChatSpinnerEnabled

func ChatSpinnerEnabled() bool

ChatSpinnerEnabled reports whether chat shows its "思考中…" waiting line while the model is asked for its next message (chat.spinner, on by default). It takes the same values as chat.markdown; a non-terminal output or NO_COLOR turns the line off anyway.

func ChatSteeringEnabled

func ChatSteeringEnabled() bool

ChatSteeringEnabled reports whether chat keeps the input line available while a turn runs (chat.steering, on by default): the person can insert a message into the running turn (Enter), end this turn only (Esc, a single Ctrl-C) or leave chat (a second Ctrl-C within a few seconds). It takes the same values as chat.markdown; a non-terminal input keeps the old behaviour anyway (no line editing, no reading during a turn).

func ChatTerminalTitleEnabled

func ChatTerminalTitleEnabled() bool

ChatTerminalTitleEnabled reports whether chat sets the terminal's window/tab title to the session, "suga · <短名称> · <会话标题>" (chat.terminal_title, on by default). It takes the same values as chat.markdown; a non-terminal output or NO_COLOR leaves the title alone anyway.

func ChatTheme

func ChatTheme() (string, error)

ChatTheme resolves chat.theme to the actual terminal palette chat paints its markdown and code with: "dark" or "light". A theme in the config file is the default; the environment variable SUGA_THEME (dark|light) overrides it, which lets one shell run chat on the other palette without touching config.yaml. auto (the default) takes the background from the terminal's COLORFGBG report ("foreground;background"; the last segment is the background): 7 or 15 mean a light background, anything else (or no report) a dark one. No terminal query is made; an unset COLORFGBG stays dark, like before the option existed.

func ChatUndoConfirmEnabled

func ChatUndoConfirmEnabled() bool

ChatUndoConfirmEnabled reports whether :undo asks for confirmation before it changes files. It is on by default and accepts the same bool/string switches as the other chat safety settings.

func ChatWin32InputMode

func ChatWin32InputMode() (string, error)

ChatWin32InputMode selects win32-input-mode (DECSET 9001) for the chat input: auto (the default) asks for it in Windows Terminal only, on always asks for it and off leaves the keys as plain bytes. With the mode on the terminal reports every key press as a record, which is what lets Ctrl+Enter put a newline into the input line instead of submitting it (WT binds Alt+Enter to fullscreen and sends Ctrl+Enter as Ctrl+J's byte otherwise).

func CheckLegacyConfig

func CheckLegacyConfig() error

CheckLegacyConfig rejects the removed llm: section and SUGA_PROVIDER.

func ContextWindowFor

func ContextWindowFor(spec ModelSpec) int

ContextWindowFor returns providers.<id>.models.<model>.context_window when set, then providers.<id>.context_window, otherwise the window inferred from the model id sent to the provider.

func ContextWindowForModel

func ContextWindowForModel(model string) int

ContextWindowForModel returns the window for a model name, or DefaultContextWindow when the model is not recognised.

func DeprecatedKeyNotices

func DeprecatedKeyNotices() []string

DeprecatedKeyNotices returns one warning per removed key the loaded configuration still sets. Callers print them to stderr once after Load, so stdout (and the stream-json contract) stays clean.

func DisabledToolNames

func DisabledToolNames() ([]string, error)

DisabledToolNames returns tools.disabled: the tool names the runtime must not offer to the model, in configured order (empty = nothing disabled). A name is removed from the tool registry, so it is absent from the tool list, from tool_search and from the manifest instead of failing on every call. Entries are trimmed and de-duplicated; a value that is not a list of names is an error.

func InferVision

func InferVision(apiModel string) bool

InferVision guesses whether a model id sent to the provider accepts images. The vendor prefix of a gateway id ("openai/gpt-4o") is dropped first, so the same family is recognized through every gateway. An unknown id counts as text-only: sending image parts to a model that cannot read them fails the whole request, while a text note only costs one line.

func IsSecretKey

func IsSecretKey(key string) bool

IsSecretKey conservatively classifies credentials before a caller displays or writes a key. A false positive is safer than putting a likely secret in YAML.

func IsSimpleConfigType

func IsSimpleConfigType(valueType ConfigValueType) bool

IsSimpleConfigType reports whether the registry can validate a value from its scalar/list representation without a structured reader.

func Load

func Load() error

Load initializes environment and YAML-backed configuration sources for the current process. Call it once near process startup before reading settings.

func LoadedHome

func LoadedHome() (string, bool)

LoadedHome returns the root Load loaded the configuration from, and whether Load ran in this process at all.

func MCPCallTimeout

func MCPCallTimeout() time.Duration

MCPCallTimeout reads mcp.call_timeout_sec (default 120): the bound on one MCP tools/call.

func MCPStartupTimeout

func MCPStartupTimeout() time.Duration

MCPStartupTimeout reads mcp.startup_timeout_sec (default 30): the bound on one server's initialize + tools/list discovery, so a slow HTTP server cannot extend the startup of the others.

func MaxOutputTokensFor

func MaxOutputTokensFor(spec ModelSpec) int

MaxOutputTokensFor returns the configured output token limit of spec's model: providers.<id>.models.<model>.max_output_tokens, else providers.<id>.max_output_tokens, else 0 for "no limit configured", which leaves the limit to the provider protocol (see ResolveMaxOutputTokens).

func ModelCatalogSource

func ModelCatalogSource() string

ModelCatalogSource reports the only environment override that changes the model selection shown by this command. It intentionally does not expose values from .env or any credential-bearing environment variable.

func ParseConfigValue

func ParseConfigValue(key, raw string) (any, error)

ParseConfigValue converts a command value according to the key descriptor. Errors name both the key and the expected type so the CLI can return input error code 2 without duplicating the registry's type rules.

func ParseThinking

func ParseThinking(v string) (string, error)

ParseThinking normalizes and validates a thinking level; "" stays unset.

func ParseThinkingStyle

func ParseThinkingStyle(v string) (string, error)

ParseThinkingStyle normalizes and validates a thinking style; "" stays unset, which keeps the model-name heuristic (see ThinkingStyleFor).

func ReadClaudeMCPConfigs

func ReadClaudeMCPConfigs(paths []string) ([]mcp.ServerSettings, error)

ReadClaudeMCPConfigs reads repeatable Claude-style stdio MCP configuration files.

func ReadDeferredNativeTools

func ReadDeferredNativeTools() ([]string, error)

ReadDeferredNativeTools reads tools.deferred_native: unset/never defers no native tool, auto selects the built-in list, and a YAML list names the tools explicitly. A name that is not a native tool is an error, so a typo or an MCP tool name fails at startup instead of silently deferring nothing.

func ReadLanguage

func ReadLanguage() (string, error)

ReadLanguage resolves the configured UI language to its canonical form: auto, zh or en. SUGA_LANGUAGE (set for one shell or by a script) wins over language: in config.yaml, and both are normalized through internal/i18n - the single alias table - so a hand-written en_US or 中文 reads back as en or zh. An absent setting is auto: the catalog then follows the machine's user locale.

func ReadMCPServerSettings

func ReadMCPServerSettings() ([]mcp.ServerSettings, error)

ReadMCPServerSettings reads mcp.servers: stdio servers (command) and Streamable HTTP servers (url) share the list. A malformed entry, a duplicate id or a command/url mix fails startup instead of silently dropping a server, so a typo cannot disable a configured server unnoticed.

func ReadMaxSteps

func ReadMaxSteps(flagMaxSteps int) (int, error)

ReadMaxSteps resolves the step limit of one main-agent turn. Precedence is the same as for the model settings: --max-steps > SUGA_MAX_STEPS > config max_steps (default 240); flagMaxSteps 0 means "not given". A value below 1 from the flag or the environment is an error rather than a silent "no limit"; a non-positive max_steps in the config keeps its older meaning (no limit). The sub-agent limit agents.max_steps is a separate setting (ReadAgentSettings).

func ReadNudgeSetting

func ReadNudgeSetting() (bool, error)

ReadNudgeSetting reads agents.nudge (default on): whether a turn that looks finished too early is checked (personal.CheckNudge). "on"/"true" and "off"/"false" are accepted; off makes every host skip the check.

func ReadProviders

func ReadProviders() (map[string]ProviderConfig, error)

ReadProviders returns every defined provider: the built-in presets, each overridden field by field by the same-named providers.<id> entry (empty fields never override), plus user-defined providers, which must set type.

func ReadRetryPolicy

func ReadRetryPolicy() (llm.RetryPolicy, error)

ReadRetryPolicy reads the top-level retry: section (how every provider retries a model request that failed for a transient reason, see llm.RetryPolicy): max_attempts (>= 1, the first attempt included; 1 turns retries off), max_elapsed (the wall-clock budget of one request's retries; "off" removes it) and the durations base_delay, max_delay and reset_after ("2s", "1m", or seconds). Unset keys take llm.DefaultRetryPolicy; an invalid value is an error. A provider may override every field with providers.<id>.retry (same fields), see applyRetryPolicy.

func ReadRuleFileName

func ReadRuleFileName() (string, error)

ReadRuleFileName reads rules.file: the project rule file read at each level, from the Git root (or cwd) down to cwd. Unset (or empty) means AGENTS.md. Only a bare file name is accepted - a path would let the value read files outside the level directory - so any other value is an error, not a fallback.

func ReadRunDeadlineEnv

func ReadRunDeadlineEnv() string

ReadRunDeadlineEnv resolves run.deadline_env: an env var name, settings like no deadline hint. Nothing here reads the referenced variable itself - the personal runner asks the process environment per request.

func Reload

func Reload() error

Reload resets the process configuration before loading the active sources. This is required after a candidate validation, which temporarily replaces the global data with the candidate document.

func ResetLoadedStateForTest

func ResetLoadedStateForTest()

ResetLoadedStateForTest forgets the loaded root, so a test can load another SUGA_HOME. Tests call it from their cleanup; production code never does.

func ResolveCoreStorePath

func ResolveCoreStorePath() (string, error)

ResolveCoreStorePath returns the single-file core store location ($SUGA_HOME/db/sessions.db).

func ResolveMaxOutputTokens

func ResolveMaxOutputTokens(flagValue int, spec ModelSpec) (int, error)

ResolveMaxOutputTokens returns how many tokens one main-loop request may answer with. Precedence is the same as for the step limit: --max-output-tokens > SUGA_MAX_OUTPUT_TOKENS > providers.<id>.models.<m>.max_output_tokens > providers.<id>.max_output_tokens; flagValue 0 means "not given".

0 means no configured limit: the protocol's own default applies then (the Claude provider sends its 32000 default, an OpenAI-compatible server uses its own). A value below 1 from the flag or the environment is an error rather than a silent "no limit", like ReadMaxSteps.

func ResolveProjectApprovalRulesPath

func ResolveProjectApprovalRulesPath(workspace string) (string, error)

ResolveProjectApprovalRulesPath returns the rule file belonging to workspace.

func ResolveSessionsDir

func ResolveSessionsDir() (string, error)

ResolveSessionsDir returns the per-session file root ($SUGA_HOME/sessions): <sessions>/<session_id>/outputs/ holds externalised tool outputs.

func ResolveSugaHome

func ResolveSugaHome() (string, error)

ResolveSugaHome locates user-level instructions from the data store location.

func ResolveUserApprovalRulesPath

func ResolveUserApprovalRulesPath() (string, error)

ResolveUserApprovalRulesPath returns the user-level rule file path.

func ResolveWorkspacePath

func ResolveWorkspacePath() string

func SessionMessageEnabled

func SessionMessageEnabled() bool

SessionMessageEnabled reports tools.session_message.enabled (default true), with SUGA_SESSION_MESSAGE=off as a process-level switch.

func SessionMessageMaxHops

func SessionMessageMaxHops() int

SessionMessageMaxHops is tools.session_message.max_hops (default 3): a session message with this many hops is queued for the next input instead of starting a turn. A value below 1 is read as the default, so the loop guard cannot be turned off by accident.

func SpillQuotaBytes

func SpillQuotaBytes() int64

SpillQuotaBytes is tools.spill.max_bytes as the session writer uses it. A value the reader rejects falls back to the default: an unreadable limit must not stop a turn (the settings registry reports the error instead).

func StreamRequiredFor

func StreamRequiredFor(spec ModelSpec) bool

StreamRequiredFor reports whether spec's model must be requested with stream=true: providers.<id>.models.<model>.stream_required when written, else providers.<id>.stream_required.

func ThinkingStyleFor

func ThinkingStyleFor(spec ModelSpec) string

ThinkingStyleFor returns the configured thinking style of spec's model (ThinkingStyles): providers.<id>.models.<model>.thinking_style, else providers.<id>.thinking_style, else "" for the model-name heuristic (see llm.applyClaudeThinking).

func TranscriptsEnabled

func TranscriptsEnabled() bool

TranscriptsEnabled reports whether chat transcripts are written. The `transcripts` key accepts a bool or a string; "off"/"false" disable it.

func ValidateConfigCandidate

func ValidateConfigCandidate(content []byte, key string, allowMissingModel ...bool) error

ValidateConfigCandidate loads a candidate into the same reader registry used at startup. The global config is deliberately reset first; callers should call Reload after the edit, whether validation or the write succeeds. allowMissingModel is used by unset model: an empty model is a valid file state for an edit command even though a later runtime start will reject it.

func ValidateConfigKey

func ValidateConfigKey(key string) error

ValidateConfigKey dispatches validation to an existing typed reader. Simple keys without a reader still get type/range/enum validation from the registry; structured values remain rejected rather than gaining a second validator.

func VisionFor

func VisionFor(spec ModelSpec) bool

Vision capability of a model (design 0.3, "vision 三态"): the model accepts images in a request. It is declared per model and per provider in the same three-state way as stream_required:

  • providers.<id>.models.<model>.vision written -> that value;
  • providers.<id>.vision written -> that value;
  • neither written -> inferred from the model id sent to the provider (InferVision), so a new model of a known family works without config and a gateway serving it over another protocol can still be pinned to false.

The capability decides two things: whether view_image is in the tool table of the current model, and whether a request carries image parts at all (a fallback model without vision gets a text note instead, see llm.NoImages).

func WriteBootstrapNotice

func WriteBootstrapNotice(w io.Writer, result BootstrapResult) error

WriteBootstrapNotice writes only the diagnostic initialization hint. The caller uses stderr for it so run stream-json and ACP protocol stdout remain machine-readable.

Types

type AgentSettings

type AgentSettings struct {
	// Enabled registers the agent tool (agents.enabled, default true).
	Enabled bool
	// Model is the sub-agents' model, <provider>/<model> (agents.model; empty:
	// the main model).
	Model string
	// MaxSteps, MaxTokens (uncached input plus output) and Timeout make a
	// sub-agent wrap up its report (agents.max_steps 30, agents.max_tokens
	// 400000, agents.timeout 10m).
	MaxSteps  int
	MaxTokens int
	Timeout   time.Duration
}

AgentSettings configure sub-agents (agents.*; the agent tool).

func ReadAgentSettings

func ReadAgentSettings() (AgentSettings, error)

ReadAgentSettings reads agents.*; unset keys take DefaultAgentSettings.

type ApprovalRulesSettings

type ApprovalRulesSettings struct {
	Enabled            bool
	AlwaysPrefixTokens int
	PersistAsk         bool
	ProjectTrust       map[string]string
}

ApprovalRulesSettings contains the non-rule-file approval settings. Rule bodies deliberately live in approval-rules.yaml so persistence can preserve the user's comments and layout.

func DefaultApprovalRulesSettings

func DefaultApprovalRulesSettings() ApprovalRulesSettings

DefaultApprovalRulesSettings returns the secure-by-default rule settings.

func ReadApprovalRulesSettings

func ReadApprovalRulesSettings() (ApprovalRulesSettings, error)

ReadApprovalRulesSettings validates tools.approval_rules. Missing settings retain the defaults, while a present value must be an object with only the documented fields. This keeps old tools.* keys untouched and fail-closed for new configuration mistakes.

type BootstrapError

type BootstrapError struct {
	Code int
	Err  error
}

BootstrapError carries the user-facing exit code for initialization policy errors, while ordinary filesystem failures continue to use exit code 1.

func (BootstrapError) Error

func (e BootstrapError) Error() string

func (BootstrapError) ExitCode

func (e BootstrapError) ExitCode() int

func (BootstrapError) Unwrap

func (e BootstrapError) Unwrap() error

type BootstrapOptions

type BootstrapOptions struct {
	Force bool
}

BootstrapOptions controls the safe, first-run initialization operation. Force only affects the home config.yaml; the .env file is never overwritten.

type BootstrapResult

type BootstrapResult struct {
	Home          string
	Config        string
	Env           string
	Source        string
	CreatedHome   bool
	CreatedConfig bool
	CreatedEnv    bool
	Backup        string
	Force         bool
}

BootstrapResult describes files considered by EnsureHome and the files it created. It is intentionally a data-only result so command output stays in the CLI layer and initialization remains useful to non-CLI callers.

func EnsureHome

func EnsureHome(opts BootstrapOptions) (BootstrapResult, error)

EnsureHome creates the private suga root and safe onboarding files. The filesystem lock and the second existence check are deliberately inside the same owner: concurrent first runs can never overwrite a user's files.

type BudgetFlags

type BudgetFlags struct {
	Tokens  int
	CostUSD float64
	Scope   string
}

BudgetFlags are the command-line budget overrides. A zero numeric value and an empty scope mean that the corresponding environment/config value applies. Estimate settings intentionally have no CLI flags in this version.

type BudgetSettings

type BudgetSettings struct {
	Tokens         int
	CostUSD        float64
	Scope          string
	Estimate       string
	EstimateFactor float64
	NoticeRatio    float64
}

BudgetSettings configures the optional turn/session token and cost budget. A zero-value BudgetSettings means that no budget is enabled.

func ReadBudgetSettings

func ReadBudgetSettings(flags BudgetFlags) (BudgetSettings, error)

ReadBudgetSettings resolves budget flags, environment overrides and config. Limits use flag > environment > config precedence. The remaining settings use their config defaults, with matching SUGA_BUDGET_* environment overrides; every explicitly supplied invalid value fails closed at startup.

type ChatSettings

type ChatSettings struct {
	History, Markdown, Spinner, HighlightInput bool
	Steering, TerminalTitle, Diff              bool
	AskOutsideDirs, UndoConfirm                bool
	AgentProgress                              string
	HistorySize, DiffLines                     int
	HistoryScope                               string
	CodeHighlight                              bool
	CodeMaxLines                               int
	Notify                                     string
	NotifyAfter                                time.Duration
	Win32InputMode                             string
	Theme                                      string
}

ReadChatSettings groups the existing chat readers without introducing another validation implementation for their defaults or accepted values.

func ReadChatSettings

func ReadChatSettings() (ChatSettings, error)

type ConfigKey

type ConfigKey struct {
	Pattern   string
	Type      ConfigValueType
	Sensitive bool
	Writable  bool
	Reader    string
}

ConfigKey describes one supported configuration path. Reader is the existing typed reader used to validate the key; an empty Reader means that the key is known but has no typed reader and must not be reported as validated.

func KnownConfigKeys

func KnownConfigKeys() []ConfigKey

KnownConfigKeys returns a copy of the fixed key descriptors. Provider and model paths are represented by the dynamic patterns returned by MatchConfigKey.

func MatchConfigKey

func MatchConfigKey(key string) (ConfigKey, error)

MatchConfigKey validates a key and returns its descriptor. Dynamic provider and model names are constrained so arbitrary YAML structure cannot be injected.

type ConfigSource

type ConfigSource string

ConfigSource identifies where an effective value came from.

const (
	SourceDefault ConfigSource = "default"
	SourceConfig  ConfigSource = "config"
	SourceEnv     ConfigSource = "env"
)

type ConfigValidationError

type ConfigValidationError struct {
	Err error
}

ConfigValidationError marks a candidate that is syntactically valid YAML but violates an existing typed configuration reader. CLI callers map it to the input/configuration exit code instead of treating it as an I/O failure.

func (ConfigValidationError) Error

func (e ConfigValidationError) Error() string

func (ConfigValidationError) ExitCode

func (e ConfigValidationError) ExitCode() int

func (ConfigValidationError) Unwrap

func (e ConfigValidationError) Unwrap() error

type ConfigValueType

type ConfigValueType string

ConfigValueType is the command-facing type of a configuration leaf.

const (
	ConfigTypeString     ConfigValueType = "string"
	ConfigTypeBool       ConfigValueType = "bool"
	ConfigTypeSwitch     ConfigValueType = "switch"
	ConfigTypeInt        ConfigValueType = "int"
	ConfigTypeInt64      ConfigValueType = "int64"
	ConfigTypeFloat      ConfigValueType = "float"
	ConfigTypeDuration   ConfigValueType = "duration"
	ConfigTypeStringList ConfigValueType = "string_list"
	ConfigTypeStringMap  ConfigValueType = "string_map"
	ConfigTypeYAML       ConfigValueType = "yaml"
	ConfigTypeEnum       ConfigValueType = "enum"
)

type ConfigWriteOptions

type ConfigWriteOptions struct {
	Validate func([]byte) error
}

ConfigWriteOptions controls candidate validation for a config edit. The validator runs before replacement and again after reading the replaced file, so a failed semantic check cannot leave a partially accepted configuration.

type ConfigWriteResult

type ConfigWriteResult struct {
	Path    string
	Backup  string
	Changed bool
}

ConfigWriteResult describes a successful read-modify-write operation.

func UnsetConfigValue

func UnsetConfigValue(path, key string, opts ConfigWriteOptions) (ConfigWriteResult, error)

UnsetConfigValue removes one YAML leaf. Empty dynamic maps are removed after the leaf, while comments attached to a removed entry are carried to the next entry or the containing mapping instead of being silently discarded.

func WriteConfigValue

func WriteConfigValue(path, key string, value any, opts ConfigWriteOptions) (ConfigWriteResult, error)

WriteConfigValue replaces or appends one YAML leaf while retaining the AST's comments and key order. Callers that own config semantics should provide a validator which uses the existing typed readers.

type FoldSettings

type FoldSettings struct {
	// Every (context.fold_every) is the batch size the fold boundary moves
	// by; 0 turns folding off.
	Every int
	// Keep (context.fold_keep) is how many recent steps stay whole (>= 1).
	Keep int
	// At (context.fold_at) is the share of the compaction threshold the
	// pre-fold request estimate has to pass before the segment starts folding
	// (0 <= at < 1; 0 disables the size trigger).
	At float64
}

FoldSettings configures history folding of the request view.

func ReadFoldSettings

func ReadFoldSettings() (FoldSettings, error)

ReadFoldSettings reads context.fold_every (>= 0), context.fold_keep (>= 1) and context.fold_at (0 <= at < 1). Unset keys take the defaults; an invalid value is an error.

type GCRetentionSettings

type GCRetentionSettings struct {
	Interactive    time.Duration
	NonInteractive time.Duration
}

GCRetentionSettings is the validated gc.retention policy.

func DefaultGCRetentionSettings

func DefaultGCRetentionSettings() GCRetentionSettings

DefaultGCRetentionSettings returns the documented defaults (180d / 30d).

func ReadGCRetentionSettings

func ReadGCRetentionSettings() (GCRetentionSettings, error)

ReadGCRetentionSettings reads gc.retention.interactive and gc.retention.noninteractive. Unknown fields are rejected, so a misspelled key cannot silently keep months of sessions. A value is a duration ("180d", "4320h") or bare seconds; a negative value is an error.

type IdleSettings

type IdleSettings struct {
	// After is the quiet time after a turn ends before consolidating
	// (context.idle_after); 0 disables it.
	After time.Duration
	// MinRatio is the share of the segment threshold the last request's
	// context must reach (context.idle_min_ratio).
	MinRatio float64
}

IdleSettings configures the chat idle consolidation.

func ReadIdleSettings

func ReadIdleSettings() (IdleSettings, error)

ReadIdleSettings reads context.idle_after (a Go duration such as "3s" or "15m", or a plain number of seconds; 0 turns it off) and context.idle_min_ratio (0..1). Unset keys take the defaults; an invalid value is an error.

type ImageSettings

type ImageSettings struct {
	HistoryTurns    int
	MaxRequestCount int
	MaxRequestBytes int
	MaxSide         int
}

ImageSettings are the effective images.* limits.

func ReadImageSettings

func ReadImageSettings() (ImageSettings, error)

ReadImageSettings reads the images.* section. Every key falls back to its built-in default; a non-positive value is a startup error instead of being guessed (a cap of 0 would silently drop every picture).

type KeyDescriptor

type KeyDescriptor = ConfigKey

KeyDescriptor is the descriptive name used by config command adapters.

type LogSettings

type LogSettings struct {
	// Level is the minimum record level (log.level; "debug" also enables the
	// stderr copy under log.stderr: auto).
	Level string
	// File is the log path, empty for the default <SUGA_HOME>/logs/suga.log,
	// LogFileOff for no file at all (log.file).
	File string
	// Stderr decides the stderr copy (log.stderr): auto|always|never.
	Stderr string
	// MaxSize is the size in bytes after which the file rotates (log.max_size).
	MaxSize int64
	// Keep is the number of rotated files to keep (log.keep).
	Keep int
	// Compress gzips rotated files as they age out (log.compress).
	Compress bool
}

LogSettings are the effective log.* settings of the process logger.

func ReadLogSettings

func ReadLogSettings() (LogSettings, error)

ReadLogSettings reads the log: section of config.yaml. Unset keys take the defaults above; an invalid value is an error naming the key, so a typo stops the run at startup instead of silently falling back.

type ModelCatalog

type ModelCatalog struct {
	Offline    bool                   `json:"offline"`
	Providers  []ModelCatalogProvider `json:"providers"`
	Models     []ModelCatalogModel    `json:"models"`
	Switchable []string               `json:"switchable"`
	Source     string                 `json:"source"`
}

ModelCatalog is the offline projection consumed by the models command and later by chat's model switcher. It contains configuration facts only; it never builds a provider or contacts an endpoint.

func BuildModelCatalog

func BuildModelCatalog(providers map[string]ProviderConfig, settings ModelSettings) ModelCatalog

BuildModelCatalog projects resolved providers and model roles. The caller is responsible for obtaining the inputs through ReadProviders and ReadModelSettings, which keeps this projection independent from runtime assembly and network-capable provider code.

type ModelCatalogModel

type ModelCatalogModel struct {
	Ref           string `json:"ref"`
	Provider      string `json:"provider"`
	Model         string `json:"model"`
	ModelID       string `json:"model_id,omitempty"`
	Type          string `json:"type,omitempty"`
	ContextWindow int    `json:"context_window"`
	Thinking      string `json:"thinking,omitempty"`
	// ThinkingStyle is the declared thinking request shape ("" = the model-name
	// heuristic), see ThinkingStyleFor.
	ThinkingStyle string `json:"thinking_style,omitempty"`
	// StreamRequired marks a model whose endpoint answers only streamed requests.
	StreamRequired bool `json:"stream_required,omitempty"`
	// Vision reports whether the model accepts images (providers.<id>.models.<model>.vision,
	// else providers.<id>.vision, else the built-in list; see VisionFor).
	Vision    bool     `json:"vision"`
	Roles     []string `json:"roles"`
	CanSwitch bool     `json:"can_switch"`
}

ModelCatalogModel is one canonical provider/model reference. ModelID is the effective upstream id, while Ref remains the stable local configuration key.

type ModelCatalogProvider

type ModelCatalogProvider struct {
	ID       string   `json:"id"`
	Kind     string   `json:"kind"`
	ModelIDs []string `json:"model_ids"`
}

ModelCatalogProvider describes a provider namespace without exposing its endpoint or credentials.

type ModelConfig

type ModelConfig struct {
	// ModelID (models.<key>.model_id) is the model id sent to the provider when
	// it differs from the configured key, so a long upstream id such as
	// "deepseek/deepseek-v4.1-flash" can be referenced by a short key.
	ModelID string
	// Type and BaseURL (models.<key>.type / base_url) override the provider's
	// for this model: a gateway such as command-code serves Claude models over
	// the Anthropic protocol and the others over OpenAI's, often at another
	// base URL. "" keeps the provider's.
	Type, BaseURL string
	ContextWindow int
	// MaxOutputTokens (models.<key>.max_output_tokens) caps how many tokens
	// this model may answer with; 0 falls back to the provider's value, see
	// ProviderConfig.MaxOutputTokens.
	MaxOutputTokens int
	// Thinking (models.<key>.thinking) is the model's thinking level, see
	// ThinkingLevels; "" falls back to the provider's.
	Thinking string
	// ThinkingStyle (models.<key>.thinking_style) pins the protocol shape of
	// extended thinking (budget|adaptive|none, see ThinkingStyles) instead of
	// guessing it from the model name; "" falls back to the provider's, and
	// then to the model-name heuristic.
	ThinkingStyle string
	// StreamRequired (models.<key>.stream_required) marks a model whose endpoint
	// answers only streamed requests: the provider sends every request with
	// stream=true. StreamRequiredSet records that the key was written, so an
	// explicit false overrides the provider level.
	StreamRequired    bool
	StreamRequiredSet bool
	// Vision (models.<key>.vision) declares whether the model accepts images.
	// VisionSet records that the key was written, so an explicit false overrides
	// the provider level and an unset key falls back to the built-in list (see
	// VisionFor).
	Vision    bool
	VisionSet bool
	// Price is the optional per-million-token price used to compute cost when
	// the provider reports none; the zero value means "no price configured".
	Price Price
}

ModelConfig is the per-model override under providers.<id>.models.<model>.

type ModelSettings

type ModelSettings struct {
	Main      ModelSpec
	Compact   *ModelSpec
	Idle      *ModelSpec
	Handoff   *ModelSpec
	Fallbacks []ModelSpec
}

ModelSettings is the effective model selection: main, optional compact (summary) model and ordered fallbacks. Idle and Handoff are the per-scenario overrides (models.idle / models.handoff); nil means the scenario falls back to the compact model, then the turn's own model.

func ReadModelSettings

func ReadModelSettings(flagModel string) (ModelSettings, error)

ReadModelSettings resolves the main model (flagModel > SUGA_MODEL > model), compact_model and fallback_models. The main ref's provider is the default provider for bare model ids in compact_model and fallback_models.

func (ModelSettings) PriceLookup

func (s ModelSettings) PriceLookup() func(provider, model string) (Price, bool)

PriceLookup returns a (provider id, model) price lookup over the main, compact and fallback models of s. Models outside these are unknown.

type ModelSpec

type ModelSpec struct {
	Provider ProviderConfig
	Model    string
	// Thinking overrides the configured thinking level (--thinking for the
	// main model); "" uses the configuration, see ThinkingLevel.
	Thinking string
}

ModelSpec is a model bound to the provider that serves it.

func ResolveModel

func ResolveModel(ref string, providers map[string]ProviderConfig, defaultProvider string) (ModelSpec, error)

ResolveModel parses "provider/model" or a bare model id. It splits only at the first "/" and only when the prefix is a defined provider; otherwise the whole string is the model id (e.g. "meta/llama-3") served by defaultProvider.

A name that is no configured model of a provider listing its models (and a bare name without a default provider) is then looked up loosely, see matchModels: a single match is used, several are an error listing them, none keeps the name as it is.

func SwitchableModelSpecs

func SwitchableModelSpecs(providers map[string]ProviderConfig, settings ModelSettings) ([]ModelSpec, error)

SwitchableModelSpecs resolves the canonical switchable references from the catalog back to the specs used by runtime model switching. Keeping the catalog's ordered refs as the source ensures CLI output and chat candidates cannot drift or produce duplicate aliases.

func (ModelSpec) APIModel

func (s ModelSpec) APIModel() string

APIModel is the model id sent to the provider: models.<key>.model_id when set, otherwise the key itself. Everything else (refs, trace, stats, price and context window lookups) uses the key.

func (ModelSpec) Ref

func (s ModelSpec) Ref() string

Ref returns the canonical "provider/model" form.

func (ModelSpec) ThinkingLevel

func (s ModelSpec) ThinkingLevel() string

ThinkingLevel is the effective thinking level of s: the override set from --thinking, then models.<key>.thinking, then providers.<id>.thinking; "" when none is set.

type NetworkProxySettings

type NetworkProxySettings struct {
	URL   string
	Sites []string
}

NetworkProxySettings is the resolved network.proxy configuration: the global proxy URL (environment references already expanded) plus the site allowlist that opts hosts into it.

func ReadNetworkProxy

func ReadNetworkProxy() (NetworkProxySettings, error)

ReadNetworkProxy validates network.proxy.url and network.proxy.sites. An empty URL means "no global proxy": web_fetch, the model clients and web_search then keep their own previous behavior (see pkg/agentcore/netproxy). A configured URL is validated here, at startup, instead of failing per request; the reader never returns the URL in an error, because it may embed proxy credentials.

type PreferredTool

type PreferredTool struct {
	Name string `yaml:"name" json:"name"`
	Kind string `yaml:"kind" json:"kind"`
	When string `yaml:"when" json:"when"`
}

PreferredTool is one user-declared command or MCP server to favor when it is available. It contains only an identifier and a human-readable use case.

func ReadPreferredTools

func ReadPreferredTools() ([]PreferredTool, error)

ReadPreferredTools reads and validates the complete tools.preferred value. Runtime discovery is deliberately outside this reader: config validation must not execute commands or start an MCP server.

type Price

type Price struct {
	Input, Output, CacheRead, CacheWrite float64
}

Price is a model price in US dollars per million tokens (providers.<id>.models.<model>.price: input, output, cache_read, cache_write).

func PriceFor

func PriceFor(spec ModelSpec) (Price, bool)

PriceFor returns the configured price of spec's model.

func (Price) IsZero

func (p Price) IsZero() bool

IsZero reports whether no price is configured.

type ProviderConfig

type ProviderConfig struct {
	ID      string
	Type    string // openai | anthropic
	BaseURL string
	APIKey  string
	Headers map[string]string
	Models  map[string]ModelConfig
	// ContextWindow (providers.<id>.context_window) is the window of every
	// model of this provider without its own models.<model>.context_window;
	// 0 = infer from the model name.
	ContextWindow int
	// MaxOutputTokens (providers.<id>.max_output_tokens) is the output limit of
	// every model of this provider without its own models.<model> value; 0
	// leaves the limit to the protocol (see MaxOutputTokensFor).
	MaxOutputTokens int
	// Thinking (providers.<id>.thinking) is the default thinking level of the
	// provider's models; "" leaves the provider's own default.
	Thinking string
	// ThinkingStyle (providers.<id>.thinking_style) is the default thinking
	// style of the provider's models; "" leaves the model-name heuristic.
	ThinkingStyle string
	// StreamRequired (providers.<id>.stream_required) sends every request of
	// this provider's models as a streamed request, summaries included: some
	// gateways answer only stream=true.
	StreamRequired bool
	// Vision (providers.<id>.vision) declares whether the provider's models
	// accept images; VisionSet records that the key was written. A gateway that
	// rejects image parts sets it to false.
	Vision    bool
	VisionSet bool
	// PromptCache (providers.<id>.prompt_cache) enables Claude cache_control
	// breakpoints; only meaningful for type anthropic.
	PromptCache bool
	// Compat (providers.<id>.compat) names gateway adapters applied on top
	// of the ones matched by base URL and model (llm.ResolveCompat).
	Compat []string
	// Retry is the retry policy: the global retry: section (ReadRetryPolicy),
	// overridden by providers.<id>.retry.
	Retry llm.RetryPolicy
	// RequestTimeout and ResponseHeaderTimeout bound one model request: they
	// come from `timeouts:` (ReadRequestTimeouts), overridden by
	// providers.<id>.timeouts. A zero value means no limit; unset keys keep the
	// default (see config/timeouts.go).
	RequestTimeout        time.Duration
	ResponseHeaderTimeout time.Duration
	// StreamIdleTimeout bounds the silence between two reads of a streamed body
	// (timeouts.stream_idle, overridden by providers.<id>.timeouts.stream_idle).
	// Zero keeps the provider default, a negative value ("off") disables it.
	StreamIdleTimeout time.Duration
}

ProviderConfig is one resolved providers.<id> entry (preset merged with user config). Headers values may contain llm.SessionIDPlaceholder, kept verbatim.

type RequestTimeouts

type RequestTimeouts struct {
	Request        time.Duration
	ResponseHeader time.Duration
	StreamIdle     time.Duration
}

RequestTimeouts bounds one model request:

  • Request bounds a non-streamed request as a whole (dial, TLS, headers, body).
  • ResponseHeader bounds the wait for a streamed request's response headers; the streamed body itself is not bounded (a long answer may stream for minutes).
  • StreamIdle bounds the silence between two reads of a streamed body: a provider that stops sending data mid-answer fails the request instead of hanging the turn (see llm.stream_idle.go).

A zero field means "no limit" ("off" in the config). StreamIdle is the one exception: left unset it takes the provider's default (llm.DefaultStreamIdleTimeout, or the longer reasoning one), and only an explicit "off" disables it. The values come from the top-level `timeouts:` section, overridden per provider by `providers.<id>.timeouts`.

func DefaultRequestTimeouts

func DefaultRequestTimeouts() RequestTimeouts

DefaultRequestTimeouts is what an unconfigured `timeouts:` section resolves to.

func ReadRequestTimeouts

func ReadRequestTimeouts() (RequestTimeouts, error)

ReadRequestTimeouts reads the top-level `timeouts:` section; unset keys keep the defaults and an invalid value is an error.

type ResolvedConfigValue

type ResolvedConfigValue struct {
	Key        string
	Type       ConfigValueType
	Value      any
	Source     ConfigSource
	SourceName string
	Sensitive  bool
}

ResolvedConfigValue is an effective value with safe source attribution. When Sensitive is true, Value is always a mask and never the secret itself.

func ReadConfigValue

func ReadConfigValue(key string) (ResolvedConfigValue, error)

ReadConfigValue resolves a key through its existing reader and applies the documented model/environment/default precedence. Sensitive values are masked.

func ResolveConfigValue

func ResolveConfigValue(key string) (ResolvedConfigValue, error)

ResolveConfigValue is an alias suited to callers that treat registry reads as resolution rather than raw configuration lookup.

type SnapshotSettings

type SnapshotSettings struct {
	Enabled         bool
	MaxFileBytes    int64
	MaxSessionBytes int64
	MaxGlobalBytes  int64
	KeepTurns       int
	KeepDays        int
	OnError         string
}

SnapshotSettings contains the file-tool checkpoint policy. The settings are kept in config rather than personal so wiring can use one validated policy for run, chat and ACP without making the storage layer read global config.

func DefaultSnapshotSettings

func DefaultSnapshotSettings() SnapshotSettings

DefaultSnapshotSettings returns the secure checkpoint policy. A caller can explicitly turn snapshots off without removing the undo command surface.

func ReadSnapshotSettings

func ReadSnapshotSettings() (SnapshotSettings, error)

ReadSnapshotSettings reads and validates tools.snapshots. Unknown fields are rejected so a misspelled limit cannot silently weaken the rollback contract.

type SpillSettings

type SpillSettings struct {
	// MaxBytes is the logical (uncompressed) byte budget of all spill files.
	MaxBytes int64
	// MaxAge is the age at which a spill file is a gc candidate.
	MaxAge time.Duration
	// CompressAfter is the age at which an idle .txt may be gzipped.
	CompressAfter time.Duration
	// Compression is gzip or off.
	Compression string
	// OnQuota is the policy for a new output over MaxBytes (only refuse).
	OnQuota string
	// KeepDays is an additional age rule; 0 means max_age alone applies.
	KeepDays int
}

SpillSettings is the spill policy read from tools.spill. The independent `gc --compress-spill` pass consumes it; the session writer only needs MaxBytes (SpillQuotaBytes).

func DefaultSpillSettings

func DefaultSpillSettings() SpillSettings

DefaultSpillSettings returns the shipped spill policy.

func ReadSpillSettings

func ReadSpillSettings() (SpillSettings, error)

ReadSpillSettings reads and validates tools.spill. An unknown key or an unusable value is an error, so a typo cannot silently drop the quota or the compression pass's age gate.

type TaskSettings

type TaskSettings struct {
	Limits tasks.Limits
	// WakeOnExit: in chat, a notice left while chat waits for input (a task
	// that ended, a watch whose result changed) starts a turn with it
	// (tasks.wake_on_exit, default true).
	WakeOnExit bool
}

TaskSettings configure background tasks (tasks.*).

func ReadTaskSettings

func ReadTaskSettings() (TaskSettings, error)

ReadTaskSettings reads tasks.max_running (>= 1), tasks.max_duration (a duration such as "2h" or seconds), tasks.max_output_bytes (>= 1) and tasks.wake_on_exit. Unset keys take tasks.DefaultLimits and true.

type ToolBodySettings

type ToolBodySettings struct {
	// InlineBytes is the threshold; the shipped default is 1,024 bytes.
	InlineBytes int64
}

ToolBodySettings is the tool body file policy (design 2026-10-19, tool-output-files): store.body_inline_bytes is the size above which a tool result moves to sessions/<id>/bodies.jsonl, 0 keeps every body in the ledger.

func DefaultToolBodySettings

func DefaultToolBodySettings() ToolBodySettings

DefaultToolBodySettings returns the shipped policy.

func ReadToolBodySettings

func ReadToolBodySettings() (ToolBodySettings, error)

ReadToolBodySettings reads the threshold; the removed old name is not read any more, so a configuration that sets only it keeps the shipped default.

type ValueType

type ValueType = ConfigValueType

ValueType is kept as a concise name for callers building config UIs.

Jump to

Keyboard shortcuts

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