proxitor 0.9.0-beta.6 → 0.9.0-beta.7
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 +12 -6
- package/dist/cli.mjs +150 -132
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -258,7 +258,7 @@ 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`**
|
|
261
|
+
**`cacheControlTtl`** (`5m` / `1h` / `omit` / `never`, 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
|
|
|
@@ -268,15 +268,19 @@ Both `cacheControl` and `sessionId` support `auto` / `always` / `never` modes:
|
|
|
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
|
-
| `never` |
|
|
271
|
+
| `never` | 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
|
|
|
275
275
|
| Value | TTL | Write cost | Use when |
|
|
276
276
|
| --- | --- | --- | --- |
|
|
277
|
-
| _(
|
|
278
|
-
| `5m` | 5 minutes | 1.25× | Explicit short cache |
|
|
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
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
|
+
| `never` | Passthrough: preserve the client's `ttl`, add nothing, ignore an inherited value | — | Ignore global TTL without stripping |
|
|
282
|
+
|
|
283
|
+
> **Note:** `null` (previously accepted in model overrides to cancel an inherited TTL) is **removed** — migrate to `never`. `null` was undocumented and unsettable from the UI.
|
|
280
284
|
|
|
281
285
|
```yaml
|
|
282
286
|
cacheControl: auto # safe default — Anthropic and safe endpoints only
|
|
@@ -288,13 +292,13 @@ cacheControlTtl: 1h
|
|
|
288
292
|
# Force caching for all models (may cause 400 on non-Anthropic /v1/chat/completions)
|
|
289
293
|
# cacheControl: always
|
|
290
294
|
|
|
291
|
-
# Per-model overrides — TTL supports '5m', '1h', or
|
|
295
|
+
# Per-model overrides — TTL supports '5m', '1h', 'omit', or 'never' (passthrough)
|
|
292
296
|
modelOverrides:
|
|
293
297
|
"gpt-*":
|
|
294
298
|
cacheControl: never # OpenAI caches automatically, no injection needed
|
|
295
299
|
sessionId: always # but sticky routing still helps
|
|
296
300
|
"claude-opus-*":
|
|
297
|
-
cacheControlTtl:
|
|
301
|
+
cacheControlTtl: never # passthrough for Opus — ignore the global 1h TTL, use the client ttl
|
|
298
302
|
```
|
|
299
303
|
|
|
300
304
|
**Why all three matter:**
|
|
@@ -386,6 +390,8 @@ proxitor doctor --offline # skip network checks
|
|
|
386
390
|
|
|
387
391
|
When adding or editing a model override, you can also configure per-model `sessionId` and `cacheControl` — useful for models that need different caching or routing behavior than the global default.
|
|
388
392
|
|
|
393
|
+
In `config edit`, any field (provider, session ID, cache control, cache TTL) can be reset to inherit the global/default value via the **Reset / inherit** prompt option. The global `config cache-control` and `config session-routing` commands support the same reset — it reverts the field to the schema default.
|
|
394
|
+
|
|
389
395
|
### Add override walkthrough
|
|
390
396
|
|
|
391
397
|
```sh
|
package/dist/cli.mjs
CHANGED
|
@@ -8369,7 +8369,6 @@ const string$2 = (params) => {
|
|
|
8369
8369
|
const integer = /^-?\d+$/;
|
|
8370
8370
|
const number$2 = /^-?\d+(?:\.\d+)?$/;
|
|
8371
8371
|
const boolean$1 = /^(?:true|false)$/i;
|
|
8372
|
-
const _null$2 = /^null$/i;
|
|
8373
8372
|
const lowercase = /^[^A-Z]*$/;
|
|
8374
8373
|
const uppercase = /^[^a-z]*$/;
|
|
8375
8374
|
//#endregion
|
|
@@ -9182,22 +9181,6 @@ const $ZodBoolean = /*@__PURE__*/ $constructor("$ZodBoolean", (inst, def) => {
|
|
|
9182
9181
|
return payload;
|
|
9183
9182
|
};
|
|
9184
9183
|
});
|
|
9185
|
-
const $ZodNull = /*@__PURE__*/ $constructor("$ZodNull", (inst, def) => {
|
|
9186
|
-
$ZodType.init(inst, def);
|
|
9187
|
-
inst._zod.pattern = _null$2;
|
|
9188
|
-
inst._zod.values = new Set([null]);
|
|
9189
|
-
inst._zod.parse = (payload, _ctx) => {
|
|
9190
|
-
const input = payload.value;
|
|
9191
|
-
if (input === null) return payload;
|
|
9192
|
-
payload.issues.push({
|
|
9193
|
-
expected: "null",
|
|
9194
|
-
code: "invalid_type",
|
|
9195
|
-
input,
|
|
9196
|
-
inst
|
|
9197
|
-
});
|
|
9198
|
-
return payload;
|
|
9199
|
-
};
|
|
9200
|
-
});
|
|
9201
9184
|
const $ZodUnknown = /*@__PURE__*/ $constructor("$ZodUnknown", (inst, def) => {
|
|
9202
9185
|
$ZodType.init(inst, def);
|
|
9203
9186
|
inst._zod.parse = (payload) => payload;
|
|
@@ -10346,13 +10329,6 @@ function _boolean(Class, params) {
|
|
|
10346
10329
|
});
|
|
10347
10330
|
}
|
|
10348
10331
|
// @__NO_SIDE_EFFECTS__
|
|
10349
|
-
function _null$1(Class, params) {
|
|
10350
|
-
return new Class({
|
|
10351
|
-
type: "null",
|
|
10352
|
-
...normalizeParams(params)
|
|
10353
|
-
});
|
|
10354
|
-
}
|
|
10355
|
-
// @__NO_SIDE_EFFECTS__
|
|
10356
10332
|
function _unknown(Class) {
|
|
10357
10333
|
return new Class({ type: "unknown" });
|
|
10358
10334
|
}
|
|
@@ -10901,13 +10877,6 @@ const numberProcessor = (schema, ctx, _json, _params) => {
|
|
|
10901
10877
|
const booleanProcessor = (_schema, _ctx, json, _params) => {
|
|
10902
10878
|
json.type = "boolean";
|
|
10903
10879
|
};
|
|
10904
|
-
const nullProcessor = (_schema, ctx, json, _params) => {
|
|
10905
|
-
if (ctx.target === "openapi-3.0") {
|
|
10906
|
-
json.type = "string";
|
|
10907
|
-
json.nullable = true;
|
|
10908
|
-
json.enum = [null];
|
|
10909
|
-
} else json.type = "null";
|
|
10910
|
-
};
|
|
10911
10880
|
const neverProcessor = (_schema, _ctx, json, _params) => {
|
|
10912
10881
|
json.not = {};
|
|
10913
10882
|
};
|
|
@@ -11577,14 +11546,6 @@ const ZodBoolean = /*@__PURE__*/ $constructor("ZodBoolean", (inst, def) => {
|
|
|
11577
11546
|
function boolean(params) {
|
|
11578
11547
|
return /* @__PURE__ */ _boolean(ZodBoolean, params);
|
|
11579
11548
|
}
|
|
11580
|
-
const ZodNull = /*@__PURE__*/ $constructor("ZodNull", (inst, def) => {
|
|
11581
|
-
$ZodNull.init(inst, def);
|
|
11582
|
-
ZodType.init(inst, def);
|
|
11583
|
-
inst._zod.processJSONSchema = (ctx, json, params) => nullProcessor(inst, ctx, json, params);
|
|
11584
|
-
});
|
|
11585
|
-
function _null(params) {
|
|
11586
|
-
return /* @__PURE__ */ _null$1(ZodNull, params);
|
|
11587
|
-
}
|
|
11588
11549
|
const ZodUnknown = /*@__PURE__*/ $constructor("ZodUnknown", (inst, def) => {
|
|
11589
11550
|
$ZodUnknown.init(inst, def);
|
|
11590
11551
|
ZodType.init(inst, def);
|
|
@@ -11994,11 +11955,17 @@ const triStateSchema = _enum([
|
|
|
11994
11955
|
"always",
|
|
11995
11956
|
"never"
|
|
11996
11957
|
]);
|
|
11958
|
+
const ttlSchema = _enum([
|
|
11959
|
+
"5m",
|
|
11960
|
+
"1h",
|
|
11961
|
+
"omit",
|
|
11962
|
+
"never"
|
|
11963
|
+
]);
|
|
11997
11964
|
const modelOverrideSchema = object({
|
|
11998
11965
|
provider: providerConfigSchema.optional(),
|
|
11999
11966
|
headers: record(string$1(), string$1()).optional(),
|
|
12000
11967
|
cacheControl: triStateSchema.optional(),
|
|
12001
|
-
cacheControlTtl:
|
|
11968
|
+
cacheControlTtl: ttlSchema.optional(),
|
|
12002
11969
|
sessionId: triStateSchema.optional()
|
|
12003
11970
|
}).strict();
|
|
12004
11971
|
const proxyConfigSchema = object({
|
|
@@ -12015,7 +11982,7 @@ const proxyConfigSchema = object({
|
|
|
12015
11982
|
attributionTitle: string$1().min(1).default("proxitor"),
|
|
12016
11983
|
headers: record(string$1(), string$1()).optional(),
|
|
12017
11984
|
cacheControl: triStateSchema.default("auto"),
|
|
12018
|
-
cacheControlTtl:
|
|
11985
|
+
cacheControlTtl: ttlSchema.optional(),
|
|
12019
11986
|
sessionId: triStateSchema.default("auto"),
|
|
12020
11987
|
modelOverrides: record(string$1().min(1), modelOverrideSchema).optional()
|
|
12021
11988
|
}).strict();
|
|
@@ -12171,7 +12138,7 @@ function applyOverride(result, override) {
|
|
|
12171
12138
|
...override.headers
|
|
12172
12139
|
};
|
|
12173
12140
|
if (override.cacheControl !== void 0) result.cacheControl = override.cacheControl;
|
|
12174
|
-
if (override.cacheControlTtl !== void 0) result.cacheControlTtl = override.cacheControlTtl
|
|
12141
|
+
if (override.cacheControlTtl !== void 0) result.cacheControlTtl = override.cacheControlTtl;
|
|
12175
12142
|
if (override.sessionId !== void 0) result.sessionId = override.sessionId;
|
|
12176
12143
|
}
|
|
12177
12144
|
/** Reject base URLs ending in /v1 — paths are forwarded as-is, so /v1 suffix causes doubled paths. */
|
|
@@ -20259,85 +20226,113 @@ async function askHost(current) {
|
|
|
20259
20226
|
const SESSION_HINTS = {
|
|
20260
20227
|
auto: "Passthrough client ID, generate if missing",
|
|
20261
20228
|
always: "Always generate proxy session ID",
|
|
20262
|
-
never: "
|
|
20229
|
+
never: "Passthrough — leave client session headers as-is"
|
|
20263
20230
|
};
|
|
20264
20231
|
/** Shared hint texts for cache control tri-state — used in add, edit, cache-control. */
|
|
20265
20232
|
const CACHE_HINTS = {
|
|
20266
20233
|
auto: "Anthropic models only",
|
|
20267
20234
|
always: "All models",
|
|
20268
|
-
never: "
|
|
20235
|
+
never: "Passthrough — leave client cache_control headers as-is"
|
|
20269
20236
|
};
|
|
20270
|
-
async function askTriState(message, current, hints) {
|
|
20271
|
-
const
|
|
20237
|
+
async function askTriState(message, current, hints, opts) {
|
|
20238
|
+
const options = [
|
|
20239
|
+
{
|
|
20240
|
+
value: "auto",
|
|
20241
|
+
label: "auto",
|
|
20242
|
+
hint: hints.auto
|
|
20243
|
+
},
|
|
20244
|
+
{
|
|
20245
|
+
value: "always",
|
|
20246
|
+
label: "always",
|
|
20247
|
+
hint: hints.always
|
|
20248
|
+
},
|
|
20249
|
+
{
|
|
20250
|
+
value: "never",
|
|
20251
|
+
label: "never",
|
|
20252
|
+
hint: hints.never
|
|
20253
|
+
}
|
|
20254
|
+
];
|
|
20255
|
+
if (opts?.removable) options.push({
|
|
20256
|
+
value: "reset",
|
|
20257
|
+
label: "Reset / inherit",
|
|
20258
|
+
hint: "Remove override"
|
|
20259
|
+
});
|
|
20260
|
+
return await select({
|
|
20272
20261
|
message,
|
|
20273
20262
|
initialValue: current ?? "auto",
|
|
20274
|
-
options
|
|
20275
|
-
{
|
|
20276
|
-
value: "auto",
|
|
20277
|
-
label: "auto",
|
|
20278
|
-
hint: hints.auto
|
|
20279
|
-
},
|
|
20280
|
-
{
|
|
20281
|
-
value: "always",
|
|
20282
|
-
label: "always",
|
|
20283
|
-
hint: hints.always
|
|
20284
|
-
},
|
|
20285
|
-
{
|
|
20286
|
-
value: "never",
|
|
20287
|
-
label: "never",
|
|
20288
|
-
hint: hints.never
|
|
20289
|
-
}
|
|
20290
|
-
]
|
|
20263
|
+
options
|
|
20291
20264
|
});
|
|
20292
|
-
if (isCancel(result)) return null;
|
|
20293
|
-
return result;
|
|
20294
20265
|
}
|
|
20295
|
-
async function askCacheControlTtl(current) {
|
|
20296
|
-
const
|
|
20297
|
-
|
|
20298
|
-
|
|
20299
|
-
|
|
20300
|
-
|
|
20301
|
-
|
|
20302
|
-
|
|
20303
|
-
|
|
20304
|
-
|
|
20305
|
-
|
|
20266
|
+
async function askCacheControlTtl(current, opts) {
|
|
20267
|
+
const inherit = opts?.globalTtl === void 0 ? "inherit global (none)" : `inherit global (${opts.globalTtl})`;
|
|
20268
|
+
const overrides = opts?.globalTtl === void 0 ? "overrides inherited" : `overrides global ${opts.globalTtl}`;
|
|
20269
|
+
const options = [
|
|
20270
|
+
{
|
|
20271
|
+
value: "5m",
|
|
20272
|
+
label: "5 minutes",
|
|
20273
|
+
hint: "Anthropic default"
|
|
20274
|
+
},
|
|
20275
|
+
{
|
|
20276
|
+
value: "1h",
|
|
20277
|
+
label: "1 hour",
|
|
20278
|
+
hint: "Higher write cost"
|
|
20279
|
+
},
|
|
20280
|
+
{
|
|
20281
|
+
value: "never",
|
|
20282
|
+
label: "Passthrough",
|
|
20283
|
+
hint: `Preserve client ttl, ${overrides}`
|
|
20284
|
+
},
|
|
20285
|
+
{
|
|
20286
|
+
value: "omit",
|
|
20287
|
+
label: "Strip",
|
|
20288
|
+
hint: `Guarantee no ttl (${overrides})`
|
|
20289
|
+
}
|
|
20290
|
+
];
|
|
20291
|
+
if (opts?.removable) options.push({
|
|
20306
20292
|
value: "reset",
|
|
20307
|
-
label: "Reset
|
|
20308
|
-
hint:
|
|
20293
|
+
label: "Reset / inherit",
|
|
20294
|
+
hint: inherit
|
|
20309
20295
|
});
|
|
20310
|
-
|
|
20296
|
+
return await select({
|
|
20311
20297
|
message: "Cache TTL",
|
|
20312
20298
|
initialValue: current ?? "5m",
|
|
20313
20299
|
options
|
|
20314
20300
|
});
|
|
20315
|
-
if (isCancel(result)) return null;
|
|
20316
|
-
if (result === "reset") return "reset";
|
|
20317
|
-
return result;
|
|
20318
20301
|
}
|
|
20319
20302
|
//#endregion
|
|
20320
20303
|
//#region src/commands/config/tri-state.ts
|
|
20321
|
-
|
|
20322
|
-
|
|
20323
|
-
if (
|
|
20324
|
-
|
|
20304
|
+
/** Apply a resolved field: {value}→assign, {remove}→delete, undefined→keep. */
|
|
20305
|
+
function applyField(obj, key, field) {
|
|
20306
|
+
if (field === void 0) return;
|
|
20307
|
+
if ("remove" in field) delete obj[key];
|
|
20308
|
+
else obj[key] = field.value;
|
|
20325
20309
|
}
|
|
20326
|
-
|
|
20327
|
-
|
|
20328
|
-
|
|
20329
|
-
|
|
20330
|
-
|
|
20331
|
-
|
|
20332
|
-
|
|
20333
|
-
|
|
20334
|
-
|
|
20335
|
-
|
|
20336
|
-
|
|
20337
|
-
|
|
20338
|
-
|
|
20339
|
-
|
|
20340
|
-
|
|
20310
|
+
async function collectSessionTriState(currentSid) {
|
|
20311
|
+
const sid = await askTriState("Session ID mode", currentSid ?? "auto", SESSION_HINTS, { removable: true });
|
|
20312
|
+
if (typeof sid === "symbol") return null;
|
|
20313
|
+
if (sid === "reset") return { sessionId: { remove: true } };
|
|
20314
|
+
return { sessionId: { value: sid } };
|
|
20315
|
+
}
|
|
20316
|
+
/** TTL is independent of cache mode. Mode-cancel aborts; TTL-cancel keeps existing TTL. */
|
|
20317
|
+
async function collectCacheTriState(currentCc, currentTtl, globalTtl) {
|
|
20318
|
+
const cc = await askTriState("Cache control mode", currentCc ?? "auto", CACHE_HINTS, { removable: true });
|
|
20319
|
+
if (typeof cc === "symbol") return null;
|
|
20320
|
+
let cacheControl;
|
|
20321
|
+
if (cc === "reset") cacheControl = { remove: true };
|
|
20322
|
+
else cacheControl = { value: cc };
|
|
20323
|
+
const ttl = await askCacheControlTtl(currentTtl, {
|
|
20324
|
+
removable: true,
|
|
20325
|
+
globalTtl
|
|
20326
|
+
});
|
|
20327
|
+
if (typeof ttl === "symbol") return { cacheControl };
|
|
20328
|
+
if (ttl === "reset") return {
|
|
20329
|
+
cacheControl,
|
|
20330
|
+
cacheControlTtl: { remove: true }
|
|
20331
|
+
};
|
|
20332
|
+
return {
|
|
20333
|
+
cacheControl,
|
|
20334
|
+
cacheControlTtl: { value: ttl }
|
|
20335
|
+
};
|
|
20341
20336
|
}
|
|
20342
20337
|
//#endregion
|
|
20343
20338
|
//#region src/commands/config/add.ts
|
|
@@ -20457,7 +20452,7 @@ async function collectSession(override) {
|
|
|
20457
20452
|
});
|
|
20458
20453
|
if (isCancel(want) || !want) return override;
|
|
20459
20454
|
const result = await collectSessionTriState();
|
|
20460
|
-
if (result) override.sessionId = result.sessionId;
|
|
20455
|
+
if (result && !("remove" in result.sessionId)) override.sessionId = result.sessionId.value;
|
|
20461
20456
|
return override;
|
|
20462
20457
|
}
|
|
20463
20458
|
async function collectCache(override) {
|
|
@@ -20468,8 +20463,8 @@ async function collectCache(override) {
|
|
|
20468
20463
|
if (isCancel(want) || !want) return override;
|
|
20469
20464
|
const result = await collectCacheTriState();
|
|
20470
20465
|
if (result) {
|
|
20471
|
-
override.cacheControl = result.cacheControl;
|
|
20472
|
-
if (result.cacheControlTtl) override.cacheControlTtl = result.cacheControlTtl;
|
|
20466
|
+
if (!("remove" in result.cacheControl)) override.cacheControl = result.cacheControl.value;
|
|
20467
|
+
if (result.cacheControlTtl && !("remove" in result.cacheControlTtl)) override.cacheControlTtl = result.cacheControlTtl.value;
|
|
20473
20468
|
}
|
|
20474
20469
|
return override;
|
|
20475
20470
|
}
|
|
@@ -20610,6 +20605,20 @@ function formatOverrideHint(override) {
|
|
|
20610
20605
|
if (override.headers) parts.push(`${Object.keys(override.headers).length} header(s)`);
|
|
20611
20606
|
return parts.join(", ") || "(empty)";
|
|
20612
20607
|
}
|
|
20608
|
+
function formatCacheHint(cc, ttl) {
|
|
20609
|
+
let ttlLabel = ttl ?? "";
|
|
20610
|
+
if (ttl === "omit") ttlLabel = "ttl strip";
|
|
20611
|
+
else if (ttl === "never") ttlLabel = "ttl passthrough";
|
|
20612
|
+
return [cc, ttlLabel].filter(Boolean).join(", ") || "(inherit)";
|
|
20613
|
+
}
|
|
20614
|
+
function readGlobalTtl(configPath) {
|
|
20615
|
+
if (!configPath) return void 0;
|
|
20616
|
+
try {
|
|
20617
|
+
return readConfigFile(configPath).cacheControlTtl;
|
|
20618
|
+
} catch {
|
|
20619
|
+
return;
|
|
20620
|
+
}
|
|
20621
|
+
}
|
|
20613
20622
|
function showCurrentConfig(modelKey, current) {
|
|
20614
20623
|
log.info(`Current config for "${modelKey}":`);
|
|
20615
20624
|
if (current.provider) for (const [field, value] of Object.entries(current.provider)) log.info(` provider.${field}: ${JSON.stringify(value)}`);
|
|
@@ -20638,21 +20647,19 @@ async function editProvider(modelKey, current, client) {
|
|
|
20638
20647
|
async function editSessionId(current) {
|
|
20639
20648
|
const result = await collectSessionTriState(current.sessionId);
|
|
20640
20649
|
if (result === null) return current;
|
|
20641
|
-
const
|
|
20642
|
-
|
|
20643
|
-
|
|
20644
|
-
sessionId: result.sessionId
|
|
20645
|
-
};
|
|
20650
|
+
const next = { ...current };
|
|
20651
|
+
applyField(next, "sessionId", result.sessionId);
|
|
20652
|
+
return next;
|
|
20646
20653
|
}
|
|
20647
20654
|
/** @internal */
|
|
20648
|
-
async function editCacheControl(current) {
|
|
20649
|
-
const
|
|
20655
|
+
async function editCacheControl(current, configPath) {
|
|
20656
|
+
const globalTtl = readGlobalTtl(configPath);
|
|
20657
|
+
const result = await collectCacheTriState(current.cacheControl, current.cacheControlTtl, globalTtl);
|
|
20650
20658
|
if (result === null) return current;
|
|
20651
|
-
const
|
|
20652
|
-
|
|
20653
|
-
|
|
20654
|
-
|
|
20655
|
-
};
|
|
20659
|
+
const next = { ...current };
|
|
20660
|
+
applyField(next, "cacheControl", result.cacheControl);
|
|
20661
|
+
applyField(next, "cacheControlTtl", result.cacheControlTtl);
|
|
20662
|
+
return next;
|
|
20656
20663
|
}
|
|
20657
20664
|
/** Run the interactive "Edit model override" flow. */
|
|
20658
20665
|
async function editOverrideCommand(client, configPath) {
|
|
@@ -20694,7 +20701,7 @@ async function editOverrideCommand(client, configPath) {
|
|
|
20694
20701
|
{
|
|
20695
20702
|
value: "cacheControl",
|
|
20696
20703
|
label: "Cache control",
|
|
20697
|
-
hint:
|
|
20704
|
+
hint: formatCacheHint(current.cacheControl, current.cacheControlTtl)
|
|
20698
20705
|
},
|
|
20699
20706
|
{
|
|
20700
20707
|
value: "done",
|
|
@@ -20711,7 +20718,7 @@ async function editOverrideCommand(client, configPath) {
|
|
|
20711
20718
|
current = await editSessionId(current);
|
|
20712
20719
|
break;
|
|
20713
20720
|
case "cacheControl":
|
|
20714
|
-
current = await editCacheControl(current);
|
|
20721
|
+
current = await editCacheControl(current, resolvedConfigPath);
|
|
20715
20722
|
break;
|
|
20716
20723
|
}
|
|
20717
20724
|
}
|
|
@@ -21251,18 +21258,21 @@ async function cacheControlCommand(opts) {
|
|
|
21251
21258
|
const currentTtl = cfg.cacheControlTtl;
|
|
21252
21259
|
log.info(`Current: cacheControl = ${currentCc}`);
|
|
21253
21260
|
if (currentTtl) log.info(`Current: cacheControlTtl = ${currentTtl}`);
|
|
21254
|
-
const cc = await askTriState("Cache control mode", currentCc, CACHE_HINTS);
|
|
21255
|
-
if (cc ===
|
|
21256
|
-
const fields = {
|
|
21257
|
-
|
|
21258
|
-
|
|
21259
|
-
|
|
21260
|
-
|
|
21261
|
-
|
|
21261
|
+
const cc = await askTriState("Cache control mode", currentCc, CACHE_HINTS, { removable: true });
|
|
21262
|
+
if (typeof cc === "symbol") return;
|
|
21263
|
+
const fields = {};
|
|
21264
|
+
fields.cacheControl = cc === "reset" ? void 0 : cc;
|
|
21265
|
+
const ttlResult = await askCacheControlTtl(currentTtl, { removable: true });
|
|
21266
|
+
if (typeof ttlResult === "symbol") {
|
|
21267
|
+
setGlobalConfigFields(configPath, fields);
|
|
21268
|
+
log.success(`cacheControl set to ${cc === "reset" ? "(default)" : cc}`);
|
|
21269
|
+
return;
|
|
21262
21270
|
}
|
|
21271
|
+
fields.cacheControlTtl = ttlResult === "reset" ? void 0 : ttlResult;
|
|
21263
21272
|
setGlobalConfigFields(configPath, fields);
|
|
21264
|
-
const
|
|
21265
|
-
|
|
21273
|
+
const ccLabel = cc === "reset" ? "(default)" : cc;
|
|
21274
|
+
const ttlLabel = ttlResult === "reset" ? "(default)" : ttlResult;
|
|
21275
|
+
log.success(`cacheControl set to ${ccLabel}, TTL = ${ttlLabel}`);
|
|
21266
21276
|
}
|
|
21267
21277
|
//#endregion
|
|
21268
21278
|
//#region src/commands/config/connection.ts
|
|
@@ -21343,8 +21353,13 @@ async function sessionRoutingCommand(opts) {
|
|
|
21343
21353
|
const configPath = requireConfigPath(opts?.configPath);
|
|
21344
21354
|
const current = readConfigFile(configPath).sessionId ?? DEFAULTS.sessionId;
|
|
21345
21355
|
log.info(`Current: sessionId = ${current}`);
|
|
21346
|
-
const result = await askTriState("Session routing mode", current, SESSION_HINTS);
|
|
21347
|
-
if (result ===
|
|
21356
|
+
const result = await askTriState("Session routing mode", current, SESSION_HINTS, { removable: true });
|
|
21357
|
+
if (typeof result === "symbol") return;
|
|
21358
|
+
if (result === "reset") {
|
|
21359
|
+
setGlobalConfigField(configPath, "sessionId", void 0);
|
|
21360
|
+
log.success("sessionId reset to default (auto)");
|
|
21361
|
+
return;
|
|
21362
|
+
}
|
|
21348
21363
|
setGlobalConfigField(configPath, "sessionId", result);
|
|
21349
21364
|
log.success(`sessionId set to ${result}`);
|
|
21350
21365
|
}
|
|
@@ -21457,7 +21472,7 @@ async function runConfigMenu(client) {
|
|
|
21457
21472
|
}
|
|
21458
21473
|
//#endregion
|
|
21459
21474
|
//#region src/version.ts
|
|
21460
|
-
const version = "0.9.0-beta.
|
|
21475
|
+
const version = "0.9.0-beta.7";
|
|
21461
21476
|
//#endregion
|
|
21462
21477
|
//#region src/commands/doctor.ts
|
|
21463
21478
|
const DEFAULT_TIMEOUT_MS = 3e3;
|
|
@@ -24748,7 +24763,10 @@ function shouldInjectCacheControl(mode, modelName, path) {
|
|
|
24748
24763
|
function buildCacheControl(existing, ttl, isAnthropic) {
|
|
24749
24764
|
const base = existing !== null && typeof existing === "object" && !Array.isArray(existing) ? { ...existing } : {};
|
|
24750
24765
|
if (!("type" in base)) base.type = "ephemeral";
|
|
24751
|
-
if (ttl
|
|
24766
|
+
if (ttl === "omit") delete base.ttl;
|
|
24767
|
+
else if (ttl === "5m" || ttl === "1h") {
|
|
24768
|
+
if (isAnthropic) base.ttl = ttl;
|
|
24769
|
+
}
|
|
24752
24770
|
return base;
|
|
24753
24771
|
}
|
|
24754
24772
|
//#endregion
|