dsh-multi-router 0.6.0 → 0.6.1

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.
Files changed (36) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +21 -6
  3. package/THIRD_PARTY_NOTICES.md +4 -0
  4. package/cordis.patch.yml +2 -2
  5. package/lib/accounts.js +2 -2
  6. package/lib/api-service.js +3 -3
  7. package/lib/{chunk-NSKCFVHP.js → chunk-2LH6TD2U.js} +15 -7
  8. package/lib/chunk-2LH6TD2U.js.map +7 -0
  9. package/lib/{chunk-SNEZMYNU.js → chunk-625KMEYS.js} +3 -3
  10. package/lib/{chunk-LLDJVBTQ.js → chunk-BSAI3SW5.js} +3 -3
  11. package/lib/{chunk-ROZINFTV.js → chunk-DZ4ZUAYH.js} +49 -6
  12. package/lib/chunk-DZ4ZUAYH.js.map +7 -0
  13. package/lib/{chunk-WVNY4LSL.js → chunk-NGVWVIBM.js} +20 -6
  14. package/lib/chunk-NGVWVIBM.js.map +7 -0
  15. package/lib/{chunk-JUOESKAK.js → chunk-VZPXRK7Q.js} +2 -2
  16. package/lib/{chunk-OCMOMSB4.js → chunk-ZQZSXCVR.js} +125 -41
  17. package/lib/chunk-ZQZSXCVR.js.map +7 -0
  18. package/lib/cli.js +4 -4
  19. package/lib/client.js +125 -40
  20. package/lib/client.js.map +2 -2
  21. package/lib/clients.js +6 -3
  22. package/lib/{host-v0.6.0.js → host-v0.6.1.js} +8 -7
  23. package/lib/host.js +8 -7
  24. package/lib/index.js +8 -7
  25. package/lib/index.js.map +2 -2
  26. package/lib/manager.js +6 -6
  27. package/lib/router.js +2 -2
  28. package/lib/shim.js +3 -3
  29. package/package.json +1 -1
  30. package/lib/chunk-NSKCFVHP.js.map +0 -7
  31. package/lib/chunk-OCMOMSB4.js.map +0 -7
  32. package/lib/chunk-ROZINFTV.js.map +0 -7
  33. package/lib/chunk-WVNY4LSL.js.map +0 -7
  34. /package/lib/{chunk-SNEZMYNU.js.map → chunk-625KMEYS.js.map} +0 -0
  35. /package/lib/{chunk-LLDJVBTQ.js.map → chunk-BSAI3SW5.js.map} +0 -0
  36. /package/lib/{chunk-JUOESKAK.js.map → chunk-VZPXRK7Q.js.map} +0 -0
@@ -6,44 +6,45 @@ import {
6
6
  refreshWorkBuddyCheckinCredential,
7
7
  supportsCheckin,
8
8
  workbuddyToken
9
- } from "./chunk-NSKCFVHP.js";
9
+ } from "./chunk-2LH6TD2U.js";
10
10
  import {
11
11
  discoverLocalAccounts,
12
12
  importAccount,
13
13
  localAccountKey,
14
14
  normalizeLocalAccountKey,
15
15
  readPortableCredential
16
- } from "./chunk-JUOESKAK.js";
16
+ } from "./chunk-VZPXRK7Q.js";
17
17
  import {
18
18
  modelWithCurrentPromotion
19
19
  } from "./chunk-TEZ2FMEO.js";
20
20
  import {
21
21
  ApiService
22
- } from "./chunk-SNEZMYNU.js";
22
+ } from "./chunk-625KMEYS.js";
23
23
  import {
24
24
  hostIsLoopback
25
25
  } from "./chunk-DNQPZMPF.js";
26
26
  import {
27
27
  Telemetry,
28
- matchModel
29
- } from "./chunk-ROZINFTV.js";
28
+ contextInfo,
29
+ matchModel,
30
+ resolveContext
31
+ } from "./chunk-DZ4ZUAYH.js";
30
32
  import {
31
33
  PROVIDERS,
32
34
  PROVIDER_NAMES,
33
35
  ROUTE_PRESETS,
34
36
  beijingDay,
35
37
  isFreeModel,
36
- reasoningModes,
37
38
  routeReasoning,
38
39
  validateConfig,
39
40
  writePrivateJson
40
- } from "./chunk-WVNY4LSL.js";
41
+ } from "./chunk-NGVWVIBM.js";
41
42
 
