Skip to content

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CodexProxy(cpx)

外挂在官方 Codex CLI 上的本地小代理:单静态二进制(Go,CGO_ENABLED=0)、零外部服务依赖、 不改 ~/.codex/config.toml、不装证书。

默认观察两个问题:① 上游声明的模型是否匹配请求;② STATE 是否符合本地预设格式。 可选开启 M2 STATE 维护,在后台采集、复验并注入票据。格式符合或模型声明匹配都不等于回答能力得到保证。 其余统计量只进审计台账(~/.codexproxy/audit.jsonl)与 cpx report。


1. 下载

平台 文件
Ubuntu / Debian x86_64 cpx-0.1.1-linux-amd64.tar.gz
Ubuntu / Debian ARM64 cpx-0.1.1-linux-arm64.tar.gz
macOS Apple Silicon cpx-0.1.1-darwin-arm64.tar.gz
macOS Intel(amd64) cpx-0.1.1-darwin-amd64.tar.gz

下载页:https://github.com/LyleLiu666/CodexProxy/releases/latest(四个包的 tar.gz + SHA256SUMS)。 文件名里的 darwin 就是 macOS(内核名):Darwin arm64 = Apple Silicon,Darwin x86_64 = Intel, Linux x86_64 / Linux aarch64 = linux-amd64 / linux-arm64。用 uname -s 与 uname -m 核对即可。 已发布的 0.1.1 包自带 5 个文件:cpx(单文件静态二进制,8–9 MB)、README.md、linux.md、model-check.md、 check-model.py(离线体检脚本,使用不需要它,见 §6.8)。校验:shasum -a 256 -c SHA256SUMS。

从源码构建见 §6.3。

2. 安装(一条命令,无需 sudo)

tar -xzf cpx-0.1.1-linux-amd64.tar.gz
cd cpx-0.1.1-linux-amd64
./cpx install --add-path      # 装到 ~/.local/bin,并把该目录幂等写进 shell 启动文件
source ~/.profile             # Ubuntu/bash;zsh 用 ~/.zshrc;或直接重开一个 SSH 窗口
cpx version                   # 确认可用(source 后仍 command not found → 执行 hash -r)

cpx install 只写两处:~/.local/bin/cpx 和 shell 启动文件里的一行 PATH;不用 sudo、不碰系统目录、可重复执行。 真实使用需要官方 codex CLI 且已 codex login(npm i -g @openai/codex;可选依赖见 §6.1)。 不需要 codex 也能安装与自检。

从源码装 / 升级(macOS 与 Linux 通用):make install —— 构建当前平台 + 装到 ~/.local/bin + 报告 PATH 状态。

3. 运行

cpx tui        # ← 主推:进入 codex TUI,下方挂 2 行实时状态面板(需要 tmux)
cpx            # 不带面板:等价于 codex(参数原样透传)
cpx selftest   # 建议首次跑一次:内置假上游自证整条链路,不需要 codex / 登录 / 联网
  • cpx tui 需要 tmux:sudo apt install tmux(macOS:brew install tmux)。没装时它会打印安装命令并 停止本次启动,不会静默降级;此时直接用 cpx,功能不受影响。
  • 已在 tmux 内 → 直接上下分屏;不在 tmux 内 → 自动建会话并 attach(Ctrl-b d 分离)。
  • 环境排查:cpx doctor(codex 路径、登录态、审计目录、监听、代理路由)。

4. 你会看到什么

面板(cpx tui 下方 2 行,独立窗格,不与 TUI 抢终端):

当前 turn 4 · 模型 ✔ · STATE 格式 292 字符 ✔
累计 · 模型正确 4 次 / 错误 0 次 · STATE 格式 292 字符符合 4 次 / 312 字符不符 0 次

STATE 显示实际字符数,默认要求为 292;✔ / ✗ 是格式检查结果,— 表示没有凭证或无法判断(不计入正确 / 错误)。 模型按请求计数,凭证按检查次数计数(请求携带与服务端返回分别计数);第一行优先显示本次服务端返回的凭证。

