Module: Anima::Settings

Defined in:
lib/anima/settings.rb

Overview

User-facing configuration backed by ~/.anima/config.toml with hot-reload.

Reads the TOML config file on each access, re-parsing only when the file’s mtime has changed. The config file is created by the installer with all values set — it is the single source of truth for all settings.

Settings are grouped into sections that mirror the TOML file structure:

[llm]       — Model selection and response limits
[timeouts]  — Network and execution timeouts (seconds)
[shell]     — Shell command output limits
[tools]     — File and web tool limits
[session]   — Conversation behavior

Examples:

Reading a setting

Anima::Settings.model          #=> "claude-sonnet-4-20250514"
Anima::Settings.api_timeout    #=> 30

Hot-reload (no restart needed)

Anima::Settings.model  #=> "claude-sonnet-4-20250514"
# user edits ~/.anima/config.toml: model = "claude-haiku-4-5"
Anima::Settings.model  #=> "claude-haiku-4-5"

See Also:

Defined Under Namespace

Classes: MissingConfigError, MissingSettingError

Constant Summary collapse

DEFAULT_PATH =
File.expand_path("~/.anima/config.toml")

Class Method Summary collapse

Class Method Details

.agent_nameString

The agent’s display name. Separates engine identity (“Anima”) from agent identity — any agent running on Anima can name itself.

Returns:

  • (String)


68
# File 'lib/anima/settings.rb', line 68

def agent_name = get("agent", "name")

.analytical_brain_blocking_on_agent_messageBoolean

Run the analytical brain asynchronously after the main agent completes.

Returns:

  • (Boolean)


234
# File 'lib/anima/settings.rb', line 234

def analytical_brain_blocking_on_agent_message = get("analytical_brain", "blocking_on_agent_message")

.analytical_brain_blocking_on_user_messageBoolean

Run the analytical brain synchronously before the main agent on user messages.

Returns:

  • (Boolean)


230
# File 'lib/anima/settings.rb', line 230

def analytical_brain_blocking_on_user_message = get("analytical_brain", "blocking_on_user_message")

.analytical_brain_max_tokensInteger

Maximum tokens per analytical brain response.

Returns:

  • (Integer)


226
# File 'lib/anima/settings.rb', line 226

def analytical_brain_max_tokens = get("analytical_brain", "max_tokens")

.analytical_brain_message_windowInteger

Number of recent messages to include in the analytical brain’s context window.

Returns:

  • (Integer)


238
# File 'lib/anima/settings.rb', line 238

def analytical_brain_message_window = get("analytical_brain", "message_window")

.api_timeoutInteger

LLM API request timeout.

Returns:

  • (Integer)

    seconds



112
# File 'lib/anima/settings.rb', line 112

def api_timeout = get("timeouts", "api")

.command_timeoutInteger

Shell command execution timeout.

Returns:

  • (Integer)

    seconds



116
# File 'lib/anima/settings.rb', line 116

def command_timeout = get("timeouts", "command")

.config_pathString

Returns active config file path.

Returns:

  • (String)

    active config file path



53
54
55
# File 'lib/anima/settings.rb', line 53

def config_path
  @config_path || DEFAULT_PATH
end

.config_path=(path) ⇒ Object

Override config file path (for testing). Resets the cache so the next access reads from the new location.

Parameters:

  • path (String, nil)

    custom path, or nil to restore default



46
47
48
49
50
# File 'lib/anima/settings.rb', line 46

def config_path=(path)
  @config_path = path
  @config_cache = nil
  @config_mtime = nil
end

.default_view_modeString

View mode applied to new sessions: “basic”, “verbose”, or “debug”. Changing this setting only affects sessions created afterwards.

Returns:

  • (String)

Raises:



182
183
184
185
186
187
188
189
# File 'lib/anima/settings.rb', line 182

def default_view_mode
  value = get("session", "default_view_mode")
  unless Session::VIEW_MODES.include?(value)
    raise MissingSettingError,
      "[session] default_view_mode must be one of: #{Session::VIEW_MODES.join(", ")} (got #{value.inspect})"
  end
  value
end

.fast_modelString

Lightweight model for fast tasks (e.g. session naming).

Returns:

  • (String)

    Anthropic model identifier



78
# File 'lib/anima/settings.rb', line 78

def fast_model = get("llm", "fast_model")

.github_labelString

Label applied to agent-created feature request issues.

Returns:

  • (String)


220
# File 'lib/anima/settings.rb', line 220

def github_label = get("github", "label")

