William Valentin b9b70ce2b1 feat: add per-tier fallback support to ModelRouter
The router now accepts a tierFallbacks map so each model tier can have
its own fallback providers. Tier fallbacks are tried before the global
fallback chain in both chat() and chatStream().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:09:38 -08:00
2026-02-05 13:07:09 -08:00

Flynn

Self-hosted personal AI assistant with Telegram and Terminal interfaces.

Features

  • Multi-Frontend: Telegram bot + Terminal UI (minimal & fullscreen modes) + Web UI dashboard
  • Multi-Model: Anthropic Claude, OpenAI, GitHub Copilot, Gemini, Bedrock, Ollama, llama.cpp with intelligent routing
  • Multi-Channel: Telegram, Discord, Slack, WhatsApp with unified adapter interface
  • Web Dashboard: SPA control panel with health monitoring, chat, session browser, and settings editor
  • Model Switching: Switch between cloud/local models on demand
  • Session Persistence: SQLite-backed conversation history
  • Fallback Chains: Automatic failover when primary model fails
  • Hook Engine: Confirmation system for sensitive operations
  • Tool Framework: Shell, file, web-fetch, web-search, browser control, image analysis, media send
  • Docker Sandboxing: Per-session container isolation for tool execution
  • Multi-Agent Routing: Config-driven agent selection per sender/channel with tool profiles
  • Media Pipeline: Image analysis, outbound attachments, audio transcription across all channels
  • Session Transfer: Move conversations between frontends
  • CLI: Full command-line interface (flynn start, send, doctor, etc.)
  • Cron Scheduling: Automated messages on cron schedules with output routing
  • Health Diagnostics: flynn doctor validates config, connectivity, and system state
  • MCP Integration: External tool servers via Model Context Protocol
  • Skills System: Extensible capability packages (bundled, managed, workspace tiers)

Quick Start

# Install dependencies
pnpm install

# Copy and configure
cp config/default.yaml ~/.config/flynn/config.yaml
# Edit config with your API keys and Telegram bot token

# Build and run
pnpm build
flynn start

# Or run without building
pnpm start

CLI Commands

Flynn provides a full CLI via the flynn binary (or npx tsx src/cli/index.ts during development):

Command Description
flynn start Start the Flynn daemon (Telegram, WebChat, cron)
flynn tui Launch the interactive terminal UI
flynn send <message> Send a one-shot message and print the response
flynn sessions List active sessions
flynn doctor Validate config and check system health
flynn config Show resolved configuration (secrets redacted)

Examples

# Start daemon with custom config
flynn start --config ~/my-config.yaml

# One-shot query
flynn send "What's the weather in London?"

# Check system health
flynn doctor --config ~/.config/flynn/config.yaml

# Show current config (secrets masked)
flynn config

# List sessions
flynn sessions

Configuration

Config location: ~/.config/flynn/config.yaml (or set FLYNN_CONFIG)

telegram:
  bot_token: "your-telegram-bot-token"
  allowed_chat_ids: [123456789]  # Your Telegram user ID

models:
  default:
    provider: anthropic
    model: claude-opus-4-5-20251101
    api_key: sk-ant-api03-...
  local:
    provider: ollama
    model: qwen2.5:14b
  fallback_chain: [local]

hooks:
  confirm: [shell.*, file.write]
  log: [web.*, file.read]
  silent: [notify]

Model Providers

Provider Config
Anthropic provider: anthropic, api_key or auth_token
OpenAI provider: openai, api_key, optional endpoint
GitHub Copilot provider: github, auto-login via OAuth device flow
Gemini provider: gemini, api_key
Bedrock provider: bedrock, AWS credentials
Ollama provider: ollama, model, optional endpoint
llama.cpp provider: llamacpp, endpoint

Model Tiers

Configure multiple models for different purposes:

models:
  fast: { provider: anthropic, model: claude-sonnet-4-... }
  default: { provider: anthropic, model: claude-opus-4-5-... }
  complex: { provider: anthropic, model: claude-opus-4-5-... }
  local: { provider: ollama, model: qwen2.5:14b }

Telegram Commands

Command Description
/start Initialize bot
/reset Clear conversation history
/status Show current model and status
/local Switch to local model
/cloud Switch to cloud model
/model Show model info and options

Web UI Dashboard

Flynn includes a built-in web control dashboard served by the WebSocket gateway. Access it at http://localhost:18800 (or your configured gateway port).

Pages

Page Description
Dashboard System health cards, channel status, usage stats. Auto-refreshes every 10s
Chat Session selector, streaming tool events, markdown rendering with syntax highlighting
Sessions Browse all sessions, view message history, delete sessions
Settings Edit hook patterns (confirm/log/silent), view tools, channels, and redacted config

The dashboard is a vanilla JS SPA with no build step — hash-based routing, ES modules, and the existing WebSocket JSON-RPC protocol.

Terminal UI

# Minimal mode (readline)
pnpm tui

# Fullscreen mode (React/Ink)
pnpm tui:fs

TUI Commands

Command Description
/help Show help
/reset Clear history
/status Show session info
/fullscreen Switch to fullscreen mode
/transfer telegram Transfer session to Telegram
/quit Exit

Running as Service

# Create systemd user service
mkdir -p ~/.config/systemd/user

