config

package
v0.8.4 Latest Latest
Warning

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

Go to latest
Published: Mar 12, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package config handles loading, defaulting, and validating Thane's YAML configuration.

Configuration is loaded from a single YAML file located via FindConfig. After Load returns, all fields carry usable values — callers never need empty-string checks or fallback logic. The load pipeline is:

  1. Read the file and expand environment variables (os.ExpandEnv).
  2. Unmarshal YAML into a Config struct.
  3. Apply sensible defaults for any unset fields ([Config.applyDefaults]).
  4. Validate internal consistency (Config.Validate).

Secrets (API keys, tokens) can be written directly in the config file. Protect the file with appropriate permissions (chmod 600). Environment variable expansion is available as a convenience for container and 12-factor deployments but is not the recommended default.

Index

Constants

View Source
const LevelTrace = slog.Level(-8)

LevelTrace is a custom slog level below slog.LevelDebug, intended for wire-level forensics (full JSON request/response payloads). The numeric value -8 follows the convention established by OpenTelemetry and other Go projects that extend slog with a Trace level.

Use sparingly — Trace output is extremely verbose and should only be enabled when diagnosing provider-specific bugs.

Variables

This section is empty.

Functions

func DefaultSearchPaths

func DefaultSearchPaths() []string

func FindConfig

func FindConfig(explicit string) (string, error)

FindConfig locates a configuration file. If explicit is non-empty, that exact path must exist or an error is returned. Otherwise, the paths from DefaultSearchPaths are tried in order, and the first that exists is returned. Returns an error if no config file can be found.

func ParseLogLevel

func ParseLogLevel(s string) (slog.Level, error)

ParseLogLevel converts a case-insensitive string to an slog.Level.

Accepted values:

Returns an error for unrecognized values. Leading and trailing whitespace is trimmed before matching.

func ReplaceLogLevelNames

func ReplaceLogLevelNames(groups []string, a slog.Attr) slog.Attr

ReplaceLogLevelNames is an slog.HandlerOptions.ReplaceAttr function that renders LevelTrace as "TRACE" in log output. Without this, slog would render it as "DEBUG-4" since it doesn't know about custom levels.

Pass it as the ReplaceAttr field when constructing a handler:

slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
    Level:       config.LevelTrace,
    ReplaceAttr: config.ReplaceLogLevelNames,
})

Types

type AgentConfig added in v0.5.1

type AgentConfig struct {
	// OrchestratorTools lists tool names to advertise when
	// DelegationRequired is true. If empty, a sensible default set
	// is applied (thane_delegate plus lightweight memory tools).
	OrchestratorTools []string `yaml:"orchestrator_tools"`

	// DelegationRequired enables orchestrator tool gating. When false
	// (the default), all tools are available on every iteration.
	DelegationRequired bool `yaml:"delegation_required"`
}

AgentConfig configures agent loop behavior. When DelegationRequired is true, the agent loop only advertises the tools listed in OrchestratorTools, steering the primary model toward delegation instead of direct tool use.

type AnalysisConfig added in v0.8.0

type AnalysisConfig struct {
	// DefaultOutputPath is the base directory for analysis output when
	// a feed has no per-feed output_path configured. Supports ~ expansion.
	// Example: ~/Sync/Aimee/Vault/Media
	DefaultOutputPath string `yaml:"default_output_path"`

	// DatabasePath is the SQLite database file for engagement tracking.
	// If empty, defaults to {data_dir}/media_engagement.db at startup.
	DatabasePath string `yaml:"database_path"`
}

AnalysisConfig configures the media analysis pipeline that produces structured markdown output in an Obsidian-compatible vault. Each feed can override the output path; otherwise the default is used.

type AnthropicConfig

type AnthropicConfig struct {
	APIKey string `yaml:"api_key"`
}

AnthropicConfig configures the Anthropic (Claude) API provider.

func (AnthropicConfig) Configured

func (c AnthropicConfig) Configured() bool

Configured reports whether an Anthropic API key is present.

type ArchiveConfig added in v0.3.0

type ArchiveConfig struct {
	// MetadataModel is a soft preference for the LLM model used when
	// generating session metadata (title, tags, summaries). Passed as a
	// hint to the model router; the router has final say. This is a
	// background operation where latency doesn't matter — ideal for
	// local/free models. Default: uses the default model.
	MetadataModel string `yaml:"metadata_model"`

	// SummarizeInterval is how often (in seconds) the background
	// summarizer scans for unsummarized sessions. Default: 300 (5 min).
	SummarizeInterval int `yaml:"summarize_interval"`

	// SummarizeTimeout is the max seconds for a single session's
	// metadata LLM call. Default: 60.
	SummarizeTimeout int `yaml:"summarize_timeout"`

	// SessionIdleMinutes is the backstop idle timeout for the
	// summarizer worker. Active sessions with no message activity
	// for this many minutes are silently closed and become eligible
	// for summarization. This complements the channel-specific idle
	// check (e.g. signal.session_idle_minutes) which sends farewell
	// messages.
	//
	// Pointer type distinguishes "omitted" (nil → inherit from
	// signal.session_idle_minutes) from "explicitly set to 0"
	// (disabled). A positive value overrides the inherited default.
	SessionIdleMinutes *int `yaml:"session_idle_minutes"`
}

ArchiveConfig configures session archive behavior.

type ArchivePrewarmConfig added in v0.8.0

type ArchivePrewarmConfig struct {
	// Enabled controls whether archive injection is active.
	// Requires the parent Prewarm.Enabled to also be true.
	// Default: false.
	Enabled bool `yaml:"enabled"`

	// MaxResults caps the number of archive search results injected.
	// Default: 3.
	MaxResults int `yaml:"max_results"`

	// MaxBytes caps the formatted output in bytes to prevent context
	// flooding. Default: 4000 (~1000 tokens).
	MaxBytes int `yaml:"max_bytes"`
}

ArchivePrewarmConfig configures archive retrieval injection for cold-start wakes. When enabled, relevant past conversation excerpts are injected into the system prompt so the model has experiential judgment — not just knowledge — before responding.

type AttachmentsConfig added in v0.8.4

type AttachmentsConfig struct {
	// StoreDir is the root directory for the content-addressed file
	// store. When set, received attachments are stored by SHA-256 hash
	// instead of being copied with their original filenames. The
	// metadata index is stored at {data_dir}/attachments.db.
	// Supports ~ expansion. Example: ~/Thane/attachments
	StoreDir string       `yaml:"store_dir"`
	Vision   VisionConfig `yaml:"vision"`
}

