@aliou/pi-neuralwatt 0.10.4 → 0.10.6

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.
@@ -5,7 +5,10 @@ import type {
5
5
  RefreshModelsContext,
6
6
  } from "@earendil-works/pi-ai";
7
7
  import type { ProviderModelConfig } from "@earendil-works/pi-coding-agent";
8
- import { HIDDEN_NEURALWATT_MODELS, loadHiddenModels } from "./hidden";
8
+ import {
9
+ EARLY_ACCESS_NEURALWATT_MODELS,
10
+ loadEarlyAccessModels,
11
+ } from "./early-access";
9
12
  import { buildLegacyNeuralwattModels } from "./legacy";
10
13
  import { NEURALWATT_MODELS } from "./public-models";
11
14
 
@@ -15,8 +18,8 @@ const API = "openai-completions" as const;
15
18
 
16
19
  export interface RefreshNeuralwattModelsOptions {
17
20
  includeLegacyModelIds: boolean;
18
- includeHiddenModels: boolean;
19
- loadHidden?: typeof loadHiddenModels;
21
+ includeEarlyAccessModels: boolean;
22
+ loadEarlyAccess?: typeof loadEarlyAccessModels;
20
23
  }
21
24
 
22
25
  function configuredModels(
@@ -59,31 +62,31 @@ function toProviderModel(model: Model<Api>): ProviderModelConfig {
59
62
  };
60
63
  }
61
64
 