cat > ~/.config/systemd/user/flynn.service << 'EOF'
[Unit]
Description=Flynn Personal AI Assistant
After=network.target ollama.service

[Service]
Type=simple
WorkingDirectory=/path/to/flynn
ExecStart=/usr/bin/pnpm start
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production

[Install]
WantedBy=default.target
EOF

# Enable and start
systemctl --user daemon-reload
systemctl --user enable --now flynn

# View logs
journalctl --user -u flynn -f

Hook Engine

Control sensitive operations with pattern matching:

hooks:
  confirm:    # Requires user approval via Telegram
    - shell.*
    - file.write
  log:        # Logs but doesn't block
    - web.*
    - file.read
  silent:     # Executes without notification
    - notify

Cron Scheduling

Schedule automated messages on cron schedules. Each job fires an inbound message through the agent pipeline and routes the response to a configured output channel.

automation:
  cron:
    - name: daily-summary
      schedule: "0 9 * * *"            # 9 AM daily
      message: "Give me a summary of today's tasks"
      output:
        channel: telegram               # Route response to Telegram
        peer: "123456789"               # Chat ID to send to
      timezone: Europe/London           # Optional timezone
      enabled: true

    - name: hourly-check
      schedule: "0 * * * *"            # Every hour
      message: "Check system status"
      output:
        channel: telegram
        peer: "123456789"
      enabled: false                    # Disabled, won't fire

Cron Config Fields

Field Required Description
name yes Unique job identifier
schedule yes Cron expression (standard 5-field)
message yes Text sent to the agent when the job fires
output.channel yes Channel name to route the response (e.g. telegram)
output.peer yes Peer/chat ID on the output channel
timezone no IANA timezone (defaults to system timezone)
enabled no Whether the job is active (default: true)

Doctor Diagnostics

flynn doctor runs 10 health checks to validate your setup:

$ flynn doctor

Flynn Doctor
============

[PASS] Config file exists (/home/user/.config/flynn/config.yaml)
[PASS] Config parses (valid YAML)
[PASS] Config validates (schema valid)
[PASS] Env vars resolved
[PASS] Data directory writable (/home/user/.local/share/flynn)
[PASS] Session DB accessible (sessions.db)
[PASS] Model connectivity (anthropic: claude-sonnet)
[PASS] Telegram bot configured (1 allowed chat(s))
[SKIP] MCP servers configured (none configured)
[PASS] Skills loaded (3 skill(s))

Results: 8 passed, 0 failed, 0 warnings, 1 skipped

Check Details

Check What it validates
Config file exists Config YAML file is present at the expected path
Config parses File is valid YAML syntax
Config validates YAML content passes Zod schema validation
Env vars resolved Any ${VAR} references in config have values set
Data directory writable Can write to ~/.local/share/flynn/
Session DB accessible SQLite database opens and queries succeed
Model connectivity Default model provider and model name are configured
Telegram bot configured Bot token is present and reasonable length
MCP servers configured Lists configured MCP tool servers
Skills loaded Discovers and loads skill packages

Exit code is 1 if any check fails, 0 otherwise. Checks that depend on a valid config are skipped when config is invalid.

Session Management

  • Sessions persist in ~/.local/share/flynn/sessions.db
  • Session ID format: {frontend}:{userId} (e.g., telegram:123456789)
  • History survives restarts
  • Transfer sessions between frontends with /transfer

Architecture

src/
├── agents/               # Multi-agent routing
├── auth/                 # OAuth flows (GitHub Copilot)
├── backends/native/      # Agent implementation + orchestrator
├── channels/             # Channel adapters (Telegram, Discord, Slack, WhatsApp, WebChat)
├── cli/                  # CLI commands (commander)
├── config/               # YAML config + Zod validation
├── context/              # Token estimation + compaction
├── daemon/               # Lifecycle management + routing
├── frontends/
│   ├── telegram/         # Telegram bot
│   └── tui/              # Terminal UI (minimal + fullscreen)
├── gateway/              # WebSocket gateway + web UI dashboard
│   ├── handlers/         # JSON-RPC method handlers
│   └── ui/               # SPA dashboard (vanilla JS)
│       ├── pages/        # Dashboard, Chat, Sessions, Settings
│       └── lib/          # WebSocket RPC client
├── hooks/                # Confirmation engine
├── mcp/                  # MCP tool server integration
├── memory/               # Persistent memory store
├── models/               # Model providers + router + media pipeline
├── prompt/               # System prompt templating
├── sandbox/              # Docker sandboxing
├── session/              # SQLite persistence
├── skills/               # Skill packages
├── tools/                # Builtin tools (shell, file, web, browser, process, media)
└── automation/           # Cron scheduler

Development

# Dev mode with watch
pnpm dev          # Daemon
pnpm tui:dev      # TUI

# Type check
pnpm typecheck

# Lint
pnpm lint

# Test
pnpm test

Environment Variables

Variable Description
FLYNN_CONFIG Override config path
ANTHROPIC_API_KEY Anthropic API key (fallback)
OPENAI_API_KEY OpenAI API key (fallback)

License

MIT

S
Description
flynn personal assistant - inspired by OpenClaw but implemented only with Pi
Readme 6.9 MiB
Languages
TypeScript 92.3%
JavaScript 6.4%
HTML 0.4%
Swift 0.3%
Makefile 0.2%
Other 0.1%