@lynn123411/dsh-a6api 1.3.0 → 1.4.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 CHANGED
@@ -18,7 +18,7 @@ A6API 多模型聚合站深度接入插件:将 A6API 聚合网关无缝注册
18
18
  - **侧边栏快捷模型卡片**:主界面左下角(设置按钮上方)常驻「A6api」入口按钮,点击向上弹出**当前会话正在使用的 A6api 模型**的完整商户卡片(与设置页同一数据源与操作能力:探测/固定/禁用/详情全部可用);会话切换模型时卡片实时跟随;当前会话未使用 A6api 模型(或子代理会话)时按钮置灰并提示。
19
19
  - **侧边栏账户速览胶囊**:浮层顶部常驻「账户余额」(纯展示,每 60s 自动同步)与「价格波动」(行为与标题栏一致,可一键跳官网)两枚胶囊,账号级数据与模型卡片无关,加载/空态恒显示。
20
20
  - **后台预热无感加载**:插件随 DSH 启动即后台预热一次完整状态,之后每 60s 静默整体刷新;服务端 `/state` 将余额/模型列表/日志/固定记录等独立上游调用并行拉取(串行 5 次 RTT → 1 次)—— 侧边栏浮层与设置页打开时数据已就绪,秒开无加载等待。
21
- - **模型目录管理**:「可用模型」右侧新增「模型目录」页——一键「从 A6API 获取市场模型」翻页拉取市场支持的全部模型 ID(参数初始为空),再「从 OpenRouter 一键查询」自动填充 `contextWindow / maxTokens / input`(查不到的保持留空可手动填写,每行也可单独查询;`name` 仅用户手动填写,未填则不写入 DSH);行内编辑全部采用 DSH `settings.yaml` 原生模型字段(name / contextWindow / maxTokens / input / reasoningEfforts),保存后若该模型已在 DSH 启用则立即重写 `llm-pi-ai.providers.a6api` 对应条目即时生效;支持按「可用(当前令牌白名单)/ 不可用」与「参数已填 / 未填」筛选;可一键「清空目录」(二次确认)后重新从 A6API 获取并重新用 OpenRouter 填充;新获取的模型默认声明 DSH 全部思考档位(off / minimal / low / medium / high / xhigh / max)。内置静态模型目录已移除,所有参数以运行时数据(`~/.dsh/dsh-a6api-catalog.json`)为准,写入 settings.yaml 时缺省字段自动省略(由 DSH 默认值兜底)。
21
+ - **模型目录管理**:「可用模型」右侧新增「模型目录」页——一键「从 A6API 获取市场模型」翻页拉取市场支持的全部模型 ID(参数初始为空),再「从 OpenRouter 一键查询」自动填充 `contextWindow / maxTokens / input`(查不到的保持留空可手动填写,每行也可单独查询;`name` 仅用户手动填写,未填则不写入 DSH);行内编辑全部采用 DSH `settings.yaml` 原生模型字段(name / contextWindow / maxTokens / input / reasoningEfforts),保存后若该模型已在 DSH 启用则立即重写 `llm-pi-ai.providers.a6api` 对应条目即时生效;支持按「可用(当前令牌白名单)/ 不可用」与「参数已填 / 未填」筛选;可一键「清空目录」(二次确认)后重新从 A6API 获取并重新用 OpenRouter 填充;新获取的模型默认声明 DSH 全部思考档位(off / minimal / low / medium / high / xhigh / max)。内置静态模型目录已移除,所有参数以运行时数据为准(v1.4 起存于 `~/.dsh/dsh-a6api/catalog.json` 插件子目录,与 DSH「组件自建 home 子目录」惯例一致;旧版根目录 `dsh-a6api-catalog.json` 首次加载时自动搬迁并删除),写入 settings.yaml 时缺省字段自动省略(由 DSH 默认值兜底)。
22
22
 
23
23
  ## 安装
24
24
 
package/lib/index.js CHANGED
@@ -2,26 +2,78 @@
2
2
  import fs from "node:fs";
3
3
  import fsp from "node:fs/promises";