退出摘要(每个会话一行;有降级/错误时多一行"明细"):

cpx: 本次会话 s-1a2b3c4d:2 请求 / 1 turns,模型 ⚠ 被替换 1 次(gpt-6-astra → gpt-5.6-sol),STATE ✔ 格式符合(见过 292 字符×2);客户端携带 1 次 / 未携带 1 次 · 上游签发新凭证 1 张
cpx: 明细:cpx report --session s-1a2b3c4d(实时:cpx watch)

事后报告(cpx report,按 turn 归组):

STATE 格式: ✔ 格式符合
  见过的长度: 292 字符×2
  来源: 客户端携带 1 次 / 未携带 1 次 · 上游签发新凭证 1 张 · 客户端带的是上游此前签发的凭证

三者同一套口径:先说结论(模型声明是否一致、STATE 格式是否符合规则),再给可直接核对的证据;判不过的凭证按原因分类 (非法 base64 / 封装不识别 / 签发时间越界 / 长度不符 / 长度非标准),不把格式检查当成上游有效性验证。

5. 常用命令

命令 说明
cpx 主形态:包裹运行 codex(参数原样透传)
cpx tui TUI + 下方 2 行状态面板(tmux 分屏)
cpx report 事后报告:按 turn 归组(--session/--json/--fail-on-degrade)
cpx watch [路径] 实时跟读审计日志(一行一条;--raw 原始 JSONL)
cpx status 当前会话状态块(--session <id> 只认本会话,--follow 持续刷新)
cpx selftest 一条命令自证:内置假上游跑完整链路(无需 codex / 登录 / 联网)
cpx doctor 自检:codex / 登录态 / 审计目录 / 监听 / 代理路由
cpx install [--add-path] 把自己装到 ~/.local/bin(无需 sudo)
cpx serve 只启动常驻代理(IDE 插件等自行指向端口)
cpx version 版本

6. 扩展能力(都不是日常路径,按需取用)

6.1 可选依赖

依赖 用途 安装
codex CLI 真实使用(cpx 是它的代理层) npm i -g @openai/codex,首次 codex login
tmux cpx tui 的实时状态面板 sudo apt install tmux / brew install tmux
libnotify-bin(Linux) 降级桌面通知(notify_on_mismatch) sudo apt install libnotify-bin

6.2 配置(可选)

~/.codexproxy/config.toml:

listen = "127.0.0.1:0"            # 默认随机端口
upstream_base = "https://chatgpt.com"
audit_enabled = true
audit_log = "~/.codexproxy/audit.jsonl"
status_file = "~/.codexproxy/status.json"   # cpx status / tmux 面板读取
notify_on_mismatch = false        # 首次降级发一条 macOS 通知(cpx tui 默认开)

[ticket]                          # M2 实验特性,默认关
enabled = false
allow_without_ticket = false      # 无已复验 STATE 时拒绝请求;显式设 true 才原样转发
models = ["gpt-6-astra", "gpt-5.6-sol"]
target_length = 292
ttl_seconds = 3600
refresh_before_seconds = 600
min_probe_interval_seconds = 60
cooldown_seconds = 300
harvest_proxy_url = ""            # 可选采集代理;复验和业务仍用原出口

环境变量覆盖:CPX_CONFIG、CPX_AUDIT_LOG、CPX_STATUS_FILE、CPX_UPSTREAM_BASE、CPX_LISTEN、 CPX_CODEX_BIN、CPX_NOTIFY、CPX_SESSION(由 cpx tui 注入,面板与主进程共享会话 id)。

