Skip to main content
Guides Last updated: 26 May 2026

Routing & sessions

Untether supports both stateless and chat modes for session handling. In stateless mode, each message starts a new session unless you reply to continue. In c...

Nathan Schram
By Nathan Schram Founder, Little Bear Apps

Untether supports both stateless and chat modes for session handling. In stateless mode, each message starts a new session unless you reply to continue. In chat mode, new messages auto-resume the previous session.

Continuation (how threads persist)

Untether supports four ways to continue a thread:

  1. Reply-to-continue (always available)
    • Reply to any bot message that contains a resume line in the footer.
    • Untether extracts the resume token and resumes that engine thread.
    • Reply resume lines always take precedence over chat sessions or topic storage.
    • The resumed run updates the stored session for that engine when the token is known.
  2. Forum topics (optional)
    • Topics can store resume tokens per topic and auto-resume new messages in that topic.
    • Topic state is stored in telegram_topics_state.json.
    • Reset with /new.
  3. Chat sessions (optional)
    • Set session_mode = "chat" to store one resume token per chat (per sender in groups).
    • Stored sessions are per engine; resuming a different engine does not overwrite others.
    • State is stored in telegram_chat_sessions_state.json.
    • Reset with /new.
  4. Cross-environment resume (/continue)
    • Resume the most recent session in the project directory, regardless of where it was started.
    • Useful for picking up a CLI session (iTerm, tmux, mosh) from Telegram while away from the terminal.
    • Uses each engine’s native “continue” flag (--continue, resume --last, --resume latest).
    • Works with Claude, Codex, OpenCode, Pi, and Gemini. Not supported for AMP. See the cross-environment resume guide.

Reply-to-continue works even if topics or chat sessions are enabled.

Listen mode (pre-routing filter)

Before routing, Untether checks the chat’s listen mode (renamed from “trigger mode” in v0.35.3 — #297). In mentions mode, messages that don’t @mention the bot, reply to the bot, or start with a known slash command are silently dropped — they never reach the router. In the default all mode, every message passes through.

Listen mode is configured per chat via /listen (or the deprecated /trigger alias) or /config, with optional per-topic overrides in forum groups. See Group chat for details.

Routing (how Untether picks a runner)

For each message, Untether:

  • parses directive prefixes (/<engine-id>, /<project-alias>, @branch) from the first non-empty line
  • attempts to extract a resume token by polling available runners
  • if a resume token is found, routes to the matching runner; otherwise uses the configured default engine

Serialization (why you don’t get overlapping runs)

Untether allows parallel runs across different threads, but enforces serialization within a thread:

  • Telegram side: jobs are queued FIFO per thread.
  • Runner side: runners enforce per-resume-token locks (so the same session can’t be resumed concurrently).

The precise invariants are specified in the Specification.

Was this helpful?

Related Articles