Inline settings menu
Adjust Untether's behaviour without editing config files or restarting — tap buttons right in Telegram.
Adjust Untether’s behaviour without editing config files or restarting — tap buttons right in Telegram. The /config command opens an interactive settings menu with inline keyboard buttons, similar to BotFather’s settings style. Navigate sub-pages, toggle settings, and return to the overview, all within a single message that edits in place.
Open the menu
Send /config in any chat:
/config
The home page shows current values grouped under Agent controls, Display and Routing, with buttons arranged in pairs (max 2 per row) for comfortable mobile tap targets:
🐕 Untether settings
Agent controls (Claude Code)
Permission mode: on · approve the plan first
Ask mode: on · interactive questions
Diff preview: off · buttons only
Display
Cost & usage: cost on, sub off
Verbose: off · compact progress
Resume line: on
Routing
Engine: claude (default)
Model: default · from CLI settings
Listen: all · respond to everything
Follow-up: queue · wait for the run
⏰ Triggers: active ← only when triggers are configured
Effort: default · high
[📋 Permission mode] [❓ Ask mode]
[📝 Diff preview] [🔍 Verbose]
[💰 Cost & usage] [↩️ Resume line]
[📡 Listen] [🔁 Loop mode]
[🧠 Reasoning] [⚙️ Engine & model]
[↪️ Follow-up] [ℹ️ About]
[⏰ Triggers] [⏸ Pause triggers] ← only when [triggers] is enabled
📖 Help guides · 🐛 Report a bug
Engine-specific controls
The home page adapts to the current engine. Claude Code shows Permission mode, Ask mode, and Diff preview under “Agent controls”. Codex CLI shows Approval policy (full auto / safe = read-only sandbox). Gemini CLI (deprecated) shows Approval mode (read-only / edit files / full access). Engines without interactive controls (OpenCode, Pi, Amp) skip the agent controls section entirely.
Navigate sub-pages
Tap any button to open that setting’s page. Each sub-page shows:
- A description of the setting
- The current effective value (resolved from override or default — never shows a bare “default” label)
- Buttons to change the value
- A Clear override button to revert to the global/engine default
- A ← Back button to return to the home page
- A 📖 Learn more link to the matching page of the help centre (
littlebearapps.com/help/untether/…)
Toggle behaviour
Most settings use a two-button selection pattern: [On] [Off] [Clear] with a ✓ on the active option. Tap either button to set the value. Tapping Clear removes the per-chat override and falls back to the global setting.
When you tap a setting button:
- Confirmation toast — a brief popup appears confirming the change (e.g. “Permission mode: off (acceptEdits)”, “Verbose: on”). This uses the same toast mechanism as Claude Code approval buttons.
- Auto-return — the menu automatically navigates back to the home page, showing the updated value across all settings. No need to tap “Back” manually.
Multi-state settings
Some settings have more than two states and use a different layout:
- Permission mode (Claude Code) — four options shown in a 2+2+1 split:
[Off] [On]on the first row,[Plan-auto] [Auto]on the second,[Clear override]on the third - Approval mode (Gemini, deprecated) — three options (read-only / edit files / full access)
- Effort (Claude Code) — low / medium / high / xhigh / max
- Reasoning (Codex) — low / medium / high / xhigh
The active option is marked with a ✓ prefix. Tap a different option to switch.
Engine-aware visibility
Settings are engine-specific and only appear when relevant:
- Permission mode — Claude Code only. Codex and Gemini have their own pre-run policies instead.
- Approval policy — Codex CLI only. Toggle between “full auto” (default, Codex’s own sandbox setting) and “safe” (read-only sandbox via
--sandbox read-only; tests, builds and cache//tmpwrites fail too). This is a pre-run policy — not interactive mid-run approval. - Approval mode — Gemini CLI only (deprecated). Toggle between “read-only”, “edit files” (file reads/writes OK, shell commands blocked via
--approval-mode auto_edit), and “full access” (all tools approved via--approval-mode yolo). This is a pre-run policy. Despite its label, “read-only” (also what an unset chat shows) runs Gemini with--approval-mode yolo, i.e. full access — see Interactive approval. - Ask mode and Diff preview — Claude Code only. Hidden for other engines.
- Follow-up — Claude Code only (#775).
queue(default) orsteerfor messages sent while a run is working; see steer follow-ups. Hidden on the home page for other engines; if you reach the page anyway it says that other engines always queue. - Reasoning — Claude Code and Codex only. Hidden for OpenCode, Pi, Gemini, and Amp.
- Engine & model — always visible. Engine and model are merged into a single page. Shows the current engine and model override; to set a model, use
/model set <name>.
When you switch engines via the Engine & model page, the home page automatically shows or hides the relevant controls.
Available settings
| Setting | Options | Persisted |
|---|---|---|
| Permission mode | off, on, plan-auto, auto | Yes (chat prefs) |
| Approval policy | full auto, safe (read-only sandbox) | Yes (chat prefs) |
| Approval mode | read-only, edit files, full access | Yes (chat prefs) |
| Ask mode | off, on | Yes (chat prefs) |
| Verbose | off, on | No (in memory, cleared on restart) |
| Diff preview | off, on | Yes (chat prefs) |
| Engine & model | any configured engine + model | Yes (chat prefs) |
| Effort / Reasoning | Claude: low, medium, high, xhigh, max; Codex: low, medium, high, xhigh | Yes (chat prefs) |
| Cost & usage | API cost, subscription usage, budget, stop at limit | Yes (chat prefs) |
| Resume line | off, on | Yes (chat prefs) |
| Listen | all, mentions | Yes (chat prefs) |
| Follow-up | queue, steer | Yes (chat prefs) |
| Budget | off, on | Yes (chat prefs) |
| Stop at limit | off, on | Yes (chat prefs) |
Approval policy appears instead of Permission mode when the engine is Codex CLI. Approval mode appears instead of Permission mode when the engine is Gemini CLI.
Triggers page
When [triggers] is enabled, the home page gains a bottom row with a ⏰ Triggers button that opens the Triggers page (config:tg), even when nothing is configured yet (the page then explains how to add one). When at least one cron or webhook is configured, the same row also carries the one-tap ⏸ Pause triggers / ▶️ Resume triggers toggle (#296) (#271 Tier 2 + #294).
The Triggers page shows:
- State and counts —
running/paused, plus per-chat cron and webhook totals. - Master pause/resume toggle — tap Pause to suspend all cron firing and webhook dispatch globally without editing config; tap Resume to clear it. While paused, webhooks return
503 triggers paused(withRetry-After: 60), the webhook server’s HTTP/healthendpoint reportspaused: true, and/pingshows⏸ triggers paused: … (suspended). Pause is in-memory only — restart auto-resumes (the safe default). - Per-chat cron list — each line shows the cron
id, human-readable schedule viadescribe_cron(schedule, timezone), project, engine, the cron’s ownmodel=/effort=when it sets one (#743), and last-fired relative time. - Per-chat webhook list — each line shows the webhook
id, path, auth scheme, project, engine, and last-fired.
Lists are scoped to the current chat (crons_for_chat() / webhooks_for_chat() with the bridge default_chat_id fallback), capped at 10 entries with a …and N more (see untether.toml) overflow marker. The pause/resume controls remain visible even when the chat has no triggers configured. 📡 is Listen only; Triggers always use ⏰, matching /ping and the run footer.
See Schedule tasks for the pause flow end-to-end.
Loop mode page
When the active engine is Claude Code, the home page gains a 🔁 Loop mode button that opens the Loop sub-page (#289). Loop mode is off by default — turning it on lets Claude schedule repeated runs: Untether declines Claude Code’s own CronCreate and runs the schedule itself, with the [loop] caps, firing each iteration with claude --resume whether or not the session is still open (#925). With it off, Claude can’t schedule recurring or timed tasks and points you here, or to /at for a one-off. Self-paced wake-ups (ScheduleWakeup) work in both modes, up to max_iterations in a row.
The page shows:
- State —
Currently: On (global)/Off (global)(no per-chat override, so the[loop] enableddefault applies) orOn (per-chat)/Off (per-chat). - Cost + quota warning — explicit reminder before turning ON: every loop fire counts against
[cost_budget], so set a budget first. - 💰 Set a budget — deep-link to the
Cost & Usagepage (config:cu) for one-tap budget setup. - Buttons —
[On] [Off]with ✓ on the active per-chat choice, then[Clear override] [💰 Set a budget]and[← Back].
/cancel and /new both drop pending loop iterations for the current chat (or forum topic); the next message resumes the session without the cancelled loop, and new loops in that session run normally (#926). /continue is unaffected (it doesn’t trigger loop replay).
Loop mode is Claude-only (LOOP_SUPPORTED_ENGINES = frozenset({"claude"})); the button is hidden for other engines. See Schedule tasks → Loop mode for the full architecture and cost guidance.
Cost & Usage page
The Cost & Usage sub-page merges cost display and budget controls into a unified page with toggle rows:
- API cost — per-run cost in the message footer (requires engine cost reporting)
- Subscription usage — 5h/weekly subscription usage in the footer (Claude Code only)
- Budget — turn budget tracking on or off for this chat (overrides global
[cost_budget]setting) - Stop at limit — per-chat override of
[cost_budget] auto_cancel. Stops new runs once the daily budget is reached and ends a session after the reply that passes the per-run budget. It can’t interrupt a reply in progress (see Cost budgets)
Each toggle uses the [✓ Label: on] [Label: off] [Clear] compact pattern (labels distinguish the four toggles). Clear removes the per-chat override and falls back to the global config.
For historical cost data across sessions, use the /stats command.
About page
ℹ️ About shows the Untether version and a py X.Y.Z · <engine> X.Y.Z · … line with the version of each available engine CLI (in alphabetical order) that answers --version (Pi included), plus GitHub, bug-report and feature-request links. The engine CLIs are checked side by side in the background, so the page opens in a few seconds without holding up the bot, and the versions are reused for 5 minutes (#951).
Callbacks vs commands
- Text command (
/config): sends a new message with the menu. - Button tap: edits the existing message in place — no message spam.
All button interactions use early callback answering for instant feedback.
Related
- Plan mode — detailed plan mode documentation
- Interactive approval — approval buttons and engine-specific policies
- Cost budgets — budget configuration and alerts
- Verbose progress — verbose mode details and global config
- Switch engines — engine selection
- Group chat — listen mode in groups