Skip to content

Latest commit

 

History

History
160 lines (133 loc) · 8.02 KB

File metadata and controls

160 lines (133 loc) · 8.02 KB

Codex Session Gateway

用于在内网单机环境中,通过 Telegram Bot 绑定指定工作目录(workdir),自动寻找其中最新 Codex Session,与本地 Codex CLI 实时交互的 Python 服务。

功能

  • Telegram 实时对话与流式输出
  • 任务运行状态提示与取消
  • 指令排队与重试
  • 本地 SQLite 记录会话与运行日志

运行环境

  • Python 3.11+
  • 本地可执行的 Codex CLI

运行说明

  • 为避免 The cursor position could not be read within a normal duration,运行 Codex CLI 时默认设置 PROMPT_TOOLKIT_NO_CPR=1TERM=xterm-256color
  • 默认使用 resume_id="auto"(按 codex_workdir 自动选择最新会话);当可解析到会话时,通过 codex exec resume <id>(非交互模式)以保证 Telegram 场景可稳定输出。

快速开始

python -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt

准备配置后启动:

python -m src.main

配置

系统会优先读取 config.toml;不存在时回退到 .env(单 bot 兼容)。

config.toml(推荐,多 bot)

  • base:基础设置(全局共享)
  • bots:每个 bot 一条记录,必须包含 name / token / allowed_user_ids / codex_workdirresume_id 可选(默认 auto
  • 支持 ${ENV:KEY} 占位符,便于把敏感信息放到 .env

resume_id 取值

  • 未配置:默认 "auto"(按 codex_workdir 自动选择最新会话)。
  • 固定值:直接填 Codex Session ID(用于“稳定绑定同一个会话”的场景)。
  • "auto":自动跟随 codex_workdir 目录树下最新的主会话(读取 ~/.codex/sessions/**.jsonlsession_meta.payload.cwd,匹配 codex_workdir 或其子目录;会对路径做 realpath/normpath 归一化)。
    • 会自动忽略 subagent 会话(session_meta.payload.sourcesubagent 的记录)。
    • 用途:当某个会话运行很久导致无法继续 compact,需要在 Codex CLI 中 /new 开新对话时,本系统可自动切换到新 Session。
    • 运行中切换:当 CODEX_JSONL_STREAM_EVENTS=1 且运行中检测到同目录树下出现更新的主会话时,JSONL tailer 会自动切换到最新会话(同样忽略 subagent),避免长任务因会话切换导致“没有输出/拿不到最终结果”。

示例(可参考 config.toml.example):

[base]
db_path = "data/app.db"
lock_path = "data/app.lock"
codex_cli_cmd = "codex"
codex_cli_args = []
codex_cli_input_mode = "stdin"
codex_cli_skip_git_check = true
jsonl_sync_interval_seconds = 3
message_chunk_limit = 3500

[[bots]]
name = "stock"
token = "${ENV:TELEGRAM_BOT_TOKEN_STOCK}"
allowed_user_ids = [123456789]
codex_workdir = "${ENV:CODEX_WORKDIR_STOCK}"

[[bots]]
name = "gateway"
token = "${ENV:TELEGRAM_BOT_TOKEN_GATEWAY}"
allowed_user_ids = [123456789]
codex_workdir = "${ENV:CODEX_WORKDIR_GATEWAY}"

.env(兼容单 bot)

至少需要配置:

  • TELEGRAM_BOT_TOKEN
  • TELEGRAM_ALLOWED_USER_IDS

可选配置:

  • CODEX_WORKDIR:工作目录(未配置时默认使用当前工作目录,通常为 systemd 的 WorkingDirectory
  • CODEX_CLI_RESUME_ID:固定 Session ID 或 "auto";未配置时默认 "auto"(按 CODEX_WORKDIR 自动选择最新会话)

其余基础设置可参考 .env.example(与 base 字段一致)。

基础设置字段说明(base.env 通用)

  • CODEX_CLI_CMD:Codex CLI 命令(默认 codex
  • CODEX_CLI_ARGS:Codex CLI 额外参数(可选)
  • CODEX_CLI_INPUT_MODEstdinarg(默认 stdin
  • CODEX_CLI_APPROVALS_MODE:审批模式(默认 3,等价于输入 /approvals 3
  • CODEX_CLI_SKIP_GIT_CHECK:是否跳过 Git 仓库检查(1/0,默认 1,用于 codex exec
  • CODEX_CLI_USE_PTY:是否使用伪终端(1/0,默认 0,用于解决 stdin is not a terminal
  • DB_PATH:SQLite 路径(默认 data/app.db
  • LOCK_PATH:进程锁文件路径(默认 data/app.lock,用于防止多重启动)
  • STREAM_FLUSH_INTERVAL:输出节流间隔秒数(默认 1.5
  • STREAM_INCLUDE_STDERR:是否显示 stderr(1/0,默认 0
  • PROGRESS_TICK_INTERVAL:进度心跳已废弃,当前版本忽略该配置
  • RUN_TIMEOUT_SECONDS:单次运行超时秒数(示例 10800,约 3 小时)
  • CONTEXT_COMPACTION_IDLE_TIMEOUT_SECONDS:检测到 Context compacted 后无新输出的等待秒数(示例 10800,约 3 小时,用于防止进程卡住)
  • NO_OUTPUT_IDLE_TIMEOUT_SECONDS:长时间无任何输出时的自动结束秒数(示例 10800,约 3 小时,用于防止僵死进程)
  • FINAL_RESULT_IDLE_TIMEOUT_SECONDS:检测到最终结果后无输出的自动结束秒数(示例 10800,约 3 小时,用于防止任务卡住)
  • JSONL_SYNC_INTERVAL_SECONDS:JSONL 同步轮询间隔秒数(默认 3,用于同步本地 CLI 的结果)
  • CODEX_JSONL_STREAM_EVENTS:是否从 Codex JSONL 实时推送事件到 Telegram(1/0,默认 1agent_reasoning 内容会被隐藏)
  • CODEX_JSONL_REASONING_THROTTLE_SECONDS:推送 agent_reasoning 占位提示的最小间隔秒数(默认 10
  • CODEX_JSONL_REASONING_MODE:推理事件展示模式,hidden(不推送)或 summary(安全摘要,默认 summary
  • MESSAGE_CHUNK_LIMIT:单条消息最大长度(默认 3500,实际会被限制在 4096 以内,并自动拆分)

Telegram 指令

  • /new <内容>:新建会话并提交指令(等效 Codex CLI /new <内容>
  • /session:查看会话绑定(只读)
  • /stop:停止当前任务
  • /status:查看状态
  • /retry:重试上一次指令
  • /lastresult:查看最近一次结果
  • /whoami:查看用户与聊天 ID
  • /help:查看帮助

systemd 服务

项目内提供服务文件模板:deploy/codex-session-gateway.service。请按实际路径修改后安装(默认使用 .venv 里的 Python)。 如需在 Codex 指令中调用 systemctl --user,请确保用户 DBus 可用(服务模板已设置 XDG_RUNTIME_DIRDBUS_SESSION_BUS_ADDRESS)。 若仍提示 Failed to connect to bus: No medium found,请启用用户常驻:loginctl enable-linger <用户>

安装示例:

sudo cp deploy/codex-session-gateway.service /etc/systemd/system/codex-session-gateway.service
sudo systemctl daemon-reload
sudo systemctl enable --now codex-session-gateway

查看日志:

sudo journalctl -u codex-session-gateway -f

授权与联网限制(容器/沙箱)

在受限环境中可能出现“有权限但无法联网/无法重启”的情况,常见表现与处理建议如下:

  • sudo: The "no new privileges" flag is set:容器启用了 no-new-privileges,即使允许提权也无法执行 sudo/systemctl
    处理:在宿主机执行重启命令,或调整容器配置关闭该标志;必要时改用用户级服务。
  • Failed to connect to bus: No medium found:用户级 DBus 不可用。
    处理:启用用户常驻 loginctl enable-linger <用户>,并确保 XDG_RUNTIME_DIRDBUS_SESSION_BUS_ADDRESS 已设置。
  • Could not resolve hostname github.com 或 Git 推送失败:运行环境无外网/DNS 被限制。
    处理:在具备外网的主机上执行 git push,或确保运行环境允许外网访问与 DNS 解析。
  • 若需让 Codex CLI 在非交互环境下自动执行审批相关操作:
    处理:在 .envconfig.tomlbase.codex_cli_args 中配置 --dangerously-bypass-approvals-and-sandbox(请谨慎使用)。

安全与审计

  • 安全与敏感信息规范:docs/security.md
  • 最近一次审计报告:docs/audits/2026-01-16-security-audit.md
  • 默认禁用 httpx/httpcore 的 INFO 请求日志,避免 Telegram Bot Token 出现在日志(URL 内嵌 token)。

常见问题与排障

  • 重复发送结果、JobQueue 警告、如何确认运行版本等:docs/troubleshooting.md

文档索引

  • 全量索引:docs/INDEX.md
  • 规划与历史记录:docs/plans/

测试

.venv/bin/python -m pytest -q