pi-nvidia-nim 1.1.22 → 1.1.23

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.
Files changed (3) hide show
  1. package/README.md +17 -12
  2. package/index.ts +70 -91
  3. package/package.json +8 -4
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # pi-nvidia-nim
2
2
 
3
- NVIDIA NIM API provider extension for [pi coding agent](https://github.com/earendil-works/pi-mono) - access 100+ models from [build.nvidia.com](https://build.nvidia.com) including DeepSeek V4 Flash/Pro, DeepSeek V3.2, Kimi K2.6, MiniMax M2.1, GLM-5, GLM-4.7, Qwen3, Llama 4, and many more.
3
+ NVIDIA NIM API provider extension for [pi coding agent](https://github.com/earendil-works/pi-mono) - access 100+ models from [build.nvidia.com](https://build.nvidia.com) including Inkling, MiniMax M3, DeepSeek V4 Flash/Pro, DeepSeek V3.2, Kimi K2.6, GLM-5, GLM-4.7, Qwen3, Llama 4, and many more.
4
4
 
5
5
  https://github.com/user-attachments/assets/f44773e4-9bf8-4bb5-a9c0-d5938030701c
6
6
 
@@ -74,35 +74,40 @@ NVIDIA NIM models use a non-standard `chat_template_kwargs` parameter to enable
74
74
 
75
75
  When you change the thinking level in pi (`Shift+Tab` to cycle), the extension:
76
76
 
77
- 1. **Maps thinking levels** to values each NIM model accepts. For DeepSeek V4, `xhigh` maps to `max`; lower enabled levels use `high`.
77
+ 1. **Maps thinking levels** to values each NIM model accepts. MiniMax M3 uses its native `disabled`/`adaptive`/`enabled` modes; Inkling and DeepSeek V4 map extended levels to `max`.
78
78
  2. **Injects `chat_template_kwargs`** per model to actually enable thinking:
79
+ - Inkling: `{ reasoning_effort: "none" | "minimal" | "low" | "medium" | "high" | "max" }`
80
+ - MiniMax M3: `{ thinking_mode: "disabled" | "adaptive" | "enabled" }`
79
81
  - DeepSeek V4: `{ thinking: true, reasoning_effort: "high" | "max" }`
80
82
  - DeepSeek V3.x, R1 distills: `{ thinking: true }`
81
83
  - GLM-5, GLM-4.7: `{ enable_thinking: true, clear_thinking: false }`
82
84
  - Kimi K2.6, K2-thinking: `{ thinking: true }`
83
85
  - Qwen3, QwQ: `{ enable_thinking: true }`
84
- 3. **Explicitly disables thinking** when the level is "off" for models that think by default (e.g., GLM-5, GLM-4.7).
86
+ 3. **Explicitly selects the lowest/off setting** when thinking is "off" for configurable models. MiniMax M3 uses `disabled`; Inkling uses `none` as a conditioning hint rather than a guarantee of zero reasoning tokens.
85
87
  4. **Uses `system` role** instead of `developer` for all NIM models - the `developer` role combined with `chat_template_kwargs` causes 500 errors on NIM.
86
88
 
87
89
  ### Supported thinking levels
88
90
 
89
91
  | pi Level | NIM Mapping | Effect |
90
92
  |----------|-------------|--------|
91
- | off | No kwargs (or explicit disable) | No reasoning output |
92
- | minimal | low, or high for DeepSeek V4 | Thinking enabled |
93
- | low | low, or high for DeepSeek V4 | Thinking enabled |
94
- | medium | medium, or high for DeepSeek V4 | Thinking enabled |
95
- | high | high | Thinking enabled |
96
- | xhigh | high, or max for DeepSeek V4 | Maximum supported thinking |
93
+ | off | MiniMax M3 `disabled`; Inkling `none`; explicit disable elsewhere | No/lowest reasoning effort |
94
+ | minimal | MiniMax M3 `adaptive`; Inkling `minimal`; low/high where required | Thinking enabled when useful |
95
+ | low | MiniMax M3 `adaptive`; low, or high for DeepSeek V4 | Thinking enabled when useful |
96
+ | medium | MiniMax M3 `adaptive`; medium, or high for DeepSeek V4 | Thinking enabled when useful |
97
+ | high | MiniMax M3 `enabled`; high elsewhere | Thinking enabled |
98
+ | xhigh | MiniMax M3 `enabled`; max for Inkling/DeepSeek V4 | Extended thinking |
99
+ | max | MiniMax M3 `enabled`; max for Inkling/DeepSeek V4 | Maximum supported thinking |
97
100
 
98
101
  ## Available Models
99
102
 
100
- The extension ships with curated metadata for 42 featured models. At startup, it also queries the NVIDIA NIM API to discover additional models automatically.
103
+ The extension ships with curated metadata for 44 featured models. At startup, it also queries the NVIDIA NIM API to discover additional models automatically.
101
104
 
102
105
  ### Featured Models
103
106
 
104
107
  | Model | Reasoning | Vision | Context |
105
108
  |-------|-----------|--------|---------|
109
+ | `thinkingmachines/inkling` | ✅ | ✅ | 1M |
110
+ | `minimaxai/minimax-m3` | ✅ | ✅ | 1M |
106
111
  | `deepseek-ai/deepseek-v4-flash` | ✅ | | 1M |
107
112
  | `deepseek-ai/deepseek-v4-pro` | ✅ | | 1M |
108
113
  | `deepseek-ai/deepseek-v3.2` | ✅ | | 128K |
@@ -138,7 +143,7 @@ This extension uses `pi.registerProvider()` to register NVIDIA NIM as a custom p
138
143
  The custom streamer:
139
144
  1. Intercepts the request payload via `onPayload` callback
140
145
  2. Injects `chat_template_kwargs` for models that need it to enable thinking
141
- 3. Maps unsupported thinking levels to NIM-compatible values (`minimal` `low`; `xhigh` `high` or DeepSeek V4 `max`)
146
+ 3. Maps unsupported thinking levels to NIM-compatible values while preserving MiniMax M3's native modes and Inkling's native effort presets
142
147
  4. Suppresses `reasoning_effort` for models that don't respond to it (e.g., DeepSeek without kwargs)
143
148
  5. Uses the standard OpenAI SSE streaming format - pi already parses `reasoning_content` and `reasoning` fields from streaming deltas
144
149
 
@@ -153,7 +158,7 @@ The only configuration needed is either the `NVIDIA_NIM_API_KEY` or `NVIDIA_API_
153
158
  - If a model isn't in the curated list, it gets a conservative 32K context window and 8K max output tokens
154
159
  - The extension filters out embedding, reward, safety, and other non-chat models automatically
155
160
  - Rate limits on free preview keys are relatively strict; you may encounter 429 errors during heavy usage
156
- - MiniMax models use `<think>` tags inline in content rather than the `reasoning_content` field
161
+ - MiniMax M3 streams thinking through `reasoning_content`; older MiniMax models may use `<think>` tags inline in content
157
162
 
158
163
  ## License
159
164
 
package/index.ts CHANGED
@@ -34,17 +34,16 @@
34
34
  * thinking settings.
35
35
  */
36
36
 
37
- import { existsSync, readFileSync } from "node:fs";
38
- import { join } from "node:path";
39
37
  import type {
40
38
  Api,
41
39
  AssistantMessageEventStream,
42
40
  Context,
43
41
  Model,
44
42
  SimpleStreamOptions,
43
+ ThinkingLevelMap,
45
44
  } from "@earendil-works/pi-ai";
46
- import { streamSimpleOpenAICompletions } from "@earendil-works/pi-ai";
47
- import { getAgentDir, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
45
+ import { streamSimpleOpenAICompletions } from "@earendil-works/pi-ai/compat";
46
+ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
48
47
 
49
48
  // =============================================================================
50
49
  // Constants
@@ -55,6 +54,8 @@ const NVIDIA_NIM_API_KEY_ENV = "NVIDIA_NIM_API_KEY";
55
54
  const NVIDIA_API_KEY_ENV = "NVIDIA_API_KEY";
56
55
  const NVIDIA_API_KEY_ENV_NAMES = [NVIDIA_NIM_API_KEY_ENV, NVIDIA_API_KEY_ENV] as const;
57
56
  const PROVIDER_NAME = "nvidia-nim";
57
+ const INKLING_MODEL_ID = "thinkingmachines/inkling";
58
+ const MINIMAX_M3_MODEL_ID = "minimaxai/minimax-m3";
58
59
 
59
60
  // =============================================================================
60
61
  // Per-model thinking configuration
@@ -185,7 +186,11 @@ const THINKING_CONFIGS: Record<string, ThinkingConfig> = {
185
186
  // Reasoning models and their capabilities
186
187
  // =============================================================================
187
188
 
188
- const REASONING_MODELS = new Set(Object.keys(THINKING_CONFIGS));
189
+ const REASONING_MODELS = new Set([
190
+ ...Object.keys(THINKING_CONFIGS),
191
+ INKLING_MODEL_ID,
192
+ MINIMAX_M3_MODEL_ID,
193
+ ]);
189
194
 
190
195
  // Models known to support image/vision input
191
196
  const VISION_MODELS = new Set([
@@ -197,6 +202,8 @@ const VISION_MODELS = new Set([
197
202
  "nvidia/llama-3.1-nemotron-nano-vl-8b-v1",
198
203
  "nvidia/nemotron-nano-12b-v2-vl",
199
204
  "nvidia/cosmos-reason2-8b",
205
+ INKLING_MODEL_ID,
206
+ MINIMAX_M3_MODEL_ID,
200
207
  ]);
201
208
 
202
209
  // Embedding / non-chat models to skip
@@ -269,6 +276,7 @@ const CONTEXT_WINDOWS: Record<string, number> = {
269
276
  "minimaxai/minimax-m2": 1048576,
270
277
  "minimaxai/minimax-m2.1": 1048576,
271
278
  "minimaxai/minimax-m2.7": 204800,
279
+ [MINIMAX_M3_MODEL_ID]: 1_048_576,
272
280
  // Meta Llama
273
281
  "meta/llama-3.1-405b-instruct": 131072,
274
282
  "meta/llama-3.1-70b-instruct": 131072,
@@ -339,6 +347,8 @@ const CONTEXT_WINDOWS: Record<string, number> = {
339
347
  "nvidia/llama-3.3-nemotron-super-49b-v1.5": 131072,
340
348
  "nvidia/nemotron-4-340b-instruct": 4096,
341
349
  "nvidia/nvidia-nemotron-nano-9b-v2": 131072,
350
+ // Thinking Machines
351
+ [INKLING_MODEL_ID]: 1_048_576,
342
352
  // OpenAI open-source
343
353
  "openai/gpt-oss-120b": 131072,
344
354
  "openai/gpt-oss-20b": 131072,
@@ -396,6 +406,7 @@ const MAX_TOKENS: Record<string, number> = {
396
406
  "minimaxai/minimax-m2": 8192,
397
407
  "minimaxai/minimax-m2.1": 8192,
398
408
  "minimaxai/minimax-m2.7": 8192,
409
+ [MINIMAX_M3_MODEL_ID]: 16_384,
399
410
  "meta/llama-4-maverick-17b-128e-instruct": 16384,
400
411
  "meta/llama-4-scout-17b-16e-instruct": 16384,
401
412
  "z-ai/glm4.7": 16384,
@@ -406,6 +417,7 @@ const MAX_TOKENS: Record<string, number> = {
406
417
  "openai/gpt-oss-20b": 16384,
407
418
  "mistralai/mistral-large-3-675b-instruct-2512": 16384,
408
419
  "mistralai/devstral-2-123b-instruct-2512": 32768,
420
+ [INKLING_MODEL_ID]: 16_384,
409
421
  };
410
422
 
411
423
  // =============================================================================
@@ -423,6 +435,7 @@ const FEATURED_MODELS = [
423
435
  "moonshotai/kimi-k2-thinking",
424
436
  "moonshotai/kimi-k2-instruct",
425
437
  "moonshotai/kimi-k2-instruct-0905",
438
+ MINIMAX_M3_MODEL_ID,
426
439
  "minimaxai/minimax-m2.1",
427
440
  "minimaxai/minimax-m2",
428
441
  "minimaxai/minimax-m2.7",
@@ -432,6 +445,7 @@ const FEATURED_MODELS = [
432
445
  "openai/gpt-oss-20b",
433
446
  "stepfun-ai/step-3.5-flash",
434
447
  "bytedance/seed-oss-36b-instruct",
448
+ INKLING_MODEL_ID,
435
449
  // Qwen
436
450
  "qwen/qwen3-coder-480b-a35b-instruct",
437
451
  "qwen/qwen3-235b-a22b",
@@ -479,14 +493,6 @@ const FEATURED_MODELS = [
479
493
  * 4. Uses onPayload callback to mutate request params before they're sent
480
494
  */
481
495
  type NimApiKeyEnvName = (typeof NVIDIA_API_KEY_ENV_NAMES)[number];
482
- type AuthStorageLike = {
483
- get?: (provider: string) => unknown;
484
- };
485
-
486
- interface NimApiKeyCredential {
487
- type: "api_key";
488
- key: string;
489
- }
490
496
 
491
497
  function getNimApiKeyEnv(): NimApiKeyEnvName | undefined {
492
498
  return NVIDIA_API_KEY_ENV_NAMES.find((envName) => !!process.env[envName]);
@@ -521,57 +527,6 @@ function resolveNimApiKeyEnvReference(value: string): string | undefined {
521
527
  return envValue || undefined;
522
528
  }
523
529
 
524
- function isNimApiKeyEnvValue(value: string): boolean {
525
- return NVIDIA_API_KEY_ENV_NAMES.some((envName) => process.env[envName]?.trim() === value);
526
- }
527
-
528
- function isNimApiKeyCredential(credential: unknown): credential is NimApiKeyCredential {
529
- return (
530
- typeof credential === "object" &&
531
- credential !== null &&
532
- (credential as { type?: unknown }).type === "api_key" &&
533
- typeof (credential as { key?: unknown }).key === "string"
534
- );
535
- }
536
-
537
- function readStoredNimApiKeyConfig(): string | undefined {
538
- try {
539
- const authPath = join(getAgentDir(), "auth.json");
540
- if (!existsSync(authPath)) return undefined;
541
-
542
- const data = JSON.parse(readFileSync(authPath, "utf-8")) as Record<string, unknown>;
543
- const credential = data[PROVIDER_NAME];
544
- return isNimApiKeyCredential(credential) ? credential.key : undefined;
545
- } catch {
546
- return undefined;
547
- }
548
- }
549
-
550
- function getStoredNimApiKeyConfig(authStorage?: AuthStorageLike): string | undefined {
551
- if (authStorage) {
552
- try {
553
- const credential = authStorage.get?.(PROVIDER_NAME);
554
- return isNimApiKeyCredential(credential) ? credential.key : undefined;
555
- } catch {
556
- return undefined;
557
- }
558
- }
559
-
560
- return readStoredNimApiKeyConfig();
561
- }
562
-
563
- function hasStoredNimCommandCredential(authStorage?: AuthStorageLike): boolean {
564
- return getStoredNimApiKeyConfig(authStorage)?.startsWith("!") ?? false;
565
- }
566
-
567
- function getStoredResolvedNimApiKey(authStorage?: AuthStorageLike): string | undefined {
568
- const configuredApiKey = getStoredNimApiKeyConfig(authStorage)?.trim();
569
- if (!configuredApiKey || configuredApiKey.startsWith("!")) return undefined;
570
-
571
- const envValue = process.env[configuredApiKey]?.trim();
572
- return envValue || configuredApiKey;
573
- }
574
-
575
530
  function normalizeResolvedNimApiKey(apiKey: string | undefined): string | undefined {
576
531
  if (apiKey === undefined) return undefined;
577
532
 
@@ -583,23 +538,17 @@ function normalizeResolvedNimApiKey(apiKey: string | undefined): string | undefi
583
538
  return trimmed;
584
539
  }
585
540
 
586
- function resolveNimApiKey(apiKey: string | undefined, authStorage?: AuthStorageLike): string | undefined {
541
+ function resolveNimApiKey(apiKey: string | undefined): string | undefined {
587
542
  const resolvedApiKey = normalizeResolvedNimApiKey(apiKey);
588
- const hasStoredCommandCredential = hasStoredNimCommandCredential(authStorage);
589
-
590
- if (
591
- hasStoredCommandCredential &&
592
- (!resolvedApiKey || isNimApiKeyEnvPlaceholder(resolvedApiKey) || isNimApiKeyEnvValue(resolvedApiKey))
593
- ) {
594
- throw new Error("NVIDIA NIM API key command resolved to an empty value.");
595
- }
596
-
597
- const storedApiKey = getStoredResolvedNimApiKey(authStorage);
598
- if (storedApiKey && (!resolvedApiKey || isNimApiKeyEnvPlaceholder(resolvedApiKey))) return storedApiKey;
599
543
 
600
544
  if (resolvedApiKey) {
601
545
  const envReferenceApiKey = resolveNimApiKeyEnvReference(resolvedApiKey);
602
546
  if (envReferenceApiKey) return envReferenceApiKey;
547
+
548
+ if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(resolvedApiKey) && Object.hasOwn(process.env, resolvedApiKey)) {
549
+ return normalizeResolvedNimApiKey(process.env[resolvedApiKey]);
550
+ }
551
+
603
552
  if (!isNimApiKeyEnvPlaceholder(resolvedApiKey)) return resolvedApiKey;
604
553
  }
605
554
 
@@ -642,7 +591,7 @@ function buildNimRequestHeaders(headers: SimpleStreamOptions["headers"], apiKey:
642
591
  const resolvedHeaders: Record<string, string> = {};
643
592
 
644
593
  for (const [key, value] of Object.entries(headers ?? {})) {
645
- if (key.toLowerCase() === "authorization") continue;
594
+ if (key.toLowerCase() === "authorization" || value === null) continue;
646
595
  resolvedHeaders[key] = value;
647
596
  }
648
597
 
@@ -669,9 +618,9 @@ function nimStreamSimple(
669
618
  const reasoning = options?.reasoning;
670
619
  const isThinkingEnabled = !!reasoning;
671
620
 
672
- // Map provider-agnostic pi levels to NIM's accepted top-level values.
673
- // Model-specific chat_template_kwargs may apply a different mapping below.
674
- const mappedReasoning = mapNimTopLevelReasoning(reasoning);
621
+ // Custom NIM thinking configs use the provider-wide effort mapping. Models that
622
+ // declare native chat-template compatibility keep their own named levels.
623
+ const mappedReasoning = thinkingConfig ? mapNimTopLevelReasoning(reasoning) : reasoning;
675
624
 
676
625
  // For models that have a thinking config: we handle thinking via chat_template_kwargs.
677
626
  // Suppress reasoning_effort (set reasoning to undefined) unless the model explicitly
@@ -743,6 +692,7 @@ interface NimModelEntry {
743
692
  id: string;
744
693
  name: string;
745
694
  reasoning: boolean;
695
+ thinkingLevelMap?: ThinkingLevelMap;
746
696
  input: ("text" | "image")[];
747
697
  contextWindow: number;
748
698
  maxTokens: number;
@@ -788,6 +738,35 @@ function buildModelEntry(modelId: string): NimModelEntry | null {
788
738
  maxTokensField: "max_tokens",
789
739
  };
790
740
 
741
+ // Inkling conditions reasoning through its chat template rather than a top-level
742
+ // reasoning_effort field. NVIDIA NIM accepts the same named effort presets as
743
+ // Inkling's tokenizer; map pi's extended levels to Inkling's 0.99 preset.
744
+ if (modelId === INKLING_MODEL_ID) {
745
+ entry.thinkingLevelMap = { off: "none", xhigh: "max", max: "max" };
746
+ entry.compat.thinkingFormat = "chat-template";
747
+ entry.compat.chatTemplateKwargs = {
748
+ reasoning_effort: { $var: "thinking.effort" },
749
+ };
750
+ }
751
+
752
+ // MiniMax M3 exposes discrete disabled/adaptive/enabled reasoning modes through
753
+ // chat_template_kwargs.thinking_mode. Map pi's effort scale to the closest mode.
754
+ if (modelId === MINIMAX_M3_MODEL_ID) {
755
+ entry.thinkingLevelMap = {
756
+ off: "disabled",
757
+ minimal: "adaptive",
758
+ low: "adaptive",
759
+ medium: "adaptive",
760
+ high: "enabled",
761
+ xhigh: "enabled",
762
+ max: "enabled",
763
+ };
764
+ entry.compat.thinkingFormat = "chat-template";
765
+ entry.compat.chatTemplateKwargs = {
766
+ thinking_mode: { $var: "thinking.effort" },
767
+ };
768
+ }
769
+
791
770
  // Mistral models on NIM need extra compat flags
792
771
  if (modelId.startsWith("mistralai/")) {
793
772
  entry.compat.requiresToolResultName = true;
@@ -819,14 +798,17 @@ function sanitizeNimLogMessage(message: string): string {
819
798
  return message.replace(/nvapi-[A-Za-z0-9._-]+/g, "nvapi-[REDACTED]");
820
799
  }
821
800
 
822
- function notifyNimDiscoveryCredentialWarning(ctx: any): void {
823
- ctx?.ui?.notify?.(NIM_DISCOVERY_CREDENTIAL_WARNING, "warning");
801
+ function notifyNimDiscoveryCredentialWarning(ctx: ExtensionContext): void {
802
+ ctx.ui.notify(NIM_DISCOVERY_CREDENTIAL_WARNING, "warning");
824
803
  }
825
804
 
826
- async function resolveNimDiscoveryApiKey(ctx: any): Promise<string | undefined> {
805
+ async function resolveNimDiscoveryApiKey(ctx: ExtensionContext): Promise<string | undefined> {
827
806
  try {
828
- const apiKey = await ctx?.modelRegistry?.getApiKeyForProvider?.(PROVIDER_NAME);
829
- return resolveNimApiKey(apiKey, ctx?.modelRegistry?.authStorage);
807
+ const apiKey = await ctx.modelRegistry.getApiKeyForProvider(PROVIDER_NAME);
808
+ if (apiKey === undefined && ctx.modelRegistry.getProviderAuthStatus(PROVIDER_NAME).configured) {
809
+ throw new Error("NVIDIA NIM configured credential resolved to an empty value.");
810
+ }
811
+ return resolveNimApiKey(apiKey);
830
812
  } catch (error) {
831
813
  const message = error instanceof Error ? error.message : String(error);
832
814
  console.warn(`pi-nvidia-nim: ${sanitizeNimLogMessage(message)}`);
@@ -901,7 +883,7 @@ export default function (pi: ExtensionAPI) {
901
883
  });
902
884
 
903
885
  // On session start, discover additional models from the API
904
- pi.on("session_start", async (_event: any, ctx: any) => {
886
+ pi.on("session_start", async (_event, ctx) => {
905
887
  const apiKey = await resolveNimDiscoveryApiKey(ctx);
906
888
  if (!apiKey) return;
907
889
 
@@ -927,13 +909,10 @@ export default function (pi: ExtensionAPI) {
927
909
  }
928
910
  }
929
911
 
930
- // Re-register with full model list if we found new ones.
931
- // NOTE: must use ctx.modelRegistry.registerProvider() here, not pi.registerProvider().
932
- // pi.registerProvider() only queues registrations for the initial extension load.
933
- // From event handlers/commands, we need to call the registry directly.
912
+ // Runtime provider registrations now apply immediately through the extension API.
934
913
  if (newModelsAdded > 0) {
935
914
  const allModels = Array.from(modelMap.values());
936
- ctx.modelRegistry.registerProvider(PROVIDER_NAME, {
915
+ pi.registerProvider(PROVIDER_NAME, {
937
916
  baseUrl: NVIDIA_NIM_BASE_URL,
938
917
  apiKey: getNimProviderApiKeyConfig(),
939
918
  api: "openai-completions",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-nvidia-nim",
3
- "version": "1.1.22",
3
+ "version": "1.1.23",
4
4
  "description": "NVIDIA NIM API provider extension for pi coding agent — access 100+ models from build.nvidia.com",
5
5
  "type": "module",
6
6
  "files": [
@@ -23,11 +23,15 @@
23
23
  "test": "node --test test/*.test.mjs"
24
24
  },
25
25
  "devDependencies": {
26
- "@earendil-works/pi-ai": "^0.74.0",
27
- "@earendil-works/pi-coding-agent": "^0.74.0",
28
- "@types/node": "^22.0.0",
26
+ "@earendil-works/pi-ai": "^0.80.10",
27
+ "@earendil-works/pi-coding-agent": "^0.80.10",
28
+ "@types/node": "^24.0.0",
29
29
  "typescript": "^6.0.3"
30
30
  },
31
+ "peerDependencies": {
32
+ "@earendil-works/pi-ai": "*",
33
+ "@earendil-works/pi-coding-agent": "*"
34
+ },
31
35
  "repository": {
32
36
  "type": "git",
33
37
  "url": "https://github.com/xRyul/pi-nvidia-nim.git"