6.3 审计与状态文件

  • 文件:~/.codexproxy/audit.jsonl(目录 0700、文件 0600),只追加,绝不含 token / 凭证原文
  • 字段:time、path、session、seq、thread、turn、turn_ordinal、request_kind、 turn_started_at、client_ticket、upstream_ticket、request_model、upstream_model、upstream_model_mismatch、 upstream_header_model(CLI 自己使用的 openai-model 响应头)、upstream_model_conflict (头/体自述不一致)、service_tier、stream、status、duration_ms、upstream_request_id、error、 client_closed(客户端读到终局事件后自行断流——SSE 的正常行为,不计入转发错误)、 client_ticket_len / client_ticket_ok / upstream_ticket_len / upstream_ticket_ok (凭证只记「长度 + 形状判定」)、client_ticket_blocks / client_ticket_issued_unix / client_ticket_id / client_ticket_shape(上游侧为同名的 upstream_ticket_*) (凭证只记长度、块数、签发时间、形状原因和一个短哈希;凭证原文绝不落盘)
  • 判定语义:响应模型为空 → 不判定;大小写不敏感;终态事件(response.completed / failed / incomplete / cancelled / done)声明的模型优先
  • 错误语义:上游 HTTP 4xx/5xx 记为请求错误;上游流在客户端仍在读时被切断记为传输错误并中止下游响应;客户端主动断开(codex 拿到终局事件就挂断、用户 Ctrl-C)记为 client_closed,不计入错误
  • 凭证语义(纯被动监控):x-codex-turn-state 是「57 字节头(版本字节 + 大端 unix 秒签发时间)
    • N 个 16 字节块」的封装,长度由块数推出:10 块 = 292 字符(默认规则)、11 块 = 312、 12 块 = 332。验收看「封装可解析且块数 == ticket.target_length 对应块数」 (docs/design.md §5.3);判不过的凭证按原因分类(base64 / envelope / timestamp / blocks / length)。历史长度/前缀兼容规则标记为 legacy,只用于被动观察,不可用于主动发布票据
  • 格式结论:所有交付面都先说「STATE ✔ 格式符合」或「STATE ✗ 格式不符(原因)」,再给证据(见过的长度、 来源、最近一张的短哈希与签发时间)。cpx watch 每条请求带 [STATE 格式 ✔ 292 字符 a1b2c3d4] 或 [STATE 格式 ✗ 长度不符(312 字符) a1b2c3d4]
  • 状态文件:status_file 按会话隔离(~/.codexproxy/status-<会话>.json,0600、原子写), 面板与 cpx status 都读它;cpx status 不带参数时读最新的一个
  • 定位到具体请求:cpx report(默认只列降级/错误行,--all 展开、--json 给脚本、 --fail-on-degrade 给 CI、--session all 看历史);cpx watch 可边跑边看

6.4 行为边界(都经过测试)

  • 退出码:cpx 返回 codex 的退出码;被信号杀死时按 shell 惯例映射为 128+N(Ctrl-C → 130,SIGTERM → 143)。
  • 监听:默认只绑回环。listen 配成非回环(如 0.0.0.0:8788)会被拒绝——那等于把你的账号借给任何能访问该端口的人;确需如此请显式 CPX_ALLOW_REMOTE=1(仍会打出警告)。
  • 上游地址:upstream_base 必须带 http:///https://,否则加载配置时就报错(而不是每个请求 502)。
  • 压缩响应:gzip 响应体会被解压后只用于审计观测,转发给 codex 的字节完全不变;压缩的 SSE 流会标记为"体未观测",而不是假装"没有矛盾"。
  • 净化:模型名/档位/请求 id 等上游可控字段在渲染前会剥离控制字符并截断——说谎的上游无法向你的终端注入转义序列。
  • 审计日志:解析时跳过损坏/超长(>4 MiB)行并计数,单行异常不会吞掉整份报告。
  • 凭证检查(被动):只读已经流过的请求/响应(不采集、不注入、不重放);分类失败只影响那一行的显示,转发字节完全不变。
  • 默认行为:M2 关闭时不新增探测或注入;开启后会增加后台探测,并可能向原本没有 STATE 的请求注入已复验票据。

