Skip to content

Releases: LIMTCYT/opencode-go-proxy-for-trae

v1.2.1 增加429的重试机制

Choose a tag to compare

@LIMTCYT LIMTCYT released this 21 Oct 11:40

v1.2.1 — 增加 429 重试机制

上游偶发返回 429(Endpoint is unavailable)会让 Trae 直接报错、中断任务。实测这类 429 基本都是上游网关的瞬时故障——前后请求都正常,中间夹一条两三秒就返回的 429。

本版本在代理层补齐自动重试,让这类瞬时错误对客户端完全透明。

自动重试

只要尚未向客户端吐出任何数据,就自动重发:

  • 覆盖 5xx,以及错误体含 Endpoint is unavailable 的 429
  • 上限 RETRY_ON_5XX_MAX,默认 10 次
  • 真正的限流类 429 与其他 4xx 不重试

同一故障在新旧路由上状态码不同:新路由 /inference/go/v1 报 503,老路由 /zen/go/v1 报 429,错误体一样。所以判断不只看状态码,还看错误体。

指数退避

429 不立即重试,按指数间隔递增,给服务端留恢复窗口:
4s → 8s → 16s → 32s → 64s → 64s ...

可用 RETRY_429_BACKOFFS 自定义。5xx 仍用 1 秒固定退避。退避期间不阻塞主循环,流式请求的心跳保活照常进行。

非流式请求的重试预算

心跳是 SSE 注释行,非流式请求(期望单个 JSON)用不了。因此改由 RETRY_BUDGET(默认 60 秒)兜底:累计等待超预算就放弃重试、原样透传真实状态码,不拖到客户端超时,也不白跑重试。

修复

  • 慢路径下已提前回 200 后不再重试的问题(心跳只是注释、不含内容,重试本应安全)。

其他

  • 控制台配色:响应状态码不是 200 的行整行标黄,一眼可见。

环境变量

变量 默认 说明
RETRY_ON_5XX_MAX 10 自动重试上限(次),0 关闭
RETRY_429_BACKOFFS 4,8,16,32,64 429 退避序列(秒)
RETRY_BUDGET 60 重试总时长预算(秒),仅非流式生效,0 不限

完整变更记录:CHANGELOG.md

增加ttft和测速,以及自动重请求防止长任务中断机制

Choose a tag to compare

@LIMTCYT LIMTCYT released this 21 Oct 06:29

v1.2.0 — 增加 TTFT 与测速,以及自动重请求防止长任务中断机制

TTFT 与测速

  • 每次请求输出一行 [ttft] 日志:首字延迟、总耗时、输出 token 数、tok/s。这样能分清是"上游不出首字"还是"出字慢",两者处理方式完全不同。
  • 新增只读接口 GET /stats:返回最近 200 条样本的整体与按模型统计(avg / p50 / p95 / min / max / errors)。p95 比平均值更能反映偶发卡死的真实频率。

自动重请求,防止长任务被上游拖死

上游迟迟不响应时,代理按下面的节奏兜底:

  • 30 秒:先回 200 + SSE,之后每 10 秒发一个心跳,让客户端不要自己超时。
  • 60 秒:另开一条连接把同一请求重发一次,谁先回数据用谁。
  • 120 秒:一直静默的连接判定失败。
  • 30 分钟:一直没有内容产出就主动终止,不再扣 token。

边界说明:重发只在还没向客户端吐过数据之前有效——流式过程中断了无法自动续上,否则会产生重复内容;且重发最多 1 次,不会无限重试。

其他调整

  • UPSTREAM_TIMEOUT 改为可配置,默认 120 秒(原固定 600 秒)。
  • 超时改为立即返回 504 并给出明确错误,不再干等;流式中断会下发 SSE error 事件,而不是静默截断。

环境变量

变量 默认 说明
UPSTREAM_TIMEOUT 120 单条上游连接的静默上限(秒)
HEARTBEAT_AFTER 30 多久后开始发心跳(秒,仅流式请求)
RETRY_AFTER 60 多久后重发一次(秒)
HEARTBEAT_INTERVAL 10 心跳间隔(秒)
CONTENT_IDLE_TIMEOUT 1800 多久没有内容产出就终止(秒,0 关闭)
STATS_WINDOW 200 /stats 聚合的样本窗口

无需第三方依赖,Python 3.6+ 直接运行。升级后如遇长任务被兜底中断,调大 CONTENT_IDLE_TIMEOUT 或设为 0。完整变更见 CHANGELOG.md 。

v1.1.0

Choose a tag to compare

@LIMTCYT LIMTCYT released this 13 Oct 07:27

Added

  • 控制台日志高亮显示。

Changed

  • 更新接口说明:OpenCode Go 接口前缀由 /zen/go/v1 切换为 /inference/go/v1(旧路由仍在上游可用),并说明 model ID 需与请求地址配套,填错会报 404。

v1.0.0

Choose a tag to compare

@LIMTCYT LIMTCYT released this 08 Sep 11:45

首个稳定版本

本地反向代理:在 Trae 与 OpenCode Go (Zen API) 之间做完整双向转发,解决 Trae 直连报
Request is missing x-opencode-session 400 错误的问题。

特性

  • 自动注入 OpenCode 要求的会话头:x-opencode-session / x-opencode-request / x-opencode-client / x-opencode-project
  • 模型别名重写:Trae 中填 proxy- 前缀模型名,代理自动还原为真实模型名,避免流量被 Trae 云端通道接管
  • 纯 Python 标准库实现,零第三方依赖,Python 3.6+ 即可运行
  • 完整支持流式(SSE)响应透传
  • 自动会话识别:显式会话 ID > 内容哈希 > 随机(同一对话保持稳定,命中上游提示词缓存)
  • 日志控制台 + 文件双输出,5MB 自动轮转
  • 进程 pid 文件记录,方便管理

快速开始

python opencode-go-proxy-for-trae.py

Trae 自定义模型配置:

配置项 值
请求地址 http://127.0.0.1:9355/zen/go/v1
模型 ID proxy- + 真实模型名(如 proxy-glm-5.3-flash)

详见 README。

许可证

MIT License