4
4
  import path from "node:path";
5
- import os from "node:os";
6
- var CATALOG_VERSION = 1;
7
- function dshHome() {
8
- return process.env.DSH_HOME || path.join(os.homedir(), ".dsh");
5
+
6
+ // node_modules/.pnpm/@deepseek-ai+dsh-home-paths@0.1.2-alpha.2_@deepseek-ai+cordis@4.0.2_@deepseek-ai+dsh-in_201e0f99eb7c6b9ed77157bb5f14e24e/node_modules/@deepseek-ai/dsh-home-paths/lib/index.js
7
+ import { opendir, realpath } from "node:fs/promises";
8
+ import { homedir } from "node:os";
9
+ import { basename, dirname, join, resolve } from "node:path";
10
+ var DSH_HOME_DIR_NAME = ".dsh";
11
+ var DEFAULT_DSH_HOME_DISPLAY = `~/${DSH_HOME_DIR_NAME}`;
12
+ var DSH_HOME_ENV = "DSH_HOME";
13
+ function defaultDshHome() {
14
+ return join(homedir(), DSH_HOME_DIR_NAME);
15
+ }
16
+ function expandHomePath(path3) {
17
+ if (path3 === "~") return homedir();
18
+ if (path3.startsWith("~/") || path3.startsWith("~\\")) return join(homedir(), path3.slice(2));
19
+ return path3;
20
+ }
21
+ function resolveDshHome(configured, env = process.env) {
22
+ const fromEnv = env[DSH_HOME_ENV];
23
+ return resolve(expandHomePath(configured ?? (fromEnv !== void 0 && fromEnv.trim().length > 0 ? fromEnv : defaultDshHome())));
24
+ }
25
+ function dshHomePath(...segments) {
26
+ return join(resolveDshHome(), ...segments);
9
27
  }
28
+
29
+ // src/server/catalog.ts
30
+ var CATALOG_VERSION = 1;
10
31
  function catalogFile() {
11
- return path.join(dshHome(), "dsh-a6api-catalog.json");
32
+ return dshHomePath("dsh-a6api", "catalog.json");
33
+ }
34
+ function legacyCatalogFile() {
35
+ return dshHomePath("dsh-a6api-catalog.json");
36
+ }
37
+ function ensureRelocated() {
38
+ const target = catalogFile();
39
+ const legacy = legacyCatalogFile();
40
+ try {
41
+ fs.accessSync(target);
42
+ try {
43
+ fs.unlinkSync(legacy);
44
+ } catch {
45
+ }
46
+ return;
47
+ } catch {
48
+ }
49
+ try {
50
+ fs.mkdirSync(path.dirname(target), { recursive: true });
51
+ fs.renameSync(legacy, target);
52
+ } catch {
53
+ }
12
54
  }
13
55
  var catalogCache = null;
14
56
  function ensureLoaded() {
15
57
  if (catalogCache) return catalogCache;
16
- try {
17
- const raw = fs.readFileSync(catalogFile(), "utf8");
18
- const j = JSON.parse(raw);
19
- catalogCache = Array.isArray(j?.entries) ? j.entries.filter((e) => e && typeof e.id === "string") : [];
20
- } catch {
21
- catalogCache = [];
58
+ ensureRelocated();
59
+ const sources = [catalogFile(), legacyCatalogFile()];
60
+ for (const file of sources) {
61
+ try {
62
+ const raw = fs.readFileSync(file, "utf8");
63
+ const j = JSON.parse(raw);
64
+ catalogCache = Array.isArray(j?.entries) ? j.entries.filter((e) => e && typeof e.id === "string") : [];
65
+ if (file !== catalogFile()) {
66
+ try {
67
+ fs.unlinkSync(file);
68
+ } catch {
69
+ }
70
+ }
71
+ return catalogCache;
72
+ } catch {
73
+ }
22
74
  }
23
- const loaded = catalogCache;
24
- return loaded;
75
+ catalogCache = [];
76
+ return catalogCache;
25
77
  }
26
78
  function getCatalog() {
27
79
  return ensureLoaded();
@@ -928,7 +980,7 @@ async function marketplaceRestoreChannel(userId, accessToken, channelId, model)
928
980
  }
929
981
 
930
982
  // src/server/probe.ts
931
- var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
983
+ var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
932
984
  async function probeSingleModel(baseURL, apiKey, userId, accessToken, modelName) {
933
985
  const targetModel = modelName || "";
934
986
  const cleanUrl = cleanBaseUrl(baseURL);
@@ -1061,7 +1113,7 @@ async function getKnownMerchantsFromLogs(userId, accessToken, modelNames = [], l
1061
1113
  import * as fs2 from "node:fs";
1062
1114
  import * as fsp2 from "node:fs/promises";
1063
1115
  import * as path2 from "node:path";
1064
- import * as os2 from "node:os";
1116
+ import * as os from "node:os";
1065
1117
  var A6API_CRED_REF = "A6API_API_KEY";
1066
1118
  var A6API_TOKEN_REF = "A6API_ACCESS_TOKEN";
1067
1119
  var A6API_USER_REF = "A6API_USER_ID";
@@ -1076,17 +1128,17 @@ async function atomicWriteFile(filePath, content, mode = 384) {
1076
1128
  await fsp2.writeFile(tmpPath, content, { mode });
1077
1129
  await fsp2.rename(tmpPath, filePath);
1078
1130
  }
1079
- function dshHome2() {
1080
- return process.env.DSH_HOME || path2.join(os2.homedir(), ".dsh");
1131
+ function dshHome() {
1132
+ return process.env.DSH_HOME || path2.join(os.homedir(), ".dsh");
1081
1133
  }
1082
1134
  function legacyConfigFile() {
1083
- return path2.join(dshHome2(), LEGACY_CONFIG_NAME);
1135
+ return path2.join(dshHome(), LEGACY_CONFIG_NAME);
1084
1136
  }
1085
1137
  function credentialsFile() {
1086
- return path2.join(dshHome2(), ".credentials.yaml");
1138
+ return path2.join(dshHome(), ".credentials.yaml");
1087
1139
  }
1088
1140
  function settingsFile() {
1089
- return path2.join(dshHome2(), "settings.yaml");
1141
+ return path2.join(dshHome(), "settings.yaml");
1090
1142
  }
1091
1143
  function getCredentials(ctx) {
1092
1144
  try {
@@ -1656,7 +1708,7 @@ function sendJson(res, status, body) {
1656
1708
  res.end(JSON.stringify(body));
1657
1709
  }
1658
1710
  function readBody(req) {
1659
- return new Promise((resolve, reject) => {
1711
+ return new Promise((resolve2, reject) => {
1660
1712
  let data = "";
1661
1713
  req.on("data", (chunk) => {
1662
1714
  data += chunk;
@@ -1665,7 +1717,7 @@ function readBody(req) {
1665
1717
  reject(new Error("Body too large"));
1666
1718
  }
1667
1719
  });
1668
- req.on("end", () => resolve(data.trim()));
1720
+ req.on("end", () => resolve2(data.trim()));
1669
1721
  req.on("error", reject);
1670
1722
  });
1671
1723
  }
@@ -1799,7 +1851,7 @@ function apply(ctx) {
1799
1851
  try {
1800
1852
  found = await Promise.race([
1801
1853
  getKnownMerchantsFromLogs(config.userId, token, missing, allLogs),
1802
- new Promise((resolve) => setTimeout(() => resolve({}), 1e4))
1854
+ new Promise((resolve2) => setTimeout(() => resolve2({}), 1e4))
1803
1855
  ]);
1804
1856
  } catch {
1805
1857
  found = {};
@@ -1867,7 +1919,7 @@ function apply(ctx) {
1867
1919
  );
1868
1920
  }
1869
1921
  })(),
1870
- new Promise((resolve) => setTimeout(() => resolve(), 1e4))
1922
+ new Promise((resolve2) => setTimeout(() => resolve2(), 1e4))
1871
1923
  ]);
1872
1924
  } catch {
1873
1925
  }