proxitor 0.9.0-beta.7 → 0.9.0-beta.9
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 +9 -9
- package/dist/cli.mjs +16 -12
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -258,17 +258,17 @@ By default, OpenRouter doesn't enable prompt caching — every request pays full
|
|
|
258
258
|
|
|
259
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
260
|
|
|
261
|
-
**`cacheControlTtl`** (`5m` / `1h` / `omit` / `
|
|
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
262
|
|
|
263
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
264
|
|
|
265
|
-
Both `cacheControl` and `sessionId` support `auto` / `always` / `
|
|
265
|
+
Both `cacheControl` and `sessionId` support `auto` / `always` / `skip` modes:
|
|
266
266
|
|
|
267
267
|
| Mode | `cacheControl` | `sessionId` |
|
|
268
268
|
| --- | --- | --- |
|
|
269
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
270
|
| `always` | All models, all endpoints | Always generate proxy session ID, ignoring client-provided |
|
|
271
|
-
| `
|
|
271
|
+
| `skip` | Passthrough: leave the client's `cache_control` untouched and inject nothing | Passthrough: leave client session headers untouched |
|
|
272
272
|
|
|
273
273
|
`cacheControlTtl` values:
|
|
274
274
|
|
|
@@ -278,9 +278,9 @@ Both `cacheControl` and `sessionId` support `auto` / `always` / `never` modes:
|
|
|
278
278
|
| `5m` | 5 minutes (Anthropic default) | 1.25× | Explicit short cache; high-frequency requests (>1 per 5 min) |
|
|
279
279
|
| `1h` | 1 hour | 2.0× | Low-frequency or long-running sessions |
|
|
280
280
|
| `omit` | Strip the `ttl` field, guaranteeing no TTL (even one sent by the client) | — | Force-disable TTL |
|
|
281
|
-
| `
|
|
281
|
+
| `skip` | Passthrough: preserve the client's `ttl`, add nothing, ignore an inherited value | — | Ignore global TTL without stripping |
|
|
282
282
|
|
|
283
|
-
> **Note:** `null` (previously accepted in model overrides to cancel an inherited TTL) is **removed** — migrate to `
|
|
283
|
+
> **Note:** `null` (previously accepted in model overrides to cancel an inherited TTL) is **removed** — migrate to `skip`. `null` was undocumented and unsettable from the UI.
|
|
284
284
|
|
|
285
285
|
```yaml
|
|
286
286
|
cacheControl: auto # safe default — Anthropic and safe endpoints only
|
|
@@ -292,13 +292,13 @@ cacheControlTtl: 1h
|
|
|
292
292
|
# Force caching for all models (may cause 400 on non-Anthropic /v1/chat/completions)
|
|
293
293
|
# cacheControl: always
|
|
294
294
|
|
|
295
|
-
# Per-model overrides — TTL supports '5m', '1h', 'omit', or '
|
|
295
|
+
# Per-model overrides — TTL supports '5m', '1h', 'omit', or 'skip' (passthrough)
|
|
296
296
|
modelOverrides:
|
|
297
297
|
"gpt-*":
|
|
298
|
-
cacheControl:
|
|
298
|
+
cacheControl: skip # OpenAI caches automatically, no injection needed
|
|
299
299
|
sessionId: always # but sticky routing still helps
|
|
300
300
|
"claude-opus-*":
|
|
301
|
-
cacheControlTtl:
|
|
301
|
+
cacheControlTtl: skip # passthrough for Opus — ignore the global 1h TTL, use the client ttl
|
|
302
302
|
```
|
|
303
303
|
|
|
304
304
|
**Why all three matter:**
|
|
@@ -366,7 +366,7 @@ If a config already exists, the wizard shows its location and asks whether to re
|
|
|
366
366
|
|
|
367
367
|
- **Show current config** — display the resolved configuration
|
|
368
368
|
- **API key & connection** — change API key, port, listen address, base URL, auth type
|
|
369
|
-
- **Session routing** — set global `sessionId` mode (`auto` / `always` / `
|
|
369
|
+
- **Session routing** — set global `sessionId` mode (`auto` / `always` / `skip`)
|
|
370
370
|
- **Cache control** — set global `cacheControl` mode and TTL
|
|
371
371
|
- **Model overrides** — add, edit, remove, list, or browse models
|
|
372
372
|
|
package/dist/cli.mjs
CHANGED
|
@@ -11953,13 +11953,13 @@ const providerConfigSchema = object({
|
|
|
11953
11953
|
const triStateSchema = _enum([
|
|
11954
11954
|
"auto",
|
|
11955
11955
|
"always",
|
|
11956
|
-
"
|
|
11956
|
+
"skip"
|
|
11957
11957
|
]);
|
|
11958
11958
|
const ttlSchema = _enum([
|
|
11959
11959
|
"5m",
|
|
11960
11960
|
"1h",
|
|
11961
11961
|
"omit",
|
|
11962
|
-
"
|
|
11962
|
+
"skip"
|
|
11963
11963
|
]);
|
|
11964
11964
|
const modelOverrideSchema = object({
|
|
11965
11965
|
provider: providerConfigSchema.optional(),
|
|
@@ -20042,6 +20042,10 @@ async function selectRoutingMode(message) {
|
|
|
20042
20042
|
});
|
|
20043
20043
|
}
|
|
20044
20044
|
async function selectProvidersByMode(mode, providerOptions) {
|
|
20045
|
+
if (providerOptions.length === 0) {
|
|
20046
|
+
log.warn("No providers available for this model — cannot configure provider routing.");
|
|
20047
|
+
return null;
|
|
20048
|
+
}
|
|
20045
20049
|
if (mode === "only") return selectOnlyProviders(providerOptions);
|
|
20046
20050
|
if (mode === "order") return selectOrderedProviders(providerOptions);
|
|
20047
20051
|
if (mode === "ignore") return selectIgnoreProviders(providerOptions);
|
|
@@ -20226,13 +20230,13 @@ async function askHost(current) {
|
|
|
20226
20230
|
const SESSION_HINTS = {
|
|
20227
20231
|
auto: "Passthrough client ID, generate if missing",
|
|
20228
20232
|
always: "Always generate proxy session ID",
|
|
20229
|
-
|
|
20233
|
+
skip: "Passthrough — leave client session headers as-is"
|
|
20230
20234
|
};
|
|
20231
20235
|
/** Shared hint texts for cache control tri-state — used in add, edit, cache-control. */
|
|
20232
20236
|
const CACHE_HINTS = {
|
|
20233
20237
|
auto: "Anthropic models only",
|
|
20234
20238
|
always: "All models",
|
|
20235
|
-
|
|
20239
|
+
skip: "Passthrough — leave client cache_control headers as-is"
|
|
20236
20240
|
};
|
|
20237
20241
|
async function askTriState(message, current, hints, opts) {
|
|
20238
20242
|
const options = [
|
|
@@ -20247,9 +20251,9 @@ async function askTriState(message, current, hints, opts) {
|
|
|
20247
20251
|
hint: hints.always
|
|
20248
20252
|
},
|
|
20249
20253
|
{
|
|
20250
|
-
value: "
|
|
20251
|
-
label: "
|
|
20252
|
-
hint: hints.
|
|
20254
|
+
value: "skip",
|
|
20255
|
+
label: "skip",
|
|
20256
|
+
hint: hints.skip
|
|
20253
20257
|
}
|
|
20254
20258
|
];
|
|
20255
20259
|
if (opts?.removable) options.push({
|
|
@@ -20278,7 +20282,7 @@ async function askCacheControlTtl(current, opts) {
|
|
|
20278
20282
|
hint: "Higher write cost"
|
|
20279
20283
|
},
|
|
20280
20284
|
{
|
|
20281
|
-
value: "
|
|
20285
|
+
value: "skip",
|
|
20282
20286
|
label: "Passthrough",
|
|
20283
20287
|
hint: `Preserve client ttl, ${overrides}`
|
|
20284
20288
|
},
|
|
@@ -20608,7 +20612,7 @@ function formatOverrideHint(override) {
|
|
|
20608
20612
|
function formatCacheHint(cc, ttl) {
|
|
20609
20613
|
let ttlLabel = ttl ?? "";
|
|
20610
20614
|
if (ttl === "omit") ttlLabel = "ttl strip";
|
|
20611
|
-
else if (ttl === "
|
|
20615
|
+
else if (ttl === "skip") ttlLabel = "ttl passthrough";
|
|
20612
20616
|
return [cc, ttlLabel].filter(Boolean).join(", ") || "(inherit)";
|
|
20613
20617
|
}
|
|
20614
20618
|
function readGlobalTtl(configPath) {
|
|
@@ -21472,7 +21476,7 @@ async function runConfigMenu(client) {
|
|
|
21472
21476
|
}
|
|
21473
21477
|
//#endregion
|
|
21474
21478
|
//#region src/version.ts
|
|
21475
|
-
const version = "0.9.0-beta.
|
|
21479
|
+
const version = "0.9.0-beta.9";
|
|
21476
21480
|
//#endregion
|
|
21477
21481
|
//#region src/commands/doctor.ts
|
|
21478
21482
|
const DEFAULT_TIMEOUT_MS = 3e3;
|
|
@@ -24756,7 +24760,7 @@ function isAnthropicEndpoint(modelName, path) {
|
|
|
24756
24760
|
return ANTHROPIC_NATIVE_ENDPOINTS.has(endpoint) || isAnthropicModel(modelName ?? "");
|
|
24757
24761
|
}
|
|
24758
24762
|
function shouldInjectCacheControl(mode, modelName, path) {
|
|
24759
|
-
if (mode === "
|
|
24763
|
+
if (mode === "skip") return false;
|
|
24760
24764
|
if (mode === "always") return true;
|
|
24761
24765
|
return isAnthropicEndpoint(modelName, path);
|
|
24762
24766
|
}
|
|
@@ -24841,7 +24845,7 @@ function extractConversationFingerprint(parsedBody, path) {
|
|
|
24841
24845
|
return hash.digest("hex");
|
|
24842
24846
|
}
|
|
24843
24847
|
function deriveSessionId(incomingHeaders, parsedBody, path, mode) {
|
|
24844
|
-
if (mode === "
|
|
24848
|
+
if (mode === "skip") return void 0;
|
|
24845
24849
|
if (mode === "auto") {
|
|
24846
24850
|
const fromHeader = incomingHeaders.get("x-claude-code-session-id");
|
|
24847
24851
|
if (fromHeader) return fromHeader.slice(0, 256);
|