AttachmentsConfig configures content-addressed attachment storage.

type CapabilityTagConfig added in v0.7.0

type CapabilityTagConfig struct {
	// Description is a human-readable summary shown in the capability
	// manifest so the agent knows what activating this tag provides.
	Description string `yaml:"description"`

	// Tools lists the tool names belonging to this tag. A tool can
	// appear in multiple tags; it loads when any of its tags is active.
	Tools []string `yaml:"tools"`

	// Context lists file paths to read into the system prompt when
	// this tag is active. Paths support kb: prefix resolution and ~
	// expansion, resolved at startup. Files are re-read on every agent
	// turn so external edits are visible without restart. Missing
	// files are logged as warnings and skipped.
	Context []string `yaml:"context"`

	// AlwaysActive tags cannot be deactivated. They are included in
	// every session regardless of channel or agent requests.
	AlwaysActive bool `yaml:"always_active"`
}

CapabilityTagConfig defines a named group of tools (and optionally talents) that can be loaded together. Tags marked AlwaysActive are included in every session unconditionally.

func (CapabilityTagConfig) Validate added in v0.7.0

func (c CapabilityTagConfig) Validate(tagName string) error

Validate checks that the capability tag configuration is internally consistent. It ensures a description is present and the tools list is non-empty. Tag names are validated by the caller since they are map keys in the parent Config struct.

type CardDAVConfig added in v0.8.0

type CardDAVConfig struct {
	Enabled  bool     `yaml:"enabled"`
	Listen   []string `yaml:"listen"`   // e.g. ["127.0.0.1:8843"]
	Username string   `yaml:"username"` // Basic Auth username
	Password string   `yaml:"password"` // Basic Auth password
}

CardDAVConfig configures the optional CardDAV server for native contact app sync. When Enabled is true and credentials are set, Thane exposes a CardDAV endpoint that can be added as an account in macOS Contacts.app, iOS, Thunderbird, or any CardDAV client.

func (CardDAVConfig) Configured added in v0.8.0

func (c CardDAVConfig) Configured() bool

Configured reports whether the CardDAV server has all required settings.

type Config

type Config struct {
	// Listen configures the primary HTTP API server (OpenAI-compatible).
	Listen ListenConfig `yaml:"listen"`

	// OllamaAPI configures the optional Ollama-compatible API server,
	// used for Home Assistant integration.
	OllamaAPI OllamaAPIConfig `yaml:"ollama_api"`

	// CardDAV configures the optional CardDAV server for native
	// contact app sync (macOS Contacts.app, iOS, Thunderbird, etc.).
	CardDAV CardDAVConfig `yaml:"carddav"`

	// HomeAssistant configures the connection to a Home Assistant instance.
	HomeAssistant HomeAssistantConfig `yaml:"homeassistant"`

	// Models configures LLM providers, model routing, and the default model.
	Models ModelsConfig `yaml:"models"`

	// Anthropic configures the Anthropic (Claude) API provider.
	Anthropic AnthropicConfig `yaml:"anthropic"`

	// Embeddings configures vector embedding generation for semantic search.
	Embeddings EmbeddingsConfig `yaml:"embeddings"`

	// Workspace configures the agent's sandboxed file system access.
	Workspace WorkspaceConfig `yaml:"workspace"`

	// Paths maps named prefixes to directory paths for file resolution.
	// Each entry creates a prefix (e.g., "kb" → kb:path resolves to
	// the configured directory). Supports ~ expansion at resolver
	// construction time.
	Paths map[string]string `yaml:"paths"`

	// ExtraPath lists additional directories to prepend to the process
	// PATH at startup, ensuring exec.LookPath finds binaries installed
	// outside the default system PATH (e.g., /opt/homebrew/bin on macOS).
	// Environment variables are expanded (e.g., $HOME/bin).
	ExtraPath []string `yaml:"extra_path"`

	// ShellExec configures the agent's ability to run shell commands.
	ShellExec ShellExecConfig `yaml:"shell_exec"`

	// DataDir is the root directory for SQLite databases (memory, facts,
	// scheduler, checkpoints, and anticipations). Default: "./db".
	DataDir string `yaml:"data_dir"`

	// TalentsDir is the directory containing talent markdown files that
	// extend the system prompt. Default: "./talents".
	TalentsDir string `yaml:"talents_dir"`

	// PersonaFile is an optional markdown file that replaces the default
	// system prompt with a custom agent identity.
	PersonaFile string `yaml:"persona_file"`

	// Context configures static context injection into the system prompt.
	Context ContextConfig `yaml:"context"`

	// Archive configures session archive behavior.
	Archive ArchiveConfig `yaml:"archive"`

	// Extraction configures automatic fact extraction from conversations.
	Extraction ExtractionConfig `yaml:"extraction"`

	// Search configures web search providers.
	Search SearchConfig `yaml:"search"`

	// Episodic configures episodic memory context injection (daily
	// memory files and recent conversation history).
	Episodic EpisodicConfig `yaml:"episodic"`

	// Agent configures agent loop behavior, including orchestrator
	// tool gating for delegation-first architecture.
	Agent AgentConfig `yaml:"agent"`

	// Delegate configures the thane_delegate tool's split-model execution.
	Delegate DelegateConfig `yaml:"delegate"`

	// CapabilityTags defines named groups of tools and talents that
	// can be activated or deactivated per session. Tags marked
	// always_active are loaded unconditionally. Other tags are
	// activated via request_capability/drop_capability tools or
	// channel-pinned configuration.
	CapabilityTags map[string]CapabilityTagConfig `yaml:"capability_tags"`

	// ChannelTags maps conversation source channels (e.g., "signal",
	// "email") to lists of capability tag names that are automatically
	// activated when a message arrives on that channel. This is
	// additive to always-active tags and any tags the agent requests
	// at runtime. Tag names must reference entries in [CapabilityTags].
	ChannelTags map[string][]string `yaml:"channel_tags"`

	// MCP configures external MCP (Model Context Protocol) server
	// connections for tool discovery. Each server provides additional
	// tools that are discovered dynamically and bridged into the
	// agent's tool registry.
	MCP MCPConfig `yaml:"mcp"`

	// MQTT configures MQTT publishing for Home Assistant device discovery
	// and sensor state reporting. When Broker and DeviceName are both
	// set, Thane connects to the broker and registers as an HA device.
	MQTT MQTTConfig `yaml:"mqtt"`

	// Person configures household member presence tracking. When Track
	// contains entity IDs, the agent receives a "People & Presence"
	// section in its system prompt on every wake, eliminating tool
	// calls for basic presence questions.
	Person PersonConfig `yaml:"person"`

	// Signal configures the Signal message bridge for inbound message
	// reception and response routing via a signal-mcp MCP server.
	Signal SignalConfig `yaml:"signal"`

	// Forge configures code forge integrations (GitHub, Gitea). When
	// configured, Thane can interact with issues, pull requests, and
	// code review directly without an MCP forge server subprocess.
	Forge forge.Config `yaml:"forge"`

	// Email configures native IMAP email access. When configured, Thane
	// can list, read, search, and manage email directly without an MCP
	// email server subprocess.
	Email email.Config `yaml:"email"`

	// Identity configures the agent's own contact identity for vCard
	// export and self-referencing operations.
	Identity IdentityConfig `yaml:"identity"`

	// Attachments configures content-addressed attachment storage.
	// When StoreDir is set, received attachments (Signal, email, etc.)
	// are stored by SHA-256 hash with a SQLite metadata index for
	// deduplication and provenance tracking.
	Attachments AttachmentsConfig `yaml:"attachments"`

	// Provenance configures git-backed file storage with SSH signature
	// enforcement. Files written through a provenance store are
	// automatically committed with cryptographic signatures, providing
	// tamper detection, audit history, and rollback. Identity files
	// (ego.md, metacognitive.md) are the primary clients.
	Provenance ProvenanceConfig `yaml:"provenance"`

	// StateWindow configures the rolling window of recent Home Assistant
	// state changes injected into the agent's system prompt on every run.
	StateWindow StateWindowConfig `yaml:"state_window"`

	// Unifi configures the UniFi network controller connection for
	// room-level presence detection via wireless AP client associations.
	Unifi UnifiConfig `yaml:"unifi"`

	// Prewarm configures context pre-warming for cold-start loops.
	// When enabled, subject-keyed facts are injected into the system
	// prompt before the model sees the triggering event.
	Prewarm PrewarmConfig `yaml:"prewarm"`

	// Media configures the media transcript retrieval tool. When yt-dlp
	// is available, the agent can fetch transcripts from YouTube, Vimeo,
	// podcasts, and other sources supported by yt-dlp.
	Media MediaConfig `yaml:"media"`

	// Metacognitive configures the perpetual metacognitive attention loop.
	// When enabled, a background goroutine monitors the environment,
	// reasons via LLM, and adapts its own sleep cycle between iterations.
	Metacognitive MetacognitiveConfig `yaml:"metacognitive"`

	// OpenClaw configures the thane:openclaw Ollama profile, which
	// replicates OpenClaw's workspace-aware agent behavior using
	// Thane's plumbing. When nil, the thane:openclaw profile is
	// unavailable and requests fall back to default routing.
	OpenClaw *OpenClawConfig `yaml:"openclaw"`

	// Debug configures diagnostic options for inspecting the assembled
	// system prompt and other internal state.
	Debug DebugConfig `yaml:"debug"`

	// Timezone is the IANA timezone for the household (e.g.,
	// "America/Chicago"). Used in the Current Conditions system prompt
	// section so the agent reasons about local time. If empty, the
	// system's local timezone is used.
	Timezone string `yaml:"timezone"`

	// Pricing maps model names to their per-million-token costs (USD).
	// When empty, built-in defaults for known Anthropic models are applied.
	// Local/Ollama models not listed here default to $0.
	Pricing map[string]PricingEntry `yaml:"pricing"`

	// Logging configures log output, rotation, and format. Thane manages
	// its own log files — no external logrotate required.
	Logging LoggingConfig `yaml:"logging"`

	// LogLevel is deprecated; use Logging.Level instead.
	// Kept for backwards compatibility — migrated in [Config.applyDefaults].
	LogLevel string `yaml:"log_level"`

	// LogFormat is deprecated; use Logging.Format instead.
	// Kept for backwards compatibility — migrated in [Config.applyDefaults].
	LogFormat string `yaml:"log_format"`
}

