Skip to content

fix(server): let SDK consumers mount the Codex proxy door - #1454

Merged
murdore merged 1 commit into
releasefrom
fix/codex-configurator-and-sdk-seam
Aug 22, 2026
Merged

murdore merged 1 commit into
releasefrom
fix/codex-configurator-and-sdk-seam

Conversation

@murdore

@murdore murdore commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Two gaps that share a root cause: Codex was treated as CLI-only.

1. An SDK consumer could not mount the Codex door at all

createAllRoutes assembled two of the three proxy doors. createCodexProxyRoutes was neither imported nor re-exported from the routes barrel, and no flag selected it — so Codex proxying was reachable only by running neurolink proxy start.

Verified through the published surface, not by reading source:

before:  createAllRoutes("/api", { proxy: true })      -> no codex door
after:   createAllRoutes("/api", { proxy: true })      -> codex door present
         createAllRoutes("/api", { codexProxy: true }) -> codex door present
         createAllRoutes("/api", {})                   -> absent (unchanged)

The unified proxy flag now means every door rather than two of three. A consumer opting into proxying is opting into proxying, and the silent omission is exactly what let this sit unnoticed. Flag me if you'd rather proxy stayed Claude+OpenAI and Codex required its own opt-in — it's a judgement call, and reverting it is one line.

A wider gap found while wiring it: the server entry re-exported no proxy factory. Claude and OpenAI were reachable only via the deep path ./routes/index.js, which is not a package export — so @juspay/neurolink/server consumers could never mount one directly. All three are exported now.

2. Codex had no configurator round-trip test — #1368 was closed as covered

Codex is the writer with the most to get wrong: it edits TOML by regex rather than round-tripping JSON, keeps its snapshot in a sidecar file, and rewrites a top-level selector that must stay in the preamble. A model_provider read from inside a [profiles.*] table would be written back as the global selector, silently repointing every Codex run at another provider.

The test drives the real writer against a config carrying that hazard, in two cases:

  • A user selector present — restore must return it verbatim. This case passes against a correct and a broken writer, because document-wide and preamble-scoped matching agree when the preamble already has one. Kept because it covers the common path, but it proves nothing on its own.
  • No global selector, only a profile's — this is what separates them. Confirmed by regressing the writer to match document-wide, watching this case fail, then restoring it.

Worth recording: my first version of case B asserted /^model_provider = /m on the whole file. That matches the line inside [profiles.work] too, so it reported a bug that did not exist. The writer was pristine the whole time; the assertion is now scoped to the preamble.

Verification

Check Result
tsc --noEmit --strict clean
eslint src test 0 errors (54 pre-existing warnings)
pnpm run build clean
continuous-test-suite-proxy 65 passed
continuous-test-suite-servers 41 passed
continuous-test-suite-codex 31 passed
Regression proof writer broken on purpose -> case B fails; restored -> passes

Stacks cleanly with #1453 (Codex model discovery); the two touch different files.

createAllRoutes assembled two of the three proxy doors. createCodexProxyRoutes
was neither imported nor re-exported from the routes barrel, and no flag
selected it, so Codex proxying was reachable only by running `neurolink proxy
start`. A consumer embedding the server could not expose it at all — not even
deliberately.

Adds a codexProxy flag and mounts the door under it. The unified `proxy` flag
now means every door rather than two of three: a consumer opting into proxying
is opting into proxying, and the omission is what let this go unnoticed. Off by
default, as before.

While wiring it, a wider gap: the server entry re-exported no proxy factory at
all. Claude and OpenAI were reachable only through the deep path
./routes/index.js, which is not a package export, so a consumer of
"@juspay/neurolink/server" could never mount one directly. All three are
exported now.

Codex was also the one configurator with no apply/restore round-trip test —
issue #1368 was closed as covered while the writer with the most to get wrong
had none. It edits TOML by regex rather than round-tripping JSON, keeps its
snapshot in a sidecar file, and rewrites a top-level selector that must stay in
the preamble: a model_provider read from inside a [profiles.*] table would be
written back as the global selector, silently repointing every Codex run at
another provider.

The test drives the real writer against a config carrying exactly that hazard,
in two cases. The first — a user selector present — passes against both a
correct writer and a broken one, because document-wide and preamble-scoped
matching agree when the preamble already has a selector. The second case is the
one that separates them: no global selector, only a profile's. Confirmed by
regressing the writer to match document-wide and watching it fail, then
restoring it.

