feat(service): transparent pass-through proxy for unhandled provider endpoints#106
Merged
Merged
Conversation
…endpoints (#100) Any path Routerly does not explicitly handle is now forwarded to the project's upstream provider with only the API key swapped, making Routerly a true drop-in replacement for OpenAI, Anthropic, Ollama and custom providers — today and for any future endpoints they add. - Extract `resolveProjectByToken()` helper from auth plugin (shared by the proxy handler so auth is never bypassed) - Add `passthrough.ts`: pure helpers (`pickUpstreamModel`, `buildUpstreamUrl`, `buildUpstreamHeaders`) + `passthroughHandler` registered as Fastify's global setNotFoundHandler - Register a `*` content-type parser in server.ts to capture non-JSON bodies as raw Buffer for verbatim forwarding - Upstream selection: body `model` field matched to project models, else first configured model; Anthropic uses x-api-key, all others Bearer — no config required - Reserved namespaces (`/`, `/health`, `/api/*`, `/dashboard*`) are guarded inside the handler and never proxied - 22 new tests covering all helpers and handler scenarios; existing server telemetry test updated to include the new mock stubs Closes #100 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #100
modelfield against project models, falling back to the first configured model; Anthropic/anthropic-web usex-api-key, all other providers useAuthorization: Bearer/,/health,/api/*,/dashboard*) are guarded inside the handler and always return 404 — never proxiedChanges
plugins/auth.ts— extractresolveProjectByToken()as a shared exported helper (no behaviour change to existing auth hook)routes/passthrough.ts— new: pure helperspickUpstreamModel,buildUpstreamUrl,buildUpstreamHeaders+passthroughHandlerregistered asfastify.setNotFoundHandlerserver.ts— add*content-type parser (non-JSON bodies captured as Buffer for verbatim forwarding) + wiresetNotFoundHandlerserver.telemetry.test.ts— add missing mock stubs (addContentTypeParser,passthroughHandler)Test plan
passthrough.test.tscovering all pure helpers and handler scenarios (model selection, URL building, header injection, proxy flow, auth failures, 502 cases, reserved-path guard)npm test --workspace=packages/service→ 1027/1027 passednpm run typecheck --workspace=packages/service→ cleanManual E2E:
🤖 Generated with Claude Code