@lyogvce/dsh-codex-subscription 0.2.2 → 0.2.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 +1 -1
- package/lib/client.js +46 -7
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
4. **原生多轮思考链回放与工具调用**
|
|
20
20
|
- 底层复用 DSH 内置的 `PiAiAdapter` 与 `@earendil-works/pi-ai` 的 `openaiCodexProvider()`,固定使用 `sse` 传输(含 `zstd` 请求体压缩、规范化纯 UUID `session-id` / `x-client-request-id` 缓存头、`reasoning.encrypted_content` 签名回放与图片自动缩放卸载)。
|
|
21
21
|
5. **Codex 订阅限额内联展示(`conversation.input.right`)**
|
|
22
|
-
- 当会话选中 `openai-codex`
|
|
22
|
+
- 当会话选中 `openai-codex` 模型时,在输入框右下角紧邻模型选择器左侧展示限额胶囊(根据 `wham/usage` 返回的 `limit_window_seconds` 自适应展示 Plus 的 `5h X% · 7d Y%` 双窗口或 Pro 的 `7d X%` 单窗口,内置 60 秒缓存、单飞合并与每轮回复结束自动刷新),点击可展开查看对应窗口进度条、重置倒计时与手动刷新按钮;切换至其他 Provider 模型时自动隐藏。
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
package/lib/client.js
CHANGED
|
@@ -25,6 +25,8 @@ window.__ModuleLoader__.load({
|
|
|
25
25
|
//#endregion
|
|
26
26
|
//#region src/client/quota.ts
|
|
27
27
|
const RING_CIRCUMFERENCE = 2 * Math.PI * 5.5;
|
|
28
|
+
const DEFAULT_PRIMARY_WINDOW_SECONDS = 18e3;
|
|
29
|
+
const DEFAULT_SECONDARY_WINDOW_SECONDS = 604800;
|
|
28
30
|
function resolveActiveProvider(directorySnapshot, projectedSelection) {
|
|
29
31
|
const dir = directorySnapshot && typeof directorySnapshot === "object" ? directorySnapshot : void 0;
|
|
30
32
|
const proj = projectedSelection && typeof projectedSelection === "object" ? projectedSelection : void 0;
|
|
@@ -46,14 +48,53 @@ window.__ModuleLoader__.load({
|
|
|
46
48
|
if (usedPercent >= 80) return "warn";
|
|
47
49
|
return "ok";
|
|
48
50
|
}
|
|
51
|
+
function resolveWindowSpan(windowSeconds, fallbackSeconds) {
|
|
52
|
+
const sec = typeof windowSeconds === "number" && Number.isFinite(windowSeconds) && windowSeconds > 0 ? windowSeconds : fallbackSeconds;
|
|
53
|
+
if (sec >= 86400) return {
|
|
54
|
+
value: Math.round(sec / 86400),
|
|
55
|
+
unit: "d"
|
|
56
|
+
};
|
|
57
|
+
if (sec >= 3600) return {
|
|
58
|
+
value: Math.round(sec / 3600),
|
|
59
|
+
unit: "h"
|
|
60
|
+
};
|
|
61
|
+
return {
|
|
62
|
+
value: Math.max(1, Math.round(sec / 60)),
|
|
63
|
+
unit: "m"
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const WINDOW_UNIT_LABELS = {
|
|
67
|
+
zh: {
|
|
68
|
+
d: "天窗口",
|
|
69
|
+
h: "小时窗口",
|
|
70
|
+
m: "分钟窗口"
|
|
71
|
+
},
|
|
72
|
+
en: {
|
|
73
|
+
d: "-day window",
|
|
74
|
+
h: "-hour window",
|
|
75
|
+
m: "-minute window"
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
function formatWindowShortLabel(windowSeconds, fallbackSeconds = DEFAULT_PRIMARY_WINDOW_SECONDS) {
|
|
79
|
+
const { value, unit } = resolveWindowSpan(windowSeconds, fallbackSeconds);
|
|
80
|
+
return `${value}${unit}`;
|
|
81
|
+
}
|
|
82
|
+
function formatWindowTitle(windowSeconds, locale, fallbackSeconds = DEFAULT_PRIMARY_WINDOW_SECONDS) {
|
|
83
|
+
const { value, unit } = resolveWindowSpan(windowSeconds, fallbackSeconds);
|
|
84
|
+
const suffix = WINDOW_UNIT_LABELS[locale][unit];
|
|
85
|
+
return locale === "en" ? `${value}${suffix}` : `${value} ${suffix}`;
|
|
86
|
+
}
|
|
49
87
|
function formatQuotaSummary(snapshot) {
|
|
50
88
|
const primaryPercent = clampPercent(snapshot.primary.usedPercent);
|
|
51
89
|
const secondaryPercent = snapshot.secondary !== null ? clampPercent(snapshot.secondary.usedPercent) : null;
|
|
90
|
+
const level = windowLevelOf(secondaryPercent !== null ? Math.max(primaryPercent, secondaryPercent) : primaryPercent, snapshot.limitReached);
|
|
91
|
+
const primaryLabel = formatWindowShortLabel(snapshot.primary.windowSeconds, DEFAULT_PRIMARY_WINDOW_SECONDS);
|
|
92
|
+
const secondaryLabel = snapshot.secondary !== null ? formatWindowShortLabel(snapshot.secondary.windowSeconds, DEFAULT_SECONDARY_WINDOW_SECONDS) : null;
|
|
52
93
|
return {
|
|
53
94
|
primaryPercent,
|
|
54
95
|
secondaryPercent,
|
|
55
|
-
level
|
|
56
|
-
pillText: secondaryPercent !== null ?
|
|
96
|
+
level,
|
|
97
|
+
pillText: secondaryPercent !== null && secondaryLabel !== null ? `${primaryLabel} ${primaryPercent}% · ${secondaryLabel} ${secondaryPercent}%` : `${primaryLabel} ${primaryPercent}%`,
|
|
57
98
|
ringDash: `${(RING_CIRCUMFERENCE * primaryPercent / 100).toFixed(2)} ${RING_CIRCUMFERENCE.toFixed(2)}`
|
|
58
99
|
};
|
|
59
100
|
}
|
|
@@ -223,8 +264,6 @@ window.__ModuleLoader__.load({
|
|
|
223
264
|
"quota.loading": "正在获取 Codex 限额…",
|
|
224
265
|
"quota.refresh": "↻ 刷新",
|
|
225
266
|
"quota.refreshing": "↻ 刷新中…",
|
|
226
|
-
"quota.window5h": "5 小时窗口",
|
|
227
|
-
"quota.window7d": "7 天窗口",
|
|
228
267
|
"quota.usedPrefix": "已用 ",
|
|
229
268
|
"quota.remainPrefix": "剩余 "
|
|
230
269
|
};
|
|
@@ -233,8 +272,6 @@ window.__ModuleLoader__.load({
|
|
|
233
272
|
"quota.loading": "Loading Codex quota…",
|
|
234
273
|
"quota.refresh": "↻ Refresh",
|
|
235
274
|
"quota.refreshing": "↻ Refreshing…",
|
|
236
|
-
"quota.window5h": "5-hour window",
|
|
237
|
-
"quota.window7d": "7-day window",
|
|
238
275
|
"quota.usedPrefix": "Used ",
|
|
239
276
|
"quota.remainPrefix": "Remaining "
|
|
240
277
|
};
|
|
@@ -357,7 +394,7 @@ window.__ModuleLoader__.load({
|
|
|
357
394
|
onClick: () => {
|
|
358
395
|
quotaStore.refresh(true);
|
|
359
396
|
}
|
|
360
|
-
}, quotaSnap.loading ? t("quota.refreshing") : t("quota.refresh"))), quota !== null ? renderWindowSection(
|
|
397
|
+
}, quotaSnap.loading ? t("quota.refreshing") : t("quota.refresh"))), quota !== null ? renderWindowSection(formatWindowTitle(quota.primary.windowSeconds, locale, DEFAULT_PRIMARY_WINDOW_SECONDS), quota.primary, primaryReached) : quotaSnap.loading || quotaSnap.error === null ? h("div", { className: "dsh-codex-quota-meta" }, t("quota.loading")) : null, quota?.secondary !== null && quota?.secondary !== void 0 ? renderWindowSection(formatWindowTitle(quota.secondary.windowSeconds, locale, DEFAULT_SECONDARY_WINDOW_SECONDS), quota.secondary, secondaryReached) : null, quotaSnap.error !== null ? h("div", { className: "dsh-codex-quota-error" }, quotaSnap.error) : null) : null);
|
|
361
398
|
}
|
|
362
399
|
const inject = ["slots", "locale"];
|
|
363
400
|
function apply(ctx) {
|
|
@@ -411,6 +448,8 @@ window.__ModuleLoader__.load({
|
|
|
411
448
|
isCodexProvider,
|
|
412
449
|
didTurnFinish,
|
|
413
450
|
windowLevelOf,
|
|
451
|
+
formatWindowShortLabel,
|
|
452
|
+
formatWindowTitle,
|
|
414
453
|
formatQuotaSummary,
|
|
415
454
|
formatResetCountdown,
|
|
416
455
|
createQuotaStore,
|
package/lib/index.d.ts
CHANGED
|
@@ -81,6 +81,7 @@ declare function sanitizeCodexPayload(payload: Record<string, unknown> | null |
|
|
|
81
81
|
declare function safeErrorMessage(error: unknown): string;
|
|
82
82
|
interface CodexQuotaWindow {
|
|
83
83
|
readonly usedPercent: number;
|
|
84
|
+
readonly windowSeconds?: number | null | undefined;
|
|
84
85
|
readonly resetAt: number | null;
|
|
85
86
|
}
|
|
86
87
|
interface CodexQuotaSnapshot {
|
package/lib/index.js
CHANGED
|
@@ -229,6 +229,8 @@ function parseWindow(raw, fetchedAtMs) {
|
|
|
229
229
|
const record = raw;
|
|
230
230
|
const usedRaw = record.used_percent;
|
|
231
231
|
if (typeof usedRaw !== "number" || !Number.isFinite(usedRaw)) return null;
|
|
232
|
+
const windowSecRaw = record.limit_window_seconds;
|
|
233
|
+
const windowSeconds = typeof windowSecRaw === "number" && Number.isFinite(windowSecRaw) && windowSecRaw > 0 ? Math.round(windowSecRaw) : null;
|
|
232
234
|
const resetAtRaw = record.reset_at;
|
|
233
235
|
const resetAfterRaw = record.reset_after_seconds;
|
|
234
236
|
let resetAt = null;
|
|
@@ -236,6 +238,7 @@ function parseWindow(raw, fetchedAtMs) {
|
|
|
236
238
|
else if (typeof resetAfterRaw === "number" && Number.isFinite(resetAfterRaw) && resetAfterRaw >= 0) resetAt = Math.floor(fetchedAtMs / 1e3) + Math.round(resetAfterRaw);
|
|
237
239
|
return {
|
|
238
240
|
usedPercent: clampPercent(usedRaw),
|
|
241
|
+
windowSeconds,
|
|
239
242
|
resetAt
|
|
240
243
|
};
|
|
241
244
|
}
|