Skip to content

[codex] fix passthrough stream idle disconnects - #10

Merged
Ingwannu merged 1 commit into
lidge-jun:mainfrom
Ingwannu:codex/stream-heartbeat
Jun 21, 2026
Merged

[codex] fix passthrough stream idle disconnects#10
Ingwannu merged 1 commit into
lidge-jun:mainfrom
Ingwannu:codex/stream-heartbeat

Conversation

@Ingwannu

Copy link
Copy Markdown
Owner

Summary

  • add heartbeat comments to OpenAI Responses SSE passthrough streams so long silent reasoning does not trip the proxy/client idle path
  • keep non-SSE passthrough responses byte-for-byte unchanged
  • fix systemd service log targets by leaving append: output specifiers unquoted

Root cause

Native GPT requests route through the OpenAI Responses passthrough path. That path relayed upstream SSE bytes verbatim, but it did not emit any keepalive bytes while the upstream was silent. Long reasoning turns could therefore leave the downstream connection idle long enough for the Bun/server-client path to close before a response.completed event arrived, which surfaced as stream disconnected before completion: stream closed before response.completed.

A separate service-unit issue quoted StandardOutput=append:..., which systemd rejected, hiding useful service logs.

Validation

  • bun test tests/passthrough-abort.test.ts tests/passthrough-headers.test.ts tests/service.test.ts
  • bun run typecheck
  • bun test tests
  • restarted opencodex-proxy.service locally and verified /healthz

@Ingwannu
Ingwannu merged commit 1bf3606 into lidge-jun:main Jun 21, 2026
2 checks passed
Ingwannu added a commit that referenced this pull request Jun 21, 2026
Co-authored-by: Ingwannu <ingwannu@users.noreply.github.com>
lidge-jun added a commit that referenced this pull request Jul 12, 2026
…p audit

BLOCKER fixes:
- outbound.ts: detached pump pattern for SSE streaming — frames now reach
  the client as they arrive instead of buffering until upstream EOF; cancel
  calls reader.cancel() instead of the locked stream (#1)
- system-env.ts: transactional launchctl injection with incremental tracking
  and rollback on mid-flight failure (#2)

MAJOR fixes:
- system-env.ts: POSIX single-quote escaping for all user-controlled values
  in the generated shell file, preventing command injection (#3)
- system-env.ts: exported applySystemEnvToggle for runtime ON/OFF lifecycle (#7)
- claude-messages.ts: 120s hard timeout on native passthrough upstream fetch
  using AbortSignal.timeout, returning Anthropic 504 on expiry (#4)
- management-api.ts: reject non-plain-object PUT bodies (null, array, primitive)
  with 400; strict validation for blockedSkills, tierModels, modelMap, and
  autoCompactWindow (integer, range 100k-1M) (#5, #6)
- management-api.ts: call applySystemEnvToggle after systemEnv config toggle (#7)
- cli/claude.ts: override stale loopback ANTHROPIC_BASE_URL with live port;
  warn on gateway-cache and agent-sync failures instead of swallowing (#8, #10)
- gateway-cache.ts: distinguish discovery failure (keep cache) from authoritative
  empty success (write {models:[]}) (#9)

Test fixes: updated assertions for single-quote shell escaping, empty cache
semantics, validation messages, incremental tracking writes, and PUT response
shape.
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