fix(usage): 列表支持显式模板查询(Sub2API/NewAPI)——对齐后端绕过 usage_kinds 的口径 — bump to v0.7.22
Release / Version consistency (push) Canceled after 0s
Release / Build (macos-latest) (push) Canceled after 0s
Release / Build (ubuntu-latest) (push) Canceled after 0s
Release / Build (windows-latest) (push) Canceled after 0s
Release / Attach macOS install script (push) Canceled after 0s
Release / Version consistency (push) Canceled after 0s
Release / Build (macos-latest) (push) Canceled after 0s
Release / Build (ubuntu-latest) (push) Canceled after 0s
Release / Build (windows-latest) (push) Canceled after 0s
Release / Attach macOS install script (push) Canceled after 0s
This commit is contained in:
1 parent
11286419b1
commit
13e15657af
9 files changed
+58
-9
No files matched your search
@@ -6,6 +6,10 @@
|
||||
|
||||
---
|
||||
|
||||
## v0.7.22 (2026-09-24)
|
||||
|
||||
- **修复 Sub2API / NewAPI 模板查询不显示**:为无预设识别类型的自定义供应商配置 Sub2API(或 NewAPI)模板后,弹窗测试可查但供应商列表始终不显示——前端列表的查询/显示门槛只看预设 `usageKinds`,显式模板被漏掉;现在与后端口径对齐(模板查询绕过 usage_kinds),列表正常显示余额 / 配额
|
||||
|
||||
## v0.7.21 (2026-09-24)
|
||||
|
||||
- **models.dev 在线同步**:高级设置新增「模型参考数据」卡片——一键在线拉取 models.dev 最新快照(上下文长度 / 能力标记 / 单价),前端与仪表盘计价即时生效,无需等待新版本;支持一键恢复随版本内置数据;显示当前数据来源与版本(同步 / 内置 + 日期 + 模型/供应商数)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# KimiSwitch v0.7.22
|
||||
|
||||
## 修复
|
||||
|
||||
- **Sub2API / NewAPI 模板查询在供应商列表不显示**:为没有预设识别类型的自定义供应商(如自家中转站)配置「Sub2API 中转站」或「NewAPI 中转站」模板后,配置弹窗里「测试查询」正常返回余额,但回到供应商列表却始终空白。根因:列表的查询与显示门槛只认预设注入的 `usageKinds`,而后端模板查询本就绕过 `usageKinds` 直接执行——前端口径与后端不一致。现在二者对齐,显式模板的供应商在列表正常显示余额 / 配额窗口、支持自动查询间隔与预警阈值。
|
||||
|
||||
## 备注
|
||||
|
||||
- 仅前端修复(`useUsageQuery` 支持判定 + 卡片渲染门槛),后端查询逻辑无变化;已补 3 个单测覆盖支持判定。
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "kimiswitch",
|
||||
"private": true,
|
||||
"version": "0.7.21",
|
||||
"version": "0.7.22",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
Generated
+1
-1
@@ -1978,7 +1978,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kimiswitch"
|
||||
version = "0.7.21"
|
||||
version = "0.7.22"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "kimiswitch"
|
||||
version = "0.7.21"
|
||||
version = "0.7.22"
|
||||
description = "Kimi Switch - model config manager"
|
||||
authors = ["codingplan.site"]
|
||||
edition = "2021"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"productName": "Kimi Switch",
|
||||
"version": "0.7.21",
|
||||
"version": "0.7.22",
|
||||
"identifier": "com.kimiswitch.app",
|
||||
"build": {
|
||||
"beforeDevCommand": "npm run dev",
|
||||
|
||||
@@ -96,7 +96,9 @@ function ProviderCard({
|
||||
provider.usageKinds,
|
||||
provider.usageConfig?.autoQueryIntervalMinutes,
|
||||
provider.usageConfig?.enabled === false,
|
||||
provider.usageConfig?.threshold
|
||||
provider.usageConfig?.threshold,
|
||||
provider.usageConfig?.templateType === "newapi" ||
|
||||
provider.usageConfig?.templateType === "sub2api"
|
||||
);
|
||||
const providerModels = Object.values(models).filter(
|
||||
(m) => m.provider === provider.name
|
||||
@@ -221,7 +223,7 @@ function ProviderCard({
|
||||
)}
|
||||
{/* compact usage summary — sits left of the switch button,
|
||||
mirroring cc-switch's card layout (usage → action buttons) */}
|
||||
{(provider.usageKinds?.length ?? 0) > 0 && (
|
||||
{usage.supported && (
|
||||
<UsageFooter usage={usage} variant="compact" />
|
||||
)}
|
||||
<button
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { isAlertTier, type UsageData } from "./useUsageQuery";
|
||||
import { isAlertTier, usageQuerySupported, type UsageData } from "./useUsageQuery";
|
||||
|
||||
/** 百分比窗口行(five_hour 等);套餐类 tier 的 unit 恒为 "%"。 */
|
||||
function percentTier(used: number): UsageData {
|
||||
@@ -42,3 +42,22 @@ describe("isAlertTier", () => {
|
||||
expect(isAlertTier({ planName: "five_hour", unit: "%", remaining: 20 }, 50)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("usageQuerySupported", () => {
|
||||
it("有识别类型即可查询", () => {
|
||||
expect(usageQuerySupported(["balance:deepseek"])).toBe(true);
|
||||
expect(usageQuerySupported([], true)).toBe(true);
|
||||
});
|
||||
|
||||
it("显式模板(newapi/sub2api)绕过 usage_kinds——自定义供应商也该查", () => {
|
||||
expect(usageQuerySupported(undefined, true)).toBe(true);
|
||||
});
|
||||
|
||||
it("无识别类型且非显式模板时不查询", () => {
|
||||
expect(usageQuerySupported(undefined)).toBe(false);
|
||||
expect(usageQuerySupported([])).toBe(false);
|
||||
// auto 模板没有识别到类型 = 不支持(与弹窗短路口径一致)
|
||||
expect(usageQuerySupported([], false)).toBe(false);
|
||||
expect(usageQuerySupported(undefined, undefined)).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -75,15 +75,30 @@ export function isAlertTier(
|
||||
return d.unit === "%" && d.used != null && d.used >= threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否值得为该供应商发起用量查询:有预设识别类型,或后端按显式模板
|
||||
* (newapi / sub2api,二者绕过 usage_kinds)查询。
|
||||
*/
|
||||
export function usageQuerySupported(
|
||||
usageKinds?: string[],
|
||||
explicitTemplate?: boolean
|
||||
): boolean {
|
||||
return (usageKinds?.length ?? 0) > 0 || explicitTemplate === true;
|
||||
}
|
||||
|
||||
export function useUsageQuery(
|
||||
agent: Agent,
|
||||
providerName: string,
|
||||
usageKinds?: string[],
|
||||
autoIntervalMinutes?: number,
|
||||
disabled?: boolean,
|
||||
threshold?: number
|
||||
threshold?: number,
|
||||
/** Backend resolves the query from an explicit template (newapi / sub2api)
|
||||
* regardless of usageKinds — those bypass kinds entirely, so the row is
|
||||
* supported even when the provider has no preset-detected kinds. */
|
||||
explicitTemplate?: boolean
|
||||
): UsageQueryState {
|
||||
const supported = (usageKinds?.length ?? 0) > 0;
|
||||
const supported = usageQuerySupported(usageKinds, explicitTemplate);
|
||||
// Cache key includes the agent so a Kimi Code provider and a Pi provider
|
||||
// with the same name do not clobber each other's cached result.
|
||||
const cacheKey = `${agent}:${providerName}`;
|
||||
|
||||
Reference in new issue
Block a user