aidaemon 0.7.1

A personal AI agent that runs as a background daemon, accessible via Telegram, Slack, or Discord, with tool use, MCP integration, and persistent memory
# aidaemon configuration
#
# Secrets resolution order:
#   1. "keychain"    → reads from OS credential store (macOS Keychain, etc.)
#   2. "${ENV_VAR}"  → reads from environment variable (for Docker/CI)
#   3. "plain-value" → used as-is (not recommended for production)
#
# The setup wizard stores secrets in the OS keychain automatically.

[provider]
# Provider type: openai_compatible, google_genai, or anthropic
api_key = "keychain"
# api_key = "${AIDAEMON_API_KEY}"
base_url = "https://openrouter.ai/api/v1"

[provider.models]
primary = "openai/gpt-4o"
fast = "openai/gpt-4o-mini"
smart = "anthropic/claude-sonnet-4"

[telegram]
bot_token = "keychain"
# bot_token = "${TELOXIDE_TOKEN}"
allowed_user_ids = [123456789]

[state]
db_path = "aidaemon.db"
working_memory_cap = 50
# consolidation_interval_hours = 6  # How often to run memory consolidation (extract durable facts from conversations)
# encryption_key = "keychain"       # Optional override; default startup uses AIDAEMON_ENCRYPTION_KEY from .env
# encryption_key = "${AIDAEMON_ENCRYPTION_KEY}"

[terminal]
# Set to ["*"] to allow all commands (only if you trust the LLM fully)
allowed_prefixes = ["ls", "cat", "head", "tail", "echo", "date", "whoami", "pwd", "find", "wc", "grep", "tree", "file", "stat", "uname", "df", "du", "ps", "which", "env", "printenv"]

[daemon]
health_port = 8080

# [daemon.queue_policy]
# # Capacity (bounded channels).
# approval_capacity = 16
# media_capacity = 16
# trigger_event_capacity = 64
#
# # Depth thresholds as queue fill ratios (0.0-1.0).
# warning_ratio = 0.75
# overload_ratio = 0.90
#
# # Overload handling.
# # Lane-specific overload and fairness settings.
# [daemon.queue_policy.lanes.approval]
# adaptive_shedding = true
# fair_sessions = true
# fair_session_window_secs = 60
# fair_max_events_per_session = 4
#
# [daemon.queue_policy.lanes.media]
# adaptive_shedding = true
# fair_sessions = true
# fair_session_window_secs = 60
# fair_max_events_per_session = 4
#
# [daemon.queue_policy.lanes.trigger]
# adaptive_shedding = true
# fair_sessions = true
# fair_session_window_secs = 60
# fair_max_events_per_session = 4
#
# # Legacy shared knobs (still accepted; applied to all lanes when lane settings are default).
# # adaptive_shedding = true
# # fair_trigger_sessions = true
# # fair_trigger_session_window_secs = 60
# # fair_trigger_max_events_per_session = 4

# [skills]
# enabled = true
# dir = "skills"    # relative to config.toml location

# [browser]
# enabled = true
# headless = true
# screenshot_width = 1280
# screenshot_height = 720
# # Use an existing Chrome profile to inherit cookies/sessions (e.g. Cloudflare, GitHub, AWS)
# user_data_dir = "~/Library/Application Support/Google/Chrome"
# profile = "Default"    # or "Profile 1", "Profile 2", etc.

# [triggers.email]
# host = "imap.gmail.com"
# port = 993
# username = "you@gmail.com"
# password = "keychain"
# # password = "${AIDAEMON_EMAIL_PASSWORD}"
# folder = "INBOX"

# [search]
# backend = "brave"
# api_key = "keychain"
# # api_key = "${AIDAEMON_SEARCH_API_KEY}"

# [subagents]
# enabled = true
# max_depth = 3            # max nesting levels for sub-agents
# max_iterations = 10      # agentic loop iterations per sub-agent
# max_response_chars = 8000
# timeout_secs = 300       # 5 minute timeout per sub-agent

# [cli_agents]
# enabled = true
# timeout_secs = 600           # default timeout per invocation
# max_output_chars = 16000     # max output before truncation
#
# # Pre-configured tools (auto-discovered on startup via `which`)
# # Override or add your own:
# [cli_agents.tools.claude]
# command = "claude"
# args = ["-p", "--output-format", "json"]
#
# [cli_agents.tools.gemini]
# command = "gemini"
# args = ["-p", "--sandbox=false", "--yolo"]
#
# [cli_agents.tools.codex]
# command = "codex"
# args = ["exec", "--json", "--dangerously-bypass-approvals-and-sandbox"]

# [mcp.filesystem]
# command = "npx"
# args = ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]

# [policy]
# All policy features are enabled by default. Uncomment to override.
# policy_shadow_mode = true          # log old-vs-new routing comparisons
# policy_enforce = true              # use policy-based model routing
# tool_filter_enforce = true         # risk-based tool filtering
# uncertainty_clarify_enforce = true  # ask for clarification on ambiguous requests
# context_refresh_enforce = true      # mid-loop context budget refresh
# learning_evidence_gate_enforce = true  # stricter evidence thresholds for auto-learning
# autotune_shadow = true             # log auto-tune adjustments
# autotune_enforce = true            # apply auto-tune adjustments
# uncertainty_clarify_threshold = 0.55
# classify_retirement_enabled = true
# classify_retirement_window_days = 7
# classify_retirement_max_divergence = 0.05
#
# [policy.write_consistency]
# # Guardrail thresholds for dual-write drift checks.
# max_abs_global_delta = 3
# max_session_mismatch_count = 0
# max_stale_task_starts = 0
# max_missing_message_id_events = 0

[diagnostics]
enabled = true
record_decision_points = true
max_events = 200
include_raw_tool_args = false