@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.
- package/extensions/litellm-provider.ts +45 -42
- package/package.json +1 -1
|
@@ -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<
|
|
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
|
-
|
|
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
|
|
158
|
+
// Try next endpoint.
|
|
133
159
|
}
|
|
134
160
|
}
|
|
135
161
|
|
|
136
|
-
|
|
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
|
}
|