dsh-multi-router 0.5.9 → 0.6.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.
Files changed (40) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +26 -1
  3. package/cordis.patch.yml +2 -2
  4. package/lib/accounts.js +4 -4
  5. package/lib/api-service.js +11 -0
  6. package/lib/api-service.js.map +7 -0
  7. package/lib/chunk-4V52V5GO.js +105 -0
  8. package/lib/chunk-4V52V5GO.js.map +7 -0
  9. package/lib/{chunk-S6ZQ45SS.js → chunk-JUOESKAK.js} +3 -3
  10. package/lib/{chunk-P43AWJ4Q.js → chunk-LLDJVBTQ.js} +3 -3
  11. package/lib/{chunk-U2MU2M5C.js → chunk-NSKCFVHP.js} +13 -111
  12. package/lib/chunk-NSKCFVHP.js.map +7 -0
  13. package/lib/{chunk-I4EW5TI7.js → chunk-OCMOMSB4.js} +46 -14
  14. package/lib/chunk-OCMOMSB4.js.map +7 -0
  15. package/lib/{chunk-FTM7RHQV.js → chunk-OK2T2UAZ.js} +4 -4
  16. package/lib/{chunk-J3XO7RTF.js → chunk-ROZINFTV.js} +3 -2
  17. package/lib/chunk-ROZINFTV.js.map +7 -0
  18. package/lib/chunk-SNEZMYNU.js +332 -0
  19. package/lib/chunk-SNEZMYNU.js.map +7 -0
  20. package/lib/{chunk-MCHV2R25.js → chunk-WVNY4LSL.js} +3 -1
  21. package/lib/{chunk-MCHV2R25.js.map → chunk-WVNY4LSL.js.map} +2 -2
  22. package/lib/cli.js +7 -6
  23. package/lib/cli.js.map +1 -1
  24. package/lib/client.js +340 -7
  25. package/lib/client.js.map +2 -2
  26. package/lib/clients.js +6 -5
  27. package/lib/{host-v0.5.9.js → host-v0.6.0.js} +18 -13
  28. package/lib/host.js +18 -13
  29. package/lib/index.js +18 -13
  30. package/lib/index.js.map +2 -2
  31. package/lib/manager.js +11 -7
  32. package/lib/router.js +2 -2
  33. package/lib/shim.js +3 -3
  34. package/package.json +1 -1
  35. package/lib/chunk-I4EW5TI7.js.map +0 -7
  36. package/lib/chunk-J3XO7RTF.js.map +0 -7
  37. package/lib/chunk-U2MU2M5C.js.map +0 -7
  38. /package/lib/{chunk-S6ZQ45SS.js.map → chunk-JUOESKAK.js.map} +0 -0
  39. /package/lib/{chunk-P43AWJ4Q.js.map → chunk-LLDJVBTQ.js.map} +0 -0
  40. /package/lib/{chunk-FTM7RHQV.js.map → chunk-OK2T2UAZ.js.map} +0 -0
@@ -6,21 +6,27 @@ import {
6
6
  refreshWorkBuddyCheckinCredential,
7
7
  supportsCheckin,
8
8
  workbuddyToken
9
- } from "./chunk-U2MU2M5C.js";
9
+ } from "./chunk-NSKCFVHP.js";
10
10
  import {
11
11
  discoverLocalAccounts,
12
12
  importAccount,
13
13
  localAccountKey,
14
14
  normalizeLocalAccountKey,
15
15
  readPortableCredential
16
- } from "./chunk-S6ZQ45SS.js";
16
+ } from "./chunk-JUOESKAK.js";
17
+ import {
18
+ modelWithCurrentPromotion
19
+ } from "./chunk-TEZ2FMEO.js";
20
+ import {
21
+ ApiService
22
+ } from "./chunk-SNEZMYNU.js";
17
23
  import {
18
24
  hostIsLoopback
19
25
  } from "./chunk-DNQPZMPF.js";
20
26
  import {
21
27
  Telemetry,
22
28
  matchModel
23
- } from "./chunk-J3XO7RTF.js";
29
+ } from "./chunk-ROZINFTV.js";
24
30
  import {
25
31
  PROVIDERS,
26
32
  PROVIDER_NAMES,
@@ -31,16 +37,13 @@ import {
31
37
  routeReasoning,
32
38
  validateConfig,
33
39
  writePrivateJson
34
- } from "./chunk-MCHV2R25.js";
35
- import {
36
- modelWithCurrentPromotion
37
- } from "./chunk-TEZ2FMEO.js";
40
+ } from "./chunk-WVNY4LSL.js";
38
41
 
