Documentation
¶
Overview ¶
Package config loads, defaults, persists, and redacts Factor's configuration.
Index ¶
- Constants
- func DefaultPath() string
- func EnsureWorkspace(workspace string) error
- func Home() string
- func Update(path string, fn func(*Config) error) error
- type AgentConfig
- type BrowserConfig
- type BudgetConfig
- type Candidate
- type Config
- func (c *Config) FilterSecrets(s string) string
- func (c *Config) Get(dottedKey string) (any, error)
- func (c *Config) Path() string
- func (c *Config) RedactedMap() (map[string]any, error)
- func (c *Config) Save() error
- func (c *Config) SecretValues() []string
- func (c *Config) Set(dottedKey string, value any) error
- type CostConfig
- type DesktopConfig
- type GatewayConfig
- type HeartbeatConfig
- type MCPConfig
- type MCPServer
- type MemoryConfig
- type Price
- type ProviderConfig
- type ReasoningConfig
- type ToolsConfig
- type UpgradeConfig
Constants ¶
const Version = 1
Variables ¶
This section is empty.
Functions ¶
func EnsureWorkspace ¶
EnsureWorkspace creates the workspace layout and default bootstrap files.
Bootstrap files belong to the user, so an upgrade must not clobber a persona or an instruction set someone wrote by hand. It may, however, carry an improved default to an install that never edited the old one: a file whose bytes still match a superseded default is replaced, everything else is left exactly as it is.
Types ¶
type AgentConfig ¶
type AgentConfig struct {
Workspace string `json:"workspace" env:"FACTOR_WORKSPACE"`
MaxToolIterations int `json:"max_tool_iterations" env:"FACTOR_MAX_TOOL_ITERATIONS"`
MaxConcurrentTurns int `json:"max_concurrent_turns"`
ContextWindowTokens int `json:"context_window_tokens"`
SummarizeAtPercent int `json:"summarize_at_percent"`
SummarizeAtMessages int `json:"summarize_at_messages"`
KeepRecentMessages int `json:"keep_recent_messages"`
ExtraInstructions string `json:"extra_instructions,omitempty"`
}
type BrowserConfig ¶
type BrowserConfig struct {
Enabled bool `json:"enabled"`
AttachURL string `json:"attach_url,omitempty" env:"FACTOR_BROWSER_ATTACH_URL"`
Command string `json:"command,omitempty"`
Headless bool `json:"headless"`
NoSandbox bool `json:"no_sandbox"` // needed as root, in containers, and where user namespaces are restricted
UserDataDir string `json:"user_data_dir,omitempty"`
// FastPath adds a second, much lighter engine that only reads pages.
// Off unless asked for: it is a whole extra browser to install, and the
// full suite already reads pages perfectly well.
FastPath bool `json:"fast_path"`
FastCommand string `json:"fast_command,omitempty"`
}
BrowserConfig controls the CDP browser integration. With AttachURL empty, Factor probes the standard DevTools port and falls back to launching a managed instance (visible unless Headless).
type BudgetConfig ¶ added in v0.19.0
type BudgetConfig struct {
SessionUSD float64 `json:"session_usd" env:"FACTOR_BUDGET_SESSION_USD"`
GlobalUSD float64 `json:"global_usd" env:"FACTOR_BUDGET_GLOBAL_USD"`
Period string `json:"period"` // day | month | total
}
BudgetConfig caps spend. Zero is no cap, on both scopes: a budget that starts refusing turns is something you ask for, never something you inherit. Period says what "global" counts — this day, this month, or everything Factor has ever spent.
func (BudgetConfig) Off ¶ added in v0.19.0
func (b BudgetConfig) Off() bool
Off reports that neither cap is set.
type Candidate ¶
type Candidate struct {
Type string `json:"type"`
APIKey string `json:"api_key,omitempty"`
APIBase string `json:"api_base,omitempty"`
Model string `json:"model"`
Reasoning *ReasoningConfig `json:"reasoning,omitempty"`
}
Candidate identifies one provider+model combination in the failover chain. A nil Reasoning inherits the provider-level setting.
type Config ¶
type Config struct {
ConfigVersion int `json:"version"`
Agent AgentConfig `json:"agent"`
Provider ProviderConfig `json:"provider"`
Memory MemoryConfig `json:"memory"`
Channels map[string]json.RawMessage `json:"channels,omitempty"`
MCP MCPConfig `json:"mcp"`
Tools ToolsConfig `json:"tools"`
Desktop DesktopConfig `json:"desktop"`
Browser BrowserConfig `json:"browser"`
Heartbeat HeartbeatConfig `json:"heartbeat"`
Gateway GatewayConfig `json:"gateway"`
Upgrade UpgradeConfig `json:"upgrade"`
Cost CostConfig `json:"cost"`
// contains filtered or unexported fields
}
Config is the root configuration. Channel sections stay raw JSON so connectors can define and decode their own config without touching core.
func Load ¶
Load reads the config file (DefaultPath when path is empty), overlays it on defaults, then applies FACTOR_* environment overrides.
func ReadFile ¶
ReadFile returns a fresh file-backed copy (no env overlay), for introspection consistent with what Update sees.
func (*Config) FilterSecrets ¶
FilterSecrets replaces occurrences of secret values in s with a placeholder.
func (*Config) Get ¶
Get returns the (secret-redacted) value at a dotted path, e.g. "provider.model" or "" for the whole config.
func (*Config) RedactedMap ¶
RedactedMap returns the config as a generic map with secret-looking values masked.
func (*Config) SecretValues ¶
SecretValues returns every configured secret worth filtering out of output.
type CostConfig ¶ added in v0.19.0
type CostConfig struct {
Track bool `json:"track"`
Budget BudgetConfig `json:"budget"`
Prices map[string]Price `json:"prices,omitempty"` // model id -> USD per million tokens
PricesURL string `json:"prices_url,omitempty"`
RefreshHours int `json:"refresh_hours"`
}
CostConfig turns token counts into money. Tracking is on by default because it costs nothing — every provider already reports the counts, and a spend you cannot see is one you find out about on an invoice. Prices are fetched from the model catalog and cached; an entry here overrides one for a model the catalog does not carry (a private endpoint, a negotiated rate).
type DesktopConfig ¶
type DesktopConfig struct {
Enabled *bool `json:"enabled,omitempty"`
ScreenshotDir string `json:"screenshot_dir,omitempty"`
}
DesktopConfig controls the desktop-control tools (windows, screenshots, mouse, keyboard, clipboard, notifications). Enabled is a tri-state: unset means "register them when a graphical session is detected", which keeps a headless server's prompt free of tools that could never work there.
func (DesktopConfig) Register ¶
func (d DesktopConfig) Register(hasDisplay bool) bool
Register reports whether the desktop tools should be registered.
type GatewayConfig ¶
type HeartbeatConfig ¶
type MCPServer ¶
type MemoryConfig ¶
type MemoryConfig struct {
Mode string `json:"mode" env:"FACTOR_MEMORY_MODE"` // sidecar | external | off
URL string `json:"url,omitempty" env:"FACTOR_MEMORY_URL"`
Command string `json:"command"`
AutoInstall bool `json:"auto_install"` // install smrti (uv/pipx/pip/venv) when missing
KeepAlive bool `json:"keep_alive"` // sidecar outlives Factor; later runs adopt it warm
Host string `json:"host"`
Port int `json:"port" env:"FACTOR_MEMORY_PORT"`
DBPath string `json:"db_path"`
Tenant string `json:"tenant"`
Space string `json:"space"`
SpaceStrategy string `json:"space_strategy"` // origin: conversations write to `space`, cron/job turns to `system_space`, each reading the other as an overlay (needs a smrti with space routing; older engines fall back to single). single: everything in `space`.
SystemSpace string `json:"system_space"`
Personality string `json:"personality" env:"FACTOR_MEMORY_PERSONALITY"`
APIKey string `json:"api_key,omitempty" env:"FACTOR_MEMORY_API_KEY"`
RecallTopK int `json:"recall_top_k"`
RecallMinConfidence float64 `json:"recall_min_confidence"`
QueryContextMsgs int `json:"query_context_msgs"`
QueryMaxChars int `json:"query_max_chars"`
InjectMaxChars int `json:"inject_max_chars"`
ReflectIntervalSecs int `json:"reflect_interval_secs"`
ExtractMode string `json:"extract_mode,omitempty" env:"FACTOR_MEMORY_EXTRACT_MODE"` // hybrid | llm | local | "" = auto
ExtractURL string `json:"extract_url,omitempty" env:"FACTOR_MEMORY_EXTRACT_URL"`
ExtractModel string `json:"extract_model,omitempty" env:"FACTOR_MEMORY_EXTRACT_MODEL"`
ExtractAPIKey string `json:"extract_api_key,omitempty" env:"FACTOR_MEMORY_EXTRACT_API_KEY"`
IgnorePatterns []string `json:"ignore_patterns,omitempty"`
StartupTimeoutSecs int `json:"startup_timeout_secs"`
}
func (MemoryConfig) BaseURL ¶
func (m MemoryConfig) BaseURL() string
BaseURL returns the effective smrti endpoint.
type Price ¶ added in v0.19.0
Price is what one model charges, in USD per million tokens — the unit model pages quote, so a hand-written override reads the way it was copied.
type ProviderConfig ¶
type ProviderConfig struct {
Type string `json:"type" env:"FACTOR_PROVIDER_TYPE"`
APIKey string `json:"api_key,omitempty" env:"FACTOR_PROVIDER_API_KEY"`
APIBase string `json:"api_base,omitempty" env:"FACTOR_PROVIDER_API_BASE"`
Model string `json:"model" env:"FACTOR_PROVIDER_MODEL"`
Reasoning ReasoningConfig `json:"reasoning"`
MaxTokens int `json:"max_tokens"`
Temperature float64 `json:"temperature,omitempty"`
Fallbacks []Candidate `json:"fallbacks,omitempty"`
MaxRetries int `json:"max_retries"`
RetryBackoffSecs int `json:"retry_backoff_secs"`
}
func (ProviderConfig) Candidates ¶
func (p ProviderConfig) Candidates() []Candidate
Candidates returns the primary candidate followed by the fallbacks, each carrying the reasoning settings it should use.
type ReasoningConfig ¶
type ReasoningConfig struct {
Effort string `json:"effort"` // xhigh | high | medium | low | minimal | none
MaxTokens int `json:"max_tokens"` // explicit thinking budget; wins over effort
Exclude bool `json:"exclude"` // think, but keep the reasoning out of the reply
}
ReasoningConfig asks the model to think before answering. Each backend spells this differently (OpenRouter takes a reasoning object, OpenAI and Groq take reasoning_effort, Anthropic takes a thinking budget); Factor translates one setting into whichever the active provider understands. The fields are written even when empty: the section is overlaid on top of the defaults at load time, so an omitted "effort" would silently restore the default xhigh instead of the "off" the user asked for.
func (ReasoningConfig) IsZero ¶
func (r ReasoningConfig) IsZero() bool
IsZero reports that nothing was configured (no reasoning parameters sent).
type ToolsConfig ¶
type ToolsConfig struct {
Disabled []string `json:"disabled,omitempty"`
RestrictToWorkspace bool `json:"restrict_to_workspace"`
AllowReadOutsideWorkspace bool `json:"allow_read_outside_workspace"`
AllowPaths []string `json:"allow_paths,omitempty"`
ExecTimeoutSecs int `json:"exec_timeout_secs"`
EnableDenyPatterns bool `json:"enable_deny_patterns"`
CustomDenyPatterns []string `json:"custom_deny_patterns,omitempty"`
AllowInstall bool `json:"allow_install"`
}
func (ToolsConfig) IsToolEnabled ¶
func (t ToolsConfig) IsToolEnabled(name string) bool
IsToolEnabled reports whether a tool name survives the user's disabled list.
type UpgradeConfig ¶ added in v0.5.0
type UpgradeConfig struct {
Check bool `json:"check"`
CheckIntervalHours int `json:"check_interval_hours"`
}
UpgradeConfig controls the release check. The gateway only ever reports a newer version — installing it stays an explicit `factor upgrade` or a request to the agent, so a daemon never swaps its own binary out from under a live conversation.