Skip to content

feat: Codex CLI Proxy (App-Server Architecture) — PROJECT-SPEC.md#1

Open
sterling-prog wants to merge 4 commits into
mainfrom
build/P120-codex-proxy-app-server
Open

feat: Codex CLI Proxy (App-Server Architecture) — PROJECT-SPEC.md#1
sterling-prog wants to merge 4 commits into
mainfrom
build/P120-codex-proxy-app-server

Conversation

@sterling-prog
Copy link
Copy Markdown
Owner

Summary

Complete TypeScript implementation of the Codex CLI App-Server proxy (P120).

Modules

  • M1 src/client/app-server.ts — AppServerClient: WebSocket JSON-RPC client, thread/turn lifecycle, cleanupDone guard, concurrency+queue, orphan sweep, auth/backend degradation, reconnect with backoff
  • M2 src/adapter/request.ts — Chat Completions → ThreadStartParams/TurnStartParams, multi-turn transcript, injection mitigation (ZWS), model validation against cache
  • M3 src/adapter/response.ts — SSE helpers, error dispatch, keepalive, Retry-After
  • M4 src/server/routes.ts + standalone.ts — Express server, global rate limit, bearer auth, health endpoints (/healthz /readyz), env validation, graceful 30s drain, /tmp/codex-proxy mkdir
  • M5 ecosystem.config.js — PM2 config for codex-app-server + codex-proxy, kill_timeout: 35000, wait_ready
  • Scripts scripts/codex-auth-check.sh — JWT exp decode, 48h Discord alert to #infra-agent-swarm

Build

npm run build — tsc, zero errors

Spec

/home/gpu1/.openclaw/workspace-scope/specs/codex-proxy/PROJECT-SPEC.md

Sterling and others added 4 commits March 21, 2026 20:22
Bug 1: add return after triggerCleanup in emitDelta when accumulatedSize
exceeds maxSize — without it, subsequent deltas still accumulate content
after the error cleanup is triggered.

Bug 2: call triggerCleanup after sendNonStreamingResponse in
onTokenUsageUpdated grace period path — slot was never released,
in-flight entry was never removed, archive never ran.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In onAgentMessageDelta, destructured turnId was never applied to
inflight.turnId. Spec requires: delta notifications themselves carry
turnId and must set inflight.turnId if not already set, triggering
buffer replay. Without this, the race window where deltas arrive before
both turn/start response and turn/started notification leaves the buffer
unresolved until turn/started eventually arrives.

Fix: if !inflight.turnId && turnId, set inflight.turnId = turnId and
call flushDeltaBuffer before falling through to emit current delta.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant