dsh-codearts 1.2.4 → 1.2.6
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/CHANGELOG.md +72 -0
- package/README.en.md +9 -0
- package/README.md +2 -0
- package/lib/bin.mjs +2 -2
- package/lib/client/index.d.cts +40 -0
- package/lib/client/index.js +534 -90
- package/lib/index.d.mts +37 -1
- package/lib/index.mjs +21 -8
- package/lib/{usage-DGIuT79_.mjs → usage-4B0o-CQN.mjs} +57 -3
- package/package.json +1 -1
package/lib/index.d.mts
CHANGED
|
@@ -1347,6 +1347,24 @@ interface UsageSnapshot {
|
|
|
1347
1347
|
byAccountToday: Record<string, UsageTotals>;
|
|
1348
1348
|
/** 账本覆盖的天数(便于「数据从哪天开始」的说明)。 */
|
|
1349
1349
|
days: number;
|
|
1350
|
+
/**
|
|
1351
|
+
* 最近 {@link TREND_DAYS} 天(含今天,按日期升序)的每日合计;没账目的日子补 0。
|
|
1352
|
+
*
|
|
1353
|
+
* 补 0 而不是跳过:横轴要固定 7 格,否则「昨天没跑」和「昨天丢了」看不出区别。
|
|
1354
|
+
*/
|
|
1355
|
+
recentDays: {
|
|
1356
|
+
date: string;
|
|
1357
|
+
totals: UsageTotals;
|
|
1358
|
+
}[];
|
|
1359
|
+
/**
|
|
1360
|
+
* 今天 0 点到 23 点的逐小时合计(固定 24 项,还没到的钟点补 0)。
|
|
1361
|
+
*
|
|
1362
|
+
* 命中率曲线用它 —— 一次长会话把命中率拉低、隔一小时又回来,按天的粒度看不见。
|
|
1363
|
+
*/
|
|
1364
|
+
todayByHour: {
|
|
1365
|
+
hour: number;
|
|
1366
|
+
totals: UsageTotals;
|
|
1367
|
+
}[];
|
|
1350
1368
|
/** 最近一次记账时间(epoch ms)。 */
|
|
1351
1369
|
lastAt?: number;
|
|
1352
1370
|
}
|
|
@@ -1385,10 +1403,21 @@ declare class CodeArtsUsageTracker {
|
|
|
1385
1403
|
noteRequest(accountId: string, model: string, at?: number): void;
|
|
1386
1404
|
/** 记一次 usage 帧。 */
|
|
1387
1405
|
noteUsage(accountId: string, model: string, raw: RawUsage | undefined, at?: number): void;
|
|
1388
|
-
/**
|
|
1406
|
+
/** 一天里的逐小时桶,第一次写的时候才建(老账本没有这个键)。 */
|
|
1407
|
+
private hoursOf;
|
|
1408
|
+
/**
|
|
1409
|
+
* 丢弃保留期之外的天(按日期键比较即可,YYYY-MM-DD 是字典序)。
|
|
1410
|
+
*
|
|
1411
|
+
* 顺带把两天之前的**小时桶**清掉:逐小时数据只有「今天按小时」在画,留着只是
|
|
1412
|
+
* 让 60 天的账本多出一个数量级的体积。
|
|
1413
|
+
*/
|
|
1389
1414
|
private prune;
|
|
1390
1415
|
/** 当前快照(卡片与 CLI 都读它)。 */
|
|
1391
1416
|
snapshot(at?: number): UsageSnapshot;
|
|
1417
|
+
/** 最近 TREND_DAYS 天的每日合计(按日期升序,缺账目的日子补 0)。 */
|
|
1418
|
+
private recentDaysOf;
|
|
1419
|
+
/** 今天 0 点起的 24 个钟点(还没到的小时补 0,横轴才有固定的 24 格)。 */
|
|
1420
|
+
private todayByHourOf;
|
|
1392
1421
|
private scheduleSave;
|
|
1393
1422
|
/** 立即落盘(关停时调用,别丢最后几秒的账)。 */
|
|
1394
1423
|
flush(): Promise<void>;
|
|
@@ -1615,6 +1644,13 @@ interface Config {
|
|
|
1615
1644
|
showCreditDock?: boolean;
|
|
1616
1645
|
/** 等上游开流时那行「排队第 N 位」是否显示。缺省 = 显示。 */
|
|
1617
1646
|
showQueueDock?: boolean;
|
|
1647
|
+
/**
|
|
1648
|
+
* 是否在 DSH 侧边栏的图标列里加一个 CodeArts 图标(点开在中间列显示整页版卡片)。
|
|
1649
|
+
*
|
|
1650
|
+
* 缺省 = **不显示**:图标列是全宿主共用的资源,每个插件都默认占一格很快就会挤满,
|
|
1651
|
+
* 而「设置 → 插件」里本来就能看到同一张卡片,所以这一格交给用户自己决定要不要。
|
|
1652
|
+
*/
|
|
1653
|
+
showSidebarPanel?: boolean;
|
|
1618
1654
|
}
|
|
1619
1655
|
declare const Config: z<Config>;
|
|
1620
1656
|
declare function apply(ctx: Context, rawConfig: Config): void;
|
package/lib/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as upstreamErrorMessage, B as modelUnavailableReason, C as isWelfareClaimedStatus, D as prepareChatBody, E as pickDailyWelfareCampaign, F as filterEnabledModels, G as codeartsAuthPath, H as CodeArtsCredentialStore, I as forgetModelUnavailable, K as startLogin, L as isBenefitBlocked, M as FALLBACK_CODEARTS_MODELS, N as clearBenefitBlocked, O as rateLimitFrame, P as creditRatioLabel, R as isBenefitModel, S as isTpmLimit, T as modelUnavailableReasonText, U as MANUAL_ACCOUNT_ID, V as CodeArtsAccountStore, W as codeartsAccountsPath, _ as isIamTokenError, a as SNAP_HOST, b as isParamInvalidFrame, c as claimDailyWelfare, d as fetchCallerIdentity, f as fetchModels, g as isConcurrencyCap, h as firstFrameError, i as refreshCatalog, j as CodeArtsCatalog, k as signedGet, l as clearQueueStatus, m as fetchWelfareCampaigns, n as codeartsUsagePath, o as canonicalModel, p as fetchQueueStatus, r as discoverModels, s as chatStream, t as CodeArtsUsageTracker, u as degradeTokenCeiling, v as isModelNotAccessible, w as maxTokensCeilingFor, x as isQueueableRate, y as isNotMultimodal, z as markModelUnavailable } from "./usage-
|
|
1
|
+
import { A as upstreamErrorMessage, B as modelUnavailableReason, C as isWelfareClaimedStatus, D as prepareChatBody, E as pickDailyWelfareCampaign, F as filterEnabledModels, G as codeartsAuthPath, H as CodeArtsCredentialStore, I as forgetModelUnavailable, K as startLogin, L as isBenefitBlocked, M as FALLBACK_CODEARTS_MODELS, N as clearBenefitBlocked, O as rateLimitFrame, P as creditRatioLabel, R as isBenefitModel, S as isTpmLimit, T as modelUnavailableReasonText, U as MANUAL_ACCOUNT_ID, V as CodeArtsAccountStore, W as codeartsAccountsPath, _ as isIamTokenError, a as SNAP_HOST, b as isParamInvalidFrame, c as claimDailyWelfare, d as fetchCallerIdentity, f as fetchModels, g as isConcurrencyCap, h as firstFrameError, i as refreshCatalog, j as CodeArtsCatalog, k as signedGet, l as clearQueueStatus, m as fetchWelfareCampaigns, n as codeartsUsagePath, o as canonicalModel, p as fetchQueueStatus, r as discoverModels, s as chatStream, t as CodeArtsUsageTracker, u as degradeTokenCeiling, v as isModelNotAccessible, w as maxTokensCeilingFor, x as isQueueableRate, y as isNotMultimodal, z as markModelUnavailable } from "./usage-4B0o-CQN.mjs";
|
|
2
2
|
import { i as lazyApi, r as createProvider } from "./models-CgKCibpk.mjs";
|
|
3
3
|
import z from "@deepseek-ai/schemastery";
|
|
4
4
|
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
@@ -1527,10 +1527,14 @@ function modelBadgesOf(models) {
|
|
|
1527
1527
|
};
|
|
1528
1528
|
});
|
|
1529
1529
|
}
|
|
1530
|
-
/**
|
|
1530
|
+
/**
|
|
1531
|
+
* 开关的默认值:没有 settings provider(或老配置没这两个键)时保持原有行为 ——
|
|
1532
|
+
* 底部两行都显示;侧边栏相反,缺省不开(那一格是所有插件共用的全局座位)。
|
|
1533
|
+
*/
|
|
1531
1534
|
const DEFAULT_DOCK_FLAGS = {
|
|
1532
1535
|
credits: true,
|
|
1533
|
-
queue: true
|
|
1536
|
+
queue: true,
|
|
1537
|
+
sidebar: false
|
|
1534
1538
|
};
|
|
1535
1539
|
/**
|
|
1536
1540
|
* 把逐账号的领取结果汇总成一条:HTTP 层只看 ok,卡片看 results 逐号展示。
|
|
@@ -1646,6 +1650,8 @@ function usageOf(deps) {
|
|
|
1646
1650
|
byModelToday: snapshot?.byModelToday ?? [],
|
|
1647
1651
|
byAccountToday: snapshot?.byAccountToday ?? {},
|
|
1648
1652
|
days: snapshot?.days ?? 0,
|
|
1653
|
+
recentDays: snapshot?.recentDays ?? [],
|
|
1654
|
+
todayByHour: snapshot?.todayByHour ?? [],
|
|
1649
1655
|
...snapshot?.lastAt === void 0 ? {} : { lastAt: snapshot.lastAt },
|
|
1650
1656
|
slots: slotsOf(deps)
|
|
1651
1657
|
};
|
|
@@ -1761,9 +1767,13 @@ function dockHandler(deps) {
|
|
|
1761
1767
|
}
|
|
1762
1768
|
try {
|
|
1763
1769
|
const body = JSON.parse(await readBody(req));
|
|
1764
|
-
const touched = [
|
|
1770
|
+
const touched = [
|
|
1771
|
+
"credits",
|
|
1772
|
+
"queue",
|
|
1773
|
+
"sidebar"
|
|
1774
|
+
].filter((key) => body[key] !== void 0);
|
|
1765
1775
|
if (touched.length === 0 || touched.some((key) => typeof body[key] !== "boolean")) {
|
|
1766
|
-
json(res, 400, { error: "expected {\"credits\"?: boolean, \"queue\"?: boolean}" });
|
|
1776
|
+
json(res, 400, { error: "expected {\"credits\"?: boolean, \"queue\"?: boolean, \"sidebar\"?: boolean}" });
|
|
1767
1777
|
return;
|
|
1768
1778
|
}
|
|
1769
1779
|
if (!await deps.setDock(Object.fromEntries(touched.map((key) => [key, body[key]])))) {
|
|
@@ -2404,7 +2414,8 @@ function unwrapConfig(value) {
|
|
|
2404
2414
|
const Config = z.object({
|
|
2405
2415
|
enabledModels: z.array(z.string()).description("Model ids offered in the model pickers (empty means every model)").volatile(),
|
|
2406
2416
|
showCreditDock: z.boolean().default(true).description("Show the remaining-credits line under the chat input box").volatile(),
|
|
2407
|
-
showQueueDock: z.boolean().default(true).description("Show the upstream queue position under the chat input box").volatile()
|
|
2417
|
+
showQueueDock: z.boolean().default(true).description("Show the upstream queue position under the chat input box").volatile(),
|
|
2418
|
+
showSidebarPanel: z.boolean().default(false).description("Show a CodeArts icon in the DSH sidebar icon column, opening this page in the middle column").volatile()
|
|
2408
2419
|
});
|
|
2409
2420
|
function settingsCompatNamespace(ctx) {
|
|
2410
2421
|
return resolveSettingsNamespaceCompat(ctx, ctx.get("settings"), CODEARTS_SETTINGS_NS);
|
|
@@ -2479,14 +2490,16 @@ function apply(ctx, rawConfig) {
|
|
|
2479
2490
|
};
|
|
2480
2491
|
const dock = () => ({
|
|
2481
2492
|
credits: current().showCreditDock !== false,
|
|
2482
|
-
queue: current().showQueueDock !== false
|
|
2493
|
+
queue: current().showQueueDock !== false,
|
|
2494
|
+
sidebar: current().showSidebarPanel === true
|
|
2483
2495
|
});
|
|
2484
2496
|
const setDock = async (patch) => {
|
|
2485
2497
|
const settings = ctx.get("settings");
|
|
2486
2498
|
if (settings === void 0) return false;
|
|
2487
2499
|
await settings.update(settingsCompatNamespace(ctx), {
|
|
2488
2500
|
...patch.credits === void 0 ? {} : { showCreditDock: patch.credits },
|
|
2489
|
-
...patch.queue === void 0 ? {} : { showQueueDock: patch.queue }
|
|
2501
|
+
...patch.queue === void 0 ? {} : { showQueueDock: patch.queue },
|
|
2502
|
+
...patch.sidebar === void 0 ? {} : { showSidebarPanel: patch.sidebar }
|
|
2490
2503
|
});
|
|
2491
2504
|
return true;
|
|
2492
2505
|
};
|
|
@@ -2769,6 +2769,14 @@ function localDateKey(at = Date.now()) {
|
|
|
2769
2769
|
const p = (n) => String(n).padStart(2, "0");
|
|
2770
2770
|
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
|
|
2771
2771
|
}
|
|
2772
|
+
/** 本地小时键 `00`..`23`(同样按本地时间切,跨零点的那一小时不会错位)。 */
|
|
2773
|
+
function localHourKey(at = Date.now()) {
|
|
2774
|
+
return localHourKeyOfHour(new Date(at).getHours());
|
|
2775
|
+
}
|
|
2776
|
+
/** 0..23 -> `00`..`23`(小时桶的键)。 */
|
|
2777
|
+
function localHourKeyOfHour(hour) {
|
|
2778
|
+
return String(hour).padStart(2, "0");
|
|
2779
|
+
}
|
|
2772
2780
|
function positiveInt(value) {
|
|
2773
2781
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : 0;
|
|
2774
2782
|
}
|
|
@@ -2879,9 +2887,14 @@ var CodeArtsUsageTracker = class {
|
|
|
2879
2887
|
if (typeof day !== "object" || day === null) continue;
|
|
2880
2888
|
const models = normalizeStore(day.models);
|
|
2881
2889
|
const accounts = normalizeStore(day.accounts);
|
|
2882
|
-
|
|
2890
|
+
const hours = day.hours;
|
|
2891
|
+
this.days.set(date, hours === void 0 ? {
|
|
2883
2892
|
models,
|
|
2884
2893
|
accounts
|
|
2894
|
+
} : {
|
|
2895
|
+
models,
|
|
2896
|
+
accounts,
|
|
2897
|
+
hours: normalizeStore(hours)
|
|
2885
2898
|
});
|
|
2886
2899
|
}
|
|
2887
2900
|
this.prune(this.now());
|
|
@@ -2915,6 +2928,7 @@ var CodeArtsUsageTracker = class {
|
|
|
2915
2928
|
const day = this.day(localDateKey(at));
|
|
2916
2929
|
addTotals(this.bucket(day.models, model), { requests: 1 });
|
|
2917
2930
|
addTotals(this.bucket(day.accounts, accountId), { requests: 1 });
|
|
2931
|
+
addTotals(this.bucket(this.hoursOf(day), localHourKey(at)), { requests: 1 });
|
|
2918
2932
|
this.lastAt = at;
|
|
2919
2933
|
this.prune(at);
|
|
2920
2934
|
this.scheduleSave();
|
|
@@ -2926,15 +2940,28 @@ var CodeArtsUsageTracker = class {
|
|
|
2926
2940
|
const day = this.day(localDateKey(at));
|
|
2927
2941
|
addTotals(this.bucket(day.models, model), usage);
|
|
2928
2942
|
addTotals(this.bucket(day.accounts, accountId), usage);
|
|
2943
|
+
addTotals(this.bucket(this.hoursOf(day), localHourKey(at)), usage);
|
|
2929
2944
|
this.lastAt = at;
|
|
2930
2945
|
this.prune(at);
|
|
2931
2946
|
this.scheduleSave();
|
|
2932
2947
|
}
|
|
2933
|
-
/**
|
|
2948
|
+
/** 一天里的逐小时桶,第一次写的时候才建(老账本没有这个键)。 */
|
|
2949
|
+
hoursOf(day) {
|
|
2950
|
+
day.hours ??= {};
|
|
2951
|
+
return day.hours;
|
|
2952
|
+
}
|
|
2953
|
+
/**
|
|
2954
|
+
* 丢弃保留期之外的天(按日期键比较即可,YYYY-MM-DD 是字典序)。
|
|
2955
|
+
*
|
|
2956
|
+
* 顺带把两天之前的**小时桶**清掉:逐小时数据只有「今天按小时」在画,留着只是
|
|
2957
|
+
* 让 60 天的账本多出一个数量级的体积。
|
|
2958
|
+
*/
|
|
2934
2959
|
prune(at) {
|
|
2935
2960
|
if (this.days.size === 0) return;
|
|
2936
2961
|
const cutoff = localDateKey(at - 5184e6);
|
|
2937
|
-
|
|
2962
|
+
const hourCutoff = localDateKey(at - 1728e5);
|
|
2963
|
+
for (const [date, day] of [...this.days.entries()]) if (date < cutoff) this.days.delete(date);
|
|
2964
|
+
else if (date < hourCutoff && day.hours !== void 0) delete day.hours;
|
|
2938
2965
|
}
|
|
2939
2966
|
/** 当前快照(卡片与 CLI 都读它)。 */
|
|
2940
2967
|
snapshot(at = this.now()) {
|
|
@@ -2961,9 +2988,36 @@ var CodeArtsUsageTracker = class {
|
|
|
2961
2988
|
})).sort((a, b) => b.totals.totalTokens - a.totals.totalTokens || (a.id < b.id ? -1 : 1)),
|
|
2962
2989
|
byAccountToday: Object.fromEntries(Object.entries(today?.accounts ?? {}).map(([id, totals]) => [id, { ...totals }])),
|
|
2963
2990
|
days: this.days.size,
|
|
2991
|
+
recentDays: this.recentDaysOf(at),
|
|
2992
|
+
todayByHour: this.todayByHourOf(today, at),
|
|
2964
2993
|
...this.lastAt === void 0 ? {} : { lastAt: this.lastAt }
|
|
2965
2994
|
};
|
|
2966
2995
|
}
|
|
2996
|
+
/** 最近 TREND_DAYS 天的每日合计(按日期升序,缺账目的日子补 0)。 */
|
|
2997
|
+
recentDaysOf(at) {
|
|
2998
|
+
const out = [];
|
|
2999
|
+
for (let back = 6; back >= 0; back -= 1) {
|
|
3000
|
+
const date = localDateKey(at - back * 864e5);
|
|
3001
|
+
const day = this.days.get(date);
|
|
3002
|
+
out.push({
|
|
3003
|
+
date,
|
|
3004
|
+
totals: day === void 0 ? emptyTotals() : sumOf(day.models)
|
|
3005
|
+
});
|
|
3006
|
+
}
|
|
3007
|
+
return out;
|
|
3008
|
+
}
|
|
3009
|
+
/** 今天 0 点起的 24 个钟点(还没到的小时补 0,横轴才有固定的 24 格)。 */
|
|
3010
|
+
todayByHourOf(today, at) {
|
|
3011
|
+
const hours = today?.hours ?? {};
|
|
3012
|
+
const currentHour = new Date(at).getHours();
|
|
3013
|
+
return Array.from({ length: 24 }, (_, hour) => {
|
|
3014
|
+
const totals = hours[localHourKeyOfHour(hour)];
|
|
3015
|
+
return {
|
|
3016
|
+
hour,
|
|
3017
|
+
totals: hour > currentHour || totals === void 0 ? emptyTotals() : { ...totals }
|
|
3018
|
+
};
|
|
3019
|
+
});
|
|
3020
|
+
}
|
|
2967
3021
|
scheduleSave() {
|
|
2968
3022
|
if (this.path === void 0) return;
|
|
2969
3023
|
if (this.saveTimer !== void 0) return;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "dsh-codearts",
|
|
3
3
|
"displayName": "DSH CodeArts Connect",
|
|
4
4
|
"description": "把华为云 CodeArts 接入 DeepSeek Harness —— 内置 OAuth2 登录(PKCE + DPoP),登录后即可在 DSH 对话窗口使用 CodeArts 的模型。",
|
|
5
|
-
"version": "1.2.
|
|
5
|
+
"version": "1.2.6",
|
|
6
6
|
"packageManager": "pnpm@11.24.0",
|
|
7
7
|
"author": "elegant01",
|
|
8
8
|
"keywords": [
|