Config is the top-level configuration for the Thane agent. It maps directly to the YAML config file structure.

func Default

func Default() *Config

Default returns a configuration suitable for local development with Ollama. All defaults are applied, so the returned Config is immediately usable without calling Load.

func Load

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

Load reads a YAML configuration file, expands environment variables, applies defaults for any unset fields, and validates the result.

After Load returns a non-nil Config, every field is usable without additional nil or empty-string checks. The load pipeline is:

  1. Read the file.
  2. Expand environment variables (e.g., ${HOME}, ${ANTHROPIC_API_KEY}).
  3. Unmarshal YAML into a Config.
  4. Apply defaults via [Config.applyDefaults].
  5. Validate via Config.Validate.

func (*Config) ContextWindowForModel

func (c *Config) ContextWindowForModel(name string, defaultSize int) int

ContextWindowForModel returns the configured context window size for the named model. If the model is not found in [ModelsConfig.Available], defaultSize is returned. This avoids the need for callers to loop over the model list themselves.

func (*Config) DeprecatedFieldsUsed added in v0.8.1

func (c *Config) DeprecatedFieldsUsed() (level, format bool)

DeprecatedFieldsUsed reports whether the legacy top-level log_level or log_format fields are set. Callers use this to emit deprecation warnings.

func (*Config) Validate

func (c *Config) Validate() error

Validate checks that the configuration is internally consistent after defaults have been applied. It returns an error describing the first problem found, or nil if the configuration is valid.

Validation checks include port ranges and log level syntax. It does not check reachability of external services (that happens at runtime).

type ContextConfig added in v0.3.1

type ContextConfig struct {
	// InjectFiles is a list of file paths to re-read and inject into
	// the system prompt on every turn. Paths support ~ expansion.
	// Missing or unreadable files are silently skipped at read time.
	InjectFiles []string `yaml:"inject_files"`
}

ContextConfig configures context injection into the system prompt. Files listed in InjectFiles are re-read on every agent turn so that external edits (e.g. MEMORY.md updated by another runtime) are visible without restart. Paths are resolved once at startup.

type DebugConfig added in v0.6.0

