annaanna
Getting Started

Configuration

All configuration is stored in a single SQLite database at ~/.anna/anna.db. There are no YAML config files. To set up or modify your configuration, run anna --open to open the web admin panel.

The home directory defaults to ~/.anna and can be changed by setting the ANNA_HOME environment variable.

Database Tables

Configuration is spread across several tables in the SQLite database.

settings

A key-value store for global settings. Each row has a key (text) and a value (JSON text). Known keys:

KeyDescription
runnerRunner type, system prompt, idle timeout, compaction settings
compactionCompaction thresholds (max_tokens, keep_tail)
heartbeatHeartbeat polling toggle and interval
pluginsJSON array of plugin definitions
runtime_pluginsJSON object of subprocess tool/channel bindings
models_cacheCached model list from providers

settings_agents

One row per agent.

ColumnTypeDescription
idTEXTAgent slug (e.g. anna)
nameTEXTDisplay name
modelTEXTDefault model in provider/model format
model_strongTEXTStrong-tier model in provider/model format
model_fastTEXTFast-tier model in provider/model format
system_promptTEXTCustom system prompt (bypasses default builder)
workspaceTEXTAbsolute path to agent workspace directory
sandboxTEXTJSON sandbox config for the agent (backend, network.mode, network.allowlist)
enabledINTEGER1 = active, 0 = disabled

settings_channels

One row per channel instance. Multiple rows can share the same platform type, such as multiple Feishu bot instances.

ColumnTypeDescription
idTEXTChannel instance identifier, such as telegram or feishu-coder
typeTEXTPlatform type: telegram, qq, feishu, or weixin
agent_idTEXTOptional dedicated agent for this channel instance
enabledINTEGER1 = active, 0 = disabled
configTEXTJSON blob with platform-specific settings (see below)

settings_users

Maps external platform users to agents.

ColumnTypeDescription
idINTEGERAuto-increment primary key
external_idTEXTUser ID on the platform
platformTEXTPlatform identifier (e.g. telegram)
nameTEXTDisplay name
default_agent_idTEXTFK to settings_agents.id -- default agent for this user

settings_channel_agents

Routes a specific group chat to a specific agent.

ColumnTypeDescription
channel_idTEXTChannel instance identifier
platformTEXTPlatform identifier
chat_idTEXTGroup or chat ID on the platform
agent_idTEXTFK to settings_agents.id

Composite primary key: (channel_id, chat_id).

Runner Settings

Stored in the settings table under the runner key as a JSON object.

FieldDefaultDescription
typegoRunner implementation (only go currently)
system""Custom system prompt (bypasses default builder)
idle_timeout10Minutes before reaping idle runners
compaction.max_tokens80000Auto-compact when history exceeds this
compaction.keep_tail20Keep N recent messages after compaction

Channel Config Blobs

Each platform stores its own JSON structure in the config column of settings_channels.

Telegram

{
  "token": "BOT_TOKEN",
  "enable_notify": false,
  "notify_chat": "123456789",
  "channel_id": "@my_channel",
  "group_mode": "mention",
  "allowed_ids": [136345060]
}

QQ

{
  "app_id": "QQ_BOT_APP_ID",
  "app_secret": "QQ_BOT_APP_SECRET",
  "enable_notify": false,
  "group_mode": "mention",
  "allowed_ids": []
}

Feishu

{
  "app_id": "FEISHU_APP_ID",
  "app_secret": "FEISHU_APP_SECRET",
  "encrypt_key": "",
  "verification_token": "",
  "enable_notify": false,
  "notify_chat": "oc_xxx",
  "group_mode": "mention",
  "allowed_ids": []
}

group_mode accepts mention, always, or disabled.

Directory Layout