.github_repoString

Repository for feature requests (owner/repo format). Falls back to parsing git remote origin when unset.

Returns:

  • (String)


216
# File 'lib/anima/settings.rb', line 216

def github_repo = get("github", "repo")

.interrupt_check_intervalNumeric

Polling interval for user interrupt checks during long-running commands. Enforces a 0.5s floor to prevent busy-polling from misconfiguration.

Returns:

  • (Numeric)

    seconds (minimum 0.5)



134
135
136
# File 'lib/anima/settings.rb', line 134

def interrupt_check_interval
  [get("timeouts", "interrupt_check"), 0.5].max
end

.max_file_sizeInteger

Maximum file size for read/edit operations (bytes).

Returns:

  • (Integer)


148
# File 'lib/anima/settings.rb', line 148

def max_file_size = get("tools", "max_file_size")

.max_output_bytesInteger

Maximum bytes of command output before truncation.

Returns:

  • (Integer)


142
# File 'lib/anima/settings.rb', line 142

def max_output_bytes = get("shell", "max_output_bytes")

.max_read_bytesInteger

Maximum bytes returned by the read_file tool.

Returns:

  • (Integer)


156
# File 'lib/anima/settings.rb', line 156

def max_read_bytes = get("tools", "max_read_bytes")

.max_read_linesInteger

Maximum lines returned by the read_file tool.

Returns:

  • (Integer)


152
# File 'lib/anima/settings.rb', line 152

def max_read_lines = get("tools", "max_read_lines")

.max_subagent_response_charsInteger

Maximum characters of sub-agent result before head+tail truncation. Higher than tool threshold because sub-agent output is already curated.

Returns:

  • (Integer)


174
# File 'lib/anima/settings.rb', line 174

def max_subagent_response_chars = get("tools", "max_subagent_response_chars")

.max_tokensInteger

Maximum tokens per LLM response.

Returns:

  • (Integer)


82
# File 'lib/anima/settings.rb', line 82

def max_tokens = get("llm", "max_tokens")

.max_tool_response_charsInteger

Maximum characters of tool output before head+tail truncation. Full output saved to a temp file for paginated reading.

Returns:

  • (Integer)


169
# File 'lib/anima/settings.rb', line 169

def max_tool_response_chars = get("tools", "max_tool_response_chars")

.max_tool_roundsInteger

Maximum consecutive tool execution rounds per LLM message. Prevents runaway tool loops.

Returns:

  • (Integer)


87
# File 'lib/anima/settings.rb', line 87

def max_tool_rounds = get("llm", "max_tool_rounds")

.max_web_response_bytesInteger

Maximum bytes from web GET responses.

Returns:

  • (Integer)


160
# File 'lib/anima/settings.rb', line 160

def max_web_response_bytes = get("tools", "max_web_response_bytes")

.mcp_response_timeoutInteger

MCP server response timeout.

Returns:

  • (Integer)

    seconds



120
# File 'lib/anima/settings.rb', line 120

def mcp_response_timeout = get("timeouts", "mcp_response")

.min_web_content_charsInteger

Minimum characters of extracted web content before flagging as possibly incomplete.

Returns:

  • (Integer)


164
# File 'lib/anima/settings.rb', line 164

def min_web_content_chars = get("tools", "min_web_content_chars")

.mneme_eviction_fractionFloat

Fraction of the viewport to evict in batch when Mneme runs.

Returns:

  • (Float)


264
# File 'lib/anima/settings.rb', line 264

def mneme_eviction_fraction = get("mneme", "eviction_fraction")

.mneme_l1_budget_fractionFloat

Fraction of the main viewport token budget reserved for L1 snapshots.

Returns:

  • (Float)


252
# File 'lib/anima/settings.rb', line 252

def mneme_l1_budget_fraction = get("mneme", "l1_budget_fraction")

.mneme_l2_budget_fractionFloat

Fraction of the main viewport token budget reserved for L2 snapshots.

Returns:

  • (Float)


256
# File 'lib/anima/settings.rb', line 256

def mneme_l2_budget_fraction = get("mneme", "l2_budget_fraction")

.mneme_l2_snapshot_thresholdInteger

Number of uncovered L1 snapshots that triggers L2 compression.

Returns:

  • (Integer)


260
# File 'lib/anima/settings.rb', line 260

def mneme_l2_snapshot_threshold = get("mneme", "l2_snapshot_threshold")

.mneme_max_tokensInteger

Maximum tokens per Mneme LLM response.

Returns:

  • (Integer)