39
42
  // src/manager.mjs
40
43
  import { createHash, randomBytes as randomBytes3, timingSafeEqual } from "node:crypto";
41
44
 
42
45
  // package.json
43
- var version = "0.5.9";
46
+ var version = "0.6.0";
44
47
 
45
48
  // src/manager.mjs
46
49
  import { readFile as readFile4, mkdir as mkdir2, mkdtemp as mkdtemp2, rm as rm3 } from "node:fs/promises";
@@ -102,7 +105,7 @@ var derive = promisify(scrypt);
102
105
  var FORMAT = "dsh-multi-router";
103
106
  var MAX_BYTES = 512 * 1024;
104
107
  var pick = (value, keys) => Object.fromEntries(keys.filter((k) => Object.hasOwn(value ?? {}, k)).map((k) => [k, value[k]]));
105
- var options = ["cooldownMs", "requestTimeoutMs", "catalogTtlMs", "retryServerErrors", "modelVisibility", "usageRetentionDays", "checkinSchedule"];
108
+ var options = ["cooldownMs", "requestTimeoutMs", "catalogTtlMs", "retryServerErrors", "modelVisibility", "usageRetentionDays", "checkinSchedule", "sidebarUsage"];
106
109
  function settings(config) {
107
110
  return {
108
111
  ...pick(config, options),
@@ -1003,6 +1006,7 @@ var WorkBuddyLogin = class {
1003
1006
 
1004
1007
  // src/manager.mjs
1005
1008
  var MANAGEMENT_PATH = "/.well-known/dsh-multi-router";
1009
+ var SUMMARY_PATH = `${MANAGEMENT_PATH}/summary`;
1006
1010
  var revisionOf = (raw) => createHash("sha256").update(JSON.stringify(raw)).digest("hex");
1007
1011
  var ManagementError = class extends Error {
1008
1012
  constructor(status, message) {
@@ -1060,6 +1064,7 @@ var Manager = class {
1060
1064
  this.checkins = new Checkins(join5(dirname3(file), "checkins.json"), this);
1061
1065
  this.workbuddyLogin = new WorkBuddyLogin(join5(dirname3(file), "workbuddy-login.json"), { fetchImpl: pluginAccess.fetchImpl });
1062
1066
  this.setupFile = join5(dirname3(file), "initial-setup.json");
1067
+ this.api = new ApiService(join5(dirname3(file), "api-service.json"), this);
1063
1068
  router.telemetry = this.telemetry;
1064
1069
  router.monitor = (a) => this.monitorAccount(a, { maxAgeMs: 6e4 });
1065
1070
  router.prepareFree = () => this.checkFreeModels(true);
@@ -1087,6 +1092,7 @@ var Manager = class {
1087
1092
  }
1088
1093
  this.telemetry.configure(this.config.usageRetentionDays);
1089
1094
  await this.telemetry.load();
1095
+ await this.api.load();
1090
1096
  await Promise.all(this.config.accounts.map((a) => this.readLogin(a)));
1091
1097
  this.publish();
1092
1098
  }
@@ -1400,6 +1406,19 @@ var Manager = class {
1400
1406
  this.refreshes.set(account.id, promise);
1401
1407
  return promise;
1402
1408
  }
1409
+ summaryState() {
1410
+ const today = new Date(this.telemetry.now()).toLocaleDateString("en-CA", { timeZone: "Asia/Shanghai" });
1411
+ const daily = this.telemetry.data.days[today] ?? {};
1412
+ return {
1413
+ pluginVersion: version,
1414
+ enabled: this.config.sidebarUsage,
1415
+ today,
1416
+ tokens: daily.tokens ?? 0,
1417
+ requests: daily.requests ?? 0,
1418
+ unmetered: daily.unmetered ?? 0,
1419
+ totalTokens: Object.values(this.telemetry.data.accounts).reduce((sum, row) => sum + (row.tokens ?? 0), 0)
1420
+ };
1421
+ }
1403
1422
  state() {
1404
1423
  const status = this.router.status();
1405
1424
  return {
@@ -1412,6 +1431,7 @@ var Manager = class {
1412
1431
  pluginUpdates: this.plugins.state(),
1413
1432
  checkins: this.checkins.state(),
1414
1433
  telemetry: this.telemetry.state(),
1434
+ apiService: this.api.state(),
1415
1435
  accounts: this.config.accounts.map((a) => ({
1416
1436
  id: a.id,
1417
1437
  provider: a.provider,
@@ -1439,12 +1459,22 @@ var Manager = class {
1439
1459
  cooldownMs: this.config.cooldownMs,
1440
1460
  requestTimeoutMs: this.config.requestTimeoutMs,
1441
1461
  retryServerErrors: this.config.retryServerErrors,
1442
- usageRetentionDays: this.config.usageRetentionDays
1462
+ usageRetentionDays: this.config.usageRetentionDays,
1463
+ sidebarUsage: this.config.sidebarUsage
1443
1464
  }
1444
1465
  };
1445
1466
  }
1446
1467
  async action(input) {
1447
1468
  if (!input || typeof input !== "object" || Array.isArray(input)) bad("\u8BF7\u6C42\u683C\u5F0F\u65E0\u6548");
1469
+ if (input.action?.startsWith("api.")) {
1470
+ let result;
1471
+ try {
1472
+ result = await this.api.action(input);
1473
+ } catch (e) {
1474
+ bad(e.message);
1475
+ }
1476
+ return { ...this.state(), ...result };
1477
+ }
1448
1478
  if (input.action === "plugin.reload") {
1449
1479
  if (!this.runtime) bad("\u5F53\u524D\u540E\u53F0\u4E0D\u652F\u6301\u91CD\u65B0\u52A0\u8F7D");
1450
1480
  this.runtime.retryAt = 0;
@@ -1787,7 +1817,7 @@ var Manager = class {
1787
1817
  if (!input.schedule) bad("\u8BF7\u586B\u5199\u7B7E\u5230\u8BA1\u5212");
1788
1818
  raw.checkinSchedule = input.schedule;
1789
1819
  } else if (input.action === "options.save") {
1790
- for (const key of ["cooldownMs", "requestTimeoutMs", "retryServerErrors", "usageRetentionDays"]) if (input[key] !== void 0) raw[key] = input[key];
1820
+ for (const key of ["cooldownMs", "requestTimeoutMs", "retryServerErrors", "usageRetentionDays", "sidebarUsage"]) if (input[key] !== void 0) raw[key] = input[key];
1791
1821
  } else bad("\u672A\u77E5\u64CD\u4F5C");
1792
1822
  let config;
1793
1823
  try {
@@ -1854,7 +1884,7 @@ var Manager = class {
1854
1884
  };
1855
1885
  }
1856
1886
  };
1857
- function managementHandler(manager) {
1887
+ function managementHandler(manager, { summaryOnly = false } = {}) {
1858
1888
  const key = randomBytes3(32).toString("base64url");
1859
1889
  const json = (res, status, value) => {
1860
1890
  res.writeHead(status, { "Content-Type": "application/json", "Cache-Control": "no-store", "X-Content-Type-Options": "nosniff" });
@@ -1868,9 +1898,10 @@ function managementHandler(manager) {
1868
1898
  if (req.headers.origin && req.headers.origin !== `http://${req.headers.host}` && req.headers.origin !== `https://${req.headers.host}`) throw new ManagementError(403, "\u6765\u6E90\u65E0\u6548");
1869
1899
  if (req.headers["sec-fetch-site"] === "cross-site") throw new ManagementError(403, "\u6765\u6E90\u65E0\u6548");
1870
1900
  if (req.method === "GET") {
1871
- json(res, 200, { ...manager.state(), key });
1901
+ json(res, 200, summaryOnly ? manager.summaryState() : { ...manager.state(), key });
1872
1902
  return;
1873
1903
  }
1904
+ if (summaryOnly) throw new ManagementError(405, "\u65B9\u6CD5\u65E0\u6548");
1874
1905
  if (req.method !== "POST") throw new ManagementError(405, "\u65B9\u6CD5\u65E0\u6548");
1875
1906
  const actual = Buffer.from(req.headers["x-multi-router-key"] ?? ""), expected = Buffer.from(key);
1876
1907
  if (actual.length !== expected.length || !timingSafeEqual(actual, expected)) throw new ManagementError(401, "\u8BF7\u5237\u65B0\u914D\u7F6E\u9875\u9762");
@@ -1904,9 +1935,10 @@ export {
1904
1935
  version,
1905
1936
  PluginReload,
1906
1937
  MANAGEMENT_PATH,
1938
+ SUMMARY_PATH,
1907
1939
  ManagementError,
1908
1940
  modelInfo,
1909
1941
  Manager,
1910
1942
  managementHandler
1911
1943
  };
1912
- //# sourceMappingURL=chunk-I4EW5TI7.js.map
1944
+ //# sourceMappingURL=chunk-OCMOMSB4.js.map