# 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
# # If cli_agent action=run omits "tool", aidaemon auto-picks:
# # claude -> gemini -> codex -> copilot -> aider (first installed)
#
# # Pre-configured tools (auto-discovered on startup via `which`)
# # Override or add your own:
# [cli_agents.tools.claude]
# command = "claude"
# args = ["-p", "--output-format", "stream-json"]
#
# [cli_agents.tools.gemini]
# command = "gemini"
# args = ["--sandbox=false", "--yolo", "--output-format", "stream-json"]
#
# [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