config

package
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Aug 15, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package config loads, defaults, persists, and redacts Factor's configuration.

Index

Constants

View Source
const Version = 1

Variables

This section is empty.

Functions

func DefaultPath

func DefaultPath() string

DefaultPath returns the default config file location.

func EnsureWorkspace

func EnsureWorkspace(workspace string) error

EnsureWorkspace creates the workspace layout and default bootstrap files.

func Home

func Home() string

Home returns $FACTOR_HOME or ~/.factor.

func Update

func Update(path string, fn func(*Config) error) error

Update atomically load-modifies-saves the config FILE. The live in-memory Config is deliberately immutable after startup (concurrent turns read it lock-free); durable changes go through here and apply on restart.

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"`
}

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 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"`
	// 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 Default

func Default() *Config

Default returns a fully populated configuration.

func Load

func Load(path string) (*Config, error)

Load reads the config file (DefaultPath when path is empty), overlays it on defaults, then applies FACTOR_* environment overrides.

func ReadFile

func ReadFile(path string) (*Config, error)

ReadFile returns a fresh file-backed copy (no env overlay), for introspection consistent with what Update sees.

func (*Config) FilterSecrets

func (c *Config) FilterSecrets(s string) string

FilterSecrets replaces occurrences of secret values in s with a placeholder.

func (*Config) Get

func (c *Config) Get(dottedKey string) (any, error)

Get returns the (secret-redacted) value at a dotted path, e.g. "provider.model" or "" for the whole config.

func (*Config) Path

func (c *Config) Path() string

Path returns where this config was loaded from (or will be saved to).

func (*Config) RedactedMap

func (c *Config) RedactedMap() (map[string]any, error)

RedactedMap returns the config as a generic map with secret-looking values masked.

func (*Config) Save

func (c *Config) Save() error

Save writes the config as indented JSON, creating parent directories.

func (*Config) SecretValues

func (c *Config) SecretValues() []string

SecretValues returns every non-empty secret for output filtering.

func (*Config) Set

func (c *Config) Set(dottedKey string, value any) error

Set applies a value at a dotted path, validates the resulting config by round-tripping it through the schema, and updates the receiver in place. The caller is responsible for calling Save.

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 GatewayConfig struct {
	Host string `json:"host" env:"FACTOR_GATEWAY_HOST"`
	Port int    `json:"port" env:"FACTOR_GATEWAY_PORT"`
}

type HeartbeatConfig

type HeartbeatConfig struct {
	Enabled         bool `json:"enabled"`
	IntervalMinutes int  `json:"interval_minutes"`
}

type MCPConfig

type MCPConfig struct {
	Servers map[string]MCPServer `json:"servers,omitempty"`
}

type MCPServer

type MCPServer struct {
	Command string            `json:"command"`
	Args    []string          `json:"args,omitempty"`
	Env     map[string]string `json:"env,omitempty"`
	Enabled *bool             `json:"enabled,omitempty"` // nil means enabled
}

func (MCPServer) IsEnabled

func (s MCPServer) IsEnabled() bool

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"`
	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"` // hybrid | llm | local | "" = auto
	ExtractURL          string   `json:"extract_url,omitempty"`
	ExtractModel        string   `json:"extract_model,omitempty"`
	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 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).

func (ReasoningConfig) Off

func (r ReasoningConfig) Off() bool

Off reports an explicit opt-out.

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.

Jump to

Keyboard shortcuts

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