Files
flynn/config/default.yaml
T
2026-02-20 00:02:11 -08:00

594 lines
21 KiB
YAML

# 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
# require_mention: false # Default false: respond to all allowed group messages
# Optional: Signal via signal-cli
# signal:
# account: "+15551234567"
# signal_cli_path: signal-cli
# allowed_numbers: [] # Empty = allow all DMs
# allowed_group_ids: [] # Empty = no groups
# require_mention: true
# mention_name: flynn
# poll_interval_ms: 5000
# send_timeout_ms: 15000
# Optional: Mattermost
# mattermost:
# server_url: ${MATTERMOST_SERVER_URL}
# bot_token: ${MATTERMOST_BOT_TOKEN}
# allowed_channel_ids: [] # Empty = allow all channels (pairing/mention rules still apply)
# require_mention: true
# mention_name: flynn
# poll_interval_ms: 3000
# Optional: Microsoft Teams (Bot Framework)
# teams:
# app_id: ${TEAMS_APP_ID}
# app_password: ${TEAMS_APP_PASSWORD}
# allowed_conversation_ids: [] # Empty = allow all conversations
# require_mention: true
# Optional: Google Chat
# google_chat:
# service_account_key_file: ~/.config/flynn/google-chat-service-account.json
# # or inline via env var expansion:
# # service_account_json: ${GOOGLE_CHAT_SERVICE_ACCOUNT_JSON}
# webhook_token: ${GOOGLE_CHAT_WEBHOOK_TOKEN}
# allowed_space_names: [] # Empty = allow all spaces
# require_mention: true
# Optional: iMessage via BlueBubbles
# bluebubbles:
# endpoint: http://localhost:1234
# api_key: ${BLUEBUBBLES_API_KEY}
# webhook_token: ${BLUEBUBBLES_WEBHOOK_TOKEN}
# allowed_chat_guids: [] # Empty = allow all chats
# require_mention: true
# mention_name: flynn
# Optional: LINE
# line:
# channel_access_token: ${LINE_CHANNEL_ACCESS_TOKEN}
# channel_secret: ${LINE_CHANNEL_SECRET}
# allowed_source_ids: [] # Empty = allow all users/groups/rooms
# require_mention: true
# mention_name: flynn
# Optional: Feishu / Lark
# feishu:
# app_id: ${FEISHU_APP_ID}
# app_secret: ${FEISHU_APP_SECRET}
# webhook_token: ${FEISHU_WEBHOOK_TOKEN}
# allowed_chat_ids: [] # Empty = allow all chats
# require_mention: true
# mention_name: flynn
# endpoint: https://open.feishu.cn
# Optional: Zalo
# zalo:
# oa_access_token: ${ZALO_OA_ACCESS_TOKEN}
# webhook_token: ${ZALO_WEBHOOK_TOKEN}
# allowed_user_ids: [] # Empty = allow all users
# require_mention: true
# mention_name: flynn
# endpoint: https://openapi.zalo.me
server:
# Tailscale Serve config (optional). Enable `serve: true` to expose the
# gateway to your tailnet via `tailscale serve`.
tailscale:
serve: false
localhost: false
port: 18800
# Maximum inbound HTTP request body size (bytes) for webhooks/Gmail push.
max_request_body_bytes: 1048576
ws_rate_limit:
enabled: true
capacity: 30
refill_per_sec: 15
max_violations: 8
violation_window_ms: 10000
# Per-session FIFO lane queue for gateway requests.
queue:
mode: collect # collect | followup | steer | steer_backlog | interrupt
cap: 50 # max queued (pending) requests per session lane
overflow: drop_old # drop_old | drop_new
debounce_ms: 0 # delay before starting next queued request
summarize_overflow: true
overrides:
channels: {} # e.g. ws: { mode: followup, cap: 10, debounce_ms: 100 }
sessions: {} # e.g. ws:vip-user: { mode: interrupt, overflow: drop_new }
# Companion-node capability negotiation surface (default disabled).
nodes:
enabled: false
allowed_roles: [companion]
feature_gates: {}
location:
enabled: false
push:
enabled: false
# Optional WebChat push subscription endpoints for PWA notifications.
# Set `enabled: true` and provide a VAPID public key for PushManager.
webchat_push:
enabled: false
# vapid_public_key: ${WEBCHAT_VAPID_PUBLIC_KEY}
max_subscriptions: 5000
# Local-network service discovery (mDNS/Bonjour). Keep disabled by default.
# Requires server.localhost: false so LAN clients can actually connect.
discovery:
enabled: false
service_name: flynn-gateway
service_type: _flynn._tcp
txt: {}
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
# api_keys: ["${ANTHROPIC_API_KEY_PRIMARY}", "${ANTHROPIC_API_KEY_SECONDARY}"] # Optional rotation pool
# supports_audio: false # Override native audio detection per tier
fast:
provider: anthropic
model: claude-haiku-4-5-20251001
complex:
provider: anthropic
model: claude-opus-4-6-20250715
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]
# Optional: external CLI backends for non-tool conversation turns.
# - native remains available unless you disable it.
# - set `default` to route normal text turns to a backend by default.
# - per-agent override is available via `agent_configs.<name>.backend`.
# backends:
# default: codex # claude_code | opencode | codex | gemini
# native:
# enabled: true
# claude_code:
# enabled: false
# # path: /usr/local/bin/claude
# # args: ["--print", "{prompt}"]
# # timeout_ms: 120000
# opencode:
# enabled: false
# # path: /usr/local/bin/opencode
# # args: ["-p", "{prompt}"]
# # timeout_ms: 120000
# codex:
# enabled: false
# # path: /usr/local/bin/codex
# # args: ["-p", "{prompt}"]
# # timeout_ms: 120000
# gemini:
# enabled: false
# # path: /usr/local/bin/gemini
# # args: ["-p", "{prompt}"]
# # timeout_ms: 120000
# Optional: Kubernetes / homelab awareness tools (k8s.pods, k8s.deployments, k8s.logs)
# k8s:
# enabled: false
# kubectl_path: kubectl
# default_namespace: default
# allowed_namespaces: [] # Empty = allow any namespace; set to restrict access.
# Optional: Browser automation tools (browser.navigate/screenshot/click/type/content/eval/evaluate)
# Requires a local Chrome/Chromium install or a remote CDP endpoint.
# browser:
# enabled: true
# # executable_path: /usr/bin/google-chrome
# # ws_endpoint: ws://127.0.0.1:9222/devtools/browser/<id>
# headless: true
# max_pages: 5
# default_timeout: 30000
#
# Tool policy reminder:
# - `tools.profile: coding` or `tools.profile: full` must allow browser.* tools.
# - `tools.deny` patterns can still block browser.* even when browser.enabled is true.
hooks:
confirm:
- shell.*
- process.start
- process.kill
- browser.*
- message.send
- cron.create
- cron.delete
- 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
agents:
# In full-access mode, sensitive operations are gated by HookEngine confirmation
# (instead of requiring temporary /elevate windows).
sensitive_mode: confirm_without_elevation
# ── Prompt Assembly ───────────────────────────────────────────────────
# Tune how much context Flynn loads into the system prompt.
#
# prompt:
# search_dirs: []
# extra_sections: []
# context_level: normal # minimal | normal | detailed | debug
# Optional: named agent profiles and routing.
# Each agent can pin model tier, tool profile, sandbox mode, and execution backend.
#
# agent_configs:
# assistant:
# system_prompt: You are helpful.
# model_tier: default
# backend: native # native | codex | claude_code | opencode | gemini
# coder:
# system_prompt: Write code.
# model_tier: complex
# backend: codex
# sandbox: true
#
# routing:
# default_agent: assistant
# channels:
# telegram: assistant
# senders:
# telegram:admin: coder
# ── Context Compaction ────────────────────────────────────────────────
# Optional proactive context monitoring and checkpointing.
#
# compaction:
# enabled: true
# threshold_pct: 80
# keep_turns: 4
# summary_max_tokens: 1024
# importance_threshold: 1
# proactive:
# enabled: false
# warn_pct: 75
# checkpoint_pct: 85
# auto_compact_pct: 95
# checkpoint_cooldown_ms: 300000
# memory_namespace: session/checkpoints
# skills:
# # Registry catalog source for discovery and install-by-id:
# # local path or HTTPS URL. Can also be set via FLYNN_SKILLS_REGISTRY_SOURCE.
# registry_source: ~/.config/flynn/skills-registry.json
# # 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:
# # shared_session: keep one session per cron job/webhook name.
# # isolated_job: create a fresh session per cron trigger/webhook request.
# # announce: create a fresh announce-style run per trigger (no shared automation history).
# delivery_mode: shared_session
# reactions:
# - name: boss-email
# on: [gmail]
# filter:
# contains: "boss@company.com"
# run: |
# Summarize this email and propose next actions.
#
# {{text}}
#
# - name: github-main-push
# on: [webhook]
# filter:
# metadata:
# webhookName: github-push
# body.ref: refs/heads/main
# run: |
# Summarize this deploy-relevant push:
# {{metadata.body.head_commit.message}}
# cron:
# - name: daily-summary
# schedule: "0 9 * * *"
# message: "Give me a summary of today's tasks"
# output:
# channel: telegram
# peer: "123456789"
# once_per_local_day: false
#
# # Optional built-in morning briefing job (auto-registered as a cron job)
# daily_briefing:
# enabled: false
# name: daily-briefing
# schedule: "0 8 * * *"
# timezone: America/New_York
# dedupe_per_local_day: true
# output:
# channel: telegram
# peer: "123456789"
# model_tier: fast
# prompt: |
# Create my daily briefing.
# Summarize today's calendar, unread/important email, and top pending tasks.
#
# # Optional scheduled MinIO -> memory synchronization
# minio_sync:
# enabled: false
# interval: "6h"
# run_on_start: false
# notify_on_success: false
# notify:
# channel: telegram
# peer: "123456789"
# tasks:
# - prefix: "knowledge/"
# namespace_base: "global/knowledge/minio"
# mode: append
# max_objects: 20
# max_chars_per_object: 8000
# force: false
#
# 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"
# notify_cooldown: "30m"
# checks: [gateway, model, channels, memory, disk, process_memory, backup, provider_errors]
# notify:
# channel: telegram
# peer: "123456789"
# failure_threshold: 2
# disk_threshold_mb: 100
# process_memory_threshold_mb: 1500
# backup_failure_threshold: 1
# provider_error_rate_threshold: 0.5
# provider_error_min_calls: 5
automation:
heartbeat:
enabled: true
interval: "5m"
notify_cooldown: "30m"
checks: [gateway, model, channels, memory, disk, process_memory, backup, provider_errors]
failure_threshold: 2
disk_threshold_mb: 100
process_memory_threshold_mb: 1500
backup_failure_threshold: 1
provider_error_rate_threshold: 0.5
provider_error_min_calls: 5
# ── Backup ──────────────────────────────────────────────────────────
# Snapshot sessions.db, vectors.db (optional), and memory/ into a tarball.
# If MinIO is enabled, upload with `mc` using ephemeral credentials.
# LINE/Zalo adapters also reuse backup.minio credentials for binary-attachment
# URL sharing when those channels are configured.
#
# backup:
# enabled: false
# # Optional cron schedule (takes precedence over interval), e.g. nightly at 2 AM.
# schedule: "0 2 * * *"
# interval: "24h"
# run_on_start: false
# notify:
# channel: telegram
# peer: "123456789"
# failure_threshold: 1
# notify_recovery: true
# local_dir: ~/.local/share/flynn/backups
# include_vectors: true
# minio:
# enabled: false
# endpoint: localhost:9000
# access_key: ${MINIO_ACCESS_KEY}
# secret_key: ${MINIO_SECRET_KEY}
# bucket: flynn-backups
# prefix: flynn
# secure: true
# ── Session Lifecycle ───────────────────────────────────────────────
# sessions:
# ttl: "30d"
# end_summary:
# enabled: false
# tier: fast
# max_messages: 50
# max_input_chars: 20000
# max_tokens: 512
# write_to_memory: true
# memory_namespace: session/summaries
# ── 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)
# talk_mode:
# enabled: false
# wake_phrase: "hey flynn"
# timeout_ms: 120000
# allow_manual_toggle: true
# ── Text-to-Speech (TTS) Output ──────────────────────────────────────
# Optional voice output for assistant replies. Uses an OpenAI-compatible
# /v1/audio/speech endpoint and attaches audio to channel replies.
#
# tts:
# enabled: false
# enabled_channels: [telegram, whatsapp, discord] # Empty = all channels
# provider:
# type: openai # openai | custom
# endpoint: "https://api.openai.com/v1/audio/speech"
# api_key: "${OPENAI_API_KEY}" # Optional Bearer token
# model: "gpt-4o-mini-tts"
# voice: "alloy"
# format: "mp3" # mp3 | wav | opus
# ── Sub-Agent Configs ────────────────────────────────────────────────
# Named agent configurations for delegation via agent.delegate tool.
# Each agent gets a focused system prompt, model tier, and tool profile.
#
# agent_configs:
# research:
# model_tier: default
# tool_profile: messaging
# system_prompt: |
# You are a research agent. Your job is to find, verify, and synthesize
# information from the web. Be thorough but concise. Cite sources when
# possible. Return structured findings — not conversational filler.
# Use web.search to find sources and web.fetch to read them.
#
# code:
# model_tier: complex
# tool_profile: coding
# system_prompt: |
# You are a code agent. Your job is to read, write, debug, refactor,
# and review code. You have full access to the filesystem and shell.
# Be precise. Read files before modifying them. Run tests after changes.
# Use file.edit/file.patch for surgical edits, not full file rewrites.
# Commit conventions: conventional commits, small atomic changes.
#
# comms:
# model_tier: fast
# tool_profile: messaging
# system_prompt: |
# You are a communications agent. Your job is to draft messages,
# summarize emails, triage inbox items, and prepare quick replies.
# Be concise and match the operator's tone. Skip marketing emails.
# Never send messages without explicit instruction — draft only.
# Optional: explicit intent rules for agent routing.
# If enabled, these rules are evaluated before default sender/channel routing.
# The research agent can already be auto-routed by prefix (`research ...`, `look up ...`)
# when agent_configs.research exists and intents are disabled.
#
# intents:
# enabled: true
# match_threshold: 0.7
# rules:
# - name: route-research
# patterns: ["research *", "look up *", "lookup *"]
# target:
# type: agent
# name: research
# priority: 10
# enabled: true