type DebugConfig struct {
	// DumpSystemPrompt enables writing the fully assembled system
	// prompt to disk on every LLM call, with section markers and
	// size annotations. The file is overwritten each call so it
	// always reflects the most recent prompt.
	DumpSystemPrompt bool `yaml:"dump_system_prompt"`

	// DumpDir is the directory where debug output files are written.
	// Created automatically on first write. Default: "./debug".
	DumpDir string `yaml:"dump_dir"`

	// DemoLoops spawns simulated loops covering all visual variants
	// (categories, parent/child, error states, node churn) so the
	// dashboard can be iterated on without real service dependencies.
	DemoLoops bool `yaml:"demo_loops"`
}

DebugConfig configures diagnostic options for inspecting the assembled system prompt and other internal state.

type DelegateConfig added in v0.8.4

type DelegateConfig struct {
	// Profiles contains per-profile overrides. The map key is the
	// profile name (e.g., "general", "ha"). Only fields that are set
	// override the builtin defaults — omitted fields keep their
	// compiled-in values.
	Profiles map[string]DelegateProfileConfig `yaml:"profiles"`
}

DelegateConfig configures the thane_delegate tool's split-model execution behavior.

type DelegateProfileConfig added in v0.8.4

type DelegateProfileConfig struct {
	// ToolTimeout is the maximum time a single tool call may run
	// before being cancelled. Accepts Go duration strings (e.g.,
	// "30s", "3m", "5m"). Zero keeps the builtin default (30s).
	ToolTimeout time.Duration `yaml:"tool_timeout"`

	// MaxDuration is the maximum wall clock time for the entire
	// delegation loop. Zero keeps the builtin default (90s).
	MaxDuration time.Duration `yaml:"max_duration"`

	// MaxIter is the maximum number of tool-calling iterations.
	// Zero keeps the builtin default (15).
	MaxIter int `yaml:"max_iter"`

	// MaxTokens is the maximum cumulative output tokens before
	// budget exhaustion. Zero keeps the builtin default (25000).
	MaxTokens int `yaml:"max_tokens"`
}

DelegateProfileConfig holds configurable overrides for a delegate profile. Zero-value fields are ignored (builtin defaults apply).

type DeviceMapping added in v0.6.0

type DeviceMapping struct {
	// MAC is the device's MAC address (e.g., "AA:BB:CC:DD:EE:FF").
	// Case-insensitive; normalized to lowercase at startup.
	MAC string `yaml:"mac"`
}

DeviceMapping maps a MAC address to a tracked person's wireless device.

type EmbeddingsConfig

type EmbeddingsConfig struct {
	Enabled bool   `yaml:"enabled"`
	Model   string `yaml:"model"`   // Embedding model name. Default: "nomic-embed-text"
	BaseURL string `yaml:"baseurl"` // Ollama URL for knowledge. Default: models.ollama_url
}

EmbeddingsConfig configures vector embedding generation for semantic search over the fact store. When Enabled is false, ingested facts are stored without embeddings and semantic search is unavailable.

type EpisodicConfig added in v0.5.0

type EpisodicConfig struct {
	// DailyDir is the directory containing daily memory files named
	// YYYY-MM-DD.md. Supports ~ expansion. If empty, daily memory
	// file injection is disabled.
	DailyDir string `yaml:"daily_dir"`

	// LookbackDays is how many days of daily memory files to include.
	// Today and the previous (LookbackDays-1) days are checked.
	// Default: 2 (today + yesterday).
	LookbackDays int `yaml:"lookback_days"`

	// HistoryTokens is the approximate token budget for recent
	// conversation history injected into the system prompt.
	// Default: 4000.
	HistoryTokens int `yaml:"history_tokens"`

	// SessionGapMinutes is the silence duration (in minutes) between
	// sessions that triggers a gap annotation in the history output.
	// Default: 30.
	SessionGapMinutes int `yaml:"session_gap_minutes"`
}

EpisodicConfig configures episodic memory context injection. When configured, the agent receives curated daily notes and a recency-graded summary of recent conversations in its system prompt, giving it continuity across sessions.

type ExtractionConfig added in v0.5.0

type ExtractionConfig struct {
	// Enabled controls whether automatic fact extraction runs.
	// Default: false (opt-in).
	Enabled bool `yaml:"enabled"`

	// Model is the LLM model used for fact extraction. This runs async
	// in the background — local/free models recommended.
	// Default: falls back to archive.metadata_model, then models.default.
	Model string `yaml:"model"`

	// MinMessages is the minimum conversation length (in messages) before
	// extraction is attempted. Very short exchanges rarely contain knowledge.
	// Default: 2.
	MinMessages int `yaml:"min_messages"`

	// TimeoutSeconds is the maximum time allowed for a single extraction
	// call. Default: 30.
	TimeoutSeconds int `yaml:"timeout_seconds"`
}

ExtractionConfig configures automatic fact extraction from conversations. When enabled, the agent asynchronously analyzes each interaction after the response is delivered and persists noteworthy facts to the fact store. This is a background operation using local models — zero cost, no latency impact.

type HomeAssistantConfig

type HomeAssistantConfig struct {
	URL   string `yaml:"url"`
	Token string `yaml:"token"`

	// Subscribe configures WebSocket event subscriptions for real-time
	// state change monitoring. When entity_globs is non-empty, only
	// matching entities are processed; when empty, all state changes
	// are accepted.
	Subscribe SubscribeConfig `yaml:"subscribe"`
}

HomeAssistantConfig configures the connection to a Home Assistant instance. Both URL and Token must be set for the connection to be established; see HomeAssistantConfig.Configured.

func (HomeAssistantConfig) Configured

func (c HomeAssistantConfig) Configured() bool

Configured reports whether both URL and Token are set. A partial configuration (URL without token or vice versa) is treated as unconfigured — Thane will start without Home Assistant tools.

type IdentityConfig added in v0.8.0

type IdentityConfig struct {
	// ContactName is the formatted name of the agent's own contact
	// record. When set, export_vcf name="self" resolves to this
	// contact.
	ContactName string `yaml:"contact_name"`
}

IdentityConfig configures the agent's own contact identity. The ContactName must match a contact record in the directory to enable self-referencing operations like vCard export.

type ListenConfig

type ListenConfig struct {
	// Address is the network address to bind to. Empty string means
	// all interfaces (0.0.0.0).
	Address string `yaml:"address"`

	// Port is the TCP port to listen on. Default: 8080.
	Port int `yaml:"port"`
}

ListenConfig configures an HTTP server's bind address and port.

type LoggingConfig added in v0.8.1

