proxitor 0.9.0-beta.9 โ 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -488
- package/dist/cli.mjs +50 -46
- package/dist/cli.mjs.map +1 -1
- package/package.json +25 -25
package/README.md
CHANGED
|
@@ -1,90 +1,70 @@
|
|
|
1
1
|
# proxitor
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<strong>A
|
|
5
|
-
Route
|
|
4
|
+
<strong>A friendly proxy between your AI CLI tools and OpenRouter.</strong><br/>
|
|
5
|
+
Route requests to the provider you want. Keep prompt caching alive. Cut costs.<br/>
|
|
6
|
+
Your tools don't even notice.
|
|
6
7
|
</p>
|
|
7
8
|
|
|
8
9
|
<p align="center">
|
|
9
10
|
<a href="https://www.npmjs.com/package/proxitor"><img src="https://img.shields.io/npm/v/proxitor?color=6366f1&labelColor=1e2327&label=npm" alt="npm version"></a>
|
|
10
|
-
<a href="
|
|
11
|
+
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-MIT-22c55e?labelColor=1e2327" alt="MIT License"></a>
|
|
11
12
|
<img src="https://img.shields.io/badge/node-%3E%3D22-3b82f6?labelColor=1e2327" alt="Node.js โฅ 22">
|
|
12
|
-
<img src="https://img.shields.io/badge/built_with-TypeScript-3178c6?labelColor=1e2327" alt="TypeScript">
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
๐ **English** ยท [ะ ัััะบะธะน](./docs/README.ru.md)
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
Claude Code / Codex
|
|
19
|
-
โ
|
|
20
|
-
โ ANTHROPIC_BASE_URL=http://localhost:8828/v1
|
|
21
|
-
โผ
|
|
22
|
-
โโโโโโโโโโโโโโโโโ
|
|
23
|
-
โ proxitor โ โ injects provider routing
|
|
24
|
-
โ :8828 โ โ streams SSE back unchanged
|
|
25
|
-
โโโโโโโโโโโโโโโโโ
|
|
26
|
-
โ
|
|
27
|
-
โ + X-OpenRouter-* headers
|
|
28
|
-
โผ
|
|
29
|
-
OpenRouter
|
|
30
|
-
โโโโโโโโฌโโโโโโโ
|
|
31
|
-
Anthropic DeepInfra Azure ...
|
|
32
|
-
```
|
|
17
|
+
<p align="center"><img src="./docs/assets/proxitor-wizard.gif" alt="proxitor setup wizard" width="640"></p>
|
|
33
18
|
|
|
34
19
|
---
|
|
35
20
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
### The prompt cache problem
|
|
21
|
+
Proxitor sits between Claude Code (or Codex, or any Anthropic/OpenAI-compatible CLI) and [OpenRouter](https://openrouter.ai). One API key, every model โ but **you** decide which provider serves each request, and you make prompt caching actually work.
|
|
39
22
|
|
|
40
|
-
|
|
23
|
+
```
|
|
24
|
+
your AI CLI โ proxitor โ OpenRouter โ the provider you picked
|
|
25
|
+
```
|
|
41
26
|
|
|
42
|
-
|
|
27
|
+
## Why you'd want this
|
|
43
28
|
|
|
44
|
-
|
|
45
|
-
# pin all Claude models to Anthropic โ prompt cache works reliably
|
|
46
|
-
modelOverrides:
|
|
47
|
-
"claude-*":
|
|
48
|
-
provider:
|
|
49
|
-
only: "anthropic"
|
|
50
|
-
```
|
|
29
|
+
OpenRouter is convenient โ one key, every model. But it load-balances across providers, and **prompt caching is provider-scoped**: a cache built on Anthropic doesn't help when the next request lands on DeepInfra. Claude Code sends a big system prompt on every request, so without a pinned provider you pay full price every time.
|
|
51
30
|
|
|
52
|
-
|
|
31
|
+
Pin `claude-*` to `anthropic`, and that system prompt gets cached after the first hit. Subsequent requests cost a fraction.
|
|
53
32
|
|
|
54
|
-
|
|
55
|
-
- **Automatic fallbacks** โ if Anthropic is degraded, fall back to DeepInfra without touching your tools
|
|
56
|
-
- **Mixed routing** โ `claude-*` on Anthropic, `gpt-*` on Azure, different rules per model
|
|
57
|
-
- **Data privacy** โ enforce `dataCollection: deny` or ZDR across all requests
|
|
33
|
+
A few other things it's good for:
|
|
58
34
|
|
|
59
|
-
|
|
35
|
+
- **Cost control** โ route specific models to cheaper providers when caching isn't the priority.
|
|
36
|
+
- **Automatic fallbacks** โ Anthropic down? Fall back to DeepInfra without touching your tools.
|
|
37
|
+
- **Mixed routing** โ `claude-*` on Anthropic, `gpt-*` on Azure, different rules per model.
|
|
38
|
+
- **Privacy** โ enforce `dataCollection: deny` or zero-data-retention across everything.
|
|
60
39
|
|
|
61
|
-
|
|
40
|
+
> Proxitor injects all of this transparently. Your tools see a normal API. Nothing on their side changes.
|
|
62
41
|
|
|
63
42
|
## Install
|
|
64
43
|
|
|
44
|
+
Requires **Node.js 22+**.
|
|
45
|
+
|
|
65
46
|
```sh
|
|
66
|
-
# npm
|
|
67
47
|
npm install -g proxitor
|
|
68
|
-
|
|
69
|
-
#
|
|
70
|
-
bun install -g proxitor
|
|
71
|
-
|
|
72
|
-
# no install needed
|
|
73
|
-
npx proxitor
|
|
48
|
+
# or: bun install -g proxitor
|
|
49
|
+
# or run it once, no install: npx proxitor
|
|
74
50
|
```
|
|
75
51
|
|
|
76
|
-
|
|
52
|
+
## Quick start
|
|
77
53
|
|
|
78
|
-
|
|
54
|
+
**1. Set it up** โ the wizard asks a few questions and writes your config:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
proxitor config wizard
|
|
58
|
+
```
|
|
79
59
|
|
|
80
|
-
**
|
|
60
|
+
**2. Run it**
|
|
81
61
|
|
|
82
62
|
```sh
|
|
83
|
-
|
|
63
|
+
proxitor
|
|
84
64
|
# Listening on http://0.0.0.0:8828
|
|
85
65
|
```
|
|
86
66
|
|
|
87
|
-
**
|
|
67
|
+
**3. Point your tool at it**
|
|
88
68
|
|
|
89
69
|
```sh
|
|
90
70
|
# Claude Code
|
|
@@ -94,469 +74,59 @@ ANTHROPIC_BASE_URL=http://localhost:8828/v1 claude
|
|
|
94
74
|
OPENAI_BASE_URL=http://localhost:8828/v1 codex
|
|
95
75
|
```
|
|
96
76
|
|
|
97
|
-
That's
|
|
98
|
-
|
|
99
|
-
---
|
|
100
|
-
|
|
101
|
-
## Configuration
|
|
102
|
-
|
|
103
|
-
Proxitor looks for a config file in this order:
|
|
104
|
-
|
|
105
|
-
```
|
|
106
|
-
proxitor.config.yaml โ proxitor.config.yml โ proxitor.config.json
|
|
107
|
-
.proxitor.yaml โ .proxitor.yml โ .proxitor.json
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
**Priority:** CLI flags > config file > environment variables > defaults
|
|
111
|
-
|
|
112
|
-
All defaults are derived from a single Zod schema (`DEFAULTS`) โ no hardcoded constants scattered across modules. Config values are validated through Zod on load, including the final merged result.
|
|
113
|
-
|
|
114
|
-
See [`proxitor.config.example.yaml`](./proxitor.config.example.yaml) for the complete reference.
|
|
115
|
-
|
|
116
|
-
### Authentication type
|
|
117
|
-
|
|
118
|
-
By default, proxitor sends the API key as a `Bearer` token (`Authorization: Bearer sk-...`). If you're using a custom proxy provider that expects an `OAuth` header instead, set `authType` to `oauth`:
|
|
119
|
-
|
|
120
|
-
```yaml
|
|
121
|
-
authType: oauth # "bearer" (default) or "oauth"
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
This changes the header to `Authorization: OAuth sk-...`.
|
|
125
|
-
|
|
126
|
-
### Custom API URL and data fallback
|
|
127
|
-
|
|
128
|
-
When using a custom `openrouterBaseUrl` that points to a third-party service, that service may not support OpenRouter-specific endpoints like `/providers` or `/models/{author}/{slug}/endpoints`. Proxitor handles this automatically:
|
|
129
|
-
|
|
130
|
-
- **Automatic fallback** โ if the custom API returns an error (4xx/5xx) or an unexpected response format for data endpoints, proxitor falls back to `https://openrouter.ai/api` (no API key needed โ these endpoints are public)
|
|
131
|
-
- **`openrouterDataUrl`** โ set this explicitly to control the primary URL for data fetching, independent of `openrouterBaseUrl` (which is used for proxying requests)
|
|
132
|
-
|
|
133
|
-
```yaml
|
|
134
|
-
# Proxy requests go to custom service, data fetching falls back to OpenRouter
|
|
135
|
-
# NOTE: do NOT include /v1 in the base URL โ request paths like /v1/chat/completions
|
|
136
|
-
# are forwarded as-is, so /v1 would be duplicated if included here
|
|
137
|
-
openrouterBaseUrl: 'https://custom-service.example.com/api'
|
|
138
|
-
|
|
139
|
-
# Explicitly set the primary data URL (optional, defaults to openrouterBaseUrl)
|
|
140
|
-
# openrouterDataUrl: 'https://openrouter.ai/api'
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
When a fallback occurs, proxitor logs a warning: `Custom API did not return providers, using OpenRouter as fallback`.
|
|
144
|
-
|
|
145
|
-
### Provider routing
|
|
146
|
-
|
|
147
|
-
Control which provider handles your requests. All three options accept a string or an array:
|
|
148
|
-
|
|
149
|
-
```yaml
|
|
150
|
-
# Strict lock โ only this provider, no fallbacks
|
|
151
|
-
provider:
|
|
152
|
-
only: "anthropic"
|
|
153
|
-
|
|
154
|
-
# Restricted pool โ load balance between these providers only
|
|
155
|
-
provider:
|
|
156
|
-
only:
|
|
157
|
-
- "anthropic"
|
|
158
|
-
- "deepinfra"
|
|
159
|
-
|
|
160
|
-
# Priority order โ try Anthropic first, fall back to others if unavailable
|
|
161
|
-
provider:
|
|
162
|
-
order: "anthropic"
|
|
163
|
-
allowFallbacks: true
|
|
164
|
-
|
|
165
|
-
# Strict order โ try in sequence, no fallbacks outside the list
|
|
166
|
-
provider:
|
|
167
|
-
order:
|
|
168
|
-
- "anthropic"
|
|
169
|
-
- "deepinfra"
|
|
170
|
-
allowFallbacks: false
|
|
171
|
-
|
|
172
|
-
# Blacklist โ never use these providers
|
|
173
|
-
provider:
|
|
174
|
-
ignore: "azure"
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
| Option | Behavior |
|
|
178
|
-
|---|---|
|
|
179
|
-
| `only` | Restrict to the listed provider(s). Load balances by price within the list. Never routes outside it โ if all are unavailable, the request fails. |
|
|
180
|
-
| `order` | Try providers in the specified priority order. If none work, falls back to other available providers (unless `allowFallbacks: false`). |
|
|
181
|
-
| `ignore` | Never route to the listed provider(s). |
|
|
182
|
-
|
|
183
|
-
Without `provider` set, requests are forwarded unchanged.
|
|
184
|
-
|
|
185
|
-
See [OpenRouter's provider routing docs](https://openrouter.ai/docs/guides/routing/provider-selection) for the full list of supported providers and options.
|
|
186
|
-
|
|
187
|
-
### Per-model overrides
|
|
188
|
-
|
|
189
|
-
Route different models differently. Keys are exact names or prefix wildcards. More specific matches win.
|
|
190
|
-
|
|
191
|
-
```yaml
|
|
192
|
-
provider:
|
|
193
|
-
order: "deepinfra" # global default
|
|
194
|
-
|
|
195
|
-
modelOverrides:
|
|
196
|
-
# Exact match โ force this model to Anthropic
|
|
197
|
-
"claude-sonnet-4-6":
|
|
198
|
-
provider:
|
|
199
|
-
only: "anthropic"
|
|
200
|
-
|
|
201
|
-
# Wildcard โ all claude-* models prefer Anthropic with fallback
|
|
202
|
-
"claude-*":
|
|
203
|
-
provider:
|
|
204
|
-
order:
|
|
205
|
-
- "anthropic"
|
|
206
|
-
- "deepinfra"
|
|
207
|
-
|
|
208
|
-
# GPT models to OpenAI/Azure, plus a custom header
|
|
209
|
-
"gpt-*":
|
|
210
|
-
provider:
|
|
211
|
-
only:
|
|
212
|
-
- "openai"
|
|
213
|
-
- "azure"
|
|
214
|
-
headers:
|
|
215
|
-
X-Model-Family: "gpt"
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
**Match priority:** exact name > longer prefix > shorter prefix.
|
|
219
|
-
|
|
220
|
-
### Custom headers
|
|
221
|
-
|
|
222
|
-
Add headers to all proxied requests, or per-model (merged on top of global):
|
|
223
|
-
|
|
224
|
-
```yaml
|
|
225
|
-
headers:
|
|
226
|
-
X-Custom-Header: "my-value"
|
|
227
|
-
X-Environment: "production"
|
|
228
|
-
|
|
229
|
-
modelOverrides:
|
|
230
|
-
"claude-*":
|
|
231
|
-
headers:
|
|
232
|
-
X-Custom-Header: "claude-override" # overrides the global value
|
|
233
|
-
X-Extra: "only-for-claude" # added only for this model
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
### Advanced provider options
|
|
237
|
-
|
|
238
|
-
```yaml
|
|
239
|
-
provider:
|
|
240
|
-
sort: "throughput" # sort by: price | throughput | latency
|
|
241
|
-
quantizations:
|
|
242
|
-
- "fp8" # filter by quantization level
|
|
243
|
-
maxPrice:
|
|
244
|
-
prompt: 1 # $/M tokens
|
|
245
|
-
completion: 2
|
|
246
|
-
requireParameters: true # only use providers that support all request params
|
|
247
|
-
dataCollection: "deny" # "allow" | "deny"
|
|
248
|
-
zdr: true # Zero Data Retention enforcement
|
|
249
|
-
preferredMinThroughput:
|
|
250
|
-
p90: 50 # tokens/sec (soft threshold)
|
|
251
|
-
preferredMaxLatency:
|
|
252
|
-
p90: 3 # seconds (soft threshold)
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### Prompt caching
|
|
256
|
-
|
|
257
|
-
By default, OpenRouter doesn't enable prompt caching โ every request pays full token price. Proxitor can inject `cache_control` and `session_id` to make caching work automatically.
|
|
258
|
-
|
|
259
|
-
**`cacheControl`** โ injects `cache_control: { "type": "ephemeral" }` into the request body. OpenRouter uses this to set cache breakpoints and advance them as conversations grow.
|
|
260
|
-
|
|
261
|
-
**`cacheControlTtl`** (`5m` / `1h` / `omit` / `skip`, default absent = passthrough) โ controls the `ttl` field on injected `cache_control` (Anthropic endpoints only). TTL only has effect when caching is active (`cacheControl` is `auto`/`always`); it is now set independently of the cache mode in the editor.
|
|
262
|
-
|
|
263
|
-
**`sessionId`** โ injects `session_id` for provider sticky routing. Without it, OpenRouter only pins to a provider after detecting a cache hit. With it, routing sticks from the **first request** โ critical for OpenAI models where delayed caching means 0 cached tokens on the first 1-2 requests.
|
|
264
|
-
|
|
265
|
-
Both `cacheControl` and `sessionId` support `auto` / `always` / `skip` modes:
|
|
266
|
-
|
|
267
|
-
| Mode | `cacheControl` | `sessionId` |
|
|
268
|
-
| --- | --- | --- |
|
|
269
|
-
| `auto` (default) | Anthropic models on `/v1/chat/completions`; all models on `/v1/messages` and `/v1/responses` | Passthrough client session ID if present; otherwise generate proxy UUID |
|
|
270
|
-
| `always` | All models, all endpoints | Always generate proxy session ID, ignoring client-provided |
|
|
271
|
-
| `skip` | Passthrough: leave the client's `cache_control` untouched and inject nothing | Passthrough: leave client session headers untouched |
|
|
272
|
-
|
|
273
|
-
`cacheControlTtl` values:
|
|
77
|
+
That's the whole setup. Requests flow through proxitor; streaming responses pass through untouched.
|
|
274
78
|
|
|
275
|
-
|
|
276
|
-
| --- | --- | --- | --- |
|
|
277
|
-
| _(absent)_ | Passthrough: preserve client `ttl`, add nothing; per-model absent inherits the global TTL | โ | Default |
|
|
278
|
-
| `5m` | 5 minutes (Anthropic default) | 1.25ร | Explicit short cache; high-frequency requests (>1 per 5 min) |
|
|
279
|
-
| `1h` | 1 hour | 2.0ร | Low-frequency or long-running sessions |
|
|
280
|
-
| `omit` | Strip the `ttl` field, guaranteeing no TTL (even one sent by the client) | โ | Force-disable TTL |
|
|
281
|
-
| `skip` | Passthrough: preserve the client's `ttl`, add nothing, ignore an inherited value | โ | Ignore global TTL without stripping |
|
|
79
|
+
## Configuring it
|
|
282
80
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
```yaml
|
|
286
|
-
cacheControl: auto # safe default โ Anthropic and safe endpoints only
|
|
287
|
-
sessionId: auto # always ensures sticky routing (client header or proxy UUID)
|
|
288
|
-
|
|
289
|
-
# Use 1-hour cache for all Anthropic models (higher write cost, longer TTL)
|
|
290
|
-
cacheControlTtl: 1h
|
|
291
|
-
|
|
292
|
-
# Force caching for all models (may cause 400 on non-Anthropic /v1/chat/completions)
|
|
293
|
-
# cacheControl: always
|
|
294
|
-
|
|
295
|
-
# Per-model overrides โ TTL supports '5m', '1h', 'omit', or 'skip' (passthrough)
|
|
296
|
-
modelOverrides:
|
|
297
|
-
"gpt-*":
|
|
298
|
-
cacheControl: skip # OpenAI caches automatically, no injection needed
|
|
299
|
-
sessionId: always # but sticky routing still helps
|
|
300
|
-
"claude-opus-*":
|
|
301
|
-
cacheControlTtl: skip # passthrough for Opus โ ignore the global 1h TTL, use the client ttl
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
**Why all three matter:**
|
|
305
|
-
|
|
306
|
-
- **Anthropic models** โ `cache_control` activates caching, `cacheControlTtl` extends it beyond 5 min, `session_id` prevents provider flip-flopping that would invalidate it
|
|
307
|
-
- **OpenAI models** โ caching is automatic (no `cache_control` needed), but `session_id` ensures sticky routing from request #1 instead of waiting for a cache hit
|
|
308
|
-
- **All models** โ `session_id` prevents the provider switch that silently resets cache
|
|
309
|
-
|
|
310
|
-
### Health check
|
|
311
|
-
|
|
312
|
-
```sh
|
|
313
|
-
curl http://localhost:8828/health
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
### Cache usage logging
|
|
317
|
-
|
|
318
|
-
Proxitor automatically logs cache token usage from upstream responses โ both non-streaming JSON and streaming SSE. No configuration needed.
|
|
319
|
-
|
|
320
|
-
```
|
|
321
|
-
[abc123] Cache read: 50000, write: 25000 tokens (99.6% hit)
|
|
322
|
-
[def456] Cache read: 1088 tokens (90.0% hit)
|
|
323
|
-
[ghi789] Cache: no cached tokens
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
Supports all three provider formats:
|
|
327
|
-
|
|
328
|
-
| Provider format | Fields |
|
|
329
|
-
| --- | --- |
|
|
330
|
-
| Anthropic | `usage.cache_read_input_tokens` / `usage.cache_creation_input_tokens` |
|
|
331
|
-
| OpenAI / OpenRouter | `usage.prompt_tokens_details.cached_tokens` / `cache_write_tokens` |
|
|
332
|
-
| Responses API | `usage.input_tokens_details.cached_tokens` / `cache_write_tokens` |
|
|
333
|
-
|
|
334
|
-
When both formats are present (e.g., OpenRouter relaying an Anthropic response), Anthropic fields take priority.
|
|
335
|
-
|
|
336
|
-
---
|
|
337
|
-
|
|
338
|
-
## Interactive Config Manager
|
|
339
|
-
|
|
340
|
-
Proxitor includes an interactive CLI for managing configuration โ global settings, model overrides, and diagnostics โ without editing YAML by hand.
|
|
341
|
-
|
|
342
|
-
### Setup wizard
|
|
343
|
-
|
|
344
|
-
Run the wizard to create or update your config interactively. If no config exists, any command will offer to launch it automatically.
|
|
81
|
+
The friendly way: an interactive menu โ no YAML required.
|
|
345
82
|
|
|
346
83
|
```sh
|
|
347
|
-
proxitor config
|
|
84
|
+
proxitor config # open the menu
|
|
85
|
+
proxitor config wizard # (re)run guided setup
|
|
348
86
|
```
|
|
349
87
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
- **OpenRouter API key** โ stored in config or set as `OPENROUTER_API_KEY` env var
|
|
353
|
-
- **Port** โ default `8828` (avoids conflicts with common dev servers on 8080)
|
|
354
|
-
- **Listen address** โ all interfaces (`0.0.0.0`), localhost only (`127.0.0.1`), or a custom address (IP, hostname, or `unix:/path`)
|
|
355
|
-
- **API base URL** โ default `https://openrouter.ai/api`; change for self-hosted or custom endpoints
|
|
356
|
-
- **Authentication type** โ `bearer` (default) or `oauth`; use `oauth` for custom proxy providers that pass tokens in the `Authorization: OAuth ...` header
|
|
357
|
-
- **Save location** โ project directory, `~/.config/proxitor/`, or `$XDG_CONFIG_HOME/proxitor/`
|
|
88
|
+
From the menu you can set your API key and connection, pick routing per model (with live provider pricing), tune caching, and add or edit model overrides. It pulls live data from OpenRouter, so you browse real models and providers with up-to-date prices.
|
|
358
89
|
|
|
359
|
-
|
|
90
|
+
Prefer to edit a file? The full **[configuration reference](./docs/configuration.md)** covers provider routing, per-model overrides, headers, caching modes, and every option. [`proxitor.config.example.yaml`](./proxitor.config.example.yaml) is a commented template.
|
|
360
91
|
|
|
361
|
-
|
|
92
|
+
## Adding a model override
|
|
362
93
|
|
|
363
|
-
|
|
94
|
+
Pin a model โ or a wildcard like `claude-*` โ to specific providers, straight from the menu. It pulls live pricing and latency for every provider of that model.
|
|
364
95
|
|
|
365
|
-
|
|
96
|
+
<p align="center"><img src="./docs/assets/proxitor-add.gif" alt="proxitor: add a model override" width="640"></p>
|
|
366
97
|
|
|
367
|
-
|
|
368
|
-
- **API key & connection** โ change API key, port, listen address, base URL, auth type
|
|
369
|
-
- **Session routing** โ set global `sessionId` mode (`auto` / `always` / `skip`)
|
|
370
|
-
- **Cache control** โ set global `cacheControl` mode and TTL
|
|
371
|
-
- **Model overrides** โ add, edit, remove, list, or browse models
|
|
98
|
+
## When something's off
|
|
372
99
|
|
|
373
100
|
```sh
|
|
374
|
-
proxitor config
|
|
375
|
-
proxitor config add # add a model override
|
|
376
|
-
proxitor config edit # edit existing override
|
|
377
|
-
proxitor config remove # remove override(s)
|
|
378
|
-
proxitor config list # show current overrides
|
|
379
|
-
proxitor config list --json # overrides as JSON
|
|
380
|
-
proxitor config show # print the resolved config (merged)
|
|
381
|
-
proxitor config show --json # same, machine-readable
|
|
382
|
-
proxitor config browse # explore models with pricing info
|
|
383
|
-
proxitor config wizard # interactive setup wizard
|
|
384
|
-
proxitor config validate # validate config file (exit 0 ok, 1 invalid)
|
|
385
|
-
proxitor config validate --json # structured JSON result
|
|
386
|
-
proxitor doctor # diagnose environment + network + port + version
|
|
387
|
-
proxitor doctor --json # machine-readable diagnostic report
|
|
388
|
-
proxitor doctor --offline # skip network checks
|
|
101
|
+
proxitor doctor # checks environment, config, key, network, port, version
|
|
389
102
|
```
|
|
390
103
|
|
|
391
|
-
|
|
104
|
+
It prints a clear report and exits non-zero if anything fails โ handy from CI too (`--json`, `--offline`, `--timeout`).
|
|
392
105
|
|
|
393
|
-
|
|
106
|
+
While proxitor runs, it logs cache usage from upstream so you can see whether caching is actually helping:
|
|
394
107
|
|
|
395
|
-
### Add override walkthrough
|
|
396
|
-
|
|
397
|
-
```sh
|
|
398
|
-
$ proxitor config add
|
|
399
|
-
|
|
400
|
-
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
401
|
-
โ Add Model Override โ
|
|
402
|
-
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
|
|
403
|
-
|
|
404
|
-
โ Search for a model
|
|
405
|
-
โ claude
|
|
406
|
-
(23 matches)
|
|
407
|
-
โ anthropic/claude-sonnet-4-6 ยท $3.00/$15.00 ยท 200k
|
|
408
|
-
โ anthropic/claude-opus-4-8 ยท $15.00/$75.00 ยท 200k
|
|
409
|
-
...
|
|
410
|
-
|
|
411
|
-
โ Configure provider routing
|
|
412
|
-
โ โ Use specific providers only
|
|
413
|
-
โ Set provider priority order
|
|
414
|
-
โ Ignore specific providers
|
|
415
|
-
โ Skip provider routing
|
|
416
108
|
```
|
|
417
|
-
|
|
418
|
-
**"Use specific providers only" / "Ignore specific providers"** โ multiselect, pick all that apply:
|
|
419
|
-
|
|
420
|
-
```text
|
|
421
|
-
โ Select providers
|
|
422
|
-
โผ anthropic (anthropic) ยท 1.0s ยท 40 t/s
|
|
423
|
-
โป google-vertex/global ยท 1.1s ยท 39 t/s
|
|
424
|
-
โป amazon-bedrock ยท 1.2s ยท 40 t/s
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
**"Set provider priority order"** โ pick providers one at a time, then select **โ Done** at the bottom to finish:
|
|
428
|
-
|
|
429
|
-
```text
|
|
430
|
-
โ Select provider #1 (or cancel to finish)
|
|
431
|
-
โ โ anthropic (anthropic) ยท 1.0s ยท 40 t/s
|
|
432
|
-
โ google-vertex/global ยท 1.1s ยท 39 t/s
|
|
433
|
-
โ amazon-bedrock ยท 1.2s ยท 40 t/s
|
|
434
|
-
โ โ Done
|
|
435
|
-
|
|
436
|
-
โ Select provider #2 (or cancel to finish)
|
|
437
|
-
โ โ google-vertex/global ยท 1.1s ยท 39 t/s
|
|
438
|
-
โ amazon-bedrock ยท 1.2s ยท 40 t/s
|
|
439
|
-
โ โ Done
|
|
440
|
-
|
|
441
|
-
โ Select provider #3 (or cancel to finish)
|
|
442
|
-
โ โ โ Done
|
|
443
|
-
|
|
444
|
-
โ Allow fallbacks to other providers? Yes
|
|
445
|
-
|
|
446
|
-
โ Save to config? Yes
|
|
447
|
-
|
|
448
|
-
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ
|
|
449
|
-
โ โ Model override saved โ
|
|
450
|
-
โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
|
|
451
|
-
```
|
|
452
|
-
|
|
453
|
-
The interface uses live data from the OpenRouter API โ model search with type-ahead, real provider availability and pricing for each model.
|
|
454
|
-
|
|
455
|
-
---
|
|
456
|
-
|
|
457
|
-
## Diagnostics
|
|
458
|
-
|
|
459
|
-
When something doesn't work, `proxitor doctor` runs a battery of checks and prints a report. Sections cover:
|
|
460
|
-
|
|
461
|
-
- **Environment** โ Node version, platform, TTY
|
|
462
|
-
- **Config** โ discovery path, validity, override count
|
|
463
|
-
- **API key** โ resolution (env vs. file; never prints the key)
|
|
464
|
-
- **Network** โ upstream reachability (with configurable timeout)
|
|
465
|
-
- **Port** โ availability of the configured port
|
|
466
|
-
- **Version** โ installed version
|
|
467
|
-
|
|
468
|
-
Statuses: `โ ok` / `โ warn` / `โ fail` / `โ skip`. Exit code is `0` when no `fail`, `1` otherwise โ scriptable from CI.
|
|
469
|
-
|
|
470
|
-
```sh
|
|
471
|
-
$ proxitor doctor
|
|
472
|
-
|
|
473
|
-
โฒ Proxitor Doctor
|
|
474
|
-
โ
|
|
475
|
-
โ Environment
|
|
476
|
-
โ โ node-version โ v22.4.1
|
|
477
|
-
โ โ platform โ darwin arm64
|
|
478
|
-
โ โ tty โ true
|
|
479
|
-
โ
|
|
480
|
-
โ Config
|
|
481
|
-
โ โ config-found โ /Users/u/proj/proxitor.config.yaml
|
|
482
|
-
โ โ config-valid โ 12 keys, 3 override(s)
|
|
483
|
-
โ
|
|
484
|
-
โ API key
|
|
485
|
-
โ โ api-key โ set (env: set, file: set)
|
|
486
|
-
โ
|
|
487
|
-
โ Network
|
|
488
|
-
โ โ upstream โ https://openrouter.ai/api โ 200, 342 models
|
|
489
|
-
โ
|
|
490
|
-
โ Port
|
|
491
|
-
โ โ port-8828 โ 127.0.0.1:8828
|
|
492
|
-
โ
|
|
493
|
-
โ Version
|
|
494
|
-
โ โ version โ 0.9.0-beta.5
|
|
495
|
-
|
|
496
|
-
โ Done. All checks passed.
|
|
497
|
-
```
|
|
498
|
-
|
|
499
|
-
Useful flags:
|
|
500
|
-
|
|
501
|
-
```sh
|
|
502
|
-
proxitor doctor --json # structured JSON for CI / scripts
|
|
503
|
-
proxitor doctor --offline # skip network checks (no upstream, no npm)
|
|
504
|
-
proxitor doctor --timeout 5000 # custom per-check network timeout (ms)
|
|
109
|
+
[abc123] Cache read: 50000, write: 25000 tokens (99.6% hit)
|
|
505
110
|
```
|
|
506
111
|
|
|
507
|
-
|
|
112
|
+
Quick health poke: `curl http://localhost:8828/health`.
|
|
508
113
|
|
|
509
|
-
##
|
|
114
|
+
## Commands at a glance
|
|
510
115
|
|
|
511
116
|
```sh
|
|
512
|
-
proxitor
|
|
513
|
-
proxitor
|
|
514
|
-
proxitor
|
|
515
|
-
proxitor
|
|
516
|
-
proxitor
|
|
517
|
-
proxitor --
|
|
518
|
-
proxitor config show # print the resolved config
|
|
519
|
-
proxitor config show --json # machine-readable config
|
|
520
|
-
proxitor config list --json # overrides as JSON
|
|
521
|
-
proxitor config wizard # interactive setup
|
|
522
|
-
proxitor config validate # check the current config (exit 0/1)
|
|
523
|
-
proxitor config validate --json # structured JSON result
|
|
524
|
-
proxitor doctor # diagnose environment, network, port, version
|
|
525
|
-
proxitor doctor --offline # skip network checks
|
|
526
|
-
proxitor --help # full help
|
|
527
|
-
proxitor --version # print version
|
|
117
|
+
proxitor # start the proxy (the default command)
|
|
118
|
+
proxitor config # interactive config menu
|
|
119
|
+
proxitor config wizard # guided setup
|
|
120
|
+
proxitor config browse # explore models + pricing
|
|
121
|
+
proxitor doctor # diagnose everything
|
|
122
|
+
proxitor --help # the rest of the flags
|
|
528
123
|
```
|
|
529
124
|
|
|
530
|
-
|
|
531
|
-
|---|---|---|
|
|
532
|
-
| `-p, --port <port>` | `8828` | Server port (validated: 1-65535) |
|
|
533
|
-
| `--host <host>` | `0.0.0.0` | Server host |
|
|
534
|
-
| `-c, --config <path>` | auto-discovered | Path to config file |
|
|
535
|
-
| `--openrouter-key <key>` / `-k <key>` | `$OPENROUTER_API_KEY` | OpenRouter API key |
|
|
536
|
-
| `--verbose` | `false` | Enable verbose logging |
|
|
537
|
-
| `--no-config` | | Skip config file discovery |
|
|
538
|
-
| `-v, --version` | | Print version |
|
|
539
|
-
| `--help` | | Print help |
|
|
125
|
+
Common flags: `--port`, `--host`, `--config <path>`, `--openrouter-key <key>`. Run `proxitor --help` and `proxitor config --help` for the full list.
|
|
540
126
|
|
|
541
|
-
|
|
127
|
+
## Contributing
|
|
542
128
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
## Development
|
|
546
|
-
|
|
547
|
-
```sh
|
|
548
|
-
pnpm install # install dependencies
|
|
549
|
-
pnpm dev # build + watch
|
|
550
|
-
pnpm test # run tests
|
|
551
|
-
pnpm test:e2e # end-to-end tests
|
|
552
|
-
pnpm typecheck # TypeScript check
|
|
553
|
-
pnpm check:biome # lint + format check
|
|
554
|
-
pnpm lint:fix # auto-fix lint issues
|
|
555
|
-
pnpm build # production build
|
|
556
|
-
pnpm check # typecheck + biome + test (full CI)
|
|
557
|
-
```
|
|
558
|
-
|
|
559
|
-
---
|
|
129
|
+
PRs welcome โ see **[CONTRIBUTING.md](./CONTRIBUTING.md)** for setup, tests, commits, and changesets.
|
|
560
130
|
|
|
561
131
|
## License
|
|
562
132
|
|