What is a Connector
A connector is a channel through which you interact with Alice. Each connector represents one surface — a Web UI tab, a Telegram chat, an MCP endpoint. Alice doesn't care which one you use; she gives the same answer regardless of where you ask.
The Connector Interface
Every connector implements a simple contract:
Connector
├── channel "web" | "telegram" | "mcp-ask"
├── to recipient identifier
├── capabilities
│ ├── push can send messages proactively?
│ └── media can send images?
├── send() deliver a completed message
└── sendStream() stream AI response in real-time (optional)
Push vs Pull — This is the key distinction between connectors:
| Connector | Mode | Description |
|---|---|---|
| Web UI | Push | Proactively sends messages via SSE. Supports streaming. |
| Telegram | Push | Proactively sends messages via bot API. |
| MCP Ask | Pull | External agents call Alice — she can't initiate. send() is a no-op. |
Push-capable connectors receive heartbeat notifications, cron results, and other automated messages. Pull-based connectors only respond when called.
ConnectorCenter
The ConnectorCenter sits above individual connectors and handles two things:
Last-Interacted Routing
ConnectorCenter tracks which channel you last interacted through. When something needs to reach you — a heartbeat alert, a cron job result, or any automated notification — it goes to that channel.
You chat via Web UI → last-interacted = "web"
Heartbeat fires → notification goes to Web UI
You switch to Telegram → last-interacted = "telegram"
Heartbeat fires → notification goes to Telegram
If no interaction has happened yet, it falls back to the first registered connector.
Delivery Methods
- notify(text) — Send to the last-interacted connector
- notifyStream(stream) — Stream to the last-interacted connector (falls back to
send()if the connector doesn't support streaming) - broadcast(text) — Send to all push-capable connectors
Connector Lifecycle
Connectors are managed as plugins:
- Core plugins (Web UI, main MCP) — Always-on, started at boot. Cannot be toggled.
- Optional plugins (Telegram, MCP Ask) — Toggleable at runtime. Enable/disable by editing
connectors.json; the reconnect system handles start/stop.
Each plugin registers its Connector with ConnectorCenter on start and unregisters on stop. The registration returns an unsubscribe function for clean teardown.
Message Flow
When Alice generates a response during automated execution (cron or heartbeat), the flow is:
CronEngine fires event
→ EventLog 'cron.fire'
→ CronListener picks it up
→ AgentCenter processes (full AI pipeline)
→ ConnectorCenter.notify(result)
→ Routes to last-interacted connector
→ Delivered to you
When you initiate a message, the flow goes the other direction — your connector receives the input, routes it through AgentCenter, and streams the response back through the same connector.
Sessions per Connector
Each connector maintains independent sessions:
| Connector | Session Path |
|---|---|
| Web UI (default) | data/sessions/web/default.jsonl |
| Web UI (sub-channel) | data/sessions/web/{channelId}.jsonl |
| Telegram | data/sessions/telegram/{chatId}.jsonl |
| MCP Ask | data/sessions/mcp-ask__{sessionId}.jsonl |
| Cron | data/sessions/cron/default.jsonl |
Conversations are completely independent across connectors. Chatting in Telegram doesn't affect your Web UI history.