Extends the gateway wire protocol with GatewayAttachment type and
attachment event. agent.send handler now accepts optional attachments
parameter and converts them for the agent pipeline. Includes 5 new
tests for protocol and handler layers.
Introduces OutboundAttachment type on OutboundMessage, an
OutboundAttachmentCollector (push/drain pattern), and a media.send
tool that queues files for outbound delivery. Each channel adapter
(Telegram, Discord, Slack, WhatsApp) sends attachments after the
text reply. Includes 15 tests for collector and tool.
Provides a factory createImageAnalyzeTool(modelClient) that sends images
to a vision-capable model and returns a textual analysis. Includes 15
tests covering base64, URL, multi-image, error, and edge cases.
GitHubModelsClient now lazily resolves tokens at first API call. If no
token exists (env var, stored OAuth, or config), it triggers the OAuth
device flow automatically via an onLoginRequired callback wired in both
the TUI and daemon entry points.
Add a new 'github' model provider backed by the Copilot API
(api.githubcopilot.com), with OAuth device flow for authentication.
- New src/auth/github.ts: device flow login, token storage at
~/.config/flynn/auth.json with 0600 permissions
- New src/models/github.ts: OpenAI-compatible client with streaming,
tool calling, and Copilot-specific headers
- Add 'github' to provider enum in config schema
- Register provider in daemon factory and TUI client factory
- Refactor TUI to use provider-agnostic client factory (was hardcoded
to AnthropicClient for all tiers)
- Add /login command to TUI for interactive OAuth authorization
- Add Copilot model cost tracking entries
Widen Message.content from string to string | MessageContentPart[] to support
multimodal content. Add Attachment type to channel layer, media conversion
utilities, and image extraction to all channel adapters (Telegram, Discord,
Slack, WhatsApp). Update all model clients (Anthropic, OpenAI, Gemini, Bedrock)
to convert structured content to provider-specific formats. Fix downstream
consumers (tokens, compaction, TUI, local models) to handle the widened type
via getMessageText() helper.
Update config schema with server auth fields (token, tailscale_identity,
auth_http), channel mention settings, browser config, and openrouter/bedrock
provider enum values. Wire GeminiClient, BedrockClient, OpenRouter into
createClientFromConfig. Initialize BrowserManager and register browser tools
in daemon startup. Pass auth config and channel mention settings through to
gateway and adapters. Add puppeteer-core, @google/generative-ai, and
@aws-sdk/client-bedrock-runtime dependencies.
Add BrowserManager (puppeteer-core) with page pool and auto-detection of
Chrome/Chromium. Six tools: browser.navigate, browser.screenshot,
browser.click, browser.type, browser.content, browser.eval. Feature is
opt-in (browser.enabled defaults to false). Add to coding tool profile.
Includes 22 unit tests for manager and all tools.
Slack: add requireMention option, resolve bot user ID on connect.
Telegram: add group chat mention/reply-to-bot detection, strip @mention
from message text, default requireMention=true for groups.
WhatsApp: add allowedGroupIds for group chat support, mention detection
via mentionedIds and body text, strip bot mention from messages.
Support ?token= query parameter as a fallback for WebSocket clients that
cannot set Authorization headers (e.g. browsers). Add authHttp option to
GatewayServer so token auth can be applied to HTTP requests too, returning
401 with WWW-Authenticate header on failure.
Add native GeminiClient using @google/generative-ai SDK and BedrockClient
using @aws-sdk/client-bedrock-runtime. Replace the previous Gemini fallback
(OpenAI-compatible shim) with the real implementation. Add OpenRouter as a
provider option (OpenAI-compatible with custom baseURL). Update model costs,
doctor CLI checks, and client factory tests.
The /model command was only updating the router's currentTier but not
the agent's currentTier. Since NativeAgent.chatWithRouter() passes its
own tier to router.chat(), switching to 'local' still sent requests
through the default (Anthropic) client first.
- Extract createClientFromConfig() to dispatch on provider field instead
of hardcoding all tiers as AnthropicClient
- Add fallback/fallbackReason metadata to ChatResponse and ChatStreamEvent
so callers know when a fallback model was used
- Enhance doctor check to report full model stack and warn on missing
API keys for cloud providers
- Log fallback warnings in NativeAgent and display them in TUI
- Support tier names and local_providers entries in fallback_chain
- Add 8 tests for createClientFromConfig covering all provider types
Implements CronScheduler as a ChannelAdapter that fires InboundMessages
on cron schedules and routes agent responses to configured output
channels (e.g. Telegram). Includes 9 tests.
Replace doctor stub with full implementation including checks for:
config existence, YAML parsing, schema validation, env vars,
data directory writability, session DB, model config, Telegram,
MCP servers, and skills loading.
Implement a three-tier skill system (bundled/managed/workspace) that
extends Flynn's abilities via SKILL.md instructions injected into the
system prompt.
- SkillManifest/Skill types with requirements gating (OS, binaries, env)
- Loader: discovers skills from directories, validates manifests,
checks system requirements, infers manifest from SKILL.md if missing
- SkillRegistry: holds skills, generates system prompt additions,
supports override by name (workspace > managed > bundled)
- SkillInstaller: copies/removes skills in managed directory with
upgrade support
- Config: add skills.workspace_dir, managed_dir, bundled_dir options
- Daemon: loads all skills at startup, injects available skill
instructions into the system prompt
- Tests: 45 new tests (loader 22, registry 11, installer 12)
Implement Model Context Protocol (MCP) support so Flynn can spawn MCP
server processes, discover their tools, and make them available to the
agent alongside builtin tools.
- McpClient: wraps @modelcontextprotocol/sdk with StdioClientTransport
for process lifecycle, tool discovery (listTools), and invocation (callTool)
- McpManager: lifecycle management for multiple MCP servers with
startAll/stopAll/restart, tool bridging into ToolRegistry
- Bridge: converts MCP tools to Flynn Tool interface with mcp:<server>:<tool>
namespacing to avoid collisions with builtin tools
- Config: add env and cwd fields to mcp server schema
- ToolRegistry: add unregister() method for MCP server cleanup
- Daemon: wire McpManager into startup and shutdown lifecycle
- Tests: 28 new tests (bridge, manager, registry unregister)
Refactor GatewayServer to serve HTTP and WebSocket on a shared
http.Server. Add static file serving with path traversal protection,
a dark-themed dashboard (system health, sessions, tools) and a
WebSocket chat interface with streaming tool events and markdown
rendering.