Skip to content

test(codex): factory wiring tests + docker harness - #176

Merged
claudiusthebot merged 1 commit into
mainfrom
feat/codex-polish-1
May 16, 2026
Merged

test(codex): factory wiring tests + docker harness#176
claudiusthebot merged 1 commit into
mainfrom
feat/codex-polish-1

Conversation

@claudiusthebot

Copy link
Copy Markdown
Collaborator

Summary

Two follow-ups to the Codex backend (PRs #174, #175):

  1. src/__tests__/codex-factory.test.ts β€” 4 new tests verifying
    the codex factory's init() produces a QueryBackend with ALL the
    expected optional methods wired (query, resolveModel,
    getModelInfo, getSettingsPresentation, getProviders,
    getProviderModels, formatModelError, listModels, runOneShotAgent,
    backendLabel). Drives resolveModel, listModels,
    getProviders through the factory wrapper to confirm end-to-end
    wiring.

  2. docker/codex-test/ β€” Docker harness for live testing the
    Codex backend against a dedicated test bot, mirroring
    docker/kilo-test/. Includes Dockerfile (node:22-slim with codex
    CLI deps), docker-compose.yml (workspace + ~/.codex auth mounts),
    and README walkthrough.

Tests

  • 2305 passing (was 2301), 12 skipped (live), 0 failing
  • tsc clean, lint 0 errors

πŸ€– Generated with Claude Code

Two additions in this PR:

1. `src/__tests__/codex-factory.test.ts` β€” 4 new tests verifying the
   codex factory's `init()` produces a QueryBackend with ALL the
   expected optional methods (query, resolveModel, getModelInfo,
   getSettingsPresentation, getProviders, getProviderModels,
   formatModelError, listModels, runOneShotAgent, backendLabel).
   Drives `resolveModel`, `listModels`, and `getProviders` through
   the factory wrapper to confirm the wiring is correct end-to-end.

   Mocks `@openai/codex-sdk` so the test doesn't spawn the real CLI.

2. `docker/codex-test/` β€” Docker harness for live testing the Codex
   backend against a dedicated test bot, mirroring `docker/kilo-test/`:
   - `Dockerfile`: node:22-slim + apt-installed curl/git/ripgrep
     (codex's built-in tools require them on PATH).
   - `docker-compose.yml`: bind-mount `~/.talon-codex-test/`,
     `~/.codex/` (for ChatGPT auth), env var `OPENAI_API_KEY`,
     container-internal port 19879 (vs prod's 19876).
   - `README.md`: setup walkthrough + coexistence-with-prod table.

Tests: 2305 passing (was 2301 + 4 new factory tests), 12 skipped
(live-tier), 0 failing.
@claudiusthebot
claudiusthebot enabled auto-merge (squash) May 15, 2026 23:58
@claudiusthebot
claudiusthebot merged commit e7d7d6e into main May 16, 2026
31 checks passed
claudiusthebot added a commit that referenced this pull request May 16, 2026
… line (#177)

Three small parity improvements building on the Codex backend
foundation (#174, #175, #176):

1. **Cleanup hook in codex factory.** Kilo/OpenCode return a
   `cleanup: stopServer` callback from their factory `init` so the
   dispatcher can clean up on hot-reload or shutdown. Codex now
   returns a `cleanup` that calls `resetCodexState()` β€” clearing the
   cached Codex instance + frontend label + gateway port. Each
   `runStreamed` spawns a fresh subprocess so there's no long-lived
   server to stop, but resetting the module-scoped state matters for
   test isolation and future hot-reload paths.

2. **Backend conformance expanded to cover Codex.** Two of the four
   conformance tests (`routeDelivery` route parity + synthetic-error
   label prefix) now drive all three remote-route-using backends
   (Kilo / OpenCode / Codex) through the same shared `routeDelivery`
   helper and assert identical decisions + identical
   `⚠️ <Backend>: <msg>` formatting. The MCP-rotation + SSE event
   tests stay Kilo/OpenCode-only since Codex's MCP wiring is
   constructor-time TOML, not HTTP-API registration.

3. **Codex model-resolution log line.** Kilo emits
   `[chatId] Kilo model resolved: provider=X model=Y`; OpenCode emits
   the same. Codex now emits `[chatId] Codex model resolved: <model>`
   on every turn so the agent log has a uniform per-turn fingerprint
   across all four backends.

Tests: 2305 passing, 12 skipped (live-tier), 0 failing.
dylanneve1 pushed a commit that referenced this pull request May 16, 2026
Two new test cases covering the factory wiring blind spots:

1. **Cleanup hook resets state for hot-reload** β€” verifies that the
   `cleanup` callback returned from `factory.init()` properly resets
   the module-scoped state (config + codex instance both null'd).
   Without this test, a regression that swallowed the resetState()
   call would silently leak state across hot-reloads.

2. **Init twice with different config re-populates without leakage** β€”
   verifies that re-running `init()` with a different frontend/port
   fully overwrites prior state. Catches the class of bug where one
   field gets re-set but another lingers from the previous init.

Together these close the testable surface of the codex factory beyond
the initial registration + method-presence checks (which #176 + #177
already cover). 8/8 codex-factory tests pass locally.

πŸ€– Generated with Claude Code (claude.com/claude-code)
claudiusthebot added a commit that referenced this pull request May 16, 2026
Two new test cases covering the factory wiring blind spots:

1. **Cleanup hook resets state for hot-reload** β€” verifies that the
   `cleanup` callback returned from `factory.init()` properly resets
   the module-scoped state (config + codex instance both null'd).
   Without this test, a regression that swallowed the resetState()
   call would silently leak state across hot-reloads.

2. **Init twice with different config re-populates without leakage** β€”
   verifies that re-running `init()` with a different frontend/port
   fully overwrites prior state. Catches the class of bug where one
   field gets re-set but another lingers from the previous init.

Together these close the testable surface of the codex factory beyond
the initial registration + method-presence checks (which #176 + #177
already cover). 8/8 codex-factory tests pass locally.

πŸ€– Generated with Claude Code (claude.com/claude-code)
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