type LoggingConfig struct {
	// Dir is the directory for log files. Relative paths are resolved
	// from the working directory (typically ~/Thane). Defaults to "logs"
	// when omitted. Set to an explicit empty string (dir: "") to disable
	// file logging (output goes to stdout only).
	Dir *string `yaml:"dir"`

	// Level sets the minimum log level. Valid values: trace, debug,
	// info, warn, error. Default: info.
	Level string `yaml:"level"`

	// Format sets the log output format. "json" produces one JSON
	// object per line; "text" produces human-readable key=value pairs.
	// Default: json.
	Format string `yaml:"format"`

	// Compress enables gzip compression of rotated log files.
	// Default: true.
	Compress *bool `yaml:"compress"`

	// RetentionDays controls how many days DEBUG and TRACE log index
	// entries are kept. Entries at INFO and above are kept indefinitely.
	// Default: 7. Set to 0 to disable pruning (keep everything).
	RetentionDays *int `yaml:"retention_days"`
}

LoggingConfig configures Thane's self-managed log output. When Dir is set, Thane writes structured log files directly (no external logrotate needed). Logs are rotated daily; old files are never deleted.

func (LoggingConfig) CompressEnabled added in v0.8.1

func (l LoggingConfig) CompressEnabled() bool

CompressEnabled returns whether rotated log compression is on. Defaults to true when Compress is nil (unset in YAML).

func (LoggingConfig) DirPath added in v0.8.1

func (l LoggingConfig) DirPath() string

DirPath returns the resolved log directory path. When Dir is nil (omitted in YAML), it returns the default "logs". When Dir is an explicit empty string, it returns "" which signals that file logging is disabled.

func (LoggingConfig) RetentionDaysDuration added in v0.8.1

func (l LoggingConfig) RetentionDaysDuration() time.Duration

RetentionDaysDuration returns the retention period for low-level log index entries. When nil (omitted in YAML), defaults to 7 days. A zero or negative value disables pruning entirely.

type MCPConfig added in v0.6.0

type MCPConfig struct {
	// Servers lists the MCP servers to connect to at startup.
	Servers []MCPServerConfig `yaml:"servers"`
}

MCPConfig configures MCP (Model Context Protocol) client connections to external tool servers. Each server provides additional tools that are discovered dynamically and bridged into the agent's tool registry.

type MCPServerConfig added in v0.6.0

type MCPServerConfig struct {
	// Name is a short identifier used in tool namespacing and logging
	// (e.g., "home-assistant", "github"). Required.
	Name string `yaml:"name"`

	// Transport is the connection type: "stdio" or "http". Required.
	Transport string `yaml:"transport"`

	// Command is the executable to spawn (stdio transport only).
	Command string `yaml:"command"`

	// Args are command-line arguments for the subprocess (stdio transport only).
	Args []string `yaml:"args"`

	// Env are additional environment variables for the subprocess
	// (stdio transport only). Format: "KEY=VALUE".
	Env []string `yaml:"env"`

	// URL is the MCP server endpoint (http transport only).
	URL string `yaml:"url"`

	// Headers are additional HTTP headers sent with every request
	// (http transport only). Useful for authentication tokens.
	Headers map[string]string `yaml:"headers"`

	// IncludeTools is an optional allowlist of MCP tool names to
	// bridge. When non-empty, only tools in this list are registered.
	// Cannot be used together with ExcludeTools.
	IncludeTools []string `yaml:"include_tools"`

	// ExcludeTools is an optional blocklist of MCP tool names to skip.
	// Cannot be used together with IncludeTools.
	ExcludeTools []string `yaml:"exclude_tools"`
}

MCPServerConfig describes a single MCP server endpoint. Each server is identified by a short name used for tool namespacing and logging.

type MQTTConfig added in v0.5.3

type MQTTConfig struct {
	// Broker is the MQTT broker URL (e.g., "mqtts://host:8883"
	// or "mqtt://host:1883").
	Broker string `yaml:"broker"`

	// Username for MQTT broker authentication.
	Username string `yaml:"username"`

	// Password for MQTT broker authentication.
	Password string `yaml:"password"`

	// DiscoveryPrefix is the Home Assistant MQTT discovery topic
	// prefix. Default: "homeassistant".
	DiscoveryPrefix string `yaml:"discovery_prefix"`

	// DeviceName drives MQTT topic paths and HA entity IDs. Example:
	// "aimee-thane" produces sensor.aimee_thane_uptime in HA.
	DeviceName string `yaml:"device_name"`

	// PublishIntervalSec is how often (in seconds) sensor states are
	// re-published to the broker. Default: 60. Minimum: 10.
	PublishIntervalSec int `yaml:"publish_interval"`

	// Subscriptions lists MQTT topics to subscribe to for ambient
	// awareness. Messages are received and logged but not autonomously
	// acted upon. Future phases will route messages to the anticipation
	// engine. Supports MQTT wildcard characters (+ and #).
	Subscriptions []SubscriptionConfig `yaml:"subscriptions"`

	// Telemetry configures operational metric publishing. When enabled,
	// a separate mqtt-telemetry loop publishes system health, token usage,
	// loop states, and other operational data as native HA sensors.
	Telemetry TelemetryConfig `yaml:"telemetry"`
}

MQTTConfig configures the MQTT connection for Home Assistant device discovery and sensor state publishing. When MQTTConfig.Configured returns true, Thane connects to the broker at startup and registers as an HA device with availability tracking and runtime sensors.

func (MQTTConfig) Configured added in v0.5.3

func (c MQTTConfig) Configured() bool

Configured reports whether both Broker and DeviceName are set. A partial configuration is treated as unconfigured — Thane will start without MQTT publishing.

type MediaConfig added in v0.7.1

type MediaConfig struct {
	// YtDlpPath is the explicit path to the yt-dlp binary. If empty,
	// the binary is located via exec.LookPath at startup.
	YtDlpPath string `yaml:"yt_dlp_path"`

	// CookiesFile is an optional path to a Netscape-format cookie file
	// for accessing auth-required content (e.g., age-restricted videos).
	CookiesFile string `yaml:"cookies_file"`

	// SubtitleLanguage is the preferred subtitle language code.
	// Default: "en".
	SubtitleLanguage string `yaml:"subtitle_language"`

	// MaxTranscriptChars limits the transcript text returned in-context.
	// Longer transcripts are truncated. Default: 50000.
	MaxTranscriptChars int `yaml:"max_transcript_chars"`

	// WhisperModel is the Ollama model name for audio transcription
	// fallback when no subtitles are available. Default: "large-v3".
	WhisperModel string `yaml:"whisper_model"`

	// TranscriptDir is the directory for durable transcript storage.
	// Each transcript is saved as a markdown file with YAML frontmatter.
	// If empty, transcripts are returned in-context only (not persisted).
	TranscriptDir string `yaml:"transcript_dir"`

	// SummarizeModel is the preferred model for transcript summarization.
	// When set, it is passed as a routing hint (soft preference, not
	// override). If empty, the router selects an appropriate local model.
	SummarizeModel string `yaml:"summarize_model"`

	// FeedCheckInterval is how often (in seconds) to poll followed RSS/Atom
	// feeds for new entries. Set to a positive value to enable polling (e.g.,
	// 3600 for hourly). Default: 0 (disabled). No default is applied —
	// users must opt in by setting a positive interval.
	FeedCheckInterval int `yaml:"feed_check_interval"`

	// MaxFeeds limits the number of feeds that can be followed.
	// Default: 50.
	MaxFeeds int `yaml:"max_feeds"`

	// Analysis configures the structured media analysis pipeline
	// that writes analysis output to an Obsidian-compatible vault.
	Analysis AnalysisConfig `yaml:"analysis"`
}

