@aliou/pi-neuralwatt 0.8.0 → 0.8.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.
|
@@ -119,14 +119,17 @@ export default async function (pi: ExtensionAPI) {
|
|
|
119
119
|
let hiddenModelsLoaded = false;
|
|
120
120
|
let hiddenModelsAbort: AbortController | undefined;
|
|
121
121
|
|
|
122
|
+
let lastSseEmitAt = 0;
|
|
123
|
+
|
|
122
124
|
const handleSseQuota = (line: string) => {
|
|
125
|
+
const now = Date.now();
|
|
126
|
+
if (now - lastSseEmitAt < HEADER_EMIT_THROTTLE_MS) return;
|
|
127
|
+
|
|
123
128
|
const quotas = updateQuotasFromSseComment(latestQuotas, line);
|
|
124
129
|
if (!quotas || quotas === latestQuotas) return;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
source: "sse",
|
|
129
|
-
});
|
|
130
|
+
|
|
131
|
+
lastSseEmitAt = now;
|
|
132
|
+
emitQuotas(quotas, "sse");
|
|
130
133
|
};
|
|
131
134
|
|
|
132
135
|
registerNeuralwattProvider(pi, handleSseQuota, hiddenModels);
|
|
@@ -17,7 +17,6 @@ export default async function (pi: ExtensionAPI) {
|
|
|
17
17
|
await configLoader.load();
|
|
18
18
|
|
|
19
19
|
let enabled = configLoader.getConfig().quotaWarnings.enabled;
|
|
20
|
-
let currentProvider: string | undefined;
|
|
21
20
|
let currentContext: ExtensionContext | undefined;
|
|
22
21
|
|
|
23
22
|
// Listen for config changes at runtime
|
|
@@ -33,36 +32,29 @@ export default async function (pi: ExtensionAPI) {
|
|
|
33
32
|
pi.events.on(NEURALWATT_QUOTAS_UPDATED_EVENT, (data: unknown) => {
|
|
34
33
|
if (!enabled) return;
|
|
35
34
|
if (!data || typeof data !== "object") return;
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
if (!currentContext) return;
|
|
36
|
+
if (currentContext.model?.provider !== "neuralwatt") return;
|
|
37
|
+
|
|
38
|
+
const { quotas } = data as NeuralwattQuotasUpdatedPayload;
|
|
39
|
+
checkQuotas(currentContext, quotas);
|
|
39
40
|
});
|
|
40
41
|
|
|
41
42
|
pi.on("session_start", async (_event, ctx) => {
|
|
42
43
|
currentContext = ctx;
|
|
43
|
-
currentProvider = ctx.model?.provider;
|
|
44
44
|
if (ctx.model?.provider !== "neuralwatt") return;
|
|
45
45
|
clearAlertState();
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
pi.on("model_select", (_event, ctx) => {
|
|
49
49
|
currentContext = ctx;
|
|
50
|
-
currentProvider = ctx.model?.provider;
|
|
51
|
-
if (ctx.model?.provider !== "neuralwatt") {
|
|
52
|
-
clearAlertState();
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
clearAlertState();
|
|
56
50
|
});
|
|
57
51
|
|
|
58
52
|
pi.on("session_before_switch", (_event, ctx) => {
|
|
59
53
|
currentContext = ctx;
|
|
60
|
-
currentProvider = ctx.model?.provider;
|
|
61
54
|
});
|
|
62
55
|
|
|
63
56
|
pi.on("session_shutdown", () => {
|
|
64
57
|
currentContext = undefined;
|
|
65
|
-
currentProvider = undefined;
|
|
66
58
|
clearAlertState();
|
|
67
59
|
});
|
|
68
60
|
|
|
@@ -11,6 +11,8 @@ interface AlertState {
|
|
|
11
11
|
lastNotifiedAt: number;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
// Module-level state so cooldowns survive across invocations of checkQuotas()
|
|
15
|
+
// within the same Pi runtime.
|
|
14
16
|
const alerts = new Map<string, AlertState>();
|
|
15
17
|
|
|
16
18
|
export function clearAlertState(): void {
|
|
@@ -22,9 +24,9 @@ function shouldNotify(key: string, severity: WarningSeverity): boolean {
|
|
|
22
24
|
if (!state) return true;
|
|
23
25
|
|
|
24
26
|
const order: WarningSeverity[] = ["warning", "critical"];
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (
|
|
27
|
+
const currentIndex = order.indexOf(severity);
|
|
28
|
+
const lastIndex = order.indexOf(state.lastSeverity);
|
|
29
|
+
if (currentIndex > lastIndex) return true;
|
|
28
30
|
|
|
29
31
|
return Date.now() - state.lastNotifiedAt >= COOLDOWN_MS;
|
|
30
32
|
}
|
|
@@ -40,7 +42,6 @@ function markNotified(key: string, severity: WarningSeverity): void {
|
|
|
40
42
|
export function checkQuotas(
|
|
41
43
|
ctx: ExtensionContext,
|
|
42
44
|
quotas: NeuralwattQuotas,
|
|
43
|
-
skipAlreadyWarned: boolean,
|
|
44
45
|
): void {
|
|
45
46
|
if (!ctx.hasUI) return;
|
|
46
47
|
|
|
@@ -55,7 +56,7 @@ export function checkQuotas(
|
|
|
55
56
|
if (pct <= 25) {
|
|
56
57
|
const severity: WarningSeverity = pct <= 10 ? "critical" : "warning";
|
|
57
58
|
const key = "credits";
|
|
58
|
-
if (
|
|
59
|
+
if (shouldNotify(key, severity)) {
|
|
59
60
|
markNotified(key, severity);
|
|
60
61
|
warnings.push(
|
|
61
62
|
`Credits: ${pct.toFixed(0)}% remaining (${formatUsd(credits_remaining_usd)} of ${formatUsd(total_credits_usd)})`,
|
|
@@ -77,7 +78,7 @@ export function checkQuotas(
|
|
|
77
78
|
? "critical"
|
|
78
79
|
: "warning";
|
|
79
80
|
const key = "energy";
|
|
80
|
-
if (
|
|
81
|
+
if (shouldNotify(key, severity)) {
|
|
81
82
|
markNotified(key, severity);
|
|
82
83
|
const tag = in_overage ? " [OVERAGE]" : "";
|
|
83
84
|
warnings.push(
|