Build a Channel from Scratch
A channel connects Wolffish to an external communication platform. The desktop UI, Telegram, and WhatsApp are all channels — they receive messages from different sources but route them through the same brain pipeline. This guide walks through implementing a new channel from scratch.What is a Channel?
A channel is aTurnSink implementation. It receives segments (streaming text, tool calls, results) and renders them to the user in whatever format the platform supports. The TurnRunner handles the agent pipeline — your channel just needs to:
- Accept incoming messages from your platform
- Send them into the agent pipeline
- Render the agent’s response back to the user
- Handle approval requests (for dangerous tool calls)
The TurnSink Interface
Methods Explained
Segment Types
- text: Streaming deltas — accumulate them to build the full response
- tool_call: The agent is invoking a tool (show a status indicator)
- tool_result: The tool finished (show output or a summary)
- turn_end: The turn is complete with a stop reason (
end_turn,tool_use,max_tokens)
Step-by-Step Implementation
Step 1: Create the Channel File
Step 2: Implement TurnSink
Step 3: Handle Incoming Messages
When your platform receives a message, load or create a conversation and send it through the TurnRunner:Step 4: Register the Channel
Add your channel to the startup flow insrc/main/index.ts:
The TurnRunner is shared across all channels. It serializes turns per conversation — a conversation’s own turns queue behind each other, but different conversations run in parallel regardless of which channel initiated them.
Per-Conversation Serialization
The TurnRunner keeps one queue per conversation (turns with no conversation id get a private lane keyed by their turn id). A second message in the same conversation waits for that conversation’s current turn to finish — preserving transcript order and preventing races in its memory and context assembly — while a message for a different conversation runs immediately, in parallel.Conversation Mapping
Your channel decides how external threads map to Wolffish conversations:/new.
Reference: Telegram Channel Pattern
The Telegram channel demonstrates the full pattern:Checklist for New Channels
Before shipping your channel:- Implements all
TurnSinkmethods - Handles approval requests with user-facing prompts
- Maps external threads to conversations consistently
- Cleans up
responseBufferononDoneandonError - Handles
onCredentialBlockedwith a helpful message - Registered in main process startup
- Tested with multi-turn conversations
- Tested with tool calls (including failures and cancellation)
- Tested with concurrent messages from multiple channels