MediaConfig configures the media transcript retrieval tool and RSS/Atom feed monitoring.

type MetacognitiveConfig added in v0.7.1

type MetacognitiveConfig struct {
	// Enabled controls whether the metacognitive loop starts. Default: false.
	Enabled bool `yaml:"enabled"`

	// StateFile is the path to the persistent state file, relative to
	// the workspace root. Default: "metacognitive.md".
	StateFile string `yaml:"state_file"`

	// MinSleep is the minimum allowed sleep duration between iterations.
	// The LLM cannot request a shorter sleep via set_next_sleep.
	// Default: "2m". Parsed as a Go duration string.
	MinSleep string `yaml:"min_sleep"`

	// MaxSleep is the maximum allowed sleep duration between iterations.
	// Default: "30m".
	MaxSleep string `yaml:"max_sleep"`

	// DefaultSleep is used when the LLM does not call set_next_sleep.
	// Default: "10m".
	DefaultSleep string `yaml:"default_sleep"`

	// Jitter is the sleep randomization factor (0.0–1.0). A value of
	// 0.2 means the actual sleep varies by ±20% of the computed
	// duration. Default: 0.2. Set to 0.0 for deterministic timing.
	Jitter float64 `yaml:"jitter"`

	// SupervisorProbability is the chance (0.0–1.0) that each wake
	// uses a frontier model with supervisor-augmented prompt.
	// Default: 0.1. Set to 0.0 to disable supervisor iterations.
	SupervisorProbability float64 `yaml:"supervisor_probability"`

	// Router configures model routing for normal (non-supervisor)
	// iterations.
	Router MetacognitiveRouterConfig `yaml:"router"`

	// SupervisorRouter configures model routing for supervisor
	// iterations (frontier model with augmented prompt).
	SupervisorRouter MetacognitiveRouterConfig `yaml:"supervisor_router"`
}

MetacognitiveConfig configures the self-regulating metacognitive loop. The loop runs perpetually in a background goroutine, using LLM calls to reason about the environment and self-determine its sleep duration between iterations. See issue #319.

type MetacognitiveRouterConfig added in v0.7.1

type MetacognitiveRouterConfig struct {
	// QualityFloor is the minimum quality rating (1–10) for model
	// selection. Default: 3 for normal iterations, 8 for supervisor.
	QualityFloor int `yaml:"quality_floor"`
}

MetacognitiveRouterConfig holds routing hints for metacognitive iterations.

type ModelConfig

type ModelConfig struct {
	Name          string `yaml:"name"`           // Model identifier (e.g., "claude-opus-4-20250514")
	Provider      string `yaml:"provider"`       // Provider name: ollama, anthropic, openai. Default: ollama
	SupportsTools bool   `yaml:"supports_tools"` // Whether the model can invoke tool calls
	ContextWindow int    `yaml:"context_window"` // Maximum context length in tokens
	Speed         int    `yaml:"speed"`          // Relative speed rating, 1 (slow) to 10 (fast)
	Quality       int    `yaml:"quality"`        // Relative quality rating, 1 (low) to 10 (high)
	CostTier      int    `yaml:"cost_tier"`      // 0=local/free, 1=cheap, 2=moderate, 3=expensive
	MinComplexity string `yaml:"min_complexity"` // Minimum task complexity: simple, moderate, complex
}

ModelConfig describes a single LLM model's identity and capabilities. The model router uses these fields to select the best model for each request.

type ModelsConfig

type ModelsConfig struct {
	// Default is the model name used when no specific model is requested.
	Default string `yaml:"default"`

	// OllamaURL is the base URL of the Ollama API server used as the
	// default LLM backend. Default: "http://localhost:11434".
	OllamaURL string `yaml:"ollama_url"`

	// LocalFirst prefers local (cost_tier=0) models over cloud models
	// when routing decisions are made by the model router.
	LocalFirst bool `yaml:"local_first"`

	// Available lists all models that Thane can route to. Each entry
	// maps a model name to a provider and declares its capabilities.
	Available []ModelConfig `yaml:"available"`
}

ModelsConfig configures LLM model routing. Each model in the Available list is mapped to a provider; requests are routed based on the model name. Unknown models fall through to Ollama.

type OllamaAPIConfig

type OllamaAPIConfig struct {
	Enabled bool   `yaml:"enabled"`
	Address string `yaml:"address"` // Bind address; empty = all interfaces
	Port    int    `yaml:"port"`    // Default: 11434
}

OllamaAPIConfig configures the optional Ollama-compatible API server. When Enabled is true, Thane exposes an additional HTTP server that speaks the Ollama wire protocol, allowing Home Assistant's built-in Ollama integration to use Thane as a drop-in backend.

type OpenClawConfig added in v0.8.2

type OpenClawConfig struct {
	// WorkspacePath is the root directory containing the agent's
	// workspace files (AGENTS.md, SOUL.md, USER.md, MEMORY.md, etc.)
	// and memory directory. Supports ~ expansion.
	// Default: ~/Thane/openclaw.
	WorkspacePath string `yaml:"workspace"`

	// SkillsDirs is a list of directories to scan for SKILL.md files.
	// Directories are searched in order; skills in earlier directories
	// override same-named skills in later ones.
	// Default: [~/Thane/openclaw/skills].
	SkillsDirs []string `yaml:"skills_dirs"`

	// MaxFileChars is the maximum characters per injected workspace
	// file. Files exceeding this limit are truncated using the 70/20
	// head/tail strategy matching OpenClaw v2026.2.9 behavior.
	// Default: 20000.
	MaxFileChars int `yaml:"max_file_chars"`
}

