@lynn123411/dsh-a6api 1.5.1 → 1.5.3
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 +2 -1
- package/lib/client.js +41 -3
- package/lib/client.js.map +2 -2
- package/lib/index.js +20 -5
- package/lib/index.js.map +2 -2
- package/lib/types/client/store.d.ts +1 -1
- package/lib/types/server/a6api-client.d.ts +7 -0
- package/lib/types/types.d.ts +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@ A6API 多模型聚合站深度接入插件:将 A6API 聚合网关无缝注册
|
|
|
6
6
|
|
|
7
7
|
- **多标签页优雅布局**:重构并优化设置交互,拆分为「可用模型」、「模型目录」、「账户资产」、「基础配置」四大专属页面,分类清晰、告别页面拥挤。
|
|
8
8
|
- **全真官方模型卡片复刻**:1:1 像素级复刻 A6API 官网模型卡片视图,包含品牌图标、模型名、商户 ID、渠道说明、输入/输出/缓存读写单价、实时倍率比值胶囊、实时/24h/7d 阶梯成功率点阵、延迟与缓存命中率进度条、智能标签(稳定/低价/高速/高质/保真)以及真实的固定与禁用操作。
|
|
9
|
+
- **混合价估算标注(≈¥x/亿 tokens)**:每张模型卡片价格区新增绿色「≈ ¥x.xx/亿」胶囊——按卡片 24h 实测缓存命中率,把「缓存读价(命中)/ 输入价(未命中)/ 输出价」折算为每 1 亿 tokens 的混合人民币成本(输出 token 占比固定 0.35%,与官网模型市场标注口径一致),悬停展示完整估算式与每 1M 单价,对比模型贵贱一目了然;按次计费等无 token 单价的卡片不展示。
|
|
9
10
|
- **给模型固定商家**:卡片一键「固定商家」/「取消固定」,直接调用 A6API 平台固定接口,把当前卡片商家绑定为该模型的服务渠道(优先路由);固定自动解析并绑定当前 API Key 令牌,异常时自动切换智能优选(平台默认兜底,无多余开关);检测到模型已固定到其他商家时,卡片自动切换为该固定商家(含价格/健康度指标),无需手动探测;卡片状态实时跟随官网——官网侧解除固定(如不接受涨价)后插件按钮自动还原。
|
|
10
11
|
- **商家禁用与恢复**:卡片一键「禁用」当前商家对该模型的服务(路由不再命中),随时「恢复」;固定/禁用状态以徽标展示(已固定 / 已固定到其他商家 / 已禁用)。
|
|
11
12
|
- **路由快照时效标注**:每张模型卡片右下角标注「路由快照」时效(该卡片商户数据来自我最近一次路由请求的时刻,相对时间 + 悬停绝对时间),与全网最近成功时间叠放两行;日志中无路由记录的模型显示灰色「从未路由」。
|
|
@@ -18,7 +19,7 @@ A6API 多模型聚合站深度接入插件:将 A6API 聚合网关无缝注册
|
|
|
18
19
|
- **「模型市场」直达胶囊**:设置页标题栏与侧边栏浮层的胶囊行中,价格波动右侧常驻同款「模型市场」胶囊(白底灰字、hover 变绿),点击新标签直达 `https://a6api.com/models`。
|
|
19
20
|
- **侧边栏快捷模型卡片**:主界面左下角(设置按钮上方)常驻「A6api」入口按钮,**任何会话(含子代理)均可展开浮层**,向上弹出当前会话所用模型对应的完整商户卡片(与设置页同一数据源与操作能力:探测/固定/禁用/详情全部可用);会话切换模型时卡片实时跟随;当前会话未使用 A6api 模型时,模型卡片区域整体置灰且不可交互,顶部账户速览胶囊(余额/价格波动/模型市场)保持正常可用。
|
|
20
21
|
- **侧边栏账户速览胶囊**:浮层顶部常驻「账户余额」(纯展示,每 60s 自动同步)、「价格波动」(行为与标题栏一致,可一键跳官网)与「模型市场」(点击新标签直达 `https://a6api.com/models`)三枚同款胶囊,账号级数据与模型卡片无关,加载/空态恒显示。
|
|
21
|
-
- **后台预热无感加载**:插件随 DSH 启动即后台预热一次完整状态,之后每 60s 静默整体刷新;服务端 `/state` 将余额/模型列表/日志/固定记录等独立上游调用并行拉取(串行 5 次 RTT → 1 次)——
|
|
22
|
+
- **后台预热无感加载**:插件随 DSH 启动即后台预热一次完整状态,之后每 60s 静默整体刷新;服务端 `/state` 将余额/模型列表/日志/固定记录等独立上游调用并行拉取(串行 5 次 RTT → 1 次)—— 侧边栏浮层与设置页打开时数据已就绪,秒开无加载等待。服务端对 `/state` 保留 120s 短缓存供轮询复用;「可用模型」页「刷新列表」按钮带 `force=1` 绕过缓存立即向 A6API 重建最新数据(v1.5.3 起)。服务端对 `/state` 保留 120s 短缓存供轮询复用;「可用模型」页「刷新列表」按钮带 `force=1` 绕过缓存立即向 A6API 重建最新数据(v1.5.3 起)。
|
|
22
23
|
- **模型目录管理**:「可用模型」右侧新增「模型目录」页——一键「从 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 默认值兜底)。
|
|
23
24
|
|
|
24
25
|
## 安装
|
package/lib/client.js
CHANGED
|
@@ -106,11 +106,11 @@ var A6ApiStore = class {
|
|
|
106
106
|
getState() {
|
|
107
107
|
return this.state;
|
|
108
108
|
}
|
|
109
|
-
async fetchState() {
|
|
109
|
+
async fetchState(force = false) {
|
|
110
110
|
this.state.loading = true;
|
|
111
111
|
this.notify();
|
|
112
112
|
try {
|
|
113
|
-
const res = await fetch("/api/dsh-a6api/state");
|
|
113
|
+
const res = await fetch("/api/dsh-a6api/state" + (force ? "?force=1" : ""));
|
|
114
114
|
if (res.ok) {
|
|
115
115
|
const json = await res.json();
|
|
116
116
|
if (json?.data) {
|
|
@@ -630,6 +630,12 @@ var formatAbsolute = (tsSec) => {
|
|
|
630
630
|
const md = `${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`;
|
|
631
631
|
return y !== nowY ? `${y}-${md}` : md;
|
|
632
632
|
};
|
|
633
|
+
var fmtSig = (n) => {
|
|
634
|
+
if (!Number.isFinite(n)) return "\u2014";
|
|
635
|
+
const s = Number(n.toPrecision(3));
|
|
636
|
+
if (Math.abs(s) >= 1e3) return s.toLocaleString("en-US", { maximumFractionDigits: 0 });
|
|
637
|
+
return String(s);
|
|
638
|
+
};
|
|
633
639
|
var MerchantCard = ({ model }) => {
|
|
634
640
|
const [expanded, setExpanded] = (0, import_react.useState)(false);
|
|
635
641
|
const [pinConfirmOpen, setPinConfirmOpen] = (0, import_react.useState)(false);
|
|
@@ -744,6 +750,19 @@ var MerchantCard = ({ model }) => {
|
|
|
744
750
|
const ratioText = merchant?.realtime_ratio_formatted || "0.0341";
|
|
745
751
|
const latencySec = merchant ? ((merchant.p50_ttft_ms || merchant.recent_p50_ms || 2340) / 1e3).toFixed(2) + "s" : model.probeLatencyMs ? (model.probeLatencyMs / 1e3).toFixed(2) + "s" : "2.34s";
|
|
746
752
|
const cacheHitPct = merchant ? merchant.cache_hit_rate_pct : 72;
|
|
753
|
+
const blend100m = merchant?.blended_price_100m_cny;
|
|
754
|
+
const blend100mValid = blend100m !== void 0 && Number.isFinite(blend100m);
|
|
755
|
+
const blendTitle = blend100mValid ? (() => {
|
|
756
|
+
const h = Math.min(100, Math.max(0, merchant.cache_hit_rate_pct)) / 100;
|
|
757
|
+
const inShare = 99.65;
|
|
758
|
+
const hSharePct = Math.round(h * inShare * 10) / 10;
|
|
759
|
+
const mSharePct = Math.round((1 - h) * inShare * 10) / 10;
|
|
760
|
+
const per1m = blend100m / 100;
|
|
761
|
+
return `\u6DF7\u5408\u4EF7\u4F30\u7B97\uFF08\xA5 / 1\u4EBF tokens\uFF0C\u8F93\u51FA\u5360\u6BD4\u56FA\u5B9A 0.35%\uFF09
|
|
762
|
+
\u547D\u4E2D ${hSharePct}% \xD7 \u7F13\u5B58\u8BFB\u4EF7 + \u672A\u547D\u4E2D ${mSharePct}% \xD7 \u8F93\u5165\u4EF7 + \u8F93\u51FA 0.35% \xD7 \u8F93\u51FA\u4EF7
|
|
763
|
+
= \xA5${Number(per1m.toPrecision(4))} /1M \u2248 \xA5${fmtSig(blend100m)} /1\u4EBF tokens
|
|
764
|
+
\u547D\u4E2D\u7387\u53D6\u5361\u7247 24h \u5B9E\u6D4B\u7F13\u5B58\u547D\u4E2D\u7387`;
|
|
765
|
+
})() : void 0;
|
|
747
766
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `dsh-a6-official-card ${model.inDsh ? "in-dsh" : ""}`, children: [
|
|
748
767
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-card-main-bar", onClick: () => setExpanded(!expanded), children: [
|
|
749
768
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-identity", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-title-col", children: [
|
|
@@ -787,6 +806,11 @@ var MerchantCard = ({ model }) => {
|
|
|
787
806
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-price-top", title: "\u8F93\u51FA\u4EF7 (1M)", children: merchant.output_price_cny }),
|
|
788
807
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-price-btm", title: "\u7F13\u5B58\u5199 (1M)", children: merchant.cache_write_price_cny })
|
|
789
808
|
] }),
|
|
809
|
+
blend100mValid && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-blend-pill", title: blendTitle, children: [
|
|
810
|
+
"\u2248 \xA5",
|
|
811
|
+
fmtSig(blend100m),
|
|
812
|
+
"/\u4EBF"
|
|
813
|
+
] }),
|
|
790
814
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-ratio-pill", title: "\u5B9E\u65F6\u500D\u7387\u6BD4\u5B98\u65B9\u4EF7", children: ratioText })
|
|
791
815
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-pricing unprobed", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
792
816
|
"div",
|
|
@@ -2089,7 +2113,7 @@ var A6ApiSettingsPanel = () => {
|
|
|
2089
2113
|
};
|
|
2090
2114
|
const handleRefreshState = async () => {
|
|
2091
2115
|
setRefreshing(true);
|
|
2092
|
-
await store.fetchState();
|
|
2116
|
+
await store.fetchState(true);
|
|
2093
2117
|
setRefreshing(false);
|
|
2094
2118
|
setRefreshSuccess(true);
|
|
2095
2119
|
setTimeout(() => setRefreshSuccess(false), 2e3);
|
|
@@ -3097,6 +3121,20 @@ var main_default = `/* A6API Plugin Styles - Clean Professional DSH Native Theme
|
|
|
3097
3121
|
white-space: nowrap;
|
|
3098
3122
|
}
|
|
3099
3123
|
|
|
3124
|
+
/* \u6DF7\u5408\u4EF7\u80F6\u56CA\uFF08\u2248\xA5x/\u4EBF tokens\uFF0C\u6309 24h \u7F13\u5B58\u547D\u4E2D\u7387\u4F30\u7B97\uFF09 */
|
|
3125
|
+
.dsh-a6-blend-pill {
|
|
3126
|
+
font-size: 11px;
|
|
3127
|
+
font-weight: 600;
|
|
3128
|
+
padding: 2px 7px;
|
|
3129
|
+
border-radius: 10px;
|
|
3130
|
+
background: rgba(16, 185, 129, 0.12);
|
|
3131
|
+
color: #0a8f5b;
|
|
3132
|
+
border: 1px solid rgba(10, 143, 91, 0.35);
|
|
3133
|
+
white-space: nowrap;
|
|
3134
|
+
font-variant-numeric: tabular-nums;
|
|
3135
|
+
cursor: help;
|
|
3136
|
+
}
|
|
3137
|
+
|
|
3100
3138
|
/* Uptime / Health Col (\u5B9E\u65F6 / 24h / 7d) */
|
|
3101
3139
|
.dsh-a6-bar-uptime {
|
|
3102
3140
|
display: flex;
|