Feature Configuration

Features are configurable capabilities with their own YAML config files in .aura/config/features/. Features that need LLM calls use a dedicated hidden agent defined in .aura/config/agents/features/.

Feature Agent Resolution

Several features delegate work to an LLM. Compaction, Thinking, Guardrail, and Title support two resolution patterns:

  1. agent: — Dedicated hidden agent with its own model/provider. Separate API call.
  2. prompt: — Reuses the current agent’s model with a named system prompt from prompts/. No extra provider config.

Resolution order: prompt: wins over agent:. If neither is set: Compaction falls back to prune-only, Title falls back to first user message, others error.

Feature agent: prompt: Notes
Compaction Yes Yes Falls back to prune-only if neither configured
Thinking Yes Yes Only runs when thinking blocks cross keep_last boundary
Guardrail Yes Yes Per-scope: scope.tool_calls.agent/prompt, scope.user_messages.agent/prompt
Title Yes Yes Falls back to first user message if neither configured
Vision, STT, TTS, Embeddings, Reranker Yes No Agent name provides model/provider — no runtime resolution

Git Snapshots

File: features/snapshot.yaml

snapshot:
  disabled: false # true = skip automatic Git working-tree snapshots

Snapshots are enabled by default in Git repositories. Set disabled: true to avoid Git snapshot initialization, working-tree scans, snapshot refs, and the Creating snapshot... status message. Git initialization is deferred until the first accepted user prompt, after feature overrides have been resolved.

The same setting works under features.snapshot in agent, mode, and task definitions. Normal precedence applies: global → agent → mode → task → CLI. Omitting disabled inherits the parent setting; explicitly setting it to false re-enables snapshots. For a single invocation:

aura --override features.snapshot.disabled=true

With snapshots disabled, /undo reports that code restore is unavailable and offers message-only rewind. Saved conversation sessions and their auto-save are unaffected. See Git snapshots and rewind.

Compaction

File: features/compaction.yaml — See Compaction

compaction:
  timeout: 0s # optional overall compaction limit; 0 uses only the caller's deadline
  threshold: 80 # context fill % that triggers compaction (1-100)
  # max_tokens: 32000    # absolute token trigger (overrides threshold)
  trim_threshold: 50 # fill % at which synthetic messages are trimmed first (must be < threshold)
  # trim_max_tokens: 16000
  keep_last_messages: 10
  chunks: 1 # 1 = single-pass; N splits history into N sequential chunks
  agent: Compaction
  # prompt: ""           # named prompt for self-compaction (overrides agent)
  tool_result_max_length: 200
  truncation_retries: [150, 100, 50, 0]
  prune:
    mode: "off" # "off", "iteration", "compaction"
    protect_percent: 30 # % of context to protect; includes the boundary message
    arg_threshold: 200 # min tokens for tool call args to be prunable

The latest unanswered tool-call batch (request and all results) is always protected from pruning until the model responds, even if it exceeds protect_percent. Oversized new results remain subject to the tool-result admission limit.

Embeddings

File: features/embeddings.yaml — See Embeddings

embeddings:
  agent: "Embeddings"
  max_results: 5
  gitignore: | # gitignore-style patterns for indexed files
    *
    !*/
    !src/**/*.go
  offload: false # unload embedding model after use (frees VRAM for reranker)
  chunking:
    strategy: "auto" # auto, ast, line
    max_tokens: 500
    overlap_tokens: 75
  reranking:
    agent: "Reranker"
    multiplier: 4 # fetch max_results * multiplier candidates, rerank down
    offload: false

Thinking

File: features/thinking.yaml — See Thinking

thinking:
  agent: "Thinking"
  # prompt: ""           # named prompt for self-rewrite (overrides agent)
  keep_last: 5 # most recent messages whose thinking blocks are always preserved
  token_threshold: 300 # min tokens for a block to be affected by strip/rewrite

Vision

File: features/vision.yaml

vision:
  agent: "Vision" # must support vision
  dimension: 1024 # max pixel dimension for compression
  quality: 75 # JPEG quality (1-100)

Speech-to-Text (STT)

File: features/stt.yaml

stt:
  agent: "Transcribe" # provider must support /v1/audio/transcriptions
  language: "" # ISO-639-1 hint (e.g. "en"). Empty = auto-detect

Text-to-Speech (TTS)

File: features/tts.yaml

tts:
  agent: "Speak" # provider must support /v1/audio/speech
  voice: "alloy" # voice identifier (server-dependent)
  format: "mp3" # mp3, opus, aac, flac, wav, pcm
  speed: 1.0 # 0.25-4.0

Title

File: features/title.yaml

title:
  disabled: false
  agent: "Title"
  prompt: "" # named prompt for self-title (overrides agent)
  max_length: 50

Tools

File: features/tools.yaml — See Tools