PathPurposeCategory
~/.anna/anna.dbSQLite database (config, memory, scheduler)Data
~/.anna/plugins/bundled/Bundled runtime plugin manifestsData
~/.anna/plugins/installed/User-installed runtime pluginsData
~/.anna/workspaces/{agent-id}/skills/Per-agent installed skillsData
~/.anna/workspaces/{agent-id}/anna.logPer-agent log fileData
~/.anna/workspaces/{agent-id}/SOUL.mdOptional soul/identity overrideData
~/.anna/workspaces/{agent-id}/SYSTEM.mdOptional system prompt overrideData
~/.anna/workspaces/{agent-id}/HEARTBEAT.mdHeartbeat instructionsData
~/.anna/cache/Model cache (safe to delete)Cache
~/.anna/cache/sandbox/Sandbox session scratch/preflight stateCache
  • anna.db is the single source of truth for all configuration, memory, and scheduler data.
  • workspaces/ contains per-agent data. Each agent gets its own directory keyed by agent ID.
  • cache/ contains regenerable data. Run anna models update to rebuild.
  • agent sandbox config lives on each agent record (settings_agents.sandbox). The agent form edits network policy; backend can also be set in the stored JSON.
    • backend: auto (default), boxsh, or docker
    • network.mode: disabled (default), allow_all, or whitelist
    • network.allowlist: required only when mode is whitelist
    • Linux and macOS validate the managed boxsh backend when selected. Runner startup fails closed when the sandbox backend is unavailable or cannot enforce the configured network mode.
    • auto selects boxsh on Linux/macOS; on other platforms it fails closed — configure docker explicitly.
    • Current boxsh client builds may reject whitelist mode at runtime; use it only when your runtime supports whitelist enforcement.
    • docker runs each session in a dedicated container built from the bundled plugins/sandbox/docker/Dockerfile. The image is version-locked to the anna binary: dev builds use a local anna-sandbox:dev tag (produced by mise run sandbox:docker:build), and tagged releases pull ghcr.io/vaayne/anna-sandbox:<version> from GHCR. It is opt-in; auto does not select it. Requires a reachable docker daemon. Useful on Windows (where boxsh is unavailable) and for workflows that need a specific Linux userspace.
    • The docker backend takes no per-agent knobs. The image, the in-container user (anna, UID 1000), and bind-mount layout are all fixed by the shipped image. When anna itself runs inside a container and talks to a host docker daemon (Docker-outside-of-Docker), set the ANNA_HOME_HOST environment variable — anna auto-derives the path translation from it.
    • Docker backend does not currently implement whitelist network mode or HTTP mediation — it fails closed, the same as boxsh. Use disabled or allow_all.
    • Docker bind-mounts the workspace root at /home/anna/workspace and each read-only path at /home/anna/readonly/<index>. Scripts that rely on absolute host paths will need to use the in-container path instead.

Example JSON for a docker-backed agent's sandbox field:

{
  "backend": "docker",
  "network": { "mode": "allow_all" }
}

Environment Variables

The old ANNA_* prefix overrides for all config fields are removed. Only the following environment variables are recognized:

VariablePurpose
ANNA_HOMEOverride the home directory (default ~/.anna)
ANNA_HOME_HOSTHost-side path of ANNA_HOME when anna runs inside a container and talks to a host docker daemon (Docker-outside-of-Docker). Required in that setup; ignored otherwise.
ANTHROPIC_API_KEYFallback API key for the Anthropic provider
ANTHROPIC_BASE_URLFallback base URL for the Anthropic provider
OPENAI_API_KEYFallback API key for the OpenAI provider
OPENAI_BASE_URLFallback base URL for the OpenAI provider

All other configuration must be set through the admin panel (anna --open) or directly in the database.

Memory Defaults

Lossless Context Management settings are currently hardcoded defaults. They will become configurable in a future release.

SettingDefaultDescription
Fresh tail count20Number of recent messages kept verbatim in context
Context threshold0.75Fraction of context window that triggers compaction
Leaf chunk size10Number of messages grouped per leaf summary

Heartbeat

Heartbeat only runs in server mode (anna). Configuration is stored in the settings table under the heartbeat key. Each tick first uses the fast model to decide skip vs run, and only run decisions are sent into the main heartbeat session and then delivered through the notifier. Instructions are read from the agent's HEARTBEAT.md file.

Plugins

Plugins are stored in the settings table under the plugins key as a JSON array. Each entry has a path to a JS file and an optional config object:

[
  { "path": "~/plugins/hello.js" },
  { "path": "/abs/path/notify.js", "config": { "webhook_url": "https://example.com" } }
]

Runtime Plugin Bindings

Subprocess plugin bindings are stored separately under the runtime_plugins key:

{
  "tools": {
    "read": "tool/read",
    "bash": "tool/bash"
  },
  "channels": {
    "telegram": "channel/telegram",
    "qq": "channel/qq"
  }
}

These bindings control which runtime plugin ID handles each built-in tool or channel slot. If a slot has no explicit override, anna falls back to the bundled first-party plugin for that slot. Use anna plugin runtime list to inspect the effective bindings and anna plugin runtime bind ... to change them.

On this page