62
- function dedupeHiddenModels(
63
- hiddenModels: ProviderModelConfig[],
65
+ function dedupeEarlyAccessModels(
66
+ earlyAccessModels: ProviderModelConfig[],
64
67
  baselineModels: ProviderModelConfig[],
65
68
  ): ProviderModelConfig[] {
66
69
  const baselineIds = new Set(baselineModels.map((model) => model.id));
67
- return hiddenModels.filter((model) => !baselineIds.has(model.id));
70
+ return earlyAccessModels.filter((model) => !baselineIds.has(model.id));
68
71
  }
69
72
 
70
- function configuredHiddenModels(
73
+ function configuredEarlyAccessModels(
71
74
  discoveredModels: ProviderModelConfig[],
72
75
  baselineModels: ProviderModelConfig[],
73
76
  ): ProviderModelConfig[] {
74
77
  const hardcodedIds = new Set(
75
- HIDDEN_NEURALWATT_MODELS.map((model) => model.id),
78
+ EARLY_ACCESS_NEURALWATT_MODELS.map((model) => model.id),
76
79
  );
77
- return dedupeHiddenModels(
80
+ return dedupeEarlyAccessModels(
78
81
  [
79
- ...HIDDEN_NEURALWATT_MODELS,
82
+ ...EARLY_ACCESS_NEURALWATT_MODELS,
80
83
  ...discoveredModels.filter((model) => !hardcodedIds.has(model.id)),
81
84
  ],
82
85
  baselineModels,
83
86
  );
84
87
  }
85
88
 
86
- function cachedHiddenModels(
89
+ function cachedEarlyAccessModels(
87
90
  stored: ModelsStoreEntry | undefined,
88
91
  ): ProviderModelConfig[] {
89
92
  if (!stored) return [];
@@ -115,16 +118,16 @@ export async function refreshNeuralwattModels(
115
118
  const baseline = configuredModels(options.includeLegacyModelIds);
116
119
  const stored = await context.store.read();
117
120
 
118
- if (!options.includeHiddenModels) {
121
+ if (!options.includeEarlyAccessModels) {
119
122
  await persistModels(context, baseline);
120
123
  return baseline;
121
124
  }
122
125
 
123
- const cachedHidden = configuredHiddenModels(
124
- cachedHiddenModels(stored),
126
+ const cachedEarlyAccess = configuredEarlyAccessModels(
127
+ cachedEarlyAccessModels(stored),
125
128
  baseline,
126
129
  );
127
- const cachedCatalog = [...baseline, ...cachedHidden];
130
+ const cachedCatalog = [...baseline, ...cachedEarlyAccess];
128
131
 
129
132
  if (!context.allowNetwork || context.signal?.aborted) {
130
133
  return cachedCatalog;
@@ -134,16 +137,19 @@ export async function refreshNeuralwattModels(
134
137
  context.credential?.type === "api_key" ? context.credential.key : undefined;
135
138
  if (!apiKey) return cachedCatalog;
136
139
 
137
- const hidden = await (options.loadHidden ?? loadHiddenModels)(
140
+ const earlyAccess = await (options.loadEarlyAccess ?? loadEarlyAccessModels)(
138
141
  apiKey,
139
142
  context.signal,
140
143
  );
141
144
  if (context.signal?.aborted) return cachedCatalog;
142
- if (!hidden) {
145
+ if (!earlyAccess) {
143
146
  throw new Error("Neuralwatt model catalog refresh failed");
144
147
  }
145
148
 
146
- const catalog = [...baseline, ...configuredHiddenModels(hidden, baseline)];
149
+ const catalog = [
150
+ ...baseline,
151
+ ...configuredEarlyAccessModels(earlyAccess, baseline),
152
+ ];
147
153
  await persistModels(context, catalog);
148
154
  return catalog;
149
155
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aliou/pi-neuralwatt",
3
- "version": "0.10.4",
3
+ "version": "0.10.6",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "private": false,
package/schema.json CHANGED
@@ -31,8 +31,8 @@
31
31
  "NeuralwattProviderConfig": {
32
32
  "additionalProperties": false,
33
33
  "properties": {
34
- "includeHiddenModels": {
35
- "description": "Include hidden Neuralwatt models discovered via the authenticated API.",
34
+ "includeEarlyAccessModels": {
35
+ "description": "Include early-access Neuralwatt models discovered via the authenticated API.",
36
36
  "type": "boolean"
37
37
  },
38
38
  "includeLegacyModelIds": {
@@ -3,7 +3,7 @@ import type { ResolvedNeuralwattConfig } from "./types";
3
3
  export const DEFAULT_CONFIG: ResolvedNeuralwattConfig = {
4
4
  provider: {
5
5
  includeLegacyModelIds: false,
6
- includeHiddenModels: false,
6
+ includeEarlyAccessModels: false,
7
7
  },
8
8
  quotaCommand: {
9
9
  enabled: true,
@@ -1,9 +1,4 @@
1
1
  export { DEFAULT_CONFIG } from "./defaults";
2
2
  export { configLoader } from "./loader";
3
3
  export { migrations } from "./migration";
4
- export type {
5
- NeuralwattConfig,
6
- NeuralwattRawConfig,
7
- PreviousNeuralwattConfig,
8
- ResolvedNeuralwattConfig,
9
- } from "./types";
4
+ export type { NeuralwattConfig, ResolvedNeuralwattConfig } from "./types";
@@ -2,70 +2,44 @@ import { buildSchemaUrl, ConfigLoader } from "@aliou/pi-utils-settings";
2
2
  import packageJson from "../../package.json";
3
3
  import { DEFAULT_CONFIG } from "./defaults";
4
4
  import { migrations } from "./migration";
5
- import type { NeuralwattRawConfig, ResolvedNeuralwattConfig } from "./types";
6
-
7
- type ConfigRecord = Record<string, unknown>;
8
-
9
- type MaybeEnabled = { enabled?: boolean };
10
- type MaybeProvider = {
11
- includeLegacyModelIds?: boolean;
12
- includeHiddenModels?: boolean;
13
- };
14
-
15
- function featureEnabled(value: unknown, fallback: boolean): boolean {
16
- if (typeof value === "boolean") return value;
17
- if (value && typeof value === "object") {
18
- const { enabled } = value as MaybeEnabled;
19
- if (typeof enabled === "boolean") return enabled;
20
- }
21
- return fallback;
22
- }
5
+ import type { NeuralwattConfig, ResolvedNeuralwattConfig } from "./types";
23
6
 
7
+ /**
8
+ * Fill in every field the rest of the code reads. Migrations already normalized
9
+ * the on-disk shape, so this only merges partial sections with the defaults.
10
+ */
24
11
  function normalizeResolvedConfig(
25
12
  resolved: ResolvedNeuralwattConfig,
26
13
  ): ResolvedNeuralwattConfig {
27
- const record = resolved as unknown as ConfigRecord;
28
- const provider =
29
- record.provider && typeof record.provider === "object"
30
- ? (record.provider as MaybeProvider)
31
- : {};
14
+ const config = resolved as Partial<ResolvedNeuralwattConfig>;
32
15
 
33
16
  return {
34
17
  provider: {
35
18
  includeLegacyModelIds:
36
- provider.includeLegacyModelIds ??
37
- (typeof record.includeLegacyModelIds === "boolean"
38
- ? record.includeLegacyModelIds
39
- : DEFAULT_CONFIG.provider.includeLegacyModelIds),
40
- includeHiddenModels:
41
- provider.includeHiddenModels ??
42
- (typeof record.includeHiddenModels === "boolean"
43
- ? record.includeHiddenModels
44
- : DEFAULT_CONFIG.provider.includeHiddenModels),
19
+ config.provider?.includeLegacyModelIds ??
20
+ DEFAULT_CONFIG.provider.includeLegacyModelIds,
21
+ includeEarlyAccessModels:
22
+ config.provider?.includeEarlyAccessModels ??
23
+ DEFAULT_CONFIG.provider.includeEarlyAccessModels,
45
24
  },
46
25
  quotaCommand: {
47
- enabled: featureEnabled(
48
- record.quotaCommand,
49
- DEFAULT_CONFIG.quotaCommand.enabled,
50
- ),
26
+ enabled:
27
+ config.quotaCommand?.enabled ?? DEFAULT_CONFIG.quotaCommand.enabled,
51
28
  },
52
29
  quotaWarnings: {
53
- enabled: featureEnabled(
54
- record.quotaWarnings,
55
- DEFAULT_CONFIG.quotaWarnings.enabled,
56
- ),
30
+ enabled:
31
+ config.quotaWarnings?.enabled ?? DEFAULT_CONFIG.quotaWarnings.enabled,
57
32
  },
58
33
  subBarIntegration: {
59
- enabled: featureEnabled(
60
- record.subBarIntegration,
34
+ enabled:
35
+ config.subBarIntegration?.enabled ??
61
36
  DEFAULT_CONFIG.subBarIntegration.enabled,
62
- ),
63
37
  },
64
38
  };
65
39
  }
66
40
 
67
41
  export const configLoader = new ConfigLoader<
68
- NeuralwattRawConfig,
42
+ NeuralwattConfig,
69
43
  ResolvedNeuralwattConfig
70
44
  >("neuralwatt", DEFAULT_CONFIG, {
71
45
  migrations,
@@ -1,7 +1,5 @@
1
1
  import type { Migration } from "@aliou/pi-utils-settings";
2
- import type { NeuralwattConfig, PreviousNeuralwattConfig } from "../types";
3
-
4
- type MigrationConfig = PreviousNeuralwattConfig | NeuralwattConfig;
2
+ import type { NeuralwattConfig } from "../types";
5
3
 
6
4
  type MutableConfigRecord = Record<string, unknown>;
7
5
 
@@ -9,7 +7,7 @@ function hasOwn(record: MutableConfigRecord, key: string): boolean {
9
7
  return Object.hasOwn(record, key);
10
8
  }
11
9
 
12
- function hasNestedConfig(config: MigrationConfig): boolean {
10
+ function hasNestedConfig(config: NeuralwattConfig): boolean {
13
11
  return Boolean(
14
12
  ("provider" in config && config.provider) ||
15
13
  (config.quotaCommand && typeof config.quotaCommand === "object") ||
@@ -20,25 +18,25 @@ function hasNestedConfig(config: MigrationConfig): boolean {
20
18
  }
21
19
 
22
20
  function isPreviousConfigWithoutLegacyDefault(
23
- config: MigrationConfig,
24
- ): config is PreviousNeuralwattConfig {
21
+ config: NeuralwattConfig,
22
+ ): boolean {
25
23
  return (
26
24
  !hasNestedConfig(config) &&
27
25
  !hasOwn(config as MutableConfigRecord, "includeLegacyModelIds")
28
26
  );
29
27
  }
30
28
 
31
- export const disableLegacyModelIdsByDefaultMigration: Migration<MigrationConfig> =
29
+ export const disableLegacyModelIdsByDefaultMigration: Migration<NeuralwattConfig> =
32
30
  {
33
31
  name: "disable-legacy-model-ids-by-default",
34
32
  shouldRun: isPreviousConfigWithoutLegacyDefault,
35
33
  message:
36
34
  "[neuralwatt] legacy model IDs (ids including the provider and the quantization) are disabled by default. You can enable them with /neuralwatt:settings.",
37
- run: (config) => {
38
- const previous = config as PreviousNeuralwattConfig;
39
- return {
40
- ...previous,
35
+ // Flat config: `includeLegacyModelIds` sits at the top level here. Migration
36
+ // 02 moves it under `provider`.
37
+ run: (config) =>
38
+ ({
39
+ ...config,
41
40
  includeLegacyModelIds: false,
42
- };
43
- },
41
+ }) as unknown as NeuralwattConfig,
44
42
  };
@@ -3,11 +3,27 @@ import { copyFile } from "node:fs/promises";
3
3
  import { basename, dirname, join } from "node:path";
4
4
  import type { Migration } from "@aliou/pi-utils-settings";
5
5
  import packageJson from "../../../package.json";
6
- import type { NeuralwattConfig, PreviousNeuralwattConfig } from "../types";
6
+ import type { NeuralwattConfig } from "../types";
7
7
 
8
- type MigrationConfig = PreviousNeuralwattConfig | NeuralwattConfig;
8
+ /** The original flat config, replaced by per-feature sections. */
9
+ interface FlatNeuralwattConfig {
10
+ /** Show the quota command (/neuralwatt:quota). */
11
+ quotaCommand?: boolean;
9
12
 
10
- type FlatConfigKey = keyof Omit<PreviousNeuralwattConfig, "$schema">;
13
+ /** Show quota warnings when credits or energy are low. */
14
+ quotaWarnings?: boolean;
15
+
16
+ /** Show usage in the sub-bar / status bar. */
17
+ subBarIntegration?: boolean;
18
+
19
+ /** Include legacy Neuralwatt model IDs in the model picker. */
20
+ includeLegacyModelIds?: boolean;
21
+
22
+ /** Renamed to `provider.includeEarlyAccessModels` by migration 03. */
23
+ includeHiddenModels?: boolean;
24
+ }
25
+
26
+ type FlatConfigKey = keyof FlatNeuralwattConfig;
11
27
  type MutableConfigRecord = Record<string, unknown>;
12
28
 
13
29
  const FLAT_CONFIG_KEYS = [
@@ -34,9 +50,7 @@ function isObject(value: unknown): value is Record<string, unknown> {
34
50
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
35
51
  }
36
52
 
37
- function isPreviousConfig(
38
- config: MigrationConfig,
39
- ): config is PreviousNeuralwattConfig {
53
+ function isPreviousConfig(config: NeuralwattConfig): boolean {
40
54
  const record = config as MutableConfigRecord;
41
55
  return FLAT_CONFIG_KEYS.some((key) => typeof record[key] === "boolean");
42
56
  }
@@ -64,16 +78,15 @@ export async function backupConfig(filePath: string): Promise<void> {
64
78
  }
65
79
  }
66
80
 
67
- export const flatToNestedConfigMigration: Migration<MigrationConfig> = {
81
+ export const flatToNestedConfigMigration: Migration<NeuralwattConfig> = {
68
82
  name: "flat-to-nested-config",
69
83
  shouldRun: isPreviousConfig,
70
84
  message: FLAT_CONFIG_MIGRATION_MESSAGE,
71
85
  run: async (config, filePath) => {
72
86
  await backupConfig(filePath);
73
87
 
74
- const previous = config as PreviousNeuralwattConfig;
75
- const nestedConfig = config as NeuralwattConfig;
76
- const record = previous as MutableConfigRecord;
88
+ const nestedConfig = config;
89
+ const record = config as unknown as MutableConfigRecord;
77
90
  const nested: NeuralwattConfig = {
78
91
  provider: {
79
92
  ...(isObject(nestedConfig.provider) ? nestedConfig.provider : {}),
@@ -100,14 +113,18 @@ export const flatToNestedConfigMigration: Migration<MigrationConfig> = {
100
113
  };
101
114
  }
102
115
 
103
- const includeHiddenModels = booleanValue(record, "includeHiddenModels");
116
+ // Flat configs predate the rename, so they still use `includeHiddenModels`.
117
+ const includeEarlyAccessModels = booleanValue(
118
+ record,
119
+ "includeHiddenModels",
120
+ );
104
121
  if (
105
- nested.provider?.includeHiddenModels === undefined &&
106
- includeHiddenModels !== undefined
122
+ nested.provider?.includeEarlyAccessModels === undefined &&
123
+ includeEarlyAccessModels !== undefined
107
124
  ) {
108
125
  nested.provider = {
109
126
  ...nested.provider,
110
- includeHiddenModels,
127
+ includeEarlyAccessModels,
111
128
  };
112
129
  }
113
130
 
@@ -0,0 +1,47 @@
1
+ import type { Migration } from "@aliou/pi-utils-settings";
2
+ import type { NeuralwattConfig } from "../types";
3
+
4
+ /** The provider section before `includeHiddenModels` was renamed. */
5
+ interface PreviousProviderConfig {
6
+ includeLegacyModelIds?: boolean;
7
+ includeEarlyAccessModels?: boolean;
8
+ /** Renamed to `includeEarlyAccessModels`. */
9
+ includeHiddenModels?: boolean;
10
+ }
11
+
12
+ function previousProvider(
13
+ config: NeuralwattConfig,
14
+ ): PreviousProviderConfig | undefined {
15
+ if (!("provider" in config)) return undefined;
16
+ const { provider } = config;
17
+ return provider && typeof provider === "object"
18
+ ? (provider as PreviousProviderConfig)
19
+ : undefined;
20
+ }
21
+
22
+ /**
23
+ * `provider.includeHiddenModels` was renamed to `provider.includeEarlyAccessModels`.
24
+ * The models were never hidden, only released to authorized accounts first.
25
+ */
26
+ export const renameHiddenToEarlyAccessMigration: Migration<NeuralwattConfig> = {
27
+ name: "rename-hidden-models-to-early-access",
28
+ shouldRun: (config) =>
29
+ previousProvider(config)?.includeHiddenModels !== undefined,
30
+ message:
31
+ "[neuralwatt] `provider.includeHiddenModels` is now `provider.includeEarlyAccessModels`.",
32
+ run: (config) => {
33
+ const provider = previousProvider(config);
34
+ if (!provider) return config;
35
+
36
+ const { includeHiddenModels, ...rest } = provider;
37
+
38
+ return {
39
+ ...config,
40
+ provider: {
41
+ ...rest,
42
+ includeEarlyAccessModels:
43
+ rest.includeEarlyAccessModels ?? includeHiddenModels,
44
+ },
45
+ };
46
+ },
47
+ };
@@ -1,16 +1,19 @@
1
1
  import type { Migration } from "@aliou/pi-utils-settings";
2
- import type { NeuralwattRawConfig } from "../types";
2
+ import type { NeuralwattConfig } from "../types";
3
3
 
4
4
  export { disableLegacyModelIdsByDefaultMigration } from "./01-disable-legacy-model-ids-by-default";
5
5
  export {
6
6
  backupConfig,
7
7
  flatToNestedConfigMigration,
8
8
  } from "./02-flat-to-nested-config";
9
+ export { renameHiddenToEarlyAccessMigration } from "./03-rename-hidden-to-early-access";
9
10
 
10
11
  import { disableLegacyModelIdsByDefaultMigration } from "./01-disable-legacy-model-ids-by-default";
11
12
  import { flatToNestedConfigMigration } from "./02-flat-to-nested-config";
13
+ import { renameHiddenToEarlyAccessMigration } from "./03-rename-hidden-to-early-access";
12
14
 
13
- export const migrations: Migration<NeuralwattRawConfig>[] = [
15
+ export const migrations: Migration<NeuralwattConfig>[] = [
14
16
  disableLegacyModelIdsByDefaultMigration,
15
17
  flatToNestedConfigMigration,
18
+ renameHiddenToEarlyAccessMigration,
16
19
  ];
@@ -1,29 +1,9 @@
1
- export interface PreviousNeuralwattConfig {
2
- /** $schema URL for editor autocomplete. */
3
- $schema?: string;
4
-
5
- /** Show the quota command (/neuralwatt:quota). */
6
- quotaCommand?: boolean;
7
-
8
- /** Show quota warnings when credits or energy are low. */
9
- quotaWarnings?: boolean;
10
-
11
- /** Show usage in the sub-bar / status bar. */
12
- subBarIntegration?: boolean;
13
-
14
- /** Include legacy Neuralwatt model IDs in the model picker. */
15
- includeLegacyModelIds?: boolean;
16
-
17
- /** Include hidden Neuralwatt models discovered via the authenticated API. */
18
- includeHiddenModels?: boolean;
19
- }
20
-
21
1
  export interface NeuralwattProviderConfig {
22
2
  /** Include legacy Neuralwatt model IDs in the model picker. */
23
3
  includeLegacyModelIds?: boolean;
24
4
 
25
- /** Include hidden Neuralwatt models discovered via the authenticated API. */
26
- includeHiddenModels?: boolean;
5
+ /** Include early-access Neuralwatt models discovered via the authenticated API. */
6
+ includeEarlyAccessModels?: boolean;
27
7
  }
28
8
 
29
9
  export interface NeuralwattQuotaCommandConfig {
@@ -58,12 +38,10 @@ export interface NeuralwattConfig {
58
38
  subBarIntegration?: NeuralwattSubBarIntegrationConfig;
59
39
  }
60
40
 
61
- export type NeuralwattRawConfig = PreviousNeuralwattConfig | NeuralwattConfig;
62
-
63
41
  export interface ResolvedNeuralwattConfig {
64
42
  provider: {
65
43
  includeLegacyModelIds: boolean;
66
- includeHiddenModels: boolean;
44
+ includeEarlyAccessModels: boolean;
67
45
  };
68
46
  quotaCommand: {
69
47
  enabled: boolean;