OpenClawConfig configures the thane:openclaw Ollama profile. This profile replicates OpenClaw's workspace-aware agent behavior (file injection, skill discovery, memory conventions) using Thane's agent loop.

type PersonConfig added in v0.6.0

type PersonConfig struct {
	// Track is a list of Home Assistant person entity IDs to monitor
	// (e.g., ["person.nugget", "person.dan"]). Each entry must begin
	// with "person.". An empty list disables person tracking.
	Track []string `yaml:"track"`

	// Devices maps tracked person entity IDs to their wireless device
	// MAC addresses. Used by the UniFi poller to determine which person
	// a wireless client belongs to for room-level presence.
	Devices map[string][]DeviceMapping `yaml:"devices"`

	// APRooms maps AP names (e.g., "ap-hor-office") to human-readable
	// room names (e.g., "office"). Only APs listed here contribute to
	// room presence; unlisted APs are ignored.
	APRooms map[string]string `yaml:"ap_rooms"`
}

PersonConfig configures household member presence tracking. When Track contains entity IDs, the person tracker maintains in-memory state from Home Assistant and injects a presence summary into the agent's system prompt on every wake.

type PrewarmConfig added in v0.7.1

type PrewarmConfig struct {
	// Enabled controls whether subject-keyed fact injection is active.
	// Default: false.
	Enabled bool `yaml:"enabled"`

	// MaxFacts caps the number of subject-matched facts injected per
	// wake. Default: 10.
	MaxFacts int `yaml:"max_facts"`

	// Archive configures Phase 2 pre-warming: injecting relevant past
	// conversation excerpts alongside Layer 1 knowledge. See issue #404.
	Archive ArchivePrewarmConfig `yaml:"archive"`
}

PrewarmConfig configures context pre-warming for cold-start loops. When enabled, subject-keyed facts are injected into the system prompt before the model sees the triggering event. This reduces wasted iterations where the model discovers facts it should already have. See issue #338.

type PricingEntry added in v0.7.1

type PricingEntry struct {
	InputPerMillion  float64 `yaml:"input_per_million"`
	OutputPerMillion float64 `yaml:"output_per_million"`
}

PricingEntry defines per-million-token costs for a model in USD.

type ProvenanceConfig added in v0.8.4

type ProvenanceConfig struct {
	// Path is the directory for the provenance git repository.
	// Supports ~ expansion. Example: ~/Thane/identity
	Path string `yaml:"path"`

	// SigningKey is the path to an SSH private key used to sign
	// commits. The key is loaded at startup and held in memory.
	// Supports ~ expansion. Example: ~/.ssh/id_ed25519
	SigningKey string `yaml:"signing_key"`
}

ProvenanceConfig configures git-backed file storage with SSH signature enforcement. When both Path and SigningKey are set, files are automatically committed with cryptographic signatures on every write.

func (ProvenanceConfig) Configured added in v0.8.4

func (c ProvenanceConfig) Configured() bool

Configured reports whether the provenance store has both a path and signing key set.

type SearchConfig added in v0.2.3

type SearchConfig struct {
	// Default is the provider name to use when the agent doesn't
	// specify one. If empty, the first configured provider is used.
	Default string `yaml:"default"`

	// SearXNG configures the self-hosted SearXNG meta-search provider.
	SearXNG search.SearXNGConfig `yaml:"searxng"`

	// Brave configures the Brave Search API provider.
	Brave search.BraveConfig `yaml:"brave"`
}

SearchConfig configures web search providers. At least one provider must be configured for the web_search tool to be available.

func (SearchConfig) Configured added in v0.2.3

func (c SearchConfig) Configured() bool

Configured reports whether at least one search provider is configured.

type ShellExecConfig

type ShellExecConfig struct {
	// Enabled must be true for the agent to execute any shell commands.
	Enabled bool `yaml:"enabled"`

	// WorkingDir is the working directory for command execution. If
	// empty, the process's current directory is used.
	WorkingDir string `yaml:"working_dir"`

	// DeniedPatterns are substrings that cause a command to be rejected.
	// Checked before AllowedPrefixes. Example: "rm -rf /".
	DeniedPatterns []string `yaml:"denied_patterns"`

	// AllowedPrefixes restricts commands to those whose first token
	// matches one of these prefixes. An empty list means all commands
	// are allowed (subject to DeniedPatterns).
	AllowedPrefixes []string `yaml:"allowed_prefixes"`

	// DefaultTimeoutSec is the maximum wall-clock time a command may
	// run before being killed. Default: 30.
	DefaultTimeoutSec int `yaml:"default_timeout_sec"`
}

ShellExecConfig configures the agent's ability to execute shell commands on the host. Disabled by default for safety. When enabled, commands are filtered through allow and deny lists before execution.

type SignalConfig added in v0.7.0

type SignalConfig struct {
	// Enabled controls whether the Signal bridge starts.
	Enabled bool `yaml:"enabled"`

	// Command is the signal-cli executable path (e.g., "signal-cli").
	Command string `yaml:"command"`

	// Account is the phone number to use (e.g., "+15124232707").
	// Passed as the -a flag to signal-cli.
	Account string `yaml:"account"`

	// Args are additional command-line arguments appended after the
	// standard "-a ACCOUNT jsonRpc" arguments.
	Args []string `yaml:"args"`

	// RateLimitPerMinute caps how many inbound messages per sender
	// are processed per minute. Zero disables rate limiting.
	// Default: 10.
	RateLimitPerMinute int `yaml:"rate_limit_per_minute"`

	// SessionIdleMinutes is the idle timeout in minutes for session
	// rotation. When a new Signal message arrives and the last message
	// from that sender was more than this many minutes ago, the
	// previous session is ended (triggering background summarization)
	// and a fresh one begins on the next agent loop call. Zero or
	// omitted disables idle rotation.
	SessionIdleMinutes int `yaml:"session_idle_minutes"`

	// Routing configures how Signal messages are routed to LLM models.
	// All fields are optional; defaults preserve the original hardcoded
	// behavior (quality_floor=6, mission=conversation, delegation_gating=disabled).
	Routing SignalRoutingConfig `yaml:"routing"`

	// AttachmentSourceDir is the directory where signal-cli stores
	// downloaded attachments. Defaults to
	// ~/.local/share/signal-cli/attachments when empty.
	AttachmentSourceDir string `yaml:"attachment_source_dir"`

	// AttachmentDir is the workspace subdirectory where received
	// attachments are copied for agent access. Defaults to
	// {workspace}/signal-attachments when empty and workspace is set.
	AttachmentDir string `yaml:"attachment_dir"`

	// MaxAttachmentSize is the maximum attachment size in bytes that
	// will be processed. Attachments exceeding this are described but
	// not copied. Zero means no limit.
	MaxAttachmentSize int64 `yaml:"max_attachment_size"`
}