Both tests run through the surface a consumer uses: the SDK seam is checked by
importing the built package and calling createAllRoutes, not by reading source.
Copilot AI lite review requested due to automatic review settings August 22, 2026 08:41
@coderabbitai

coderabbitai Bot commented Aug 22, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@murdore, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 2 minutes

Limit details: You’ve used all 2 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9c4820ae-b7fc-4dd8-b634-36889e76e725

📥 Commits

Reviewing files that changed from the base of the PR and between 69d8493 and 3e792e9.

📒 Files selected for processing (5)
  • src/lib/server/index.ts
  • src/lib/server/routes/index.ts
  • src/lib/types/server.ts
  • test/continuous-test-suite-proxy.ts
  • test/continuous-test-suite-servers.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Single Commit Policy - COMPLIANT

Status: Policy requirements met • 1 commit • Valid format • Ready for merge

📊 View validation details

📝 Commit Details

  • Hash: 3e792e9acce43a7da63e11db0d1ec016d00da347
  • Message: fix(server): let SDK consumers mount the Codex proxy door
  • Author: Sachin Sharma

✅ Validation Results

  • Single commit requirement met
  • No merge commits in branch
  • Semantic commit message format verified
  • Ready for squash merge to release branch

🤖 Automated validation by NeuroLink Single Commit Enforcement

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 AI Review & Build Compliance ✅

Status: AI analysis complete • Build rules validated • Ready for review

📊 View detailed analysis results

🛡️ Analysis Complete

  • ✅ Security scan (vulnerabilities, API keys)
  • ✅ TypeScript safety & code quality
  • ✅ Error handling & best practices
  • ✅ Build rule enforcement validated
  • ✅ Commit format & compliance checks

📋 Ready for Merge When

  • All CI checks passing
  • Manual review approved
  • Any AI-flagged issues resolved

🤖 AI analysis complete - check individual code comments for specific feedback

@Tara-ag

Tara-ag commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Review Summary

Decision: APPROVED ✅

Findings

No issues found. This is a clean feature addition that properly exposes Codex proxy functionality through the SDK.

Changes Reviewed

File: src/lib/server/index.ts

  • ✅ Added re-exports of createClaudeProxyRoutes, createOpenAIProxyRoutes, and createCodexProxyRoutes
  • These proxy route creators were previously only accessible internally, now exposed for SDK consumers
  • No breaking changes - purely additive

File: src/lib/server/routes/index.ts

  • ✅ Added import and export for createCodexProxyRoutes
  • ✅ Updated createAllRoutes() to support codexProxy flag alongside existing claudeProxy/openaiProxy flags
  • ✅ Unified proxy flag now enables all three proxy doors
  • Implementation correctly mirrors the Claude/OpenAI pattern

File: src/lib/types/server.ts

  • ✅ Added codexProxy?: boolean option to CreateRoutesOptions type
  • ✅ Documentation explains historical context

File: test/continuous-test-suite-proxy.ts

  • ✅ Excellent round-trip test for Codex configurator (testCodexConfiguratorRoundTrip)
  • Tests critical hazard: profile-level vs global model_provider selector
  • Validates apply/restore behavior with real TOML config

File: test/continuous-test-suite-servers.ts

  • ✅ Added testCodexProxyReachableFromSDK() - verifies SDK consumers can mount Codex proxy door
  • Tests both dedicated codexProxy: true flag and unified proxy: true flag
  • Verifies Codex is off by default when no flag specified

Impact on Existing Code

  • Blast radius: Low - all changes are additive to public API surface
  • Breaking changes: None
  • Backward compatibility: Fully maintained - legacy per-format flags still work
  • Dependencies: No new external dependencies added

Review Scope

Reviewed 5 changed files covering:

  • Public API exports
  • Route creation logic
  • Type definitions
  • Integration tests
  • SDK seam verification

The implementation is solid, well-tested, and follows established patterns in the codebase. No action required beyond merging.

@murdore
murdore merged commit 926397b into release Aug 22, 2026
19 of 20 checks passed
@murdore
murdore deleted the fix/codex-configurator-and-sdk-seam branch August 22, 2026 15:07
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 11.17.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants