ccus-cli 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/dist/lib/codex-fetcher.js +64 -6
- package/package.json +1 -1
|
@@ -61,19 +61,77 @@ function readResetsAtMs(window) {
|
|
|
61
61
|
}
|
|
62
62
|
return n < 10_000_000_000 ? n * 1000 : n;
|
|
63
63
|
}
|
|
64
|
+
// Codex app-server 各 rate-limit 窗口自带的时长(分钟):5h 窗 300、周窗 10080。
|
|
65
|
+
const CODEX_SESSION_WINDOW_MINUTES = 300;
|
|
66
|
+
const CODEX_WEEKLY_WINDOW_MINUTES = 10080;
|
|
67
|
+
// 容忍老版本 bucket 长度 off-by-one-minute 的漂移,不吸收其它时长。
|
|
68
|
+
const CODEX_WINDOW_DURATION_TOLERANCE_MINUTES = 1;
|
|
69
|
+
/** 读窗口时长(分钟):驼峰 windowDurationMins 优先,兼容下划线变体。 */
|
|
70
|
+
function readWindowDurationMins(window) {
|
|
71
|
+
if (!isRecord(window)) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
return toFiniteNumber(window.windowDurationMins ?? window.window_duration_mins ?? window.windowDurationMinutes);
|
|
75
|
+
}
|
|
76
|
+
/** 按时长认桶:300→session(5h)、10080→weekly(7d),未知时长返回 null。 */
|
|
77
|
+
function classifyWindowByDuration(durationMins) {
|
|
78
|
+
if (durationMins === null) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
if (Math.abs(durationMins - CODEX_SESSION_WINDOW_MINUTES) <= CODEX_WINDOW_DURATION_TOLERANCE_MINUTES) {
|
|
82
|
+
return "session";
|
|
83
|
+
}
|
|
84
|
+
if (Math.abs(durationMins - CODEX_WEEKLY_WINDOW_MINUTES) <= CODEX_WINDOW_DURATION_TOLERANCE_MINUTES) {
|
|
85
|
+
return "weekly";
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
64
89
|
/**
|
|
65
|
-
* 解析 account/rateLimits/read 的 result
|
|
66
|
-
*
|
|
90
|
+
* 解析 account/rateLimits/read 的 result。
|
|
91
|
+
*
|
|
92
|
+
* 首选按各窗口自带的 `windowDurationMins` 认桶(300→5h、10080→7d,±1 容差),不依赖
|
|
93
|
+
* primary/secondary 顺序——实测 app-server 可能把周额度放在 primary。`windowDurationMins`
|
|
94
|
+
* 缺失或无法归类时,退回 legacy `primary→5h、secondary→weekly`。字段缺失时对应窗口为 null。
|
|
67
95
|
*/
|
|
68
96
|
function parseRateLimitsResult(result) {
|
|
69
97
|
const wrapper = isRecord(result) && isRecord(result.rateLimits) ? result.rateLimits : null;
|
|
70
98
|
if (!wrapper) {
|
|
71
99
|
return { fiveHour: null, sevenDay: null, resetsAt: null };
|
|
72
100
|
}
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
101
|
+
const mappable = (window) => {
|
|
102
|
+
if (!isRecord(window) || readUsedPercent(window) === null) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
return window;
|
|
106
|
+
};
|
|
107
|
+
const primary = mappable(wrapper.primary);
|
|
108
|
+
const secondary = mappable(wrapper.secondary);
|
|
109
|
+
let session = null;
|
|
110
|
+
let weekly = null;
|
|
111
|
+
for (const window of [primary, secondary]) {
|
|
112
|
+
if (!window) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const kind = classifyWindowByDuration(readWindowDurationMins(window));
|
|
116
|
+
if (kind === "session" && !session) {
|
|
117
|
+
session = window;
|
|
118
|
+
}
|
|
119
|
+
else if (kind === "weekly" && !weekly) {
|
|
120
|
+
weekly = window;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// duration 缺失/未知时退回 legacy 位置映射(primary→5h、secondary→7d)。
|
|
124
|
+
if (!session && primary && classifyWindowByDuration(readWindowDurationMins(primary)) === null) {
|
|
125
|
+
session = primary;
|
|
126
|
+
}
|
|
127
|
+
if (!weekly && secondary && classifyWindowByDuration(readWindowDurationMins(secondary)) === null) {
|
|
128
|
+
weekly = secondary;
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
fiveHour: readUsedPercent(session),
|
|
132
|
+
sevenDay: readUsedPercent(weekly),
|
|
133
|
+
resetsAt: readResetsAtMs(session) ?? readResetsAtMs(weekly),
|
|
134
|
+
};
|
|
77
135
|
}
|
|
78
136
|
function getCodexHome(codexHomePath) {
|
|
79
137
|
return codexHomePath ?? process.env.CODEX_HOME ?? (0, node_path_1.join)((0, node_os_1.homedir)(), ".codex");
|