SignalConfig configures the native Signal message bridge using signal-cli's jsonRpc mode over stdin/stdout.

func (SignalConfig) Configured added in v0.7.0

func (c SignalConfig) Configured() bool

Configured reports whether the Signal bridge has the minimum required configuration (enabled with a command and account).

type SignalRoutingConfig added in v0.7.0

type SignalRoutingConfig struct {
	// Model sets an explicit model for Signal messages. When non-empty,
	// the router is bypassed entirely. Empty means use the router with
	// the hint-based defaults below.
	Model string `yaml:"model"`

	// QualityFloor is the minimum model quality rating (1-10) passed
	// to the router. Default: "6".
	QualityFloor string `yaml:"quality_floor"`

	// Mission describes the task context for routing. Default: "conversation".
	Mission string `yaml:"mission"`

	// DelegationGating controls whether delegation-first tool gating
	// is active. Default: "disabled".
	DelegationGating string `yaml:"delegation_gating"`
}

SignalRoutingConfig controls model selection for Signal messages. When Model is set, the router is bypassed entirely and the named model handles every Signal message. The remaining fields are passed as routing hints when the router is active.

type StateWindowConfig added in v0.7.0

type StateWindowConfig struct {
	// MaxEntries is the circular buffer capacity. When the buffer is
	// full, the oldest entry is overwritten. Default: 50.
	MaxEntries int `yaml:"max_entries"`

	// MaxAgeMinutes controls how long entries remain visible. Entries
	// older than this are excluded from the context output at read
	// time. Default: 30.
	MaxAgeMinutes int `yaml:"max_age_minutes"`
}

StateWindowConfig configures the rolling window of recent Home Assistant state changes injected into the agent's system prompt.

type SubscribeConfig added in v0.6.0

type SubscribeConfig struct {
	// EntityGlobs is a list of glob patterns (using path.Match syntax)
	// that select which entity IDs to process. Examples: "person.*",
	// "binary_sensor.*door*", "light.living_room". An empty list
	// means all entities are accepted.
	EntityGlobs []string `yaml:"entity_globs"`

	// RateLimitPerMinute caps how many state changes per entity are
	// forwarded per minute. Zero means no rate limiting.
	RateLimitPerMinute int `yaml:"rate_limit_per_minute"`

	// CooldownMinutes is the per-anticipation cooldown period in minutes.
	// After an anticipation triggers a wake, it cannot trigger again until
	// this interval elapses. Defaults to 5 minutes via applyDefaults.
	CooldownMinutes int `yaml:"cooldown_minutes"`
}

SubscribeConfig configures entity-level filtering and rate limiting for Home Assistant WebSocket state_changed event subscriptions.

type SubscriptionConfig added in v0.5.4

type SubscriptionConfig struct {
	// Topic is the MQTT topic filter (e.g., "homeassistant/+/+/state",
	// "frigate/events"). Supports MQTT wildcard characters.
	Topic string `yaml:"topic"`
}

SubscriptionConfig describes a single MQTT topic subscription. Each entry is subscribed on every broker (re-)connect. Wildcards (+ and #) are supported per the MQTT specification.

type TelemetryConfig added in v0.8.4

type TelemetryConfig struct {
	// Enabled activates the mqtt-telemetry loop. Requires MQTT to be
	// configured (broker + device_name).
	Enabled bool `yaml:"enabled"`

	// Interval is how often (in seconds) telemetry metrics are
	// collected and published. Default: 60. Minimum: 10.
	Interval int `yaml:"interval"`
}

TelemetryConfig configures MQTT telemetry publishing. When Enabled is true and MQTT is configured, a dedicated loop publishes operational metrics (DB sizes, token usage, loop states, etc.) as native Home Assistant sensors via MQTT Discovery.

type UnifiConfig added in v0.6.0

type UnifiConfig struct {
	// URL is the base URL of the UniFi controller
	// (e.g., "https://192.168.1.1").
	URL string `yaml:"url"`

	// APIKey is the API key for UniFi controller authentication.
	// Sent as X-API-KEY header.
	APIKey string `yaml:"api_key"`

	// PollIntervalSec is how often (in seconds) to poll for wireless
	// client station data. Default: 30. Minimum: 10.
	PollIntervalSec int `yaml:"poll_interval"`
}

UnifiConfig configures the UniFi network controller connection for room-level presence detection via AP client associations.

func (UnifiConfig) Configured added in v0.6.0

func (c UnifiConfig) Configured() bool

Configured reports whether both URL and APIKey are set, indicating the UniFi integration should be enabled.

type VisionConfig added in v0.8.4

type VisionConfig struct {
	Enabled bool   `yaml:"enabled"` // enable auto-analysis on image ingest
	Model   string `yaml:"model"`   // vision model name (must be in models.available)
	Prompt  string `yaml:"prompt"`  // custom analysis prompt; empty uses default
	Timeout string `yaml:"timeout"` // per-image timeout (Go duration); empty → 30s
}

VisionConfig configures automatic vision analysis of image attachments. When enabled, images are analyzed on ingest using a vision-capable LLM and the resulting description is cached in the attachment metadata index.

func (VisionConfig) ParsedTimeout added in v0.8.4

func (v VisionConfig) ParsedTimeout() time.Duration

ParsedTimeout returns the configured timeout as a time.Duration, defaulting to 30 seconds when empty. Invalid durations are caught by Config.Validate; this method assumes the value is already validated and falls back to the default on any parse error.

type WorkspaceConfig

type WorkspaceConfig struct {
	// Path is the root directory for file operations. If empty, file
	// tools are disabled entirely.
	Path string `yaml:"path"`

	// ReadOnlyDirs are additional directories the agent can read from
	// but not write to. Useful for giving the agent access to reference
	// material outside its workspace.
	ReadOnlyDirs []string `yaml:"read_only_dirs"`
}

WorkspaceConfig configures the agent's sandboxed file system access. When Path is set, the agent can read and write files within that directory. All paths passed to file tools are resolved relative to Path and cannot escape it.

Jump to

Keyboard shortcuts

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