6.5 它是怎么工作的

cpx [codex 参数...]
  ├─ 启动 127.0.0.1 随机端口上的进程内代理
  ├─ spawn codex,临时注入(不落盘):
  │    -c model_provider=cpx
  │    -c model_providers.cpx.base_url="http://127.0.0.1:<port>/backend-api/codex"
  │    -c model_providers.cpx.requires_openai_auth=true   (复用 codex login 登录态)
  │    -c model_providers.cpx.supports_websockets=false
  │    + 环境变量 NO_PROXY=127.0.0.1,localhost
  ├─ 请求:codex ──HTTP──▶ cpx ──▶ https://chatgpt.com/backend-api/codex/...
  │      · SSE 逐帧透传(不缓冲、不改语义),tee 观测
  │      · 回源自动走 HTTPS_PROXY 环境变量或 macOS 系统代理(scutil)
  └─ codex 退出 → 打印本次会话审计摘要

M0 实测发现:macOS 的系统代理会劫持(本机)loopback 请求,且 reqwest 不遵守例外列表, 因此 cpx 必须给 codex 子进程注入 NO_PROXY;反之 cpx 回源 chatgpt.com 时必须自己走系统代理。 细节见 m0/experiment1.md。 -c features.respect_system_proxy=false 实测无效(见 m0/experiment1.md 追加实验)。 CLI 侧行为考证(turn-state 契约、openai-model 头、provider schema):docs/codex-source-notes.md。

6.6 从源码构建 / 交叉编译 / 推到远端

make build                 # 生成 dist/cpx
make install               # 本机装好:构建当前平台 → ~/.local/bin → 报告 PATH 状态(macOS/Linux 通用)
make cross                 # darwin/arm64+amd64、linux/arm64+amd64、windows/amd64(CGO_ENABLED=0)
make release               # → dist/release/cpx-<版本>-<平台>.tar.gz ×4 + SHA256SUMS

# 有 ssh 直达时,一条命令推到远端并自检(自动识别远端系统/架构:linux 与 macOS 都支持)
make push HOST=user@ubuntu
make push HOST=user@macbook DIR=bin        # 换目录

# 没有 ssh 直达时手工三步(以 Ubuntu 为例)
scp dist/cpx-linux-amd64 user@ubuntu:/tmp/cpx
ssh user@ubuntu 'chmod +x /tmp/cpx && /tmp/cpx install --add-path'
ssh user@ubuntu 'source ~/.profile && cpx doctor'

单个二进制约 8–9 MB、静态链接,Ubuntu 20.04+ 直接跑(不需要 glibc 版本对齐、不需要运行时依赖)。 macOS 侧同样:下载包里的 darwin-arm64/amd64 二进制与本机 make install 装的是同一个(Mach-O、无外部依赖), 升级就是再跑一次 make install,或解压新的 darwin 包执行 ./cpx install。 Linux 细节(systemd 常驻、代理环境变量、通知、容器 E2E 实录)见 docs/linux.md。

6.7 M2 STATE 维护与对照探针(实验特性,默认关闭)

M2 已在当前源码实现:采集候选 STATE → 日常业务出口复验 → 内存缓存 → 未携带 STATE 的请求注入 → 提前续期与异常作废。 开启方式及完整边界见 M2 使用说明。已发布的 0.1.1 安装包不因此自动获得此功能;当前源码构建标识为 0.2.0-dev。

  • 默认拒绝首次采集中、采集失败或票据过期时的新请求(503);显式设置 allow_without_ticket = true 才会在无票据时原样转发。
  • 已有 CLI STATE 不覆盖、不因票据空窗而拒绝,也不自动重放请求。
  • 默认 60 分钟 TTL、提前 10 分钟续期、采集最低间隔 60 秒、失败冷却 300 秒。
  • 票据不落盘;按账号、OAuth token、模型与业务出口配置隔离。
  • 面板、watch、report 和退出摘要记录 M2 实际动作;没有注入时不宣称已生效。
  • 当前验证为受控上游自动化,真实账号上的模型路由、能力和并发收益仍待验证。