244
# File 'lib/anima/settings.rb', line 244

def mneme_max_tokens = get("mneme", "max_tokens")

.mneme_pinned_budget_fractionFloat

Fraction of the main viewport token budget reserved for pinned messages. Pinned messages appear between snapshots and the sliding window.

Returns:

  • (Float)


269
# File 'lib/anima/settings.rb', line 269

def mneme_pinned_budget_fraction = get("mneme", "pinned_budget_fraction")

.mneme_viewport_fractionFloat

Fraction of the main viewport token budget allocated to Mneme’s viewport.

Returns:

  • (Float)


248
# File 'lib/anima/settings.rb', line 248

def mneme_viewport_fraction = get("mneme", "viewport_fraction")

.modelString

Primary model for conversations.

Returns:

  • (String)

    Anthropic model identifier



74
# File 'lib/anima/settings.rb', line 74

def model = get("llm", "model")

.name_generation_intervalInteger

Regenerate session name every N messages.

Returns:

  • (Integer)


193
# File 'lib/anima/settings.rb', line 193

def name_generation_interval = get("session", "name_generation_interval")

.project_files_max_depthInteger

Maximum directory depth for project file scanning.

Returns:

  • (Integer)


209
# File 'lib/anima/settings.rb', line 209

def project_files_max_depth = get("environment", "project_files_max_depth")

.project_files_whitelistArray<String>

Filenames to scan for in the working directory.

Returns:

  • (Array<String>)


205
# File 'lib/anima/settings.rb', line 205

def project_files_whitelist = get("environment", "project_files")

.recall_budget_fractionFloat

Fraction of the main viewport token budget reserved for recalled memories.

Returns:

  • (Float)


279
# File 'lib/anima/settings.rb', line 279

def recall_budget_fraction = get("recall", "budget_fraction")

.recall_max_resultsInteger

Maximum search results returned per FTS5 query.

Returns:

  • (Integer)


275
# File 'lib/anima/settings.rb', line 275

def recall_max_results = get("recall", "max_results")

.recall_max_snippet_tokensInteger

Maximum tokens per individual recall snippet.

Returns:

  • (Integer)


283
# File 'lib/anima/settings.rb', line 283

def recall_max_snippet_tokens = get("recall", "max_snippet_tokens")

.recall_recency_decayFloat

Recency decay factor for search ranking (0.0 = pure relevance).

Returns:

  • (Float)


287
# File 'lib/anima/settings.rb', line 287

def recall_recency_decay = get("recall", "recency_decay")

.reset!Object

Resets to default path and clears cached config. Useful in test teardown.



59
60
61
# File 'lib/anima/settings.rb', line 59

def reset!
  self.config_path = nil
end

.soul_pathString

Path to the soul file — the agent’s self-authored identity.

Returns:

  • (String)

    absolute path



199
# File 'lib/anima/settings.rb', line 199

def soul_path = get("paths", "soul")

.subagent_modelString

Model for sub-agent sessions. Sonnet is cost-effective for focused tasks.

Returns:

  • (String)

    Anthropic model identifier



101
# File 'lib/anima/settings.rb', line 101

def subagent_model = get("llm", "subagent_model")

.subagent_token_budgetInteger

Context window budget for sub-agent sessions. Smaller than main to keep sub-agents out of the “dumb zone”.

Returns:

  • (Integer)


106
# File 'lib/anima/settings.rb', line 106

def subagent_token_budget = get("llm", "subagent_token_budget")

.thinking_budgetInteger

Maximum character length for the Think tool’s thoughts parameter. Sub-agents receive half this budget (their tasks are less complex).

Returns:

  • (Integer)


97
# File 'lib/anima/settings.rb', line 97

def thinking_budget = get("llm", "thinking_budget")

.token_budgetInteger

Context window budget — tokens reserved for conversation history. Set this based on your model’s context window minus system prompt.

Returns:

  • (Integer)


92
# File 'lib/anima/settings.rb', line 92

def token_budget = get("llm", "token_budget")

.tool_timeoutInteger

Per-tool-call timeout. Used as the default deadline for orphan detection and as the default value for the tool’s ‘timeout` input parameter.

Returns:

  • (Integer)

    seconds



129
# File 'lib/anima/settings.rb', line 129

def tool_timeout = get("timeouts", "tool")

.web_request_timeoutInteger

Web fetch request timeout.

Returns:

  • (Integer)

    seconds



124
# File 'lib/anima/settings.rb', line 124

def web_request_timeout = get("timeouts", "web_request")