@gehennawu/dsh-service 1.9.2 → 1.9.4
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.en.md +16 -9
- package/README.md +16 -9
- package/client.js +1 -1
- package/index.js +283 -72
- package/package.json +1 -1
- package/quota-routes.js +10 -1
package/README.en.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<em>DeepSeek Harness (DSH) Web 服务控制与运维插件。</em>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
|
-
[](package.json)
|
|
13
13
|
[](LICENSE)
|
|
14
14
|
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
15
15
|
[](https://cordis.moe/)
|
|
@@ -92,7 +92,9 @@ Under **Plugins → Plugin configuration**, twelve host-level switches: **Health
|
|
|
92
92
|

|
|
93
93
|
|
|
94
94
|
- Uptime, memory, session count, active agents, and background jobs; a "Process and runtime" card shows platform, architecture, and Node version
|
|
95
|
-
- Full diagnostics: session storage, workspace registry, backup storage, tar availability, file permissions, runtime environment,
|
|
95
|
+
- Full diagnostics: session storage, workspace registry, backup storage, tar availability, file permissions, runtime environment, Node version, and the **usage index** — rendered as a two-line check list (name + status dot / detail) with abnormal rows locally emphasized
|
|
96
|
+
- **Usage index**: reports how many sessions are indexed, when the index was last updated, and how many sessions failed to index (a failed fold silently undercounts usage). Failed sessions are partial-success, so they are a warning rather than a failure and also surface as an overview attention item; an index that has never been built (the Model statistics page has not been opened yet) is informational; the whole check is omitted while the Model usage feature is off (the host only skips refreshing the index in that state, so reporting would be stale and misleading)
|
|
97
|
+
- **Notification permission**: the diagnostics page appends a browser-side check after the host checks — a blocked or not-yet-granted system-notification permission both mean "notifications will not fire", with a pointer to restore it; an unsupported browser is informational. The row stays inside the diagnostics page: it never enters overview attention items or lights the ⚠ (using notifications is a user choice), and it is not rendered at all while Task notifications is off
|
|
96
98
|
- **Plugin health checks**: checks for anomalies only (the official plugin page already provides the full inventory and toggles, so no duplicate list here) — a failed plugin or one waiting on dependencies marks the check as error/warning, while fresh pending/loading fibers receive a short startup grace period; disposed or unknown states are explicit informational rows and do not become warnings. Affected plugins are listed below the check list with clipped, redacted failure text and missing deps; failed plugins can be reloaded behind a two-step confirmation (only entries the host confirmed as failed); manually disabled plugins (built-in or custom) never count as an anomaly
|
|
97
99
|
- **Plugin compatibility**: every enabled plugin is scanned against the interfaces DSH alpha versions have removed or changed (client suppliers, the SQLite persistence backend, chat/status-line style hashes, deprecated attributes) — a hit flags the plugin as "possibly incompatible" with the concrete reason (e.g. "Declares the removed client supplier @deepseek-ai/dsh-client-runtime"). Tiered verdict: only a real `require`/`import` reference is flagged "possibly incompatible"; a supplier that appears only in the manifest (unused in code) falls back to a gray "stale declaration" note — the official loader silently skips missing suppliers, so it is harmless and merely signals the author to clean up; retired slots (e.g. settings.plugin.item) kept for dual-version compatibility or display-only migrations are downgraded to a blue "retired interface" notice that does not disrupt plugin execution or raise a yellow warning. Before upgrading to alpha or right after doing so, you can see whether third-party plugins kept up; fully local scan with cached results, zero network
|
|
98
100
|
- File-permission deep scan and repair (two-step confirmation) behind a collapsed "Permissions & repair" section
|
|
@@ -102,11 +104,15 @@ Under **Plugins → Plugin configuration**, twelve host-level switches: **Health
|
|
|
102
104
|
|
|
103
105
|

|
|
104
106
|
|
|
105
|
-
- 7-day stacked bar chart of input / output / cache tokens; filter by project, hover for exact values; legend and refresh live in a unified region header; an accessible text summary accompanies the chart
|
|
107
|
+
- 7-day stacked bar chart of input / output / cache tokens; filter by project, hover for exact values; legend and refresh live in a unified region header; an accessible text summary accompanies the chart. The hover tooltip has seven lines: the date plus input/output/cache-hit detail, then **total tokens, successful model steps, and cache hit rate**; the hit rate is the host's per-day weighted value (ratios must not be summed across buckets)
|
|
106
108
|
- Per-model horizontal bars with a "Today / Last 7 days / All time" toggle
|
|
107
|
-
-
|
|
109
|
+
- A **daily usage heatmap calendar** at the bottom of the card: every day in the index (up to 20 weeks, columns aligned to Monday), four intensity steps by single-day peak, hover for that day's details; follows the project filter. The chart covers only the last 7 days, so this adds the long-range view
|
|
110
|
+
- The heatmap header can switch to an **hourly punch card**: 7 rows (Monday–Sunday) × 24 columns (00–23), each cell the tokens for that slot, answering "when am I busiest". It is the same hourly buckets re-folded along a different axis, with no new persisted fields. The square-cell layout reserves space for weekday labels and gaps, with internal horizontal scrolling on narrow screens
|
|
111
|
+
- **Indexed usage is kept permanently**: deleting a session or a project folder never subtracts history, so totals and the heatmap are always the complete history since the index was built; an index version bump preserves old summaries until readable sessions are fully rebuilt successfully; failures retain history and are retried
|
|
112
|
+
- When a **project folder no longer exists**, that project disappears from the project filter, yet its usage still counts toward the "All projects" totals, day buckets, and model breakdown
|
|
113
|
+
- Last-48-hour model/tool errors (collapsed by default, rendered only when present)
|
|
108
114
|
- Steps whose provider reports no token usage are excluded
|
|
109
|
-
- A session that cannot be read, migrated, or parsed no longer blocks other sessions. An all-projects warning shows successful/skipped counts and expandable session IDs, error categories, and safe summaries. Previously indexed data is retained and marked stale; first-time failures contribute nothing and are retried on the next refresh. Only global errors, such as an unavailable service, failed session listing, or failed index write, fail the entire refresh
|
|
115
|
+
- A session that cannot be read, migrated, or parsed no longer blocks other sessions. An all-projects warning shows successful/skipped counts and expandable session IDs, error categories, and safe summaries. Previously indexed data is retained and marked stale; first-time failures contribute nothing and are retried on the next refresh. Only global errors, such as an unavailable service, failed session listing, or failed index write, fail the entire refresh. The warning can be dismissed (remembered locally), and silencing it mutes only that same failure set: a newly skipped session or a changed error category brings it back, so dismissing once never hides a new problem for good
|
|
110
116
|
|
|
111
117
|
### Quota lookup
|
|
112
118
|
|
|
@@ -189,7 +195,7 @@ Under **Plugins → Plugin configuration**, twelve host-level switches: **Health
|
|
|
189
195
|
- Off by default; active only below a 1024 px viewport (phones / narrow windows), desktops unaffected
|
|
190
196
|
- Sidebar becomes a drawer, details column is hidden on mobile (matching the official narrow-screen behavior), modals become full-screen panels, settings left nav a horizontal top strip
|
|
191
197
|
- The model picker collapses to an icon on phones (≤480 px, mirroring the official narrow-container form; from 481 px up it still shows the model name and reasoning effort) — the plugin's mobile layout widens the composer column, so the official `@container (width<=360px)` collapse rule never fires on 428~440 px devices; this aligns with the official narrow-container form explicitly
|
|
192
|
-
- The stats line under the composer ("turns/steps · tok/s | tok · cache hit") **stays on one line and
|
|
198
|
+
- The stats line under the composer ("turns/steps · tok/s | tok · cache hit") **stays on one line, centred and straight** on phones: this row's own horizontal padding is tightened (official 32 px → 2 px) along with its gaps to free up width, and the official `justify-content` centres both chips — zero truncation from ~420 px up, proportionally less text cut than the official fixed truncation below that, with no wrapping and no horizontal scrolling; this also works on older DSH (on 0.1.5-rc.2 the row spans the full width, where the earlier sub-item `flex-grow` pushed both chips as a group to the left — they no longer grow) (desktops unaffected)
|
|
193
199
|
- The session header is re-flowed on phones (≤560 px): the title row keeps only the **title + preset chip** (the chip hugs the "…" button on the right, the title stays nearly fully visible), while the "N subagents" and "N background jobs running" counter chips park as a pair on the right of the Conversation/Trajectory tab row (tab gap 36→20, tapping a chip still opens its menu); the official crumbs **hard-clip** is eliminated, and layouts ≥561 px keep the official flow
|
|
194
200
|
- The Agent Team panel stays on screen on phones (<1024 px): the official panel is left-anchored (`left:0`), so sitting in the header's right-hand action slot pushes it off the right edge (measured 112–352 px past the viewport at 320–1023 px). On mobile the session header becomes the positioning context and the panel is re-anchored to the **right with a 16 px inset** and capped at `100vw − 32px`, leaving 16 px on each side; desktop ≥1024 px keeps the official geometry byte-for-byte
|
|
195
201
|
- Scroll immersion: inside a conversation, swiping down auto-hides the header and composer for full-screen reading (the composer also yields its layout space so the transcript really fills the screen; on reveal, if you are still at the end of the conversation it re-aligns to the bottom). Swipe up, tapping the official "Back to bottom" button, or focusing the composer brings them back (no extra floating button); already sitting at the end of the conversation, a single small backward nudge reveals it right away (no full threshold needed), and after a back-to-bottom tap the resting position gets one extra bottom snap. Programmatic scrolling (streaming pinning, anchor jumps) never triggers it
|
|
@@ -217,9 +223,10 @@ Under **Plugins → Plugin configuration**, twelve host-level switches: **Health
|
|
|
217
223
|
- The **model button in the composer shows the current provider's brand icon**: on wide screens (>480px) it is **prepended to the model name**; on phones (≤480px, where the official UI collapses the name into an icon) it **replaces** the official generic icon
|
|
218
224
|
- **Providers with no matching icon keep the official default icon untouched** (nothing prepended on wide screens, official icon unchanged on phones) — never a blank or a wrong logo
|
|
219
225
|
- Covers **38 of pi-ai's 40 built-in providers** (`ant-ling` and `radius` have no matching brand mark, so they fall back), plus commonly used routes: Ollama, vLLM, LM Studio, Perplexity, Cohere, Volcengine, Doubao, Hunyuan, Yuanbao, StepFun, SenseNova, Baichuan, 01.AI, Fal, Replicate, Midjourney and more — 62 marks across 76 provider mappings; regional and billing variants (e.g. `xiaomi-token-plan-*`, `qwen-token-plan-*`) share one brand mark
|
|
220
|
-
- **Custom route names are recognised by prefix/alias**: `opencode-goo` → opencode, `openrouter-f` → openrouter, `zai-coding-cn` → Zhipu, `xiaomi-token-plan-cn` → Xiaomi, `command-goat` → Command Code
|
|
221
|
-
- **
|
|
222
|
-
- **
|
|
226
|
+
- **Custom route names are recognised by prefix/alias**: `opencode-goo` → opencode, `openrouter-f` → openrouter, `zai-coding-cn` → Zhipu, `xiaomi-token-plan-cn` → Xiaomi, `command-goat` → Command Code
|
|
227
|
+
- **Unrecognised names fall back to the quota manual adaptation**: when a channel matches neither the built-in table nor any prefix rule, but you have **manually adapted** it in the quota page to some kind (`cpa` → CLIProxyAPI, or any relay → OpenRouter / Zhipu / Command Code / StepFun…), its brand mark is shown; changing the adapted kind swaps the icon immediately, and un-adapting falls back to the official default icon. Two premises: only **manual** adaptation counts (a kind merely auto-inferred from the baseURL does not), and **the channel name always wins** when it matches (`openrouter-f` keeps showing OpenRouter even if you adapt it to something else)
|
|
228
|
+
- **The CLIProxyAPI icon appears on demand**: the hand-drawn "concave diamond + mirrored swirl" mark shows on the model button **only after you have manually adapted some provider as CLIProxyAPI in the quota page** (regardless of the provider's name — `cpa` or a custom one alike); it is one instance of the fallback rule above, and un-adapting immediately falls back to the official default icon
|
|
229
|
+
- **Quota cards carry the icons too**: adapted provider cards show the same brand mark before the channel name (14px; colour tiers keep their brand colour, mono tiers follow the theme text colour). The same "fall back to the manual adaptation" rule applies here — the card list is exactly where you adapt, so the mark appears/swaps immediately
|
|
223
230
|
- **Legible in both light and dark themes**: a brand colour is kept only when its contrast is adequate against **both** a light and a dark background; otherwise the icon automatically switches to a monochrome variant that follows the theme's text colour — so you never get a black logo on a dark background, or a nearly invisible one in light mode
|
|
224
231
|
- **Zero runtime network requests**: icons are inlined into the client bundle at build time, so it works offline, needs no CSP exceptions, and never leaks your provider names to a third party
|
|
225
232
|
- The icon is sized to match the **quota ring** beside the composer (each mark's viewBox is tightened to its real drawn extent and squared at build time, so every brand reads at the same visual size instead of some filling the box and others shrinking)
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<em>A service-control & operations plugin for DeepSeek Harness (DSH) Web.</em>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
|
-
[](package.json)
|
|
13
13
|
[](LICENSE)
|
|
14
14
|
[](https://github.com/deepseek-ai/deepseek-harness)
|
|
15
15
|
[](https://cordis.moe/)
|
|
@@ -92,7 +92,9 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
|
|
|
92
92
|

|
|
93
93
|
|
|
94
94
|
- 运行时间、内存、会话数、活跃 Agent 与后台任务;「进程与运行环境」卡显示平台、架构与 Node 版本
|
|
95
|
-
- 完整诊断:会话存储、工作区注册表、备份目录、tar
|
|
95
|
+
- 完整诊断:会话存储、工作区注册表、备份目录、tar 可用性、文件权限、运行环境、Node 版本与**使用统计索引**——**两行检查清单**(检查名+状态点 / 详情),异常行局部淡染强调、正常行低对比
|
|
96
|
+
- **使用统计索引**:报出已索引会话数、索引更新时间与未能索引的会话数(单会话折读失败会让用量静默少算)。失败会话按「部分成功」处理,记警告而非故障,并作为可行动项进概览;尚未建立索引(还没打开过模型统计页)记信息级;「模型统计」开关关闭时整项不检查(宿主在该状态下本就不刷新索引,报了只会是陈旧误导)
|
|
97
|
+
- **通知权限**:诊断页在宿主检查项之后追加一行浏览器侧检查——系统通知被拒绝或尚未授权都意味着「通知不会响」,并给出恢复入口;浏览器不支持时记信息级。该行只留在诊断页内,不进概览可行动项、不点亮标签 ⚠(是否用通知是用户选择),「任务通知」开关关闭时整行不渲染
|
|
96
98
|
- **插件健康检查**:只检查异常(官方插件页已有完整清单与开关,这里不做重复清单)——插件失败或依赖未就绪时检查项报错/警告,刚启动的 pending/loading 有短暂宽限;已释放或未知状态显式标为信息级,不误报为警告。检查清单下方列出异常插件(名称、已脱敏且限长的错误、缺失依赖);失败插件可**两段式确认后重新加载**(只作用于宿主已确认失败的条目);手动停用的插件(无论内置还是自定义)一律不算异常
|
|
97
99
|
- **插件兼容性**:对照 DSH alpha 版本已移除/变更的接口(客户端供应商、SQLite 持久化后端、聊天/统计条样式哈希、弃用属性)扫描每个启用插件——命中即提示「可能不兼容」并给出具体原因(如「声明了已移除的客户端供应商 @deepseek-ai/dsh-client-runtime」)。分级判定:**代码真实 require/import 才报「可能不兼容」**;仅在 manifest 声明、代码未引用的供应商降为灰色「仅声明残留」(官方加载器对缺失供应商静默跳过,实际无害,提示作者清理即可);退役槽位(如 settings.plugin.item)等为双版本兼容保留或仅展示位变动的接口降为蓝色「已退役接口」提示,不影响插件运行亦不触发黄色警告。升级 alpha 前或刚升级后看一眼就知道第三方插件有没有跟上;纯本地扫描、结果缓存、零网络
|
|
98
100
|
- 文件权限深检与修复(两段式确认)收敛在**默认折叠**的「权限与修复」区(有异常时按钮显示计数)
|
|
@@ -102,11 +104,15 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
|
|
|
102
104
|
|
|
103
105
|

|
|
104
106
|
|
|
105
|
-
- 近 7 天输入 / 输出 / 缓存 token
|
|
107
|
+
- 近 7 天输入 / 输出 / 缓存 token 堆叠柱图,按项目筛选、悬停显示精确值;**图例与刷新统一收进统计区头部行**,图表带可访问的文本摘要。悬浮提示为七行:日期 + 输入/输出/缓存命中三项明细,再追加 **token 总量、成功模型步骤、缓存命中率**;命中率取宿主按当日桶加权的值(比率不跨桶相加)
|
|
106
108
|
- 模型明细横条,列表头部「今日 / 近 7 天 / 累计」切换
|
|
107
|
-
-
|
|
109
|
+
- 卡片最下方**日用量热力日历**:覆盖索引内全部日期(上限 20 周、起点对齐周一),四档强度按单日峰值分位、悬停看当日明细;随项目筛选联动。主图只画近 7 天,这里补上长期视图
|
|
110
|
+
- 热力块右上角可切到**「小时」打卡图**:7 行(周一–周日)× 24 列(0–23 时),格 = 该时段累计 token,回答「几点最忙」;同一批小时桶换个维度折出,不新增持久化字段。方格布局为星期标签与间距预留宽度,窄屏在块内横向滚动
|
|
111
|
+
- **已统计的用量永久保留**:删除会话或删除项目文件夹都不会扣减历史,总量与热力图始终是「索引建立以来的完整历史」;索引版本升级先保留旧摘要,可读取的会话仅在完整重建成功后替换,失败时保留历史并重试
|
|
112
|
+
- **项目文件夹已删除**时,该项目不再出现在项目筛选入口里,但它贡献的用量仍计入「全部」总量、日期桶与模型明细
|
|
113
|
+
- 最近 48 小时模型 / 工具报错统计(默认折叠、仅非空渲染)
|
|
108
114
|
- 提供方未上报 token 用量的步骤不纳入统计
|
|
109
|
-
- 单个会话无法读取、迁移或解析时继续统计其他会话,显示全项目成功/跳过数量与可展开的会话 ID
|
|
115
|
+
- 单个会话无法读取、迁移或解析时继续统计其他会话,显示全项目成功/跳过数量与可展开的会话 ID、错误类别及安全摘要;失败会话有旧缓存时保留并标明过期,首次失败不计入,下次刷新重试。只有服务不可用、列表读取或索引写入失败等全局错误才让整次刷新失败。该提示可关闭(关闭后记入本地存储),且**只静音同一批失败**——出现新的跳过会话或错误类别变化时会再次提示,不会一次关闭就永久盖住新问题
|
|
110
116
|
|
|
111
117
|
### 额度查询
|
|
112
118
|
|
|
@@ -204,7 +210,7 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
|
|
|
204
210
|
- 默认关闭;仅在视口 <1024px(手机竖屏 / 窄窗口)生效,桌面完全无感
|
|
205
211
|
- 侧栏变抽屉、详情列移动端隐藏(对齐官方窄屏语义)、模态变全屏面板、设置左列导航变顶部横滑
|
|
206
212
|
- 模型选择按钮在手机上收成图标(≤480px,与官方窄容器同形态;481px 以上仍显示模型名与推理等级)——插件移动端把中列拉宽,官方 `@container (width<=360px)` 那条收起规则在 428~440px 机型上永远不会触发,故显式对齐官方窄容器形态
|
|
207
|
-
- 统计条(输入框下方「轮/步/tok/s | tok
|
|
213
|
+
- 统计条(输入框下方「轮/步/tok/s | tok/缓存命中」)在手机上**保持一行、居中且不歪**:收紧这一行自身的左右内边距(官方 32px→2px)与列间距换出可用宽度,两枚统计交给官方 `justify-content` 居中排开——≥~420px 视口零截断,更窄视口按比例各让一点(远少于官方的固定截断),不换行、不横向滚动;同时兼容老版本 DSH(0.1.5-rc.2 上这条行是整行宽,早期实现的子项 `flex-grow` 会把两枚统计整组推到左边,现已改为不生长)(桌面不受影响)
|
|
208
214
|
- 会话顶栏手机端重排(≤560px):标题行只留**标题 + 模式芯片**(芯片右靠贴住「…」钮,标题基本完整可见),「N 个子代理」与「N 个后台任务运行中」两枚计数芯片泊到「对话/轨迹」标签行右缘成一对(标签间距 36→20,点芯片本体仍开各自菜单);官方 crumbs 放不下时的**拦腰硬裁**彻底消除,561px 以上与桌面保持官方原布局
|
|
209
215
|
- Agent Team 弹窗手机端不越屏(<1024px):官方 Agent Team 面板自带左锚(`left:0`),挂在头部右侧动作槽上会整体右移出屏(实测 320~1023px 越出 112~352px)。移动端把会话头部设为定位上下文、面板改**右锚 16px** 并按 `100vw − 32px` 封顶,两缘各留 16px;桌面 ≥1024px 官方几何逐字不变
|
|
210
216
|
- 滑动沉浸:会话内下滑自动收起头部与输入框全屏阅读(收起时让出输入框占位,正文真正铺满整屏;回显时若仍停在会话末尾会自动对齐到底),上滑 / 点「回到底部」浮钮 / 聚焦输入框即恢复(无额外悬浮钮);已经停在会话末尾时往回一点即回显(不再等满阈值),点回底后停留位置会补一次贴底对齐;流式贴底、锚点跳转等程序化滚动绝不误触发
|
|
@@ -219,9 +225,10 @@ DSH Web 服务控制与运维插件:安全重启、版本管理与一键升级
|
|
|
219
225
|
- 输入框里那颗**模型按钮会显示当前渠道的厂家图标**:宽屏(>480px)加在模型名**前面**;手机上(≤480px,官方把名称收成图标的形态)**替换**掉官方那枚通用图标
|
|
220
226
|
- **没适配的渠道保持官方默认图标不变**(宽屏不加、手机照旧显示官方图标),不会出现空缺或错图
|
|
221
227
|
- 覆盖 **pi-ai 内置 40 个 provider 中的 38 个**(`ant-ling`、`radius` 无对应品牌图形,走默认图标),并补充 ollama、vLLM、LM Studio、Perplexity、Cohere、火山引擎、豆包、混元、元宝、阶跃、商汤、百川、零一万物、Fal、Replicate、Midjourney 等常用渠道,共 62 张图形 / 76 条渠道映射;区域与计费变体(如 `xiaomi-token-plan-*`、`qwen-token-plan-*`)共用同一品牌图形
|
|
222
|
-
- **自定义渠道名按前缀/别名自动识别**:`opencode-goo` → opencode、`openrouter-f` → openrouter、`zai-coding-cn` → 智谱、`xiaomi-token-plan-cn` → 小米、`command-goat` → Command Code
|
|
223
|
-
-
|
|
224
|
-
-
|
|
228
|
+
- **自定义渠道名按前缀/别名自动识别**:`opencode-goo` → opencode、`openrouter-f` → openrouter、`zai-coding-cn` → 智谱、`xiaomi-token-plan-cn` → 小米、`command-goat` → Command Code 等
|
|
229
|
+
- **识别不到时按余额查询的手动适配兜底**:某个渠道名既不在内置表、也不符合前缀规则时,如果你在余额查询里把它**手动适配**成了某个类型(如 `cpa` → CLIProxyAPI,或任意中转 → OpenRouter / 智谱 / Command Code / StepFun 等),就显示该类型的厂家图标;适配类型一改图标立即跟着换,撤销适配立即回落官方默认图标。两个前提:只有**手动**适配算数(仅由 baseURL 自动推断出来的类型不算),且**名字能识别时以名字为准**(叫 `openrouter-f` 的渠道即使另外适配成别的类型,也仍显示 OpenRouter 标)
|
|
230
|
+
- **CLIProxyAPI 图标按需出现**:手绘的「内凹菱形 + 镜像漩涡」品牌标**只在你在余额查询里把某个渠道手动适配成 CLIProxyAPI 后**才显示在模型按钮上(渠道名不限,叫 `cpa` 还是自定义名都一样);它就是上面那条兜底规则的一个实例,撤销适配立即回落官方默认图标
|
|
231
|
+
- **余额查询的渠道卡片同样带图标**:已适配卡片的渠道名前显示同一套厂家小图标(14px;彩色档原样上品牌色、单色档跟随主题文字色)。上面那条「按手动适配兜底」的规则在这里同样生效——卡片区正是你做适配的地方,改完适配立即出现/换标
|
|
225
232
|
- **浅色 / 深色都清晰**:品牌色对浅底与深底**两侧**对比度都达标才保留原色,否则自动改用跟随主题文字色的单色版——不会出现深色模式下「黑图标糊在黑底上」或浅色模式下近乎隐形
|
|
226
233
|
- **零运行期网络请求**:图标在构建期内联进客户端产物,离线可用、不影响 CSP,也不向第三方暴露你的渠道名称
|
|
227
234
|
- 图标尺寸与输入框旁的**额度圆环**一致(生成期把每个图标的 viewBox 收紧到真实绘制范围并正方形化,所以各品牌「看起来一样大」,不会有的满格有的缩成一团)
|