Telegram bot for running local Codex sessions from Telegram chats.
Windows is the primary runtime target. CI also runs a basic Ubuntu sanity check.
- Receives Telegram messages and runs them through local
codex exec/codex exec resume. - Sends plain text messages as Codex prompts (no command prefix required).
- Supports multiple local chats (
alias) inside one Telegram chat. - Stores and reuses
session_idper local chat. - Switches Codex accounts by replacing
auth.json. - Can auto-switch accounts when configured limit markers are detected.
- Supports per-chat runtime settings: model, reasoning, sandbox mode.
- Supports session file workflows: attach, clone/export/sync for VSCode views.
- Python
>=3.13 - Codex CLI installed and available in
PATH - Telegram bot token
- At least one Codex account with file-based auth (
auth.json)
python -m pip install -e .Copy the example and fill required fields:
Copy-Item config.example.json config.jsonFor a quick first run, keep allowed_chat_ids as an empty list ([]).
After the bot works, use /chatid and set an explicit allow-list.
Set at least:
telegram_tokencodex.cwdcodex.state_diraccounts[].auth_file
Optional but useful:
codex.limit_markersfor auto account switch behavioraccounts[].extra_filesif your auth setup requires extra files
Make sure accounts[].auth_file points to a real file before running checks.
Example (PowerShell):
New-Item -ItemType Directory -Path accounts\acc1 -Force | Out-Null
Copy-Item C:\path\to\real\auth.json accounts\acc1\auth.jsoncodex-dispatcherShort alias after install:
cdxOr with explicit config path:
codex-dispatcher C:\path\to\codex-dispatcher\config.jsonRead-only CLI snapshots (without Telegram polling):
codex-dispatcher --accounts
codex-dispatcher --status-chat-id 123456
codex-dispatcher --health-chat-id 123456
codex-dispatcher --threads-chat-id 123456SDK-backed state updates (without Telegram polling):
codex-dispatcher --new-chat 123456 bugfix
codex-dispatcher --use-chat 123456 bugfix
codex-dispatcher --set-model 123456 gpt-5.4
codex-dispatcher --set-reasoning 123456 high
codex-dispatcher --set-sandbox 123456 workspace-writeSDK-backed session and VSCode flows (without Telegram polling):
codex-dispatcher --attach-session 123456 019d....
codex-dispatcher --clone-vscode 123456
codex-dispatcher --export-vscode 123456
codex-dispatcher --sync-vscode 123456
codex-dispatcher --delete-vscode-copy <cloned-session-id>Run a prompt from CLI via SDK (without Telegram polling):
codex-dispatcher --ask 123456 "summarize this repository"Recommended structured SDK CLI mode (no sdk prefix):
codex-dispatcher status 123456
codex-dispatcher threads 123456
codex-dispatcher new-chat 123456 bugfix
codex-dispatcher set-model 123456 gpt-5.4
codex-dispatcher ask 123456 "summarize this repository"Same commands with short alias:
cdx status 123456
cdx threads 123456
cdx ask 123456 "summarize this repository"Backward-compatible legacy form is still supported:
codex-dispatcher sdk status 123456Use one of these checks:
codex-dispatcher --checkor
python scripts/check_env.pyThe checker validates token/binary/workspace/state-dir/account file basics and prints actionable issues.
Problem: Config file not found ...- Fix: copy
config.example.jsontoconfig.jsonor pass an explicit config path.
- Fix: copy
Problem: Telegram token looks invalid or placeholder.- Fix: set a real
telegram_tokeninconfig.json.
- Fix: set a real
Problem: Codex binary was not found ...- Fix: install Codex CLI or set
codex.binaryto a valid executable path.
- Fix: install Codex CLI or set
Problem: account 'acc1' auth_file is missing ...- Fix: point
accounts[].auth_fileto a real auth file and rerun--check.
- Fix: point
- Telegram says
This bot is not enabled for this chat.- Fix: start with
allowed_chat_ids: [], then run/chatidand lock it down.
- Fix: start with
If setup still fails, run codex-dispatcher --check again and then /health after startup.
codex-dispatcher- Send
/start - Send a plain text prompt, for example:
summarize this repository - Check state with
/status - Run
/chatidand lock downallowed_chat_idsinconfig.jsonif needed
/start
<send plain text prompt>
/status
/sessionid
Use this when validating that routing and session creation work end-to-end.
Local chats are separate tracked contexts (alias) inside one Telegram chat.
/newchat bugfix
/ask inspect failing tests
/newchat docs
/use bugfix
/threads
These settings apply to the currently active local chat.
/model gpt-5.4
/reasoning high
/sandbox workspace-write
/settings
Attach is useful when you already have a session id or rollout file and want to continue it in the active local chat.
/attachsession <session_id>
or
/attachsession C:\path\to\rollout-....jsonl
clonecreates a temporary independent view copy.exportsafely writes a local chat to VSCode home without overwriting.syncexplicitly updates an existing VSCode copy.
/clonevscode
/deletevscodecopy <id>
/exportvscode
/syncvscode
/accounts
/switch acc2
If codex.auto_switch_on_limit is enabled, the bot can also switch accounts automatically on detected limit markers.
Use /help for grouped command list and /help <command> (or /doc <command>) for mini docs.
/start/help [command]
/ask <text>/newchat [alias]/threads/use <alias>/status/sessionid/resetchat/attachsession <session_id_or_path>
/accounts/switch <account>/settings/model <name|default>/reasoning <low|medium|high|xhigh|default>/sandbox <read-only|workspace-write|danger-full-access|default>/edit on|off|full|default/fullaccess
/clonevscode [title]/deletevscodecopy <cloned_session_id>/exportvscode [alias]/syncvscode [alias]
/health/chatid
Typing / in Telegram also shows command hints published by the bot.
You can drive the same orchestration layer from Python without Telegram:
from codex_dispatcher.sdk import Dispatcher
dispatcher = Dispatcher.from_config("config.json")
code, report = dispatcher.check()
status = dispatcher.status(chat_id=123456)The SDK currently exposes first-step high-level methods for checks, chat/session state, settings, and prompt execution.
See docs/sdk.md for method map and practical examples.
danger-full-accessdisables sandbox protections and approvals. Use only when you understand the risk.workspace-writeandread-onlyare safer defaults for most tasks.- Session file operations (
attach,clone,export,sync) can change what session data is linked or copied. Make sure you understand which session id/path you are using.
- The execution queue is sequential: one Codex run at a time.
- The bot stores runtime state in
data/bot_state.json. codex.state_diracts as sharedCODEX_HOMEfor Codex runs.- Avoid running other tools that mutate the same auth files in the same
state_dirduring bot execution.
Codex did not finish successfully.- Check return code and bot logs for command output.
- Auto-switch on limits did not trigger.
- Update
codex.limit_markersto match your real limit text.
- Update
/attachsessioncannot find session.- Use a valid session id from
session_index.jsonlor a valid rollout file path.
- Use a valid session id from
- VSCode view copy looks stale.
- Reopen or refresh VSCode view, or create a fresh clone.
Use purge utility to remove a specific session from a selected Codex home.
Preview only:
python -m codex_dispatcher.purge_codex_session <session-id> --home C:\Users\<your-user>\.codexApply changes:
python -m codex_dispatcher.purge_codex_session <session-id> --home C:\Users\<your-user>\.codex --applyThe utility updates:
state_5.sqlitesession_index.jsonl- rollout history file
- related SQLite links (if present)
Backups are created in backups/purge-<timestamp>/.
python -m unittest discover -s tests -vCHANGELOG.mddocs/architecture.mddocs/sdk.mddocs/release_notes_v0.1.0.mddocs/release_notes_v0.1.1.mddocs/release_checklist.mdRELEASE.mdCONTRIBUTING.mdSECURITY.mdCODE_OF_CONDUCT.md
Apache 2.0 - see LICENSE.