@narumitw/pi-usage 0.60.11 → 0.61.1
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 +16 -2
- package/dist/index.ts +99 -19
- package/dist/index.ts.map +2 -2
- package/docs/providers.md +11 -6
- package/package.json +1 -1
- package/src/codex-fast.ts +1 -0
- package/src/format.ts +22 -6
- package/src/index.ts +1 -0
- package/src/providers/deepseek.ts +1 -1
- package/src/providers/kimi-coding.ts +41 -2
- package/src/settings.ts +13 -0
- package/src/types.ts +2 -0
- package/src/usage-settings-ui.ts +27 -7
- package/src/usage.ts +10 -3
package/README.md
CHANGED
|
@@ -66,7 +66,7 @@ Read the [query and reset guide](./docs/operations.md) for target selection, can
|
|
|
66
66
|
|
|
67
67
|
## ⚙️ Settings
|
|
68
68
|
|
|
69
|
-
Choose **Settings** in `/usage` to edit Codex Fast mode and the
|
|
69
|
+
Choose **Settings** in `/usage` to edit Codex Fast mode, percentage display, and the reset countdown through Pi's settings-list interaction in TUI mode.
|
|
70
70
|
RPC mode reports the active manual settings path instead of opening terminal UI.
|
|
71
71
|
|
|
72
72
|
These preferences live in `pi-usage.json` under Pi's user agent directory, normally `~/.pi/agent/pi-usage.json`.
|
|
@@ -87,7 +87,7 @@ Run `/fast` without arguments to toggle Fast for the active supported Codex mode
|
|
|
87
87
|
Fast is about 1.5× faster and uses more of your plan allowance.
|
|
88
88
|
The `codexFastMode` preference defaults to Off.
|
|
89
89
|
|
|
90
|
-
Fast currently applies only to official `openai-codex-responses` requests for `gpt-5.5`, `gpt-5.6-sol`, `gpt-5.6-terra`,
|
|
90
|
+
Fast currently applies only to official `openai-codex-responses` requests for `gpt-5.5`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, and `gpt-6-sol` at `https://chatgpt.com`.
|
|
91
91
|
It sends `service_tier: "priority"` while enabled and explicit `service_tier: "default"` otherwise.
|
|
92
92
|
The statusline adds `fast` only while the preference is effective, for example `codex fast 59% ↻ 2h30m` with the default reset countdown.
|
|
93
93
|
Unsupported models and custom or proxy origins are left unchanged.
|
|
@@ -95,6 +95,20 @@ Unsupported models and custom or proxy origins are left unchanged.
|
|
|
95
95
|
A toggle affects provider requests whose payload hook starts after the save; a request already sent is unchanged.
|
|
96
96
|
Repair or remove an invalid file, then run `/reload` before trying the toggle again.
|
|
97
97
|
|
|
98
|
+
### Codex statusline percentage
|
|
99
|
+
|
|
100
|
+
The `codexStatusPercentage` preference accepts `"remaining"` or `"used"` and defaults to `"remaining"` to preserve existing output.
|
|
101
|
+
Choose **Codex percentage** in the TUI Settings screen, or set the field manually and run `/reload`:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"codexStatusPercentage": "used"
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
With `"used"`, a limit with 70% remaining appears as `30%`; its reset countdown or window label stays unchanged.
|
|
110
|
+
This preference changes only Codex statusline formatting, not provider data or the detailed `/usage` report.
|
|
111
|
+
|
|
98
112
|
### Codex statusline reset countdown
|
|
99
113
|
|
|
100
114
|
The `codexStatusResetCountdown` preference defaults to `true`. It replaces the window labels with the time remaining until each returned limit resets.
|
package/dist/index.ts
CHANGED
|
@@ -9,7 +9,8 @@ var CODEX_FAST_MODEL_IDS = /* @__PURE__ */ new Set([
|
|
|
9
9
|
"gpt-5.5",
|
|
10
10
|
"gpt-5.6-luna",
|
|
11
11
|
"gpt-5.6-sol",
|
|
12
|
-
"gpt-5.6-terra"
|
|
12
|
+
"gpt-5.6-terra",
|
|
13
|
+
"gpt-6-sol"
|
|
13
14
|
]);
|
|
14
15
|
function codexFastAvailability(model, enabled) {
|
|
15
16
|
if (model?.provider !== "openai-codex") return { kind: "not-codex" };
|
|
@@ -591,7 +592,7 @@ function deepSeekCurrency(value) {
|
|
|
591
592
|
return CURRENCIES.find((currency) => currency === value);
|
|
592
593
|
}
|
|
593
594
|
function decimalAmount2(value) {
|
|
594
|
-
return typeof value === "string" && value.length <= 64 &&
|
|
595
|
+
return typeof value === "string" && value.length <= 64 && /^-?(?:0|[1-9]\d*)(?:\.\d+)?$/u.test(value);
|
|
595
596
|
}
|
|
596
597
|
|
|
597
598
|
// src/providers/fireworks.ts
|
|
@@ -936,11 +937,18 @@ var FIVE_HOUR_WINDOW_MINUTES = 300;
|
|
|
936
937
|
var DAILY_WINDOW_MINUTES = 1440;
|
|
937
938
|
var WEEKLY_WINDOW_MINUTES = 10080;
|
|
938
939
|
var FIXED_POINT_UNITS_PER_CENT = 1e6;
|
|
940
|
+
var RATIO_WINDOWS = [
|
|
941
|
+
{ key: "limit_5h", id: "five-hour", label: "Five-hour window", windowMinutes: FIVE_HOUR_WINDOW_MINUTES },
|
|
942
|
+
{ key: "limit_week", id: "weekly", label: "Weekly window", windowMinutes: WEEKLY_WINDOW_MINUTES },
|
|
943
|
+
{ key: "limit_month_total", id: "monthly", label: "Monthly window" }
|
|
944
|
+
];
|
|
939
945
|
function normalizeKimiCodingUsagePayload(payload, capturedAt) {
|
|
940
946
|
const root = asObject6(payload);
|
|
941
947
|
if (!root) throw new Error("Kimi Coding usage response was not an object.");
|
|
942
948
|
const candidates = [];
|
|
949
|
+
const explicitWindows = /* @__PURE__ */ new Set();
|
|
943
950
|
let omittedWindow = false;
|
|
951
|
+
if (root.usage !== void 0) explicitWindows.add(WEEKLY_WINDOW_MINUTES);
|
|
944
952
|
const summary = parseUsageRow(root.usage, WEEKLY_WINDOW_MINUTES, "Weekly window");
|
|
945
953
|
if (summary) candidates.push(summary);
|
|
946
954
|
else if (root.usage !== void 0) omittedWindow = true;
|
|
@@ -948,6 +956,7 @@ function normalizeKimiCodingUsagePayload(payload, capturedAt) {
|
|
|
948
956
|
for (const raw of root.limits) {
|
|
949
957
|
const item = asObject6(raw);
|
|
950
958
|
const windowMinutes = parseWindowMinutes(item?.window);
|
|
959
|
+
if (windowMinutes !== void 0) explicitWindows.add(windowMinutes);
|
|
951
960
|
const label = sanitizedLabel(item?.name);
|
|
952
961
|
const bucket = windowMinutes === void 0 ? void 0 : parseUsageRow(item?.detail, windowMinutes, label ?? defaultWindowLabel(windowMinutes));
|
|
953
962
|
if (bucket) candidates.push(bucket);
|
|
@@ -966,8 +975,23 @@ function normalizeKimiCodingUsagePayload(payload, capturedAt) {
|
|
|
966
975
|
if (rows.length === 1) buckets.push(rows[0]);
|
|
967
976
|
else omittedWindow = true;
|
|
968
977
|
}
|
|
969
|
-
|
|
970
|
-
|
|
978
|
+
const usages = asObject6(root.usages);
|
|
979
|
+
if (root.usages !== void 0 && !usages) omittedWindow = true;
|
|
980
|
+
if (usages) {
|
|
981
|
+
for (const window of RATIO_WINDOWS) {
|
|
982
|
+
const raw = usages[window.key];
|
|
983
|
+
if (raw === void 0 || "windowMinutes" in window && explicitWindows.has(window.windowMinutes)) continue;
|
|
984
|
+
const bucket = parseRatioWindow(raw, window.id, window.label);
|
|
985
|
+
if (bucket) {
|
|
986
|
+
buckets.push({
|
|
987
|
+
...bucket,
|
|
988
|
+
..."windowMinutes" in window ? { windowMinutes: window.windowMinutes } : {}
|
|
989
|
+
});
|
|
990
|
+
} else omittedWindow = true;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
buckets.sort((left, right) => (left.windowMinutes ?? Infinity) - (right.windowMinutes ?? Infinity));
|
|
994
|
+
const metrics = parseBoosterWallet(root.boosterWallet === void 0 ? root.booster_wallet : root.boosterWallet);
|
|
971
995
|
if (buckets.length === 0 && metrics.length === 0) {
|
|
972
996
|
throw new Error("Kimi Coding usage endpoint returned no displayable usage data.");
|
|
973
997
|
}
|
|
@@ -1006,6 +1030,21 @@ function parseUsageRow(value, windowMinutes, label) {
|
|
|
1006
1030
|
...resetsAt !== void 0 ? { resetsAt } : {}
|
|
1007
1031
|
};
|
|
1008
1032
|
}
|
|
1033
|
+
function parseRatioWindow(value, id, label) {
|
|
1034
|
+
const row = asObject6(value);
|
|
1035
|
+
const ratio = row?.used_ratio;
|
|
1036
|
+
if (typeof ratio !== "number" || !Number.isFinite(ratio) || ratio < 0 || ratio > 1) return void 0;
|
|
1037
|
+
const resetsAt = asIsoEpochSeconds(row?.reset_time);
|
|
1038
|
+
const used = ratio * 100;
|
|
1039
|
+
return {
|
|
1040
|
+
id,
|
|
1041
|
+
label,
|
|
1042
|
+
used,
|
|
1043
|
+
remaining: 100 - used,
|
|
1044
|
+
unit: "percent",
|
|
1045
|
+
...resetsAt !== void 0 ? { resetsAt } : {}
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1009
1048
|
function parseWindowMinutes(value) {
|
|
1010
1049
|
const window = asObject6(value);
|
|
1011
1050
|
if (!window) return void 0;
|
|
@@ -3189,10 +3228,10 @@ function formatUsageReport(report2, displayState) {
|
|
|
3189
3228
|
}
|
|
3190
3229
|
return lines.join("\n").trimEnd();
|
|
3191
3230
|
}
|
|
3192
|
-
function formatUsageStatusline(report2, model, now = Date.now(), showCodexResetCountdown = true) {
|
|
3231
|
+
function formatUsageStatusline(report2, model, now = Date.now(), showCodexResetCountdown = true, codexStatusPercentage = "remaining") {
|
|
3193
3232
|
if (report2.providerId === "baseten") return formatBasetenStatusline(report2);
|
|
3194
3233
|
if (report2.providerId === "openai-codex") {
|
|
3195
|
-
return formatCodexStatusline(report2, model, now, showCodexResetCountdown);
|
|
3234
|
+
return formatCodexStatusline(report2, model, now, showCodexResetCountdown, codexStatusPercentage);
|
|
3196
3235
|
}
|
|
3197
3236
|
if (report2.providerId === "deepseek") return formatDeepSeekStatusline(report2);
|
|
3198
3237
|
if (report2.providerId === "fireworks") return formatFireworksStatusline(report2);
|
|
@@ -3387,6 +3426,12 @@ function formatOpenCodeZenStatusline(report2) {
|
|
|
3387
3426
|
function formatKimiCodingReport(lines, report2) {
|
|
3388
3427
|
for (const bucket of report2.buckets) {
|
|
3389
3428
|
const reset = bucket.resetsAt ? ` (resets ${formatReset(bucket.resetsAt)})` : "";
|
|
3429
|
+
if (bucket.unit === "percent") {
|
|
3430
|
+
const remaining = bucket.remaining === void 0 ? void 0 : Math.round(clampPercent4(bucket.remaining));
|
|
3431
|
+
const value = bucket.used === void 0 || remaining === void 0 ? "unavailable" : `${100 - remaining}% used \xB7 ${remaining}% left`;
|
|
3432
|
+
lines.push(`${`${bucket.label}:`.padEnd(VALUE_COLUMN)}${value}${reset}`);
|
|
3433
|
+
continue;
|
|
3434
|
+
}
|
|
3390
3435
|
if (bucket.used === void 0 || bucket.limit === void 0) {
|
|
3391
3436
|
lines.push(`${`${bucket.label}:`.padEnd(VALUE_COLUMN)}unavailable${reset}`);
|
|
3392
3437
|
continue;
|
|
@@ -3415,15 +3460,18 @@ function formatKimiCodingReport(lines, report2) {
|
|
|
3415
3460
|
function formatKimiCodingStatusline(report2) {
|
|
3416
3461
|
const fiveHour = report2.buckets.find((bucket) => bucket.id === "five-hour");
|
|
3417
3462
|
const weekly = report2.buckets.find((bucket) => bucket.id === "weekly");
|
|
3418
|
-
const
|
|
3419
|
-
const
|
|
3463
|
+
const monthly = report2.buckets.find((bucket) => bucket.id === "monthly");
|
|
3464
|
+
const subWindow = fiveHour ?? report2.buckets.find((bucket) => bucket.id !== "weekly" && bucket.id !== "monthly");
|
|
3465
|
+
const selected = [subWindow, weekly, monthly].filter(
|
|
3420
3466
|
(bucket, index, buckets) => bucket !== void 0 && buckets.indexOf(bucket) === index
|
|
3421
3467
|
);
|
|
3422
3468
|
const parts = ["kimi"];
|
|
3423
3469
|
for (const bucket of selected) {
|
|
3424
|
-
if (
|
|
3470
|
+
if (bucket.remaining === void 0 || bucket.unit !== "percent" && !bucket.limit) continue;
|
|
3425
3471
|
const fallback = bucket.id === "weekly" ? "weekly" : "5h";
|
|
3426
|
-
|
|
3472
|
+
const window = bucket.id === "monthly" ? "mo" : formatWindowLabel(bucket.windowMinutes, fallback, true);
|
|
3473
|
+
const remaining = bucket.unit === "percent" ? Math.round(clampPercent4(bucket.remaining)) : percentRemaining(bucket);
|
|
3474
|
+
parts.push(`${remaining}% ${window}`);
|
|
3427
3475
|
}
|
|
3428
3476
|
return parts.length > 1 ? parts.join(" ") : void 0;
|
|
3429
3477
|
}
|
|
@@ -3597,7 +3645,7 @@ function formatGenericReport(lines, report2) {
|
|
|
3597
3645
|
lines.push(`${`${metric2.label}:`.padEnd(VALUE_COLUMN)}${formatMetricValue(metric2.value, metric2.unit)}`);
|
|
3598
3646
|
}
|
|
3599
3647
|
}
|
|
3600
|
-
function formatCodexStatusline(report2, model, now = Date.now(), showResetCountdown = true) {
|
|
3648
|
+
function formatCodexStatusline(report2, model, now = Date.now(), showResetCountdown = true, percentage = "remaining") {
|
|
3601
3649
|
const group = selectCodexGroup(report2, model);
|
|
3602
3650
|
if (!group) return formatCodexCreditsStatus(report2);
|
|
3603
3651
|
const buckets = report2.buckets.filter((bucket) => (bucket.groupId ?? bucket.id) === group);
|
|
@@ -3605,7 +3653,8 @@ function formatCodexStatusline(report2, model, now = Date.now(), showResetCountd
|
|
|
3605
3653
|
const parts = [group === "codex" ? "codex" : `codex ${compactLimitLabel(labelBucket?.groupLabel ?? group)}`];
|
|
3606
3654
|
for (const bucket of buckets) {
|
|
3607
3655
|
if (bucket.remaining === void 0) continue;
|
|
3608
|
-
const
|
|
3656
|
+
const displayedPercentage = percentage === "used" ? bucket.used ?? 100 - bucket.remaining : bucket.remaining;
|
|
3657
|
+
const percent = `${clampPercent4(displayedPercentage).toFixed(0)}%`;
|
|
3609
3658
|
const fallback = bucket.id.endsWith(":secondary") ? "weekly" : "5h";
|
|
3610
3659
|
const window = formatWindowLabel(bucket.windowMinutes, fallback, true);
|
|
3611
3660
|
if (!showResetCountdown) {
|
|
@@ -3739,6 +3788,7 @@ var MAX_USAGE_SETTINGS_BYTES = 64 * 1024;
|
|
|
3739
3788
|
var DEFAULT_USAGE_SETTINGS = Object.freeze({
|
|
3740
3789
|
codexFastMode: false,
|
|
3741
3790
|
codexStatusResetCountdown: true,
|
|
3791
|
+
codexStatusPercentage: "remaining",
|
|
3742
3792
|
selectedTargets: Object.freeze({})
|
|
3743
3793
|
});
|
|
3744
3794
|
function usageSettingsPath() {
|
|
@@ -3752,6 +3802,9 @@ function normalizeUsageSettings(value) {
|
|
|
3752
3802
|
if (Object.hasOwn(value, "codexStatusResetCountdown") && typeof value.codexStatusResetCountdown !== "boolean") {
|
|
3753
3803
|
return void 0;
|
|
3754
3804
|
}
|
|
3805
|
+
if (Object.hasOwn(value, "codexStatusPercentage") && value.codexStatusPercentage !== "remaining" && value.codexStatusPercentage !== "used") {
|
|
3806
|
+
return void 0;
|
|
3807
|
+
}
|
|
3755
3808
|
if (Object.hasOwn(value, "fireworksAccountId") && !isFireworksAccountId(value.fireworksAccountId)) {
|
|
3756
3809
|
return void 0;
|
|
3757
3810
|
}
|
|
@@ -3764,6 +3817,7 @@ function normalizeUsageSettings(value) {
|
|
|
3764
3817
|
return {
|
|
3765
3818
|
codexFastMode: typeof value.codexFastMode === "boolean" ? value.codexFastMode : DEFAULT_USAGE_SETTINGS.codexFastMode,
|
|
3766
3819
|
codexStatusResetCountdown: typeof value.codexStatusResetCountdown === "boolean" ? value.codexStatusResetCountdown : DEFAULT_USAGE_SETTINGS.codexStatusResetCountdown,
|
|
3820
|
+
codexStatusPercentage: value.codexStatusPercentage === "used" ? "used" : DEFAULT_USAGE_SETTINGS.codexStatusPercentage,
|
|
3767
3821
|
selectedTargets: effectiveTargets
|
|
3768
3822
|
};
|
|
3769
3823
|
}
|
|
@@ -4166,6 +4220,12 @@ import { getSettingsListTheme } from "@earendil-works/pi-coding-agent";
|
|
|
4166
4220
|
import { Key, matchesKey, SettingsList, Text } from "@earendil-works/pi-tui";
|
|
4167
4221
|
var OFF = "Off";
|
|
4168
4222
|
var ON = "On";
|
|
4223
|
+
var REMAINING = "Remaining";
|
|
4224
|
+
var USED = "Used";
|
|
4225
|
+
function settingValueLabel(id, value) {
|
|
4226
|
+
if (id === "codexStatusPercentage") return value === "used" ? USED : REMAINING;
|
|
4227
|
+
return value === true ? ON : OFF;
|
|
4228
|
+
}
|
|
4169
4229
|
async function showUsageSettings(ctx, settingsRuntime, parentSignal, isCurrent, onApplied) {
|
|
4170
4230
|
if (ctx.mode !== "tui") {
|
|
4171
4231
|
if (ctx.hasUI) ctx.ui.notify(`Edit settings manually: ${settingsRuntime.get().path}`, "info");
|
|
@@ -4194,6 +4254,13 @@ async function showUsageSettings(ctx, settingsRuntime, parentSignal, isCurrent,
|
|
|
4194
4254
|
description: "Show time remaining until each Codex usage limit resets.",
|
|
4195
4255
|
currentValue: state.settings.codexStatusResetCountdown ? ON : OFF,
|
|
4196
4256
|
values: [OFF, ON]
|
|
4257
|
+
},
|
|
4258
|
+
{
|
|
4259
|
+
id: "codexStatusPercentage",
|
|
4260
|
+
label: "Codex percentage",
|
|
4261
|
+
description: "Show remaining or used Codex quota in the statusline.",
|
|
4262
|
+
currentValue: settingValueLabel("codexStatusPercentage", state.settings.codexStatusPercentage),
|
|
4263
|
+
values: [REMAINING, USED]
|
|
4197
4264
|
}
|
|
4198
4265
|
];
|
|
4199
4266
|
const rule = new HorizontalRule({ ruleStyle: (text) => theme.fg("border", text) });
|
|
@@ -4208,7 +4275,7 @@ async function showUsageSettings(ctx, settingsRuntime, parentSignal, isCurrent,
|
|
|
4208
4275
|
saveQueue = saveQueue.then(async () => {
|
|
4209
4276
|
const previous = settingsRuntime.get().settings[id];
|
|
4210
4277
|
if (settingsRuntime.get().kind === "invalid") {
|
|
4211
|
-
settingsList.updateValue(id, previous
|
|
4278
|
+
settingsList.updateValue(id, settingValueLabel(id, previous));
|
|
4212
4279
|
if (!signal.aborted && isCurrent()) {
|
|
4213
4280
|
ctx.ui.notify("Repair pi-usage.json and reload before changing settings.", "error");
|
|
4214
4281
|
tui.requestRender();
|
|
@@ -4216,10 +4283,12 @@ async function showUsageSettings(ctx, settingsRuntime, parentSignal, isCurrent,
|
|
|
4216
4283
|
return;
|
|
4217
4284
|
}
|
|
4218
4285
|
try {
|
|
4219
|
-
|
|
4286
|
+
const patch = {};
|
|
4287
|
+
patch[id] = requested;
|
|
4288
|
+
await settingsRuntime.update(patch, signal);
|
|
4220
4289
|
} catch (error) {
|
|
4221
4290
|
if (signal.aborted || !isCurrent()) return;
|
|
4222
|
-
settingsList.updateValue(id, previous
|
|
4291
|
+
settingsList.updateValue(id, settingValueLabel(id, previous));
|
|
4223
4292
|
ctx.ui.notify(`Could not save pi-usage.json: ${errorMessage(error)}`, "error");
|
|
4224
4293
|
tui.requestRender();
|
|
4225
4294
|
return;
|
|
@@ -4239,7 +4308,11 @@ async function showUsageSettings(ctx, settingsRuntime, parentSignal, isCurrent,
|
|
|
4239
4308
|
getSettingsListTheme(),
|
|
4240
4309
|
(id, value) => {
|
|
4241
4310
|
if (closing || signal.aborted || !isCurrent()) return;
|
|
4242
|
-
|
|
4311
|
+
if (id === "codexStatusPercentage") {
|
|
4312
|
+
queueUpdate(id, value === USED ? "used" : "remaining", value);
|
|
4313
|
+
} else if (id === "codexFastMode" || id === "codexStatusResetCountdown") {
|
|
4314
|
+
queueUpdate(id, value === ON, value);
|
|
4315
|
+
}
|
|
4243
4316
|
},
|
|
4244
4317
|
cancel
|
|
4245
4318
|
);
|
|
@@ -4368,9 +4441,16 @@ function usageExtension(pi, dependencies = {}) {
|
|
|
4368
4441
|
}
|
|
4369
4442
|
return;
|
|
4370
4443
|
}
|
|
4371
|
-
const
|
|
4444
|
+
const settings = settingsRuntime.get().settings;
|
|
4445
|
+
const showCodexResetCountdown = outcome.state.report.providerId === "openai-codex" && settings.codexStatusResetCountdown;
|
|
4372
4446
|
const now = Date.now();
|
|
4373
|
-
const rawValue = formatUsageStatusline(
|
|
4447
|
+
const rawValue = formatUsageStatusline(
|
|
4448
|
+
outcome.state.report,
|
|
4449
|
+
model,
|
|
4450
|
+
now,
|
|
4451
|
+
showCodexResetCountdown,
|
|
4452
|
+
settings.codexStatusPercentage
|
|
4453
|
+
);
|
|
4374
4454
|
const value = rawValue ? fastRuntime.decorateStatus(model, rawValue) : void 0;
|
|
4375
4455
|
if (!safeSetStatus(ctx, value)) return;
|
|
4376
4456
|
if (shouldSchedule && sessionActive) scheduleStatusRefresh(ctx, model);
|
|
@@ -5063,7 +5143,7 @@ function usageExtension(pi, dependencies = {}) {
|
|
|
5063
5143
|
controller.signal,
|
|
5064
5144
|
() => statusGeneration === menuGeneration && !controller.signal.aborted,
|
|
5065
5145
|
(id) => {
|
|
5066
|
-
if (id === "codexStatusResetCountdown" && stableCurrent && statusGeneration === menuGeneration && !controller.signal.aborted) {
|
|
5146
|
+
if ((id === "codexStatusResetCountdown" || id === "codexStatusPercentage") && stableCurrent && statusGeneration === menuGeneration && !controller.signal.aborted) {
|
|
5067
5147
|
publishStableCurrent(ctx, stableCurrent);
|
|
5068
5148
|
}
|
|
5069
5149
|
}
|