@preapexis/pi-kit 1.1.3 → 1.2.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.
@@ -3,29 +3,21 @@ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
3
3
 
4
4
  type LiteLlmModelInfo = {
5
5
  model_name?: string;
6
- litellm_params?: {
7
- model?: string;
8
- };
9
6
  model_info?: {
10
7
  id?: string;
11
8
  name?: string;
12
9
  display_name?: string;
13
- description?: string;
14
10
  max_tokens?: number;
15
11
  max_input_tokens?: number;
16
12
  context_window?: number;
17
13
  input_cost_per_token?: number;
18
14
  output_cost_per_token?: number;
19
15
  supports_vision?: boolean;
20
- supports_function_calling?: boolean;
21
- mode?: string;
22
16
  };
23
17
  };
24
18
 
25
19
  type OpenAiModel = {
26
20
  id?: string;
27
- object?: string;
28
- owned_by?: string;
29
21
  };
30
22
 
31
23
  type ModelPayload = {
@@ -45,10 +37,6 @@ type PiModel = {
45
37
  };
46
38
  contextWindow: number;
47
39
  maxTokens: number;
48
- compat?: {
49
- supportsDeveloperRole?: boolean;
50
- supportsReasoningEffort?: boolean;
51
- };
52
40
  };
53
41
 
54
42
  const PROVIDER_ID = "litellm";
@@ -59,9 +47,13 @@ export default async function (pi: ExtensionAPI): Promise<void> {
59
47
  process.env.LITELLM_BASE_URL ?? DEFAULT_BASE_URL
60
48
  );
61
49
 
62
- async function registerLiteLlmProvider(): Promise<void> {
50
+ async function registerLiteLlmProvider(): Promise<number> {
63
51
  const models = await discoverModels(baseUrl);
64
52
 
53
+ if (models.length === 0) {
54
+ return 0;
55
+ }
56
+
65
57
  pi.registerProvider(PROVIDER_ID, {
66
58
  name: "LiteLLM",
67
59
  baseUrl,
@@ -69,20 +61,54 @@ export default async function (pi: ExtensionAPI): Promise<void> {
69
61
  api: "openai-completions",
70
62
  models
71
63
  });
64
+
65
+ return models.length;
72
66
  }
73
67
 
74
- await registerLiteLlmProvider();
68
+ try {
69
+ const count = await registerLiteLlmProvider();
70
+
71
+ if (count > 0) {
72
+ console.log(`[litellm] Registered ${count} models from ${baseUrl}`);
73
+ } else {
74
+ console.log("[litellm] No models found. Provider was not registered.");
75
+ }
76
+ } catch (error) {
77
+ console.log(
78
+ [
79
+ "[litellm] Provider skipped.",
80
+ error instanceof Error ? error.message : String(error),
81
+ "Start LiteLLM and run /litellm-refresh."
82
+ ].join("\n")
83
+ );
84
+ }
75
85
 
76
86
  pi.registerCommand("litellm-refresh", {
77
87
  description: "Refresh LiteLLM models from the LiteLLM proxy",
78
88
  handler: async (_args, ctx) => {
79
89
  try {
80
- await registerLiteLlmProvider();
90
+ const count = await registerLiteLlmProvider();
91
+
92
+ if (count === 0) {
93
+ ctx.ui.notify(
94
+ [
95
+ "LiteLLM refresh finished, but no models were found.",
96
+ "",
97
+ `Base URL: ${baseUrl}`,
98
+ "",
99
+ "Make sure LiteLLM is running."
100
+ ].join("\n"),
101
+ "warning"
102
+ );
103
+
104
+ return;
105
+ }
81
106
 
82
107
  ctx.ui.notify(
83
108
  [
84
109
  "LiteLLM models refreshed.",
85
110
  "",
111
+ `Models found: ${count}`,
86
112
  `Base URL: ${baseUrl}`,
87
113
  "",
88
114
  "Run /model to select a LiteLLM model."
@@ -129,26 +155,11 @@ async function discoverModels(baseUrl: string): Promise<PiModel[]> {
129
155
  return models;
130
156
  }
131
157
  } catch {
132
- // Try the next endpoint.
158
+ // Try next endpoint.
133
159
  }
134
160
  }
135
161
 
136
- const fallbackModels = getFallbackModels();
137
-
138
- if (fallbackModels.length > 0) {
139
- return fallbackModels;
140
- }
141
-
142
- throw new Error(
143
- [
144
- "Could not discover LiteLLM models.",
145
- "",
146
- `Tried: ${endpoints.join(", ")}`,
147
- "",
148
- "Make sure LiteLLM is running and set LITELLM_API_KEY if your proxy requires auth.",
149
- "You can also set LITELLM_MODELS as a comma-separated fallback."
150
- ].join("\n")
151
- );
162
+ return getFallbackModels();
152
163
  }
153
164
 
154
165
  async function fetchModelPayload(url: string): Promise<ModelPayload> {
@@ -228,11 +239,7 @@ function modelFromPayloadItem(
228
239
  cacheWrite: 0
229
240
  },
230
241
  contextWindow,
231
- maxTokens,
232
- compat: {
233
- supportsDeveloperRole: false,
234
- supportsReasoningEffort: false
235
- }
242
+ maxTokens
236
243
  };
237
244
  }
238
245
 
@@ -293,10 +300,6 @@ function getFallbackModels(): PiModel[] {
293
300
  cacheWrite: 0
294
301
  },
295
302
  contextWindow: 128000,
296
- maxTokens: 4096,
297
- compat: {
298
- supportsDeveloperRole: false,
299
- supportsReasoningEffort: false
300
- }
303
+ maxTokens: 4096
301
304
  }));
302
305
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@preapexis/pi-kit",
3
- "version": "1.1.3",
3
+ "version": "1.2.0",
4
4
  "description": "Personal Pi coding-agent kit with safety extensions, status UI, prompt workflows, skills, and themes.",
5
5
  "keywords": [
6
6
  "pi-package",