@aliou/pi-neuralwatt 0.10.2 → 0.10.4
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.
|
@@ -6,7 +6,40 @@ import { NEURALWATT_MODELS } from "./public-models";
|
|
|
6
6
|
// Hidden aliases that work for authorized accounts but are omitted from the
|
|
7
7
|
// authenticated /v1/models response. Keep these gated by includeHiddenModels.
|
|
8
8
|
// Move an entry to public-models.ts once Neuralwatt advertises it publicly.
|
|
9
|
-
export const HIDDEN_NEURALWATT_MODELS: ProviderModelConfig[] = [
|
|
9
|
+
export const HIDDEN_NEURALWATT_MODELS: ProviderModelConfig[] = [
|
|
10
|
+
// DeepSeek V4 Flash Canary - early-access 284B/13B-active MoE served on B200s.
|
|
11
|
+
// Neuralwatt omits it from the authenticated catalog. Context and runtime
|
|
12
|
+
// capabilities were verified directly; pricing follows DeepSeek's upstream
|
|
13
|
+
// rates until Neuralwatt publishes model metadata.
|
|
14
|
+
{
|
|
15
|
+
id: "deepseek-v4-flash",
|
|
16
|
+
name: "DeepSeek V4 Flash (Canary)",
|
|
17
|
+
reasoning: true,
|
|
18
|
+
input: ["text", "image"],
|
|
19
|
+
cost: {
|
|
20
|
+
input: 0.14,
|
|
21
|
+
output: 0.28,
|
|
22
|
+
cacheRead: 0.0028,
|
|
23
|
+
cacheWrite: 0,
|
|
24
|
+
},
|
|
25
|
+
contextWindow: 1_000_000,
|
|
26
|
+
maxTokens: 384_000,
|
|
27
|
+
thinkingLevelMap: {
|
|
28
|
+
off: "none",
|
|
29
|
+
minimal: "low",
|
|
30
|
+
low: "low",
|
|
31
|
+
medium: "medium",
|
|
32
|
+
high: "high",
|
|
33
|
+
xhigh: null,
|
|
34
|
+
max: "max",
|
|
35
|
+
},
|
|
36
|
+
compat: {
|
|
37
|
+
supportsDeveloperRole: false,
|
|
38
|
+
maxTokensField: "max_tokens",
|
|
39
|
+
requiresReasoningContentOnAssistantMessages: true,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
];
|
|
10
43
|
|
|
11
44
|
// Per-ID overrides for known hidden models. The authenticated /v1/models endpoint
|
|
12
45
|
// exposes pricing and capabilities, but some Pi-specific behavior (thinking levels,
|
|
@@ -3,6 +3,25 @@ import type { ProviderModelConfig } from "@earendil-works/pi-coding-agent";
|
|
|
3
3
|
// Public models returned by https://api.neuralwatt.com/v1/models (unauthenticated view).
|
|
4
4
|
// Pricing, capabilities, and limits are sourced from the API metadata fields.
|
|
5
5
|
export const NEURALWATT_MODELS: ProviderModelConfig[] = [
|
|
6
|
+
// Gemma 4 31B - NVIDIA NVFP4 checkpoint
|
|
7
|
+
{
|
|
8
|
+
id: "nvidia/Gemma-4-31B-IT-NVFP4",
|
|
9
|
+
name: "Gemma 4 31B (NVFP4)",
|
|
10
|
+
reasoning: false,
|
|
11
|
+
input: ["text", "image"],
|
|
12
|
+
cost: {
|
|
13
|
+
input: 0.144,
|
|
14
|
+
output: 0.42,
|
|
15
|
+
cacheRead: 0.036,
|
|
16
|
+
cacheWrite: 0,
|
|
17
|
+
},
|
|
18
|
+
contextWindow: 262128,
|
|
19
|
+
maxTokens: 16384,
|
|
20
|
+
compat: {
|
|
21
|
+
supportsDeveloperRole: false,
|
|
22
|
+
maxTokensField: "max_tokens",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
6
25
|
// Gemma 4 31B - Google, served from NVIDIA's NVFP4 checkpoint
|
|
7
26
|
{
|
|
8
27
|
id: "gemma-4-31b",
|
|
@@ -86,7 +105,7 @@ export const NEURALWATT_MODELS: ProviderModelConfig[] = [
|
|
|
86
105
|
cacheWrite: 0,
|
|
87
106
|
},
|
|
88
107
|
contextWindow: 199984,
|
|
89
|
-
maxTokens:
|
|
108
|
+
maxTokens: 32000,
|
|
90
109
|
thinkingLevelMap: {
|
|
91
110
|
off: "none",
|
|
92
111
|
minimal: null,
|
|
@@ -115,7 +134,7 @@ export const NEURALWATT_MODELS: ProviderModelConfig[] = [
|
|
|
115
134
|
cacheWrite: 0,
|
|
116
135
|
},
|
|
117
136
|
contextWindow: 199984,
|
|
118
|
-
maxTokens:
|
|
137
|
+
maxTokens: 32000,
|
|
119
138
|
compat: {
|
|
120
139
|
supportsDeveloperRole: false,
|
|
121
140
|
maxTokensField: "max_tokens",
|
|
@@ -5,6 +5,13 @@ import { formatKwh, formatUsd } from "../../src/utils/quota-format";
|
|
|
5
5
|
export type WarningSeverity = "warning" | "critical";
|
|
6
6
|
|
|
7
7
|
const COOLDOWN_MS = 60 * 60 * 1000; // 60 minutes
|
|
8
|
+
const LOW_PCT = 25;
|
|
9
|
+
const CRITICAL_PCT = 10;
|
|
10
|
+
|
|
11
|
+
/** Per-kWh price once a subscription's included kWh are exhausted. */
|
|
12
|
+
const OVERAGE_RATE_PER_KWH_SUBSCRIBED = 5;
|
|
13
|
+
/** Per-kWh price when there is no active subscription (no included kWh). */
|
|
14
|
+
const OVERAGE_RATE_PER_KWH_UNSUBSCRIBED = 10;
|
|
8
15
|
|
|
9
16
|
interface AlertState {
|
|
10
17
|
lastSeverity: WarningSeverity;
|
|
@@ -19,14 +26,16 @@ export function clearAlertState(): void {
|
|
|
19
26
|
alerts.clear();
|
|
20
27
|
}
|
|
21
28
|
|
|
29
|
+
function severityForPct(pct: number): WarningSeverity {
|
|
30
|
+
return pct <= CRITICAL_PCT ? "critical" : "warning";
|
|
31
|
+
}
|
|
32
|
+
|
|
22
33
|
function shouldNotify(key: string, severity: WarningSeverity): boolean {
|
|
23
34
|
const state = alerts.get(key);
|
|
24
35
|
if (!state) return true;
|
|
25
36
|
|
|
26
37
|
const order: WarningSeverity[] = ["warning", "critical"];
|
|
27
|
-
|
|
28
|
-
const lastIndex = order.indexOf(state.lastSeverity);
|
|
29
|
-
if (currentIndex > lastIndex) return true;
|
|
38
|
+
if (order.indexOf(severity) > order.indexOf(state.lastSeverity)) return true;
|
|
30
39
|
|
|
31
40
|
return Date.now() - state.lastNotifiedAt >= COOLDOWN_MS;
|
|
32
41
|
}
|
|
@@ -35,9 +44,121 @@ function markNotified(key: string, severity: WarningSeverity): void {
|
|
|
35
44
|
alerts.set(key, { lastSeverity: severity, lastNotifiedAt: Date.now() });
|
|
36
45
|
}
|
|
37
46
|
|
|
47
|
+
interface PendingWarning {
|
|
48
|
+
key: string;
|
|
49
|
+
severity: WarningSeverity;
|
|
50
|
+
message: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Subscription energy (kWh) — the primary billing pool while subscribed. */
|
|
54
|
+
function energyWarning(
|
|
55
|
+
sub: NonNullable<NeuralwattQuotas["subscription"]>,
|
|
56
|
+
): PendingWarning | undefined {
|
|
57
|
+
if (sub.kwh_included <= 0) return;
|
|
58
|
+
const pct = (sub.kwh_remaining / sub.kwh_included) * 100;
|
|
59
|
+
if (pct > LOW_PCT) return;
|
|
60
|
+
return {
|
|
61
|
+
key: "energy",
|
|
62
|
+
severity: severityForPct(pct),
|
|
63
|
+
message: `Energy: ${pct.toFixed(0)}% remaining (${formatKwh(sub.kwh_remaining)} of ${formatKwh(sub.kwh_included)})`,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Balance credits (USD) — on-demand top-up pool. */
|
|
68
|
+
function creditsWarning(quotas: NeuralwattQuotas): PendingWarning | undefined {
|
|
69
|
+
const { credits_remaining_usd, total_credits_usd } = quotas.balance;
|
|
70
|
+
if (total_credits_usd <= 0) return;
|
|
71
|
+
const pct = (credits_remaining_usd / total_credits_usd) * 100;
|
|
72
|
+
if (pct > LOW_PCT) return;
|
|
73
|
+
return {
|
|
74
|
+
key: "credits",
|
|
75
|
+
severity: severityForPct(pct),
|
|
76
|
+
message: `Credits: ${pct.toFixed(0)}% remaining (${formatUsd(credits_remaining_usd)} of ${formatUsd(total_credits_usd)})`,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Overage usage billed against the overage cap, derived from kWh usage. */
|
|
81
|
+
interface OverageProgress {
|
|
82
|
+
/** kWh billed at the overage rate. */
|
|
83
|
+
overageKwh: number;
|
|
84
|
+
/** Per-kWh rate applied (USD). */
|
|
85
|
+
rate: number;
|
|
86
|
+
/** Cost of the overage kWh so far (USD). */
|
|
87
|
+
costUsd: number;
|
|
88
|
+
/** Configured overage cap (USD), or 0 when none. */
|
|
89
|
+
capUsd: number;
|
|
90
|
+
/** Remaining cap headroom (USD), clamped at 0. */
|
|
91
|
+
remainingUsd: number;
|
|
92
|
+
/** Remaining cap as a percentage of the cap (0-100). 0 when no cap. */
|
|
93
|
+
pctRemaining: number;
|
|
94
|
+
/** Cap exhausted (overage cost has reached or passed the cap). */
|
|
95
|
+
exhausted: boolean;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function computeOverageProgress(
|
|
99
|
+
quotas: NeuralwattQuotas,
|
|
100
|
+
): OverageProgress {
|
|
101
|
+
const capUsd = quotas.limits.overage_limit_usd ?? 0;
|
|
102
|
+
const hasSub = quotas.subscription !== null;
|
|
103
|
+
|
|
104
|
+
// Subscribed: only kWh beyond the included quota are billed at the overage
|
|
105
|
+
// rate. Unsubscribed: every kWh is billable — the monthly usage total is the
|
|
106
|
+
// overage pool (there is no included quota to subtract from).
|
|
107
|
+
const overageKwh = hasSub
|
|
108
|
+
? Math.max(
|
|
109
|
+
0,
|
|
110
|
+
(quotas.subscription?.kwh_used ?? 0) -
|
|
111
|
+
(quotas.subscription?.kwh_included ?? 0),
|
|
112
|
+
)
|
|
113
|
+
: quotas.usage.current_month.energy_kwh;
|
|
114
|
+
|
|
115
|
+
const rate = hasSub
|
|
116
|
+
? OVERAGE_RATE_PER_KWH_SUBSCRIBED
|
|
117
|
+
: OVERAGE_RATE_PER_KWH_UNSUBSCRIBED;
|
|
118
|
+
const costUsd = overageKwh * rate;
|
|
119
|
+
const remainingUsd = Math.max(0, capUsd - costUsd);
|
|
120
|
+
const pctRemaining = capUsd > 0 ? (remainingUsd / capUsd) * 100 : 0;
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
overageKwh,
|
|
124
|
+
rate,
|
|
125
|
+
costUsd,
|
|
126
|
+
capUsd,
|
|
127
|
+
remainingUsd,
|
|
128
|
+
pctRemaining,
|
|
129
|
+
exhausted: capUsd > 0 && remainingUsd <= 0,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function overageWarning(progress: OverageProgress): PendingWarning {
|
|
134
|
+
const pct = Math.max(0, Math.min(100, progress.pctRemaining));
|
|
135
|
+
return {
|
|
136
|
+
key: "overage",
|
|
137
|
+
// Entering overage is itself worth a critical alert; the % controls the
|
|
138
|
+
// message, not whether we notify.
|
|
139
|
+
severity: "critical",
|
|
140
|
+
message: `Overage cap: ${pct.toFixed(0)}% remaining (${formatUsd(progress.remainingUsd)} of ${formatUsd(progress.capUsd)}, ${formatKwh(progress.overageKwh)} over @ ${formatUsd(progress.rate)}/kWh)`,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
38
144
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
145
|
+
* Warning progression mirrors Neuralwatt's billing order. Each stage uses its
|
|
146
|
+
* own alert key, so once a later stage starts the earlier one stops — the
|
|
147
|
+
* warning "moves on" instead of re-reporting a depleted pool forever.
|
|
148
|
+
*
|
|
149
|
+
* subscribed, not in overage → energy (kWh remaining of quota)
|
|
150
|
+
* subscribed, in overage, cap set → overage cap progress (credits unreachable)
|
|
151
|
+
* subscribed, in overage, cap exhausted→ balance credits
|
|
152
|
+
* subscribed, in overage, no cap → balance credits (overage draws them down)
|
|
153
|
+
* no subscription, cap set → overage cap progress (all kWh billable)
|
|
154
|
+
* no subscription, no cap → balance credits
|
|
155
|
+
*
|
|
156
|
+
* Overage cost is derived from kWh usage: subscribed pays $5/kWh for kWh
|
|
157
|
+
* beyond the included quota; unsubscribed pays $10/kWh for all usage. There is
|
|
158
|
+
* no overage-spent counter in the API, so progress is computed.
|
|
159
|
+
*
|
|
160
|
+
* Usage totals (monthly/lifetime cost in USD) are deliberately not used as a
|
|
161
|
+
* threshold basis — they are not directly tied to the subscription's kWh quota.
|
|
41
162
|
*/
|
|
42
163
|
export function checkQuotas(
|
|
43
164
|
ctx: ExtensionContext,
|
|
@@ -45,55 +166,59 @@ export function checkQuotas(
|
|
|
45
166
|
): void {
|
|
46
167
|
if (!ctx.hasUI) return;
|
|
47
168
|
|
|
48
|
-
const
|
|
49
|
-
const
|
|
169
|
+
const pending: PendingWarning[] = [];
|
|
170
|
+
const sub = quotas.subscription;
|
|
50
171
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
warnings.push(
|
|
62
|
-
`Credits: ${pct.toFixed(0)}% remaining (${formatUsd(credits_remaining_usd)} of ${formatUsd(total_credits_usd)})`,
|
|
63
|
-
);
|
|
64
|
-
}
|
|
172
|
+
if (sub?.in_overage) {
|
|
173
|
+
const cap = quotas.limits.overage_limit_usd;
|
|
174
|
+
if (cap !== null && cap > 0) {
|
|
175
|
+
const progress = computeOverageProgress(quotas);
|
|
176
|
+
if (progress.exhausted) {
|
|
177
|
+
// Cap spent — fall through to the balance credits.
|
|
178
|
+
const cw = creditsWarning(quotas);
|
|
179
|
+
if (cw) pending.push(cw);
|
|
180
|
+
} else {
|
|
181
|
+
pending.push(overageWarning(progress));
|
|
65
182
|
}
|
|
183
|
+
} else {
|
|
184
|
+
// No cap: overage spends down the balance credits directly.
|
|
185
|
+
const cw = creditsWarning(quotas);
|
|
186
|
+
if (cw) pending.push(cw);
|
|
66
187
|
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (shouldNotify(key, severity)) {
|
|
82
|
-
markNotified(key, severity);
|
|
83
|
-
const tag = in_overage ? " [OVERAGE]" : "";
|
|
84
|
-
warnings.push(
|
|
85
|
-
`Energy${tag}: ${pct.toFixed(0)}% remaining (${formatKwh(kwh_remaining)} of ${formatKwh(kwh_included)})`,
|
|
86
|
-
);
|
|
87
|
-
}
|
|
188
|
+
} else if (sub) {
|
|
189
|
+
const ew = energyWarning(sub);
|
|
190
|
+
if (ew) pending.push(ew);
|
|
191
|
+
} else {
|
|
192
|
+
// No subscription. All kWh bill at the unsubscribed rate; warn on the
|
|
193
|
+
// overage cap when one is set, otherwise on the balance credits.
|
|
194
|
+
const cap = quotas.limits.overage_limit_usd;
|
|
195
|
+
if (cap !== null && cap > 0) {
|
|
196
|
+
const progress = computeOverageProgress(quotas);
|
|
197
|
+
if (progress.exhausted) {
|
|
198
|
+
const cw = creditsWarning(quotas);
|
|
199
|
+
if (cw) pending.push(cw);
|
|
200
|
+
} else if (progress.pctRemaining <= LOW_PCT) {
|
|
201
|
+
pending.push(overageWarning(progress));
|
|
88
202
|
}
|
|
203
|
+
} else {
|
|
204
|
+
const cw = creditsWarning(quotas);
|
|
205
|
+
if (cw) pending.push(cw);
|
|
89
206
|
}
|
|
90
207
|
}
|
|
91
208
|
|
|
92
|
-
|
|
209
|
+
const fired = pending.filter((w) => {
|
|
210
|
+
if (shouldNotify(w.key, w.severity)) {
|
|
211
|
+
markNotified(w.key, w.severity);
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
return false;
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
if (fired.length === 0) return;
|
|
93
218
|
|
|
94
|
-
const hasCritical =
|
|
219
|
+
const hasCritical = fired.some((w) => w.severity === "critical");
|
|
95
220
|
ctx.ui.notify(
|
|
96
|
-
`Neuralwatt quota warning:\n${
|
|
221
|
+
`Neuralwatt quota warning:\n${fired.map((w) => ` - ${w.message}`).join("\n")}`,
|
|
97
222
|
hasCritical ? "error" : "warning",
|
|
98
223
|
);
|
|
99
224
|
}
|