已有独立对照探针(会消耗账号配额):

make probe
./dist/cpx-probe -mode harvest -n 5 -out m0/probe-harvest.jsonl
./dist/cpx-probe -mode ab -n 20 -out m0/probe-ab.jsonl

采集成功要求 HTTP 成功、完整成功响应模型匹配、头体不矛盾及严格 STATE 格式校验。 A/B 交替执行带 STATE / 不带 STATE,记录完整成功且模型匹配的次数、耗时和错误;没有采到可用候选时返回非零退出码。 独立探针使用日常出口;可选 harvest_proxy_url 用于 M2 后台维护。

6.8 离线体检脚本 check-model.py(默认不主推)

check-model.py 与 cpx 一起打进安装包(在解压目录里),用来体检"这台机器、这个账号、这条链路"。 日常不需要它——面板 / 报告 / 摘要已经回答了两个业务问题。

# 在解压出来的包目录里:只跑本地链路自检(不联网、不用账号、无副作用)
python3 check-model.py --binary ./cpx --offline
# 在源码仓库里:
python3 scripts/check-model.py --binary dist/cpx --offline

去掉 --offline 会额外跑一份内置遗传学题目(默认 3 轮、gpt-5.6-sol / medium), 会消耗已登录账号的配额,只在"刚换网络 / 刚换账号 / 怀疑固定被降级"时用:

python3 check-model.py --archive cpx-0.1.1-linux-amd64.tar.gz       # 需要 codex 已登录

标准答案 46.24,答出 48 只标记"答题异常",不据此断言换模型或凭证失效;每轮独立审计、答案与汇总都落盘。 只需 Python 标准库。详细用法与判定口径见 docs/model-check.md。

6.9 安全与合规

  • 只监听 127.0.0.1;不修改用户配置、不装根证书、不接管系统流量。
  • 日志与报错不含 Authorization、access_token、凭证原文。
  • STATE 采集/注入默认关闭;实验请求使用自己的账号并消耗配额。本项目与 OpenAI 无任何关联。
  • 被动格式检查与 M2 主动维护分别记录;长度/封装规则不是上游有效性或模型能力的证明。
  • loopback 端口可被同机其他进程访问(等于借用你的账号转发)——介意时用 cpx wrapper 形态(默认随机端口 + 生命周期跟随进程)。

7. 项目状态

阶段 状态
M0-1 集成链路验证 ✅ 通过(m0/experiment1.md)
M0-2 铸凭证 / M0-3 A/B 增益 ⏳ 待用真实账号运行 dist/cpx-probe
M1 wrapper + 审计 MVP ✅ 本仓库
M2 STATE 维护 当前源码已实现,默认关闭;受控测试通过,真实收益待验证
M3 三平台发布、doctor/watch、文档 部分(doctor/watch 已可用)

8. 开发与文档

make test    # go test ./...
make check   # go test -race + go vet + Python 端到端
make cross   # 五平台交叉编译
e2e/linux/run.sh   # 真 Ubuntu 容器端到端(需 docker;无 codex 登录也能跑)

平台:Linux/Ubuntu 用法见 docs/linux.md(含 systemd、代理环境变量、容器 E2E 实录)。 自动检测说明:docs/model-check.md;降级可视化设计:docs/ux-degradation-report.md; M2:docs/m2.md;整体设计:docs/design.md;CLI 行为考证:docs/codex-source-notes.md。

目录:cmd/cpx(CLI)、cmd/cpx-probe(M0 探针)、e2e/linux(Linux 端到端)、 internal/{config,audit,proxy,upstream,wrapper,auth,ticket,tmux,tty}。 许可:MIT。机制参考 sub2api(LGPL-3.0-or-later)但未复制代码。

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages