Skip to content

Commit 0358e5d

Browse files
committed
Merge Anthropic Messages API compatibility
2 parents 571b757 + 9403fd2 commit 0358e5d

12 files changed

Lines changed: 1393 additions & 80 deletions

README.md

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<p><strong>Stop rewiring your AI tools every time an account hits quota.</strong></p>
55
<p>
66
A macOS menu-bar router that puts your connected accounts, models,
7-
API keys, and fallback routes behind one local chat-completions endpoint.
7+
API keys, and fallback routes behind one local endpoint.
88
</p>
99
<p>
1010
<a href="https://rerouted.dev">Website</a> |
@@ -31,7 +31,7 @@
3131

3232
Your editor should not need to know which account still has quota, which provider is having a bad morning, or which model you want to try next.
3333

34-
ReRouted gives compatible chat-completions clients the same local contract:
34+
ReRouted gives compatible OpenAI and Anthropic clients the same local contract:
3535

3636
```text
3737
Base URL http://127.0.0.1:4949/v1
@@ -41,7 +41,7 @@ Model coding
4141

4242
`coding` is a route you own. Put your preferred model first, another account second, and a backup provider third. When an upstream rate-limits, times out, or returns a retryable failure before output begins, ReRouted advances through the route without changing the URL or model name your client uses.
4343

44-
The promise is deliberately focused: ReRouted exposes model discovery and OpenAI-style chat completions. It is a routing layer, not a clone of every OpenAI API.
44+
The promise is deliberately focused: ReRouted exposes model discovery, OpenAI-style chat completions and Responses requests, plus Anthropic Messages compatibility for Claude Code and similar clients. It is a routing layer, not a clone of either platform API.
4545

4646
## Why ReRouted exists
4747

@@ -60,7 +60,7 @@ No hosted control plane. No account with ReRouted. No Dock icon. The gateway and
6060
```text
6161
editor / agent / script
6262
|
63-
| POST /v1/chat/completions
63+
| POST /v1/chat/completions or /v1/messages
6464
| model: "coding"
6565
v
6666
127.0.0.1:4949/v1
@@ -72,7 +72,7 @@ No hosted control plane. No account with ReRouted. No Dock icon. The gateway and
7272
3. backup provider
7373
|
7474
v
75-
normalized OpenAI-style response
75+
response in the client's original API shape
7676
```
7777

7878
Routes support two strategies:
@@ -134,7 +134,23 @@ curl http://127.0.0.1:4949/v1/chat/completions \
134134
-d '{"model":"coding","messages":[{"role":"user","content":"Say hello in three words."}]}'
135135
```
136136

137-
Then enter the same base URL, gateway key, and route name in a configurable client that supports OpenAI-style chat completions. Setting names vary by client. Switch providers, accounts, models, and route order inside ReRouted; leave the client configuration alone.
137+
Then enter the same base URL, gateway key, and route name in a configurable OpenAI-style client. Setting names vary by client. Switch providers, accounts, models, and route order inside ReRouted; leave the client configuration alone.
138+
139+
Claude Code uses the Anthropic Messages route. Point it at the gateway with its generated key and map each alias to a ReRouted model or named route:
140+
141+
```json
142+
{
143+
"env": {
144+
"ANTHROPIC_BASE_URL": "http://127.0.0.1:4949/v1",
145+
"ANTHROPIC_AUTH_TOKEN": "rr-your-generated-key",
146+
"ANTHROPIC_DEFAULT_OPUS_MODEL": "coding",
147+
"ANTHROPIC_DEFAULT_SONNET_MODEL": "coding",
148+
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "fast"
149+
}
150+
}
151+
```
152+
153+
ReRouted accepts both `/v1/messages` and `/v1/v1/messages`, so current Claude Code versions work whether they append `/messages` or `/v1/messages` to that base URL.
138154

139155
## The menu-bar control plane
140156

@@ -161,8 +177,10 @@ The gateway continues running when the panel is hidden. Quitting ReRouted stops
161177
| `GET /v1/models` | Enabled direct models and named routes |
162178
| `POST /v1/chat/completions` | Streaming or non-streaming routed chat completions |
163179
| `POST /v1/responses` | Streaming or non-streaming routed Responses API requests |
180+
| `POST /v1/messages` | Streaming or non-streaming Anthropic Messages requests |
181+
| `POST /v1/messages/count_tokens` | Local best-effort Anthropic input-token estimate |
164182

165-
Requests require a generated bearer key except for `/` and `/health`. OpenAI-style image inputs inside chat-completion messages are supported when the selected upstream model accepts them. The separate `/v1/images` generation API, embeddings, audio, and the rest of the OpenAI platform API are outside ReRouted's scope.
183+
Requests require a generated gateway key except for `/` and `/health`. OpenAI routes accept `Authorization: Bearer`; Anthropic routes accept that header or `x-api-key`. OpenAI-style image inputs inside chat-completion messages and Anthropic image blocks are supported when the selected upstream model accepts them. The separate `/v1/images` generation API, embeddings, audio, Anthropic Batches, and the rest of both platform APIs are outside ReRouted's scope.
166184

167185
## Local-first, with the boundaries stated plainly
168186

@@ -207,7 +225,7 @@ The implementation is intentionally small: Electron, Node's built-in HTTP server
207225

208226
## Current release
209227

210-
ReRouted `0.4.7` accepts the standalone authorization code shown by xAI while preserving callback-state validation and PKCE binding. The xAI connection panel now presents the code field directly instead of hiding it under troubleshooting. Public builds are Developer ID signed, notarized, stapled, and distributed through stable GitHub Releases with in-app updates. The public API is intentionally limited to health, model discovery, and chat completions; a published third-party client compatibility matrix is still forthcoming.
228+
Public builds are Developer ID signed, notarized, stapled, and distributed through stable GitHub Releases with in-app updates. The public API is intentionally limited to health, model discovery, chat completions, Responses, and Anthropic Messages compatibility; a published third-party client compatibility matrix is still forthcoming.
211229

212230
## License
213231

docs/architecture.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ ReRouted is one Electron process with three jobs:
1313
There is no separate daemon. Closing or hiding the panel does not stop the gateway; quitting ReRouted does.
1414

1515
```text
16-
OpenAI-style chat-completions client
16+
OpenAI-style or Anthropic Messages client
1717
|
18-
| Bearer rr-... + /v1/chat/completions
18+
| rr-... + /v1/chat/completions, /v1/responses, or /v1/messages
1919
v
2020
src/lib/gateway.js
2121
|
@@ -29,7 +29,7 @@ src/lib/providers/* ---> upstream provider API
2929
|
3030
| normalize response/SSE
3131
v
32-
OpenAI-style chat-completions response
32+
Response in the client's original API shape
3333
```
3434

3535
## Main process and panel
@@ -51,11 +51,15 @@ The renderer is vanilla HTML, CSS, and JavaScript. It renders onboarding and the
5151
| `GET /v1/models` | Bearer key | Enabled provider models plus named route IDs |
5252
| `POST /v1/chat/completions` | Bearer key | Streaming or non-streaming routed chat completion |
5353
| `POST /v1/responses` | Bearer key | Responses requests adapted through the chat-completions router |
54+
| `POST /v1/messages` | Bearer key or `x-api-key` | Anthropic Messages requests adapted through the chat-completions router |
55+
| `POST /v1/messages/count_tokens` | Bearer key or `x-api-key` | Local best-effort input-token estimate without an upstream request |
5456

5557
The default bind is `127.0.0.1:4949`. Settings can switch the host to `0.0.0.0` for LAN or Tailscale access. CORS is currently `*`, so the bearer key is the gateway's access boundary when network binding is enabled.
5658

5759
JSON request bodies are limited to 32 MiB. Oversized requests receive a JSON `413` response before routing begins.
5860

61+
Anthropic Messages requests are normalized into the same internal OpenAI chat-completions shape used by the router, so account pools, named routes, retries, fallback, round robin, activity, and usage all follow the existing path. Responses are converted back to Anthropic JSON or SSE, including text, tool use, tool results, stop reasons, and token usage. Native Claude thinking, signatures, cache-control blocks, and stop sequences are preserved in memory when a Messages request routes back to Claude, while the private metadata is not serialized to non-Claude providers. Both `/v1/messages` and the duplicate-prefix `/v1/v1/messages` form are accepted for compatibility with Claude Code versions and base-URL conventions that each add `/v1`.
62+
5963
## Model IDs and routes
6064

6165
Provider model IDs are generated by `src/lib/providers/index.js`. Custom OpenAI-compatible connections use the readable form `<connection name>/custom/<upstream model>` while legacy hash-qualified IDs remain resolvable. A direct model resolves to one enabled provider/model pair.

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "rerouted",
3-
"version": "0.4.16",
3+
"version": "0.4.17",
44
"description": "A macOS menu-bar router for accounts, models, and automatic fallback.",
55
"author": "gitcommit90",
66
"license": "MIT",

0 commit comments

Comments
 (0)