Volt is a lightweight Zig CLI for local std-IO execution and Telegram gateway setup/runtime.
zig buildRun the CLI:
zig build run -- --helpInstall release binary as volt:
mkdir -p "$HOME/.local/bin"
zig build install -Doptimize=ReleaseFast --prefix "$HOME/.local"Then run:
volt --helpBundle zolt during install if you want Volt to ship its own dispatch dependency:
zig build install -Dwith-zolt=true -Doptimize=ReleaseFast --prefix "$HOME/.local"By default, Volt uses ~/.volt as the workspace root (or --home).
Initialize workspace layout with:
volt initThis creates volt.json and seeds default markdown guidance files for the first-run bootstrap:
AGENTS.md, BOOTSTRAP.md, SOUL.md, TOOLS.md, IDENTITY.md, USER.md, and HEARTBEAT.md.
Use token-only setup:
volt telegram setup --token "<bot_token>"Set zolt defaults (global or account-scoped) with dedicated model commands:
volt model set --provider openai --model gpt-5-chat-latest
volt model set --account work --provider opencode --model claude-sonnet-4-6
volt model show --account work--allow-from is optional. If omitted, Volt allows all chats to use the bot.
No --chat-id is needed for setup; chat ids are discovered from incoming Telegram messages.
- Create a Telegram bot with
@BotFatherand copy the bot token. - Initialize Volt workspace:
volt init- Save the token:
volt telegram setup --token "<bot_token>"- Run Telegram polling in foreground:
volt --telegram --zolt-
Send a message to your bot in Telegram and run
/statusto confirm the active session/model. -
Optional daemon mode (keeps Volt running in background):
volt telegram install --zolt
volt telegram statusUse volt telegram restart ..., volt telegram stop ..., and volt telegram uninstall ... to manage it later.
When --zolt is enabled, Volt resolves provider/model from config in this order:
- account config in
volt.json(zolt.accounts.<account>.provider/model) - global config in
volt.json(zolt.provider/model)
Volt also registers a Telegram slash-command menu (/help, /commands, /sessions, /status, /reset, /models, /model) when the gateway starts, so you can discover commands in the Telegram UI.
Volt can render Telegram responses with Markdown formatting when the reply contains markdown markers (lists, headings, backticks, links, fences).
If Telegram rejects Markdown for a response, Volt automatically retries as plain text.
Telegram image attachments are downloaded into <home>/telegram/media/<account>/<chat_id>/ and injected into zolt prompts as @path references so zolt can inspect them with its image-aware tooling.
In Telegram, send:
/helpto view the menu summary/commandsfor the full command list/sessionsto show the mapped zolt session for this chat/statusto show runtime details, including last provider/model, token usage, context-left estimate, and compaction count when available from zolt JSON output/resetto clear the mapped zolt session/modelsto list models for configured providers only (requires--zolt)/modelto show/set provider+model for the current account (/model <provider> <model>or/model <model>)
To get your chat id, send a message to the bot and inspect chat.id from:
curl -s "https://api.telegram.org/bot<TOKEN>/getUpdates"Enable debug tracing when needed:
VOLT_DEBUG=1 volt --telegram --zoltDebug output prints the exact zolt command line and stdout/stderr snippets in stderr.
Volt can run Telegram polling as a background service:
volt telegram install [--home <path>] [--token <token>] [--account <id>] [--dispatch <command>] [--zolt] [--zolt-path <path>] [--zolt-output <text|json|logs|json-stream>] [--poll-ms <ms>]
volt telegram start|stop|restart|status|uninstall [--home <path>] [--token <token>] [--account <id>] [--dispatch <command>] [--zolt] [--zolt-path <path>] [--zolt-output <text|json|logs|json-stream>] [--poll-ms <ms>]
volt telegram list [--home <path>] [--account <id>]Commands:
install: writes the OS service definition and starts the Telegram worker.start: starts an installed service.stop: stops a running service.restart: restarts a service.status: prints current service status using the native OS service manager.uninstall: stops and removes the service definition.list: shows configured accounts, token/model/provider defaults, mapped chat counts, and which account the service is currently bound to.
Volt can bundle a local zolt checkout so --zolt can run without a preinstalled system zolt binary. When bundling is enabled, Volt prefers:
- local source via
-Dzolt-source=...(or../zoltif present), - dependency named
zoltdeclared inbuild.zig.zon(default points togithub.com/JonathanRiche/zolt).
Options:
-Dwith-zolt=trueto enable bundling (defaults tofalse).-Dzolt-source=<path>to point at a local zolt source checkout.-Dzolt-dependency=<name>to override the dependency key inbuild.zig.zon(defaults tozolt).--zolt-pathflag orVOLT_ZOLT_PATHenv var still override any bundled executable.
Set provider/model defaults with:
volt model set --provider <provider> --model <model> [--account <id>] [--home <path>]
volt model show [--account <id>] [--home <path>]If you want to refresh the zolt package hash yourself:
zig fetch --save git+https://github.com/JonathanRiche/zoltzig build run -- gateway --port 18789 --zoltThen send a POST to:
curl -H "Authorization: Bearer volt-gateway-token" \
-H "Content-Type: application/json" \
-d '{"message":"hello","chat_id":123}' \
http://127.0.0.1:18789/invokeWith --zolt, Volt executes zolt run --session <session_id> {message} and stores Telegram chat/session mappings in:
<home>/credentials/telegram-zolt-sessions.json
Behavior:
- first message for a chat bootstraps a new zolt session (
zolt run --output json <message>); the first message is auto-prefixed with a.voltbootstrap context: workspace layout, key state files, and discovered markdown guidance files. - first successful response writes the returned
session_idinto Volt’s mapping file; - subsequent messages reuse that mapping via
zolt run --session <session_id> <message>; - stale mappings are recreated automatically if zolt returns
session not found.
Gateway session IDs are resolved as:
- explicit
sessionin JSON payload - else
gateway:<account>:<chat_id>whenchat_idis present - else
gateway:<account>
Volt can manage the gateway as a background service:
volt gateway install [--home <path>] [--bind <ip>] [--port <port>] [--account <id>] [--dispatch <command>] [--zolt] [--zolt-path <path>] [--zolt-output <text|json|logs|json-stream>] [--auth-token <token>]
volt gateway start|stop|restart|status|uninstall [--home <path>] [--bind <ip>] [--port <port>] [--account <id>] [--dispatch <command>] [--zolt] [--zolt-path <path>] [--zolt-output <text|json|logs|json-stream>] [--auth-token <token>]Commands:
install: writes the OS service definition and starts the gateway.start: starts an installed service.stop: stops a running service.restart: restarts a service.status: prints current service status using the native OS service manager.uninstall: stops and removes the service definition.
This currently integrates with systemd (Linux) and launchd (macOS).
USAGE.md— command usage, flags, and environment variables.