Skip to main content
The Conversation Hub carries a conversation across channels. A topic started on Telegram continues when you open chatcli on your notebook; what you answer in the notebook becomes context on Telegram/Slack/WhatsApp. Both sides stay in sync — without you repeating anything.
The hub is a momentary bridge, not long-term memory. It keeps the current conversation in sync across channels, with a bounded database (automatic pruning). Persistent memory across projects/sessions is still the memory system (/memory) and /session save.

How it works

  • Principal: the shared conversation identity. In single-user mode (the default), the local CLI and the gateway collapse to the same principal (default if you set nothing), so everything shares with zero configuration.
  • hub.db: an append-only SQLite log (~/.chatcli/hub.db). The CLI and the gateway daemon open the same file — that is how they understand each other across processes.
  • Ephemeral per session: opening chatcli starts a fresh conversation and the previous one is pruned — the database never grows and you don’t load a giant history. Conversations idle past the TTL (CHATCLI_HUB_TTL_HOURS, default 24h) are swept.
  • Silent: turns from other channels enter the model’s context without being printed in your prompt (no noise, no “press Enter to continue”).
  • /newsession resets the shared conversation for every channel.
It works in chat, /agent and /coder: the request and the final answer cross channels (tool-execution detail stays local on each machine).

Modes

The simplest case — chatcli + gateway on one notebook, zero configuration (the default principal is enough):
export CHATCLI_TELEGRAM_BOT_TOKEN=123:abc
chatcli                 # opens the REPL (enters local hub mode)
# inside it:
/gateway start          # starts the daemon, inheriting the environment
Talk on the notebook, then pick up the topic on Telegram → it has the context. Send on Telegram with the prompt open → it enters the context of the notebook’s next turn.
Cross-process, the notebook picks up context on its next turn (there is no live push into an already-open prompt). For real time, use the co-located mode below.

Commands

/hub whoami                         # your principal and the active conversation
/hub bind telegram 123 alice        # bind a channel identity to a principal
/hub bindings [principal]           # list channel→principal bindings
Hub settings are mutable at runtime and persist in hub.db (read live by the gateway, no restart):
/config hub                         # panel: effective value + source (setting/env/default)
/config hub set principal alice
/config hub set isolate on
/config hub set ttl_hours 72
/config hub reset principal         # back to env/default
Resolution precedence: setting (db) > environment variable > default.

Shared identity (single-user vs multi-user)

ScenarioConfigurationResult
Just you (notebook + personal bot)nothing (or CHATCLI_HUB_PRINCIPAL=me)everything collapses to one principal → one shared conversation
Multi-user/public botCHATCLI_HUB_ISOLATE=true (+ bindings)each identity isolated; bindings merge whoever you choose

Relationship to memory and sessions

MechanismForPersistence
Conversation Hubcross-channel context of the current conversationephemeral/bounded (prune + TTL)
Memory (/memory)long-term facts/learningspermanent
Sessions (/session save)explicit conversation snapshotJSON file
The hub is an additive parallel rail: local history, /session save and memory keep working exactly as before.

Observability — the hub never dies silently

Continuity depends on the hub being up, so every state it can be in is explicit in the log:
  • Hub active: the daemon logs gateway: conversation hub active (principal=…, isolate=…, idle_ttl=…) at boot; the CLI logs local hub mode enabled.
  • Hub disabled: a Warn names the exact source of the decisiondb setting enabled=false, env CHATCLI_HUB_ENABLED=false or default — instead of simply making continuity vanish.
  • Daemon serving without the hub (database unreachable): a once-per-run warning makes it clear replies have no cross-channel context.
The daemon inherits the environment of the shell that ran /gateway start, and .env does not override already-exported variables. A forgotten CHATCLI_HUB_ENABLED=false in the shell kills continuity even with a correct .env — the provenance log above exists precisely to catch that (ps eww <pid> confirms the process’s real environment).

See also