@aliou/pi-neuralwatt 0.7.4 → 0.8.0
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 +4 -2
- package/{src/extensions → extensions}/command-quotas/command.ts +2 -2
- package/extensions/command-quotas/components/progress-bar.ts +38 -0
- package/{src/extensions → extensions}/command-quotas/components/quota-tabs.ts +4 -4
- package/{src/extensions → extensions}/command-quotas/components/quotas-display.ts +1 -1
- package/{src/extensions → extensions}/command-quotas/index.ts +3 -3
- package/extensions/provider/commands/settings/index.ts +246 -0
- package/{src/extensions → extensions}/provider/index.ts +28 -20
- package/{src/extensions → extensions}/provider/models/hidden.ts +3 -3
- package/{src/extensions → extensions}/provider/models/legacy.ts +2 -0
- package/{src/extensions → extensions}/provider/models/public-models.ts +132 -46
- package/{src/extensions → extensions}/provider/quota-store.ts +4 -4
- package/{src/extensions → extensions}/provider/sse-quotas.ts +1 -1
- package/{src/extensions → extensions}/quota-warnings/index.ts +6 -7
- package/{src/extensions → extensions}/quota-warnings/notifier.ts +2 -2
- package/{src/extensions → extensions}/sub-bar-integration/index.ts +9 -10
- package/{src/extensions → extensions}/sub-bar-integration/snapshot.ts +3 -3
- package/package.json +20 -14
- package/schema.json +50 -6
- package/src/config/defaults.ts +17 -0
- package/src/config/index.ts +9 -0
- package/src/config/loader.ts +74 -0
- package/src/config/migration/01-disable-legacy-model-ids-by-default.ts +44 -0
- package/src/config/migration/02-flat-to-nested-config.ts +149 -0
- package/src/config/migration/index.ts +16 -0
- package/src/config/types.ts +77 -0
- package/src/{types/quota-events.ts → events.ts} +25 -13
- package/src/lib/neuralwatt-api.ts +1 -1
- package/src/types/quota-result.ts +12 -0
- package/src/utils/quota-bar.ts +0 -38
- package/src/config.ts +0 -210
- /package/{src/lib/env.ts → extensions/_shared/auth.ts} +0 -0
- /package/{src/extensions → extensions}/provider/context-overflow.ts +0 -0
- /package/{src/extensions → extensions}/provider/models/cache.ts +0 -0
- /package/{src/extensions → extensions}/provider/models/index.ts +0 -0
- /package/{src/extensions → extensions}/provider/rate-limit-error.ts +0 -0
- /package/{src/extensions → extensions}/provider/stream-simple.ts +0 -0
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ pi install npm:@aliou/pi-neuralwatt
|
|
|
36
36
|
pi install git:github.com/aliou/pi-neuralwatt
|
|
37
37
|
|
|
38
38
|
# Local development
|
|
39
|
-
pi -e ./
|
|
39
|
+
pi -e ./extensions/provider/index.ts
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
## Usage
|
|
@@ -80,9 +80,11 @@ Configure features with `/neuralwatt:settings`:
|
|
|
80
80
|
|
|
81
81
|
The provider itself cannot be disabled — it is always loaded.
|
|
82
82
|
|
|
83
|
+
Configuration uses nested per-feature sections. Existing flat config files are migrated automatically, with a backup written next to the migrated config.
|
|
84
|
+
|
|
83
85
|
## Adding or Updating Models
|
|
84
86
|
|
|
85
|
-
Models are hardcoded in `
|
|
87
|
+
Models are hardcoded in `extensions/provider/models/public-models.ts` and validated against the live API. To update:
|
|
86
88
|
|
|
87
89
|
1. Run `pnpm test` — it fetches `/v1/models` and compares against hardcoded definitions
|
|
88
90
|
2. Fix any discrepancies (missing models, changed context windows)
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
type ExtensionAPI,
|
|
4
4
|
getAgentDir,
|
|
5
5
|
} from "@earendil-works/pi-coding-agent";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { fetchQuotas } from "../../src/lib/neuralwatt-api";
|
|
7
|
+
import { getNeuralwattApiKey } from "../_shared/auth";
|
|
8
8
|
import { QuotasComponent } from "./components/quotas-display";
|
|
9
9
|
|
|
10
10
|
function missingAuthMessage(): string {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import type { Severity } from "../../../src/utils/quota-bar";
|
|
3
|
+
|
|
4
|
+
export type BarStyle = "filled-used" | "filled-remaining";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Render a progress bar.
|
|
8
|
+
*
|
|
9
|
+
* filled-used: filled region = used portion (colored by severity of remaining%)
|
|
10
|
+
* filled-remaining: filled region = remaining portion (colored by severity of remaining%)
|
|
11
|
+
*/
|
|
12
|
+
export function renderProgressBar(
|
|
13
|
+
percent: number,
|
|
14
|
+
width: number,
|
|
15
|
+
theme: Theme,
|
|
16
|
+
severity: Severity,
|
|
17
|
+
style: BarStyle = "filled-remaining",
|
|
18
|
+
): string {
|
|
19
|
+
const clamped = Math.max(0, Math.min(100, Math.round(percent)));
|
|
20
|
+
const filledCount = Math.round((clamped / 100) * width);
|
|
21
|
+
|
|
22
|
+
const parts: string[] = [];
|
|
23
|
+
for (let idx = 0; idx < width; idx++) {
|
|
24
|
+
const isFilled = idx < filledCount;
|
|
25
|
+
if (style === "filled-used") {
|
|
26
|
+
// filled = used (severity color), empty = remaining (dim)
|
|
27
|
+
parts.push(
|
|
28
|
+
isFilled ? theme.fg(severity, "\u2593") : theme.fg("success", "\u2591"),
|
|
29
|
+
);
|
|
30
|
+
} else {
|
|
31
|
+
// filled = remaining (severity color), empty = used (dim)
|
|
32
|
+
parts.push(
|
|
33
|
+
isFilled ? theme.fg(severity, "\u2588") : theme.fg("dim", "\u2591"),
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return parts.join("");
|
|
38
|
+
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { truncateToWidth } from "@earendil-works/pi-tui";
|
|
3
|
-
import type { NeuralwattQuotas } from "../../../types/quota-api";
|
|
3
|
+
import type { NeuralwattQuotas } from "../../../src/types/quota-api";
|
|
4
4
|
import {
|
|
5
5
|
percentCreditsRemaining,
|
|
6
6
|
percentEnergyRemaining,
|
|
7
|
-
renderProgressBar,
|
|
8
7
|
severityFromPercent,
|
|
9
|
-
} from "../../../utils/quota-bar";
|
|
8
|
+
} from "../../../src/utils/quota-bar";
|
|
10
9
|
import {
|
|
11
10
|
formatKwh,
|
|
12
11
|
formatTokens,
|
|
13
12
|
formatUsd,
|
|
14
|
-
} from "../../../utils/quota-format";
|
|
13
|
+
} from "../../../src/utils/quota-format";
|
|
14
|
+
import { renderProgressBar } from "./progress-bar";
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Subscription tab — plan details, energy quota, billing period.
|
|
@@ -2,7 +2,7 @@ import type { Theme } from "@earendil-works/pi-coding-agent";
|
|
|
2
2
|
import { DynamicBorder } from "@earendil-works/pi-coding-agent";
|
|
3
3
|
import type { Component, TUI } from "@earendil-works/pi-tui";
|
|
4
4
|
import { Loader, matchesKey, truncateToWidth } from "@earendil-works/pi-tui";
|
|
5
|
-
import type { NeuralwattQuotas } from "../../../types/quota-api";
|
|
5
|
+
import type { NeuralwattQuotas } from "../../../src/types/quota-api";
|
|
6
6
|
import {
|
|
7
7
|
renderCreditsTab,
|
|
8
8
|
renderSubscriptionTab,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { configLoader } from "../../src/config";
|
|
2
3
|
import {
|
|
3
|
-
configLoader,
|
|
4
4
|
NEURALWATT_EXTENSIONS_REGISTER_EVENT,
|
|
5
5
|
NEURALWATT_EXTENSIONS_REQUEST_EVENT,
|
|
6
|
-
} from "../../
|
|
6
|
+
} from "../../src/events";
|
|
7
7
|
import { registerQuotasCommand } from "./command";
|
|
8
8
|
|
|
9
9
|
export default async function (pi: ExtensionAPI) {
|
|
@@ -11,7 +11,7 @@ export default async function (pi: ExtensionAPI) {
|
|
|
11
11
|
|
|
12
12
|
const config = configLoader.getConfig();
|
|
13
13
|
|
|
14
|
-
if (config.quotaCommand) {
|
|
14
|
+
if (config.quotaCommand.enabled) {
|
|
15
15
|
registerQuotasCommand(pi);
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import {
|
|
2
|
+
registerSettingsCommand,
|
|
3
|
+
type SettingsSection,
|
|
4
|
+
} from "@aliou/pi-utils-settings";
|
|
5
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
6
|
+
import type { SettingItem } from "@earendil-works/pi-tui";
|
|
7
|
+
import {
|
|
8
|
+
configLoader,
|
|
9
|
+
type NeuralwattConfig,
|
|
10
|
+
type NeuralwattRawConfig,
|
|
11
|
+
type ResolvedNeuralwattConfig,
|
|
12
|
+
} from "../../../../src/config";
|
|
13
|
+
import {
|
|
14
|
+
NEURALWATT_CONFIG_UPDATED_EVENT,
|
|
15
|
+
type NeuralwattFeatureId,
|
|
16
|
+
} from "../../../../src/events";
|
|
17
|
+
|
|
18
|
+
export interface RegisterNeuralwattSettingsOptions {
|
|
19
|
+
getLoadedFeatures: () => Set<NeuralwattFeatureId>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function emitConfigUpdated(pi: ExtensionAPI): void {
|
|
23
|
+
pi.events.emit(NEURALWATT_CONFIG_UPDATED_EVENT, {
|
|
24
|
+
config: configLoader.getConfig(),
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function featureRow(
|
|
29
|
+
id: NeuralwattFeatureId,
|
|
30
|
+
label: string,
|
|
31
|
+
description: string,
|
|
32
|
+
configValue: boolean,
|
|
33
|
+
isLoaded: boolean,
|
|
34
|
+
): SettingItem {
|
|
35
|
+
if (isLoaded) {
|
|
36
|
+
return {
|
|
37
|
+
id,
|
|
38
|
+
label,
|
|
39
|
+
description,
|
|
40
|
+
currentValue: configValue ? "enabled" : "disabled",
|
|
41
|
+
values: ["enabled", "disabled"],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
id,
|
|
46
|
+
label,
|
|
47
|
+
description: `${description} (Not loaded by Pi)`,
|
|
48
|
+
currentValue: "unavailable",
|
|
49
|
+
values: [],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function optionalFeatureValue(value: unknown): boolean | undefined {
|
|
54
|
+
if (typeof value === "boolean") return value;
|
|
55
|
+
if (value && typeof value === "object") {
|
|
56
|
+
const enabled = (value as { enabled?: boolean }).enabled;
|
|
57
|
+
if (typeof enabled === "boolean") return enabled;
|
|
58
|
+
}
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function featureValue(value: unknown, fallback: boolean): boolean {
|
|
63
|
+
return optionalFeatureValue(value) ?? fallback;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function toNestedConfig(config: NeuralwattRawConfig): NeuralwattConfig {
|
|
67
|
+
const provider = "provider" in config ? config.provider : undefined;
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
provider: {
|
|
71
|
+
...(provider ?? {}),
|
|
72
|
+
includeLegacyModelIds:
|
|
73
|
+
provider?.includeLegacyModelIds ??
|
|
74
|
+
("includeLegacyModelIds" in config
|
|
75
|
+
? config.includeLegacyModelIds
|
|
76
|
+
: undefined),
|
|
77
|
+
includeHiddenModels:
|
|
78
|
+
provider?.includeHiddenModels ??
|
|
79
|
+
("includeHiddenModels" in config
|
|
80
|
+
? config.includeHiddenModels
|
|
81
|
+
: undefined),
|
|
82
|
+
},
|
|
83
|
+
quotaCommand: {
|
|
84
|
+
...(typeof config.quotaCommand === "object" ? config.quotaCommand : {}),
|
|
85
|
+
enabled: optionalFeatureValue(config.quotaCommand),
|
|
86
|
+
},
|
|
87
|
+
quotaWarnings: {
|
|
88
|
+
...(typeof config.quotaWarnings === "object" ? config.quotaWarnings : {}),
|
|
89
|
+
enabled: optionalFeatureValue(config.quotaWarnings),
|
|
90
|
+
},
|
|
91
|
+
subBarIntegration: {
|
|
92
|
+
...(typeof config.subBarIntegration === "object"
|
|
93
|
+
? config.subBarIntegration
|
|
94
|
+
: {}),
|
|
95
|
+
enabled: optionalFeatureValue(config.subBarIntegration),
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function registerNeuralwattSettings(
|
|
101
|
+
pi: ExtensionAPI,
|
|
102
|
+
options: RegisterNeuralwattSettingsOptions,
|
|
103
|
+
): void {
|
|
104
|
+
const { getLoadedFeatures } = options;
|
|
105
|
+
|
|
106
|
+
registerSettingsCommand<NeuralwattRawConfig, ResolvedNeuralwattConfig>(pi, {
|
|
107
|
+
commandName: "neuralwatt:settings",
|
|
108
|
+
title: "Neuralwatt Settings",
|
|
109
|
+
configStore: configLoader,
|
|
110
|
+
buildSections: (tabConfig, resolved): SettingsSection[] => {
|
|
111
|
+
const loaded = getLoadedFeatures();
|
|
112
|
+
return [
|
|
113
|
+
{
|
|
114
|
+
label: "Features",
|
|
115
|
+
items: [
|
|
116
|
+
featureRow(
|
|
117
|
+
"quotaCommand",
|
|
118
|
+
"Quota command",
|
|
119
|
+
"Toggle the /neuralwatt:quota command, showing your API usage at a glance",
|
|
120
|
+
featureValue(
|
|
121
|
+
tabConfig?.quotaCommand,
|
|
122
|
+
resolved.quotaCommand.enabled,
|
|
123
|
+
),
|
|
124
|
+
loaded.has("quotaCommand"),
|
|
125
|
+
),
|
|
126
|
+
featureRow(
|
|
127
|
+
"quotaWarnings",
|
|
128
|
+
"Quota warnings",
|
|
129
|
+
"Toggle notifications when credits or energy are running low",
|
|
130
|
+
featureValue(
|
|
131
|
+
tabConfig?.quotaWarnings,
|
|
132
|
+
resolved.quotaWarnings.enabled,
|
|
133
|
+
),
|
|
134
|
+
loaded.has("quotaWarnings"),
|
|
135
|
+
),
|
|
136
|
+
featureRow(
|
|
137
|
+
"subBarIntegration",
|
|
138
|
+
"Sub-bar integration",
|
|
139
|
+
"Toggle integration with the status bar and sub-core",
|
|
140
|
+
featureValue(
|
|
141
|
+
tabConfig?.subBarIntegration,
|
|
142
|
+
resolved.subBarIntegration.enabled,
|
|
143
|
+
),
|
|
144
|
+
loaded.has("subBarIntegration"),
|
|
145
|
+
),
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
label: "Other settings",
|
|
150
|
+
items: [
|
|
151
|
+
{
|
|
152
|
+
id: "includeLegacyModelIds",
|
|
153
|
+
label: "Legacy model IDs",
|
|
154
|
+
description:
|
|
155
|
+
"Include deprecated Neuralwatt model IDs as aliases in the model picker",
|
|
156
|
+
currentValue:
|
|
157
|
+
((tabConfig &&
|
|
158
|
+
"provider" in tabConfig &&
|
|
159
|
+
tabConfig.provider?.includeLegacyModelIds) ??
|
|
160
|
+
(tabConfig &&
|
|
161
|
+
"includeLegacyModelIds" in tabConfig &&
|
|
162
|
+
tabConfig.includeLegacyModelIds) ??
|
|
163
|
+
resolved.provider.includeLegacyModelIds)
|
|
164
|
+
? "include"
|
|
165
|
+
: "ignore",
|
|
166
|
+
values: ["include", "ignore"],
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
id: "includeHiddenModels",
|
|
170
|
+
label: "Hidden models",
|
|
171
|
+
description:
|
|
172
|
+
"Include Neuralwatt models that are accessible via API key but not advertised in the public model list",
|
|
173
|
+
currentValue:
|
|
174
|
+
((tabConfig &&
|
|
175
|
+
"provider" in tabConfig &&
|
|
176
|
+
tabConfig.provider?.includeHiddenModels) ??
|
|
177
|
+
(tabConfig &&
|
|
178
|
+
"includeHiddenModels" in tabConfig &&
|
|
179
|
+
tabConfig.includeHiddenModels) ??
|
|
180
|
+
resolved.provider.includeHiddenModels)
|
|
181
|
+
? "include"
|
|
182
|
+
: "ignore",
|
|
183
|
+
values: ["include", "ignore"],
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
},
|
|
187
|
+
];
|
|
188
|
+
},
|
|
189
|
+
onSettingChange: (id, newValue, config) => {
|
|
190
|
+
// Non-feature toggles are handled first so they are not blocked by the
|
|
191
|
+
// loaded-features guard (they are managed directly by the provider).
|
|
192
|
+
if (id === "includeLegacyModelIds") {
|
|
193
|
+
const nestedConfig = toNestedConfig(config);
|
|
194
|
+
return {
|
|
195
|
+
...nestedConfig,
|
|
196
|
+
provider: {
|
|
197
|
+
...nestedConfig.provider,
|
|
198
|
+
includeLegacyModelIds: newValue === "include",
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (id === "includeHiddenModels") {
|
|
204
|
+
const nestedConfig = toNestedConfig(config);
|
|
205
|
+
return {
|
|
206
|
+
...nestedConfig,
|
|
207
|
+
provider: {
|
|
208
|
+
...nestedConfig.provider,
|
|
209
|
+
includeHiddenModels: newValue === "include",
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (!getLoadedFeatures().has(id as NeuralwattFeatureId)) {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const enabled = newValue === "enabled";
|
|
219
|
+
switch (id) {
|
|
220
|
+
case "quotaCommand":
|
|
221
|
+
return {
|
|
222
|
+
...toNestedConfig(config),
|
|
223
|
+
quotaCommand: { ...toNestedConfig(config).quotaCommand, enabled },
|
|
224
|
+
};
|
|
225
|
+
case "quotaWarnings":
|
|
226
|
+
return {
|
|
227
|
+
...toNestedConfig(config),
|
|
228
|
+
quotaWarnings: { ...toNestedConfig(config).quotaWarnings, enabled },
|
|
229
|
+
};
|
|
230
|
+
case "subBarIntegration":
|
|
231
|
+
return {
|
|
232
|
+
...toNestedConfig(config),
|
|
233
|
+
subBarIntegration: {
|
|
234
|
+
...toNestedConfig(config).subBarIntegration,
|
|
235
|
+
enabled,
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
|
+
default:
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
onSave: async () => {
|
|
243
|
+
emitConfigUpdated(pi);
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
}
|
|
@@ -1,25 +1,22 @@
|
|
|
1
|
-
import { getApiProvider } from "@earendil-works/pi-ai";
|
|
1
|
+
import { getApiProvider } from "@earendil-works/pi-ai/compat";
|
|
2
2
|
import type {
|
|
3
3
|
ExtensionAPI,
|
|
4
4
|
ProviderModelConfig,
|
|
5
5
|
} from "@earendil-works/pi-coding-agent";
|
|
6
|
+
import { configLoader } from "../../src/config";
|
|
6
7
|
import {
|
|
7
|
-
configLoader,
|
|
8
|
-
emitConfigUpdated,
|
|
9
8
|
NEURALWATT_CONFIG_UPDATED_EVENT,
|
|
10
9
|
NEURALWATT_EXTENSIONS_REGISTER_EVENT,
|
|
11
10
|
NEURALWATT_EXTENSIONS_REQUEST_EVENT,
|
|
12
|
-
type NeuralwattFeatureId,
|
|
13
|
-
registerNeuralwattSettings,
|
|
14
|
-
} from "../../config";
|
|
15
|
-
import { getNeuralwattApiKey } from "../../lib/env";
|
|
16
|
-
import { fetchQuotas } from "../../lib/neuralwatt-api";
|
|
17
|
-
import type { NeuralwattQuotas } from "../../types/quota-api";
|
|
18
|
-
import {
|
|
19
11
|
NEURALWATT_QUOTAS_REQUEST_EVENT,
|
|
20
12
|
NEURALWATT_QUOTAS_UPDATED_EVENT,
|
|
13
|
+
type NeuralwattFeatureId,
|
|
21
14
|
type NeuralwattQuotasUpdatedPayload,
|
|
22
|
-
} from "../../
|
|
15
|
+
} from "../../src/events";
|
|
16
|
+
import { fetchQuotas } from "../../src/lib/neuralwatt-api";
|
|
17
|
+
import type { NeuralwattQuotas } from "../../src/types/quota-api";
|
|
18
|
+
import { getNeuralwattApiKey } from "../_shared/auth";
|
|
19
|
+
import { registerNeuralwattSettings } from "./commands/settings";
|
|
23
20
|
import { normalizeNeuralwattContextOverflowError } from "./context-overflow";
|
|
24
21
|
import {
|
|
25
22
|
getNeuralwattModels,
|
|
@@ -38,16 +35,23 @@ import { wrapNeuralwattStreamSimple } from "./stream-simple";
|
|
|
38
35
|
|
|
39
36
|
const HEADER_EMIT_THROTTLE_MS = 5_000;
|
|
40
37
|
|
|
38
|
+
function emitConfigUpdated(pi: ExtensionAPI): void {
|
|
39
|
+
pi.events.emit(NEURALWATT_CONFIG_UPDATED_EVENT, {
|
|
40
|
+
config: configLoader.getConfig(),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
41
44
|
function registerNeuralwattProvider(
|
|
42
45
|
pi: ExtensionAPI,
|
|
43
46
|
onSseQuota: (line: string) => void,
|
|
44
47
|
hiddenModels: ProviderModelConfig[] = [],
|
|
45
48
|
): void {
|
|
46
|
-
const {
|
|
47
|
-
configLoader.getConfig();
|
|
49
|
+
const { provider: providerConfig } = configLoader.getConfig();
|
|
48
50
|
|
|
49
|
-
const publicModels = getNeuralwattModels({
|
|
50
|
-
|
|
51
|
+
const publicModels = getNeuralwattModels({
|
|
52
|
+
includeLegacyModelIds: providerConfig.includeLegacyModelIds,
|
|
53
|
+
});
|
|
54
|
+
const resolvedHiddenModels = providerConfig.includeHiddenModels
|
|
51
55
|
? dedupeHiddenModels(hiddenModels, publicModels)
|
|
52
56
|
: [];
|
|
53
57
|
|
|
@@ -109,7 +113,7 @@ export default async function (pi: ExtensionAPI) {
|
|
|
109
113
|
// load time. `session_start` then revalidates from the live API and writes
|
|
110
114
|
// the cache back. First run with no cache still warns once.
|
|
111
115
|
let hiddenModels: ProviderModelConfig[] = [];
|
|
112
|
-
if (configLoader.getConfig().includeHiddenModels) {
|
|
116
|
+
if (configLoader.getConfig().provider.includeHiddenModels) {
|
|
113
117
|
hiddenModels = loadCachedHiddenModels();
|
|
114
118
|
}
|
|
115
119
|
let hiddenModelsLoaded = false;
|
|
@@ -139,7 +143,7 @@ export default async function (pi: ExtensionAPI) {
|
|
|
139
143
|
// cache so previously discovered models are available immediately without
|
|
140
144
|
// waiting for the next session_start revalidation.
|
|
141
145
|
if (
|
|
142
|
-
configLoader.getConfig().includeHiddenModels &&
|
|
146
|
+
configLoader.getConfig().provider.includeHiddenModels &&
|
|
143
147
|
!hiddenModelsLoaded &&
|
|
144
148
|
hiddenModels.length === 0
|
|
145
149
|
) {
|
|
@@ -257,15 +261,19 @@ export default async function (pi: ExtensionAPI) {
|
|
|
257
261
|
|
|
258
262
|
pi.on("session_start", async (_event, ctx) => {
|
|
259
263
|
pendingRateLimitInfo = undefined;
|
|
260
|
-
|
|
261
|
-
|
|
264
|
+
const messages = [...new Set(configLoader.drainMessages())];
|
|
265
|
+
if (messages.length > 0) {
|
|
266
|
+
ctx.ui.notify(messages.join("\n"), "info");
|
|
262
267
|
}
|
|
263
268
|
|
|
264
269
|
loadedFeatures.clear();
|
|
265
270
|
pi.events.emit(NEURALWATT_EXTENSIONS_REQUEST_EVENT, undefined);
|
|
266
271
|
emitConfigUpdated(pi);
|
|
267
272
|
|
|
268
|
-
if (
|
|
273
|
+
if (
|
|
274
|
+
!hiddenModelsLoaded &&
|
|
275
|
+
configLoader.getConfig().provider.includeHiddenModels
|
|
276
|
+
) {
|
|
269
277
|
hiddenModelsLoaded = true;
|
|
270
278
|
hiddenModelsAbort?.abort();
|
|
271
279
|
hiddenModelsAbort = new AbortController();
|
|
@@ -2,9 +2,9 @@ import type {
|
|
|
2
2
|
AuthStorage,
|
|
3
3
|
ProviderModelConfig,
|
|
4
4
|
} from "@earendil-works/pi-coding-agent";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
5
|
+
import { fetchNeuralwattModels } from "../../../src/lib/neuralwatt-api";
|
|
6
|
+
import type { NeuralwattApiModel } from "../../../src/types/models-api";
|
|
7
|
+
import { getNeuralwattApiKey } from "../../_shared/auth";
|
|
8
8
|
import { NEURALWATT_MODELS } from "./public-models";
|
|
9
9
|
|
|
10
10
|
// Per-ID overrides for known hidden models. The authenticated /v1/models endpoint
|
|
@@ -7,6 +7,8 @@ export const LEGACY_MODEL_ALIAS_MAP = {
|
|
|
7
7
|
"glm-5.1": "glm-5.2",
|
|
8
8
|
"glm-5.1-fast": "glm-5.2-fast",
|
|
9
9
|
"zai-org/GLM-5.1-FP8": "glm-5.2",
|
|
10
|
+
"moonshotai/Kimi-K2.5": "kimi-k2.6",
|
|
11
|
+
"kimi-k2.5-fast": "kimi-k2.6-fast",
|
|
10
12
|
"moonshotai/Kimi-K2.6": "kimi-k2.6",
|
|
11
13
|
"Qwen/Qwen3.5-397B-A17B-FP8": "qwen3.5-397b",
|
|
12
14
|
"Qwen/Qwen3.6-35B-A3B": "qwen3.6-35b",
|