tools:
  mode: percentage # "tokens" or "percentage" guard mode
  result:
    max_tokens: 20000 # max tokens per result (mode: tokens)
    max_percentage: 95 # max context fill after result (mode: percentage)
  read_small_file_tokens: 2000
  max_steps: 50
  # call_limits:           # exact tool names; omitted tools are unlimited
  #   Gotify:
  #     max: 1
  #     count: success     # attempt (default) or success; resets on /new
  token_budget: 0 # cumulative input+output limit; 0 = disabled
  rejection_message: >-
    Error: Tool result too large (%d tokens, limit %d).
    Try a more specific query or use offset/limit parameters.
  bash:
    truncation:
      max_output_bytes: 1048576 # 1MB per stream; 0 = disabled
      max_lines: 200
      head_lines: 100
      tail_lines: 80
    rewrite: "" # Go text/template rewriting Bash commands; receives {{ .Command }}
  webfetch_max_body_size: 5242880
  # parallel: false      # omit or true = parallel tool calls (default)
  user_input_max_percentage: 80 # max context fill after user message; 0 = disabled
  read_before:
    write: true # require read before overwriting files
    delete: false # require read before deleting files
  enabled: [] # default include patterns (glob); empty = all
  disabled: ["mcp__*"] # default exclude patterns (glob)
  policy: # global default tool policy (additive baseline for agent/mode policies)
    auto: [] # tool/Bash patterns auto-approved
    confirm: [] # tool/Bash patterns requiring user approval
    deny: [] # tool/Bash patterns hard-blocked
  opt_in: [] # tools hidden unless explicitly named
  deferred: [] # tools excluded from request, loaded on demand via LoadTools

Sandbox

File: features/sandbox.yaml — See Sandboxing

sandbox:
  enabled: true
  restrictions:
    ro: [] # read-only paths (support $HOME expansion)
    rw: [] # read-write paths
  # extra:    # additive paths from agent/mode frontmatter
  #   ro: []
  #   rw: []

Subagent

File: features/subagent.yaml

subagent:
  max_steps: 25
  default_agent: "" # agent for Task tool calls; empty = parent agent

Plugins

File: features/plugins.yaml — See Plugins

plugins:
  dir: "" # plugin directory relative to config home; empty = "plugins/"
  unsafe: false # allow plugins compiled without safety checks
  include: [] # load only matching names; empty = all
  exclude: [] # skip matching names (applied after include)
  config:
    global: {} # key-value pairs sent to ALL plugins
    local: {} # per-plugin overrides keyed by plugin name

MCP

File: features/mcp.yaml — See MCP

mcp:
  enabled: [] # include patterns (glob); empty = all servers
  disabled: [] # exclude patterns (glob)

Guardrail

File: features/guardrail.yaml — See Guardrail

guardrail:
  mode: "" # "block", "log", "" (disabled)
  # on_error: ""         # "block" (fail-closed) or "allow" (fail-open); inherits from mode
  timeout: 2m
  scope:
    tool_calls:
      agent: ""
      prompt: ""
    user_messages:
      agent: ""
      prompt: ""
  tools:
    enabled: [] # only check matching tools (empty = all)
    disabled: [] # skip matching tools

Estimation

File: features/estimation.yaml

Ollama’s native estimator uses a chat request with thinking disabled and at most one generated token. Its count includes chat-template overhead, so it is conservative for individual content fragments and costs an inference round trip. On context overflow, Aura retains at least the context-window size or the local estimate, whichever is larger. Use rough+tiktoken to avoid these extra inference requests.

estimation:
  # rough = chars/divisor | tiktoken = tiktoken encoding
  # rough+tiktoken = max of both (default) | native = provider tokenization
  method: "rough+tiktoken"
  divisor: 4 # chars-per-token for rough estimation
  encoding: "cl100k_base"

Tool-result percentage budgets are measured against max_percentage, not the full context window. Every output payload is subject to the configured budget, including short replies. Execution status is independent: omitted output leaves an explicit acknowledgement that execution succeeded, in both main and subagent conversations. That acknowledgement is not evidence of external delivery, and output rejection does not authorize repeating a mutation. Fixed-token mode enforces its configured per-result limit in the same way.

Global Tool Policy

File: features/tools.yaml

tools:
  policy:
    auto: []
    confirm: []
    deny:
      - "Bash:sudo *"
      - "Bash:rm -rf *"

The global policy is a baseline merged additively with agent, mode, and task policies. See Tools — Global Tool Policy.

Override Precedence

Each level merges non-zero values on top of the previous:

  1. Global defaultsfeatures/*.yaml (+ ApplyDefaults() for omitted fields)
  2. CLI flags — e.g. --max-steps overrides tools.max_steps
  3. Agent frontmatterfeatures: block (see Agents)
  4. Mode frontmatterfeatures: block (see Modes)
  5. Task definitionfeatures: block (see Tasks)
  6. --override / -O — dot-notation overrides (highest priority, see Runtime Overrides)

Omitting a field preserves the value from the previous level.


Back to top

Copyright © 2026 idelchi. Distributed under the MIT License.