42
43
  // src/manager.mjs
43
44
  import { createHash, randomBytes as randomBytes3, timingSafeEqual } from "node:crypto";
44
45
 
45
46
  // package.json
46
- var version = "0.6.0";
47
+ var version = "0.6.1";
47
48
 
48
49
  // src/manager.mjs
49
50
  import { readFile as readFile4, mkdir as mkdir2, mkdtemp as mkdtemp2, rm as rm3 } from "node:fs/promises";
@@ -109,10 +110,10 @@ var options = ["cooldownMs", "requestTimeoutMs", "catalogTtlMs", "retryServerErr
109
110
  function settings(config) {
110
111
  return {
111
112
  ...pick(config, options),
112
- models: Object.fromEntries(Object.entries(config.models ?? {}).map(([p, rows]) => [p, Object.fromEntries(Object.entries(rows).map(([id, pref]) => [id, pick(pref, ["name", "visible"])]))])),
113
+ models: Object.fromEntries(Object.entries(config.models ?? {}).map(([p, rows]) => [p, Object.fromEntries(Object.entries(rows).map(([id, pref]) => [id, pick(pref, ["name", "visible", "contextWindow", "supportsImages", "reasoningEffort"])]))])),
113
114
  accounts: config.accounts.map((a) => pick(a, ["id", "provider", "name", "enabled", "autoCheckin"])),
114
115
  routes: Object.fromEntries(Object.entries(config.routes).map(([id, r]) => [id, {
115
- ...pick(r, ["name", "visible", "strategy", "contextWindow", "maxTokens", "preferExpiringCredits", "expiringWithinDays", "freeOnly", "freeModels"]),
116
+ ...pick(r, ["name", "visible", "strategy", "contextMode", "contextWindow", "maxTokens", "preferExpiringCredits", "expiringWithinDays", "freeOnly", "freeModels"]),
116
117
  targets: r.targets.map((t) => pick(t, ["provider", "account", "model", "models", "weight", "tokenBudget", "creditBudget"]))
117
118
  }]))
118
119
  };
@@ -1033,8 +1034,8 @@ function modelInfo(row) {
1033
1034
  return {
1034
1035
  id: row.id,
1035
1036
  name: row.name || row.id,
1036
- contextWindow: finite(row.contextWindow, 2e5),
1037
- maxTokens: Math.min(finite(row.maxTokens, 32e3), finite(row.contextWindow, 2e5)),
1037
+ ...contextInfo(row),
1038
+ maxTokens: Math.min(finite(row.maxTokens, 32e3), contextInfo(row).maxContextWindow),
1038
1039
  supportsImages: row.supportsImages === true || row.multimodal === true || row.input?.includes("image") === true,
1039
1040
  ...reasoning ? { reasoning } : {},
1040
1041
  ...billing ? { billing } : {},
@@ -1085,7 +1086,7 @@ var Manager = class {
1085
1086
  for (const account of this.config.accounts) {
1086
1087
  const item = saved[account.id];
1087
1088
  if (item?.credentialFile === account.credentialFile && Array.isArray(item.models)) {
1088
- this.catalogs.set(account.id, { ...item, models: item.models.filter((m) => typeof m.id === "string" && m.id.length > 0).map(modelInfo) });
1089
+ this.catalogs.set(account.id, { ...item, ...item.contextVersion !== 1 ? { fetchedAt: 0 } : {}, models: item.models.filter((m) => typeof m.id === "string" && m.id.length > 0).map(modelInfo) });
1089
1090
  }
1090
1091
  }
1091
1092
  } catch {
@@ -1284,16 +1285,25 @@ var Manager = class {
1284
1285
  const id = `free_${createHash("sha256").update(JSON.stringify([parentId, account.provider, model.id])).digest("hex").slice(0, 24)}`;
1285
1286
  if (!groups.has(id)) groups.set(id, { id, models: [], targets: [], accountNames: [], modelName: model.name, provider: account.provider, modelId: model.id });
1286
1287
  const group = groups.get(id);
1287
- group.models.push({ model, provider: account.provider });
1288
+ group.models.push({ model, provider: account.provider, accountId: account.id });
1288
1289
  group.targets.push({ provider: account.provider, account: account.id, model: model.id });
1289
1290
  group.accountNames.push(account.name ?? account.id);
1290
1291
  }
1291
1292
  }
1292
1293
  return [...groups.values()].map(({ models, ...group }) => {
1293
- const preference = row.freeModels?.[group.id] ?? {}, reasoning = routeReasoning(models);
1294
+ const preference = row.freeModels?.[group.id] ?? {};
1295
+ const context = resolveContext(models.map((s) => s.model), preference.contextWindow ?? (row.contextMode === "custom" ? row.contextWindow : null), row.contextWindow);
1296
+ const eligible = models.filter((s) => contextInfo(s.model).maxContextWindow >= context.contextWindow);
1297
+ const eligibleAccountIds = eligible.map((s) => s.accountId);
1298
+ const reasoning = routeReasoning(eligible);
1294
1299
  const selected = preference.reasoningEffort;
1295
1300
  return {
1296
1301
  ...group,
1302
+ ...context,
1303
+ eligibleAccountIds,
1304
+ targets: group.targets.filter((t) => eligibleAccountIds.includes(t.account)),
1305
+ accountNames: group.accountNames.filter((_, i) => eligibleAccountIds.includes(models[i].accountId)),
1306
+ enforceContext: true,
1297
1307
  parentId,
1298
1308
  dynamicFree: true,
1299
1309
  freeOnly: true,
@@ -1306,9 +1316,8 @@ var Manager = class {
1306
1316
  effortUnavailable: !!selected && !reasoning?.supportedEfforts.includes(selected),
1307
1317
  visible: row.visible !== false && preference.visible !== false,
1308
1318
  selected: preference.visible !== false,
1309
- supportsImages: models.every(({ model }) => model.supportsImages),
1310
- contextWindow: Math.min(row.contextWindow, ...models.map(({ model }) => model.contextWindow)),
1311
- maxTokens: Math.min(row.maxTokens, ...models.map(({ model }) => model.maxTokens), ...models.map(({ model }) => model.contextWindow))
1319
+ supportsImages: eligible.every(({ model }) => model.supportsImages),
1320
+ maxTokens: Math.min(row.maxTokens, context.contextWindow, ...eligible.map(({ model }) => model.maxTokens))
1312
1321
  };
1313
1322
  });
1314
1323
  }
@@ -1323,7 +1332,7 @@ var Manager = class {
1323
1332
  publish() {
1324
1333
  this.telemetry.configure(this.config.usageRetentionDays);
1325
1334
  this.revision = revisionOf(this.raw);
1326
- const routes = { ...this.config.routes };
1335
+ const routes = Object.fromEntries(this.routeModels().map((row) => [row.id, row]));
1327
1336
  for (const model of this.adapterModels().filter((m) => m.dynamicFree)) routes[model.id] = model;
1328
1337
  for (const provider of PROVIDERS) for (const model of this.providerModels(provider)) {
1329
1338
  routes[`${provider}::${model.id}`] = { ...model, targets: [{ provider, model: model.id }] };
@@ -1335,23 +1344,30 @@ var Manager = class {
1335
1344
  const rows = /* @__PURE__ */ new Map();
1336
1345
  for (const account of this.config.accounts.filter((a) => a.provider === provider && a.enabled !== false)) {
1337
1346
  for (const model of this.catalogs.get(account.id)?.models ?? []) {
1338
- const old = rows.get(model.id);
1339
- rows.set(model.id, old ? {
1340
- ...old,
1341
- contextWindow: Math.min(old.contextWindow, model.contextWindow),
1342
- maxTokens: Math.min(old.maxTokens, model.maxTokens),
1343
- supportsImages: old.supportsImages && model.supportsImages,
1344
- reasoning: routeReasoning([{ model: old, provider }, { model, provider }])
1345
- } : {
1346
- ...model,
1347
- ...reasoningModes(model, provider).length ? { reasoning: routeReasoning([{ model, provider }]) } : {}
1348
- });
1347
+ if (!rows.has(model.id)) rows.set(model.id, []);
1348
+ rows.get(model.id).push(model);
1349
1349
  }
1350
1350
  }
1351
- return [...rows.values()].map((model) => ({
1352
- ...model,
1353
- name: this.config.models[provider]?.[model.id]?.name ?? model.name
1354
- }));
1351
+ return [...rows.values()].map((models) => {
1352
+ const model = models[0], preference = this.config.models[provider]?.[model.id] ?? {};
1353
+ const context = resolveContext(models, preference.contextWindow);
1354
+ const eligible = models.filter((m) => contextInfo(m).maxContextWindow >= context.contextWindow);
1355
+ const reasoning = routeReasoning(eligible.map((model2) => ({ model: model2, provider })));
1356
+ const selected = preference.reasoningEffort;
1357
+ return {
1358
+ ...model,
1359
+ ...context,
1360
+ enforceContext: true,
1361
+ name: preference.name ?? model.name,
1362
+ reasoning,
1363
+ supportsImages: preference.supportsImages !== false && eligible.every((m) => m.supportsImages),
1364
+ imageCapable: eligible.every((m) => m.supportsImages),
1365
+ ...selected && reasoning?.supportedEfforts.includes(selected) ? { reasoningEffort: selected } : {},
1366
+ configuredEffort: selected ?? null,
1367
+ effortUnavailable: !!selected && !reasoning?.supportedEfforts.includes(selected),
1368
+ maxTokens: Math.min(context.contextWindow, ...eligible.map((m) => m.maxTokens))
1369
+ };
1370
+ });
1355
1371
  }
1356
1372
  hiddenModels(provider) {
1357
1373
  return this.providerModels(provider).filter((m) => !this.modelVisible(provider, m.id)).map((m) => m.id);
@@ -1365,14 +1381,19 @@ var Manager = class {
1365
1381
  const sources = effectiveTargets.flatMap((target) => this.config.accounts.filter((a) => a.enabled !== false && a.provider === target.provider && (!target.account || target.account === a.id)).flatMap((a) => {
1366
1382
  const catalog = this.catalogs.get(a.id)?.models ?? [];
1367
1383
  const models2 = target.models ? target.models.map((model) => catalog.find((m) => m.id === model)).filter(Boolean) : [matchModel(id, target, catalog)].filter(Boolean);
1368
- return models2.map((model) => ({ model, provider: a.provider }));
1384
+ return models2.map((model) => ({ model, provider: a.provider, accountId: a.id }));
1369
1385
  }));
1370
- const models = sources.map((s) => s.model), reasoning = routeReasoning(sources);
1386
+ const context = resolveContext(sources.map((s) => s.model), row.contextMode === "custom" ? row.contextWindow : null, row.contextWindow);
1387
+ const eligible = sources.filter((s) => contextInfo(s.model).maxContextWindow >= context.contextWindow);
1388
+ const models = eligible.map((s) => s.model), reasoning = routeReasoning(eligible);
1371
1389
  return {
1372
1390
  ...row,
1391
+ ...context,
1392
+ enforceContext: true,
1373
1393
  supportsImages: models.length > 0 && models.every((m) => m.supportsImages),
1374
1394
  reasoning,
1375
- ...row.freeOnly && models.length ? { contextWindow: Math.min(row.contextWindow, ...models.map((m) => m.contextWindow)), maxTokens: Math.min(row.maxTokens, ...models.map((m) => m.maxTokens), ...models.map((m) => m.contextWindow)) } : {},
1395
+ eligibleAccountIds: [...new Set(eligible.map((s) => s.accountId))],
1396
+ maxTokens: Math.min(row.maxTokens, context.contextWindow, ...models.map((m) => m.maxTokens)),
1376
1397
  id,
1377
1398
  name: row.name ?? id,
1378
1399
  expiringStatus: { ...this.telemetry.data.expiringRounds[id] },
@@ -1394,7 +1415,7 @@ var Manager = class {
1394
1415
  const client = await this.router.client(account);
1395
1416
  const models = (await client.models(AbortSignal.timeout(6e4), !!force)).map(modelInfo);
1396
1417
  if (this.closed || !this.config.accounts.some((a) => a.id === account.id && a.credentialFile === account.credentialFile)) return;
1397
- this.catalogs.set(account.id, { credentialFile: account.credentialFile, fetchedAt: Date.now(), pricingVersion: 1, models });
1418
+ this.catalogs.set(account.id, { credentialFile: account.credentialFile, fetchedAt: Date.now(), pricingVersion: 1, contextVersion: 1, models });
1398
1419
  this.catalogErrors.delete(account.id);
1399
1420
  await withFileLock3(this.catalogFile, () => writePrivateJson(this.catalogFile, Object.fromEntries(this.catalogs)));
1400
1421
  } catch (error) {
@@ -1451,6 +1472,7 @@ var Manager = class {
1451
1472
  presets: Object.entries(ROUTE_PRESETS).map(([id, route]) => ({
1452
1473
  id,
1453
1474
  ...structuredClone(route),
1475
+ providerCount: route.targets.length,
1454
1476
  added: Object.hasOwn(this.config.routes, id),
1455
1477
  availableProviders: [...new Set(route.targets.filter((t) => route.freeOnly ? this.config.accounts.some((a) => a.enabled !== false && a.provider === t.provider && this.freeModels(a).length) : matchModel(id, t, this.providerModels(t.provider))).map((t) => t.provider))]
1456
1478
  })),
@@ -1466,6 +1488,63 @@ var Manager = class {
1466
1488
  }
1467
1489
  async action(input) {
1468
1490
  if (!input || typeof input !== "object" || Array.isArray(input)) bad("\u8BF7\u6C42\u683C\u5F0F\u65E0\u6548");
1491
+ if (input.action === "model.test") {
1492
+ const model = this.providerModels(input.provider).find((m) => m.id === input.id);
1493
+ if (!model) bad("\u8BF7\u5148\u5237\u65B0\u5E76\u9009\u62E9\u5DF2\u53D1\u73B0\u7684\u6A21\u578B");
1494
+ if (this.modelTestFlight || Date.now() - (this.modelTestAt ?? 0) < 1e4) bad("\u8BF7\u7B49\u5F85\u5F53\u524D\u6D4B\u8BD5\u5B8C\u6210\uFF0C\u6D4B\u8BD5\u95F4\u9694\u81F3\u5C11 10 \u79D2");
1495
+ this.modelTestFlight = true;
1496
+ this.modelTestAt = Date.now();
1497
+ this.modelTestAbort = new AbortController();
1498
+ const started = performance.now();
1499
+ let modelTest;
1500
+ try {
1501
+ const { response } = await this.router.chat(
1502
+ {
1503
+ model: `${input.provider}::${input.id}`,
1504
+ stream: true,
1505
+ messages: [{ role: "system", content: "Answer briefly." }, { role: "user", content: "Reply with OK." }],
1506
+ max_tokens: 16
1507
+ },
1508
+ AbortSignal.any([this.modelTestAbort.signal, AbortSignal.timeout(45e3)])
1509
+ );
1510
+ const reader = response.body.getReader();
1511
+ let size = 0, text = "";
1512
+ const decoder = new TextDecoder();
1513
+ try {
1514
+ for (; ; ) {
1515
+ const chunk = await reader.read();
1516
+ if (chunk.done) break;
1517
+ size += chunk.value.byteLength;
1518
+ if (size > 1024 * 1024) throw Error("probe_response_too_large");
1519
+ text += decoder.decode(chunk.value, { stream: true });
1520
+ }
1521
+ text += decoder.decode();
1522
+ let answered = false;
1523
+ for (const line of text.split(/\r?\n/).filter((l) => l.startsWith("data:"))) {
1524
+ if (line.slice(5).trim() === "[DONE]") continue;
1525
+ const payload = JSON.parse(line.slice(5));
1526
+ if (payload.error || payload.choices?.some((c) => c.finish_reason === "error")) throw Error("probe_stream_failed");
1527
+ answered ||= payload.choices?.some((c) => c.delta?.content || c.delta?.reasoning_content || c.delta?.tool_calls?.length) ?? false;
1528
+ }
1529
+ if (!answered || !/^data:\s*\[DONE\]\s*$/m.test(text)) throw Error("probe_incomplete");
1530
+ } finally {
1531
+ await reader.cancel().catch(() => {
1532
+ });
1533
+ reader.releaseLock();
1534
+ }
1535
+ modelTest = { ok: true, elapsedMs: Math.round(performance.now() - started) };
1536
+ } catch (error) {
1537
+ modelTest = {
1538
+ ok: false,
1539
+ status: Number(error.status) || 502,
1540
+ hint: error.hint || "\u6D4B\u8BD5\u672A\u901A\u8FC7\uFF0C\u8BF7\u67E5\u770B\u8D26\u53F7\u72B6\u6001\uFF1B\u4E0D\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002"
1541
+ };
1542
+ } finally {
1543
+ this.modelTestFlight = false;
1544
+ this.modelTestAbort = void 0;
1545
+ }
1546
+ return { ...this.state(), modelTest };
1547
+ }
1469
1548
  if (input.action?.startsWith("api.")) {
1470
1549
  let result;
1471
1550
  try {
@@ -1769,22 +1848,27 @@ var Manager = class {
1769
1848
  }
1770
1849
  } else if (input.action === "model.update") {
1771
1850
  if (!PROVIDERS.includes(input.provider) || typeof input.id !== "string" || !input.id || input.id.length > 256) bad("\u6A21\u578B\u65E0\u6548");
1851
+ const model = this.providerModels(input.provider).find((m) => m.id === input.id);
1852
+ if (input.contextWindow != null && (!Number.isSafeInteger(input.contextWindow) || input.contextWindow <= 0 || !model || input.contextWindow > model.maxContextWindow)) bad("\u4E0A\u4E0B\u6587\u9884\u7B97\u4E0D\u80FD\u8D85\u8FC7\u8BE5\u6E20\u9053\u6A21\u578B\u7684\u6700\u5927\u5BB9\u91CF");
1853
+ if (input.supportsImages === true && !model?.imageCapable) bad("\u8BE5\u6A21\u578B\u672A\u58F0\u660E\u56FE\u7247\u8F93\u5165\u80FD\u529B");
1854
+ if (input.reasoningEffort != null && !model?.reasoning?.supportedEfforts.includes(input.reasoningEffort)) bad("\u6B64\u6A21\u578B\u4E0D\u652F\u6301\u6240\u9009\u63A8\u7406\u7B49\u7EA7");
1772
1855
  raw.models = { ...raw.models, [input.provider]: {
1773
1856
  ...raw.models?.[input.provider],
1774
1857
  [input.id]: {
1775
1858
  ...raw.models?.[input.provider]?.[input.id],
1776
- ...input.name !== void 0 ? { name: input.name } : {},
1777
- ...input.visible !== void 0 ? { visible: input.visible } : {}
1859
+ ...Object.fromEntries(["name", "visible", "contextWindow", "supportsImages", "reasoningEffort"].filter((k) => input[k] !== void 0).map((k) => [k, input[k]]))
1778
1860
  }
1779
1861
  } };
1780
1862
  } else if (input.action === "free.model.update") {
1781
1863
  const parent = raw.routes[input.parentId];
1782
1864
  if (!parent?.freeOnly || !this.freeRoutes(input.parentId, this.config.routes[input.parentId]).some((m) => m.id === input.id)) bad("\u514D\u8D39\u6A21\u578B\u5DF2\u66F4\u65B0\uFF0C\u8BF7\u5237\u65B0\u9875\u9762");
1783
1865
  const model = this.freeRoutes(input.parentId, this.config.routes[input.parentId]).find((m) => m.id === input.id);
1866
+ if (input.contextWindow != null && (!Number.isSafeInteger(input.contextWindow) || input.contextWindow <= 0 || input.contextWindow > model.maxContextWindow)) bad("\u4E0A\u4E0B\u6587\u9884\u7B97\u4E0D\u80FD\u8D85\u8FC7\u8BE5\u514D\u8D39\u6A21\u578B\u7684\u6700\u5927\u5BB9\u91CF");
1784
1867
  if (input.reasoningEffort !== void 0 && input.reasoningEffort !== null && !model.reasoning?.supportedEfforts.includes(input.reasoningEffort)) bad("\u6B64\u514D\u8D39\u6A21\u578B\u4E0D\u652F\u6301\u6240\u9009\u63A8\u7406\u7B49\u7EA7");
1785
1868
  parent.freeModels = { ...parent.freeModels, [input.id]: {
1786
1869
  ...parent.freeModels?.[input.id],
1787
1870
  ...input.visible !== void 0 ? { visible: input.visible } : {},
1871
+ ...input.contextWindow !== void 0 ? { contextWindow: input.contextWindow } : {},
1788
1872
  ...input.reasoningEffort !== void 0 ? { reasoningEffort: input.reasoningEffort } : {}
1789
1873
  } };
1790
1874
  } else if (input.action === "route.save") {
@@ -1941,4 +2025,4 @@ export {
1941
2025
  Manager,
1942
2026
  managementHandler
1943
2027
  };
1944
- //# sourceMappingURL=chunk-OCMOMSB4.js.map
2028
+ //# sourceMappingURL=chunk-ZQZSXCVR.js.map