# Flynn Configuration
# Copy to ~/.config/flynn/config.yaml and customize

# Log verbosity: debug | info | warn | error | silent (default: info)
# Set to 'debug' to see model fallback details.
# log_level: info

telegram:
  bot_token: ${FLYNN_TELEGRAM_TOKEN}
  allowed_chat_ids: []  # Add your Telegram chat ID

server:
  # Tailscale Serve config (optional). Enable `serve: true` to expose the
  # gateway to your tailnet via `tailscale serve`.
  tailscale:
    serve: false
  localhost: true
  port: 18800

models:
  # ── Model tiers ────────────────────────────────────────────────────
  # Each tier (default, fast, complex, local) defines a primary model.
  # When an Anthropic tier fails, Flynn automatically tries the same
  # model via GitHub Models before falling through to the global chain.
  #
  # You can override auto-fallback with an inline `fallback:` block:
  #
  #   default:
  #     provider: anthropic
  #     model: claude-sonnet-4-20250514
  #     fallback:                          # ← inline per-tier fallback
  #       provider: openai
  #       model: gpt-4o
  #
  # ── Fallback order ─────────────────────────────────────────────────
  # 1. Primary client for the tier
  # 2. Auto same-model fallback via GitHub Models (Anthropic tiers only,
  #    skipped when an inline `fallback:` block is present)
  # 3. Inline `fallback:` client (if configured)
  # 4. Global fallback_chain (tried in order)
  #
  default:
    provider: anthropic
    model: claude-sonnet-4-20250514
    # auth_mode: auto                  # auto | api_key | oauth (provider-specific)
    # use_oauth: false                 # compat alias for auth_mode: oauth
    # supports_audio: false            # Override native audio detection per tier
  local:
    provider: ollama
    model: glm-4.7-flash

  # ── Global fallback chain ──────────────────────────────────────────
  # Entries can be tier names (default, fast, complex, local) or keys
  # from local_providers below. Tried in order after per-tier fallbacks
  # are exhausted.
  fallback_chain: [local]

  # ── Named providers (optional) ─────────────────────────────────────
  # Define additional providers that can be referenced by name in
  # fallback_chain. Useful for secondary API accounts or self-hosted
  # endpoints that aren't tied to a specific tier.
  #
  # Use /backend <name> in the TUI to switch between these providers
  local_providers:
    ollama:
      provider: ollama
      model: glm-4.7-flash
      endpoint: http://localhost:11434
    llamacpp:
      provider: llamacpp
      model: gpt-oss-20b
      endpoint: http://localhost:8080
  #
  # Then reference them in fallback_chain:
  #   fallback_chain: [ollama, llamacpp, local]

hooks:
  confirm:
    - shell.*
    - file.write
    - file.patch
  log:
    - web.*
    - file.read
  silent:
    - notify

# ── Safety Notes ─────────────────────────────────────────────────────
# - Tool policy (tools.profile/allow/deny) controls which tools are available.
# - Skills can declare capability permissions in skills/<name>/manifest.json under `permissions`.
#   Those permissions are enforced at runtime when requests are routed into a skill context.
# - See: docs/security/SAFE_PERSONAL_AGENT.md

# ── Prompt Assembly ───────────────────────────────────────────────────
# Tune how much context Flynn loads into the system prompt.
#
# prompt:
#   search_dirs: []
#   extra_sections: []
#   context_level: normal  # minimal | normal | detailed | debug

# skills:
#   # Global installer execution policy.
#   # disabled: never run installer commands (default)
#   # enabled: allow command execution only with --execute --confirm
#   installation_execution: disabled
#   # Allow shell-based installer runner when --runner shell is requested.
#   allow_shell_runner: false
#   # Allowlist command patterns for shell runner (`*` wildcard supported).
#   # Empty list means no shell commands are allowed.
#   shell_runner_allowlist: []
#   # Governance metadata for shell-runner allowlist and rollout decisions.
#   shell_runner_governance:
#     owner: "skills-team"               # Required when allow_shell_runner is true
#     review_cadence_days: 7              # Review `skills rollout-status` at this cadence
#     promotion_min_success_rate: 0.9     # Rollout threshold for broader enablement

# ── Automation ──────────────────────────────────────────────────────
# Uncomment and configure any automation sources you need.

# automation:
#   cron:
#     - name: daily-summary
#       schedule: "0 9 * * *"
#       message: "Give me a summary of today's tasks"
#       output:
#         channel: telegram
#         peer: "123456789"
#
#   webhooks:
#     - name: github-push
#       secret: "whsec_..."
#       message: "GitHub push to {{json.repository.full_name}}: {{json.head_commit.message}}"
#       output:
#         channel: telegram
#         peer: "123456789"
#
#   gmail:
#     enabled: false
#     credentials_file: ~/.config/flynn/gmail-credentials.json
#     token_file: ~/.config/flynn/gmail-token.json
#
#     # Optional Pub/Sub delivery
#     # Push mode: configure a topic and a push subscription that POSTs to /gmail/push
#     pubsub_topic: projects/your-project/topics/gmail-push
#     disable_push: false
#
#     # Pull mode: no inbound webhook required (requires Application Default Credentials)
#     pubsub_subscription_id: projects/your-project/subscriptions/gmail-pull
#     pubsub_pull_interval: "60s"
#     pubsub_max_messages: 10
#     watch_labels: [INBOX]
#     poll_interval: "60s"
#     message: "New email from {{from}}: {{subject}}\n\n{{snippet}}"
#     output:
#       channel: telegram
#       peer: "123456789"
#
#   heartbeat:
#     enabled: false
#     interval: "5m"
#     checks: [gateway, model, channels, memory, disk]
#     notify:
#       channel: telegram
#       peer: "123456789"
#     failure_threshold: 2
#     disk_threshold_mb: 100

# ── Audio ────────────────────────────────────────────────────────────
# Configure a Whisper-compatible endpoint for audio transcription.
# Models that support native audio input (Gemini, OpenAI, GitHub) will
# receive raw audio directly; others fall back to this endpoint.
#
# For local transcription with whisper.cpp:
#   docker run -d --name whisper-server -p 18801:8080 \
#     ghcr.io/ggml-org/whisper.cpp:main \
#     --model /app/models/ggml-base.en.bin \
#     --host 0.0.0.0 --port 8080 --convert --language en \
#     --inference-path /v1/audio/transcriptions
#
# audio:
#   enabled: true
#   provider:
#     type: custom                            # openai, groq, ollama, llamacpp, custom
#     endpoint: "http://localhost:18801/v1/audio/transcriptions"
#     api_key: "${WHISPER_API_KEY}"            # Optional Bearer token
#     model: "whisper-1"                       # Model name (default: whisper-1)
