pi-provider-litellm 2.2.0 → 2.2.1
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 +1 -0
- package/dist/discover.d.ts +1 -1
- package/dist/discover.js +3 -3
- package/dist/index.js +33 -20
- package/dist/mcp-tools.d.ts +2 -2
- package/dist/mcp-tools.js +8 -8
- package/dist/skills.d.ts +3 -3
- package/dist/skills.js +9 -9
- package/dist/types.d.ts +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -115,6 +115,7 @@ Provider fields:
|
|
|
115
115
|
| `headers` | `$LITELLM_HEADERS` for `litellm`; unset for aliases | JSON string env reference or inline object of request headers |
|
|
116
116
|
| `displayName` | provider name | Label shown in Pi UI |
|
|
117
117
|
| `enabled` | `true` | Set `false` to skip an alias |
|
|
118
|
+
| `allowInsecureHttp` | `false` | Set `true` to permit plaintext HTTP for this provider, for example `http://host.docker.internal`. Credentials and request data will not be encrypted. Loopback HTTP works without this setting. |
|
|
118
119
|
|
|
119
120
|
`/login litellm` and Google ADC token auth remain scoped to the default `litellm` provider. Aliases use their configured `apiKey` or manually stored auth entries matching the alias name.
|
|
120
121
|
|
package/dist/discover.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Api, Model } from "@earendil-works/pi-ai";
|
|
2
2
|
import type { DiscoveredModel, DiscoveryOptions, DiscoveryResult } from "./types.js";
|
|
3
|
-
export declare function normalizeBaseUrl(input: string): string;
|
|
3
|
+
export declare function normalizeBaseUrl(input: string, allowInsecureHttp?: boolean): string;
|
|
4
4
|
export declare function isMoonshotModel(modelId: string): boolean;
|
|
5
5
|
export declare function isGpt55Model(modelId: string): boolean;
|
|
6
6
|
export declare function shouldSuppressReasoningContent(modelId: string): boolean;
|
package/dist/discover.js
CHANGED
|
@@ -4,11 +4,11 @@ const DEFAULT_TIMEOUT_MS = 5000;
|
|
|
4
4
|
const DEFAULT_CONTEXT_WINDOW = 128_000;
|
|
5
5
|
const DEFAULT_MAX_TOKENS = 16_384;
|
|
6
6
|
const KNOWN_PROVIDER_SET = new Set(getProviders());
|
|
7
|
-
export function normalizeBaseUrl(input) {
|
|
7
|
+
export function normalizeBaseUrl(input, allowInsecureHttp = false) {
|
|
8
8
|
const url = new URL(input);
|
|
9
9
|
const hostname = url.hostname.toLowerCase();
|
|
10
10
|
const loopback = hostname === "localhost" || hostname === "[::1]" || (isIP(hostname) === 4 && hostname.startsWith("127."));
|
|
11
|
-
if (url.protocol !== "https:" && !(url.protocol === "http:" && loopback)) {
|
|
11
|
+
if (url.protocol !== "https:" && !(url.protocol === "http:" && (loopback || allowInsecureHttp))) {
|
|
12
12
|
throw new Error("LiteLLM base URL must use HTTPS except for loopback hosts");
|
|
13
13
|
}
|
|
14
14
|
return input.replace(/\/+$/, "").replace(/\/v1\/?$/i, "");
|
|
@@ -275,7 +275,7 @@ function deduplicateModels(models) {
|
|
|
275
275
|
});
|
|
276
276
|
}
|
|
277
277
|
export async function discoverModels(baseUrl, apiKey, options = {}) {
|
|
278
|
-
const base = normalizeBaseUrl(baseUrl);
|
|
278
|
+
const base = normalizeBaseUrl(baseUrl, options.allowInsecureHttp);
|
|
279
279
|
const progress = options.silent ? undefined : options.onProgress;
|
|
280
280
|
progress?.("Querying /model/info endpoint...");
|
|
281
281
|
const infoResult = await fetchJson(`${base}/model/info`, apiKey, options);
|
package/dist/index.js
CHANGED
|
@@ -335,7 +335,7 @@ async function resolveCredentials(definition, { executeHelpers = true } = {}) {
|
|
|
335
335
|
apiKeyConfig = `$${ENV_API_KEY}`;
|
|
336
336
|
}
|
|
337
337
|
return {
|
|
338
|
-
baseUrl: configuredBase ? normalizeBaseUrl(configuredBase) : undefined,
|
|
338
|
+
baseUrl: configuredBase ? normalizeBaseUrl(configuredBase, definition.allowInsecureHttp) : undefined,
|
|
339
339
|
apiKey: apiKey || undefined,
|
|
340
340
|
apiKeyConfig,
|
|
341
341
|
};
|
|
@@ -393,6 +393,7 @@ function getProviderDefinitions(settings) {
|
|
|
393
393
|
useDefaultEnv: isDefault,
|
|
394
394
|
useGcloudTokenAuth: isDefault,
|
|
395
395
|
enableOAuth: isDefault,
|
|
396
|
+
allowInsecureHttp: raw?.allowInsecureHttp === true,
|
|
396
397
|
});
|
|
397
398
|
const definitions = [makeDefinition(PROVIDER_NAME, defaultSettings, true)];
|
|
398
399
|
for (const [name, raw] of Object.entries(providerSettings ?? {})) {
|
|
@@ -405,7 +406,7 @@ function getProviderDefinitions(settings) {
|
|
|
405
406
|
}
|
|
406
407
|
return definitions;
|
|
407
408
|
}
|
|
408
|
-
async function loginApiKey(interaction) {
|
|
409
|
+
async function loginApiKey(interaction, allowInsecureHttp = false) {
|
|
409
410
|
const rawBaseUrl = (await interaction.prompt({
|
|
410
411
|
type: "text",
|
|
411
412
|
message: "Enter LiteLLM proxy URL (no trailing /v1):",
|
|
@@ -416,7 +417,7 @@ async function loginApiKey(interaction) {
|
|
|
416
417
|
const key = (await interaction.prompt({ type: "secret", message: "Enter API key:" })).trim();
|
|
417
418
|
if (!key)
|
|
418
419
|
throw new Error("Both base URL and API key are required");
|
|
419
|
-
return { type: "api_key", key, env: { [ENV_BASE_URL]: normalizeBaseUrl(rawBaseUrl) } };
|
|
420
|
+
return { type: "api_key", key, env: { [ENV_BASE_URL]: normalizeBaseUrl(rawBaseUrl, allowInsecureHttp) } };
|
|
420
421
|
}
|
|
421
422
|
async function startCliSso(baseUrl, signal, headers) {
|
|
422
423
|
const response = await fetch(`${baseUrl}/sso/cli/start`, {
|
|
@@ -559,7 +560,7 @@ async function loginWithPastedToken(interaction, baseUrl, headers) {
|
|
|
559
560
|
}
|
|
560
561
|
return { type: "oauth", access, refresh: "", expires, baseUrl };
|
|
561
562
|
}
|
|
562
|
-
async function loginOAuth(interaction, headers) {
|
|
563
|
+
async function loginOAuth(interaction, headers, allowInsecureHttp = false) {
|
|
563
564
|
const rawBaseUrl = (await interaction.prompt({
|
|
564
565
|
type: "text",
|
|
565
566
|
message: "Enter LiteLLM proxy URL (no trailing /v1):",
|
|
@@ -567,7 +568,7 @@ async function loginOAuth(interaction, headers) {
|
|
|
567
568
|
})).trim();
|
|
568
569
|
if (!rawBaseUrl)
|
|
569
570
|
throw new Error("Base URL is required");
|
|
570
|
-
const baseUrl = normalizeBaseUrl(rawBaseUrl);
|
|
571
|
+
const baseUrl = normalizeBaseUrl(rawBaseUrl, allowInsecureHttp);
|
|
571
572
|
const cliSso = await startCliSso(baseUrl, interaction.signal, headers);
|
|
572
573
|
if (!cliSso)
|
|
573
574
|
return loginWithPastedToken(interaction, baseUrl, headers);
|
|
@@ -610,7 +611,7 @@ async function resolveApiKeyAuth(definition, ctx, credential, executeHelpers = t
|
|
|
610
611
|
if (stored) {
|
|
611
612
|
source = "stored credential";
|
|
612
613
|
creds = {
|
|
613
|
-
baseUrl: baseUrl ? normalizeBaseUrl(baseUrl) : undefined,
|
|
614
|
+
baseUrl: baseUrl ? normalizeBaseUrl(baseUrl, definition.allowInsecureHttp) : undefined,
|
|
614
615
|
apiKey: stored,
|
|
615
616
|
};
|
|
616
617
|
}
|
|
@@ -647,7 +648,7 @@ async function resolveApiKeyAuth(definition, ctx, credential, executeHelpers = t
|
|
|
647
648
|
}
|
|
648
649
|
}
|
|
649
650
|
if (!creds.baseUrl && baseUrl)
|
|
650
|
-
creds.baseUrl = normalizeBaseUrl(baseUrl);
|
|
651
|
+
creds.baseUrl = normalizeBaseUrl(baseUrl, definition.allowInsecureHttp);
|
|
651
652
|
}
|
|
652
653
|
if (!creds.apiKey)
|
|
653
654
|
return undefined;
|
|
@@ -657,7 +658,7 @@ async function resolveApiKeyAuth(definition, ctx, credential, executeHelpers = t
|
|
|
657
658
|
baseUrl: creds.baseUrl ? `${creds.baseUrl}/v1` : undefined,
|
|
658
659
|
headers: await resolveHeadersFromContext(definition, ctx.env),
|
|
659
660
|
},
|
|
660
|
-
env: baseUrl ? { [ENV_BASE_URL]: normalizeBaseUrl(baseUrl) } : undefined,
|
|
661
|
+
env: baseUrl ? { [ENV_BASE_URL]: normalizeBaseUrl(baseUrl, definition.allowInsecureHttp) } : undefined,
|
|
661
662
|
source: source ?? creds.apiKeyConfig ?? ENV_API_KEY,
|
|
662
663
|
};
|
|
663
664
|
}
|
|
@@ -665,7 +666,9 @@ function createProviderAuth(definition) {
|
|
|
665
666
|
return {
|
|
666
667
|
apiKey: {
|
|
667
668
|
name: `${definition.displayName} API key`,
|
|
668
|
-
login: definition.name === PROVIDER_NAME
|
|
669
|
+
login: definition.name === PROVIDER_NAME
|
|
670
|
+
? (interaction) => loginApiKey(interaction, definition.allowInsecureHttp)
|
|
671
|
+
: undefined,
|
|
669
672
|
check: async ({ ctx, credential }) => {
|
|
670
673
|
const baseUrl = credential?.env?.[ENV_BASE_URL] ??
|
|
671
674
|
definition.baseUrl ??
|
|
@@ -701,14 +704,16 @@ function createProviderAuth(definition) {
|
|
|
701
704
|
? {
|
|
702
705
|
name: "LiteLLM SSO",
|
|
703
706
|
loginLabel: "Sign in with LiteLLM SSO",
|
|
704
|
-
login: (interaction) => loginOAuth(interaction, resolveHeaders(definition)),
|
|
707
|
+
login: (interaction) => loginOAuth(interaction, resolveHeaders(definition), definition.allowInsecureHttp),
|
|
705
708
|
refresh: async (credential, signal) => ({
|
|
706
709
|
...(await refreshLiteLLM(credential, signal)),
|
|
707
710
|
type: "oauth",
|
|
708
711
|
}),
|
|
709
712
|
toAuth: async (credential) => ({
|
|
710
713
|
apiKey: credential.access,
|
|
711
|
-
baseUrl: credential.baseUrl
|
|
714
|
+
baseUrl: credential.baseUrl
|
|
715
|
+
? `${normalizeBaseUrl(String(credential.baseUrl), definition.allowInsecureHttp)}/v1`
|
|
716
|
+
: undefined,
|
|
712
717
|
headers: resolveHeaders(definition),
|
|
713
718
|
}),
|
|
714
719
|
}
|
|
@@ -939,23 +944,29 @@ export default async function (pi) {
|
|
|
939
944
|
const baseUrl = cleanConfig(definition.baseUrl) ??
|
|
940
945
|
(definition.useDefaultEnv ? cleanConfig(process.env[ENV_BASE_URL]) : undefined) ??
|
|
941
946
|
"https://litellm.example.com";
|
|
942
|
-
return `${normalizeBaseUrl(baseUrl)}/v1`;
|
|
947
|
+
return `${normalizeBaseUrl(baseUrl, definition.allowInsecureHttp)}/v1`;
|
|
943
948
|
}
|
|
944
949
|
async function authForCredential(definition, credential, executeHelpers = true) {
|
|
945
950
|
if (credential?.type === "oauth") {
|
|
946
951
|
const baseUrl = typeof credential.baseUrl === "string"
|
|
947
|
-
? normalizeBaseUrl(credential.baseUrl)
|
|
948
|
-
: normalizeBaseUrl(requestBaseUrl(definition));
|
|
949
|
-
return {
|
|
952
|
+
? normalizeBaseUrl(credential.baseUrl, definition.allowInsecureHttp)
|
|
953
|
+
: normalizeBaseUrl(requestBaseUrl(definition), definition.allowInsecureHttp);
|
|
954
|
+
return {
|
|
955
|
+
baseUrl,
|
|
956
|
+
apiKey: credential.access,
|
|
957
|
+
headers: resolveHeaders(definition),
|
|
958
|
+
allowInsecureHttp: definition.allowInsecureHttp,
|
|
959
|
+
};
|
|
950
960
|
}
|
|
951
961
|
const resolved = await resolveApiKeyAuth(definition, { env: async (name) => process.env[name] }, credential, executeHelpers);
|
|
952
962
|
if (!resolved?.auth.apiKey) {
|
|
953
963
|
throw new Error(`no credentials for ${definition.name}. Run /login litellm or set env vars.`);
|
|
954
964
|
}
|
|
955
965
|
return {
|
|
956
|
-
baseUrl: normalizeBaseUrl(resolved.auth.baseUrl ?? requestBaseUrl(definition)),
|
|
966
|
+
baseUrl: normalizeBaseUrl(resolved.auth.baseUrl ?? requestBaseUrl(definition), definition.allowInsecureHttp),
|
|
957
967
|
apiKey: resolved.auth.apiKey,
|
|
958
968
|
headers: resolved.auth.headers,
|
|
969
|
+
allowInsecureHttp: definition.allowInsecureHttp,
|
|
959
970
|
};
|
|
960
971
|
}
|
|
961
972
|
let registeredMcpIdentity;
|
|
@@ -963,7 +974,7 @@ export default async function (pi) {
|
|
|
963
974
|
let defaultRuntimeAuth;
|
|
964
975
|
function mcpCatalogIdentity(auth) {
|
|
965
976
|
return JSON.stringify({
|
|
966
|
-
baseUrl: normalizeBaseUrl(auth.baseUrl),
|
|
977
|
+
baseUrl: normalizeBaseUrl(auth.baseUrl, auth.allowInsecureHttp),
|
|
967
978
|
apiKey: auth.apiKey,
|
|
968
979
|
headers: Object.entries(auth.headers ?? {}).sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0)),
|
|
969
980
|
});
|
|
@@ -979,9 +990,10 @@ export default async function (pi) {
|
|
|
979
990
|
return undefined;
|
|
980
991
|
const headers = Object.fromEntries(Object.entries(auth.auth.headers ?? provider?.headers ?? {}).filter((entry) => typeof entry[1] === "string"));
|
|
981
992
|
return {
|
|
982
|
-
baseUrl: normalizeBaseUrl(baseUrl),
|
|
993
|
+
baseUrl: normalizeBaseUrl(baseUrl, definitions[0]?.allowInsecureHttp),
|
|
983
994
|
apiKey,
|
|
984
995
|
headers: Object.keys(headers).length > 0 ? headers : undefined,
|
|
996
|
+
allowInsecureHttp: definitions[0]?.allowInsecureHttp,
|
|
985
997
|
};
|
|
986
998
|
}
|
|
987
999
|
async function resolveDefaultRuntimeAuth(ctx) {
|
|
@@ -1056,11 +1068,12 @@ export default async function (pi) {
|
|
|
1056
1068
|
timeoutMs: getDiscoveryTimeoutMs(),
|
|
1057
1069
|
signal,
|
|
1058
1070
|
headers: auth.headers,
|
|
1071
|
+
allowInsecureHttp: auth.allowInsecureHttp,
|
|
1059
1072
|
silent: !isVerboseDiscovery(),
|
|
1060
1073
|
onProgress: isVerboseDiscovery() ? (message) => process.stderr.write(`LiteLLM: ${message}\n`) : undefined,
|
|
1061
1074
|
});
|
|
1062
1075
|
signal?.throwIfAborted();
|
|
1063
|
-
return { ...result, baseUrl: `${normalizeBaseUrl(auth.baseUrl)}/v1` };
|
|
1076
|
+
return { ...result, baseUrl: `${normalizeBaseUrl(auth.baseUrl, auth.allowInsecureHttp)}/v1` };
|
|
1064
1077
|
}
|
|
1065
1078
|
// Pi's startup path only ever refreshes with allowNetwork:false, and it returns before the
|
|
1066
1079
|
// network phase, so the provider would stay empty until the user opens /model. Discover here
|
|
@@ -1147,7 +1160,7 @@ export default async function (pi) {
|
|
|
1147
1160
|
if (!auth)
|
|
1148
1161
|
return;
|
|
1149
1162
|
defaultRuntimeAuth = auth;
|
|
1150
|
-
const skills = await listSkills(auth.baseUrl, auth.apiKey, auth.headers);
|
|
1163
|
+
const skills = await listSkills(auth.baseUrl, auth.apiKey, auth.headers, auth.allowInsecureHttp);
|
|
1151
1164
|
section = createSkillsPromptSection(skills);
|
|
1152
1165
|
}
|
|
1153
1166
|
catch (error) {
|
package/dist/mcp-tools.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ExtensionContext, type ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import type { LiteLLMMcpTool, LiteLLMRuntimeAuth } from "./types.js";
|
|
3
|
-
export declare function discoverMcpTools(baseUrl: string, apiKey: string, headers?: Record<string, string>, onProgress?: (message: string) => void, parentSignal?: AbortSignal): Promise<LiteLLMMcpTool[]>;
|
|
4
|
-
export declare function executeMcpTool(baseUrl: string, apiKey: string, serverId: string, toolName: string, args: Record<string, unknown>, headers?: Record<string, string
|
|
3
|
+
export declare function discoverMcpTools(baseUrl: string, apiKey: string, headers?: Record<string, string>, onProgress?: (message: string) => void, parentSignal?: AbortSignal, allowInsecureHttp?: boolean): Promise<LiteLLMMcpTool[]>;
|
|
4
|
+
export declare function executeMcpTool(baseUrl: string, apiKey: string, serverId: string, toolName: string, args: Record<string, unknown>, headers?: Record<string, string>, allowInsecureHttp?: boolean): Promise<string>;
|
|
5
5
|
export declare function createMcpToolDefinitions(getAuth: (ctx?: ExtensionContext) => Promise<LiteLLMRuntimeAuth>, onProgress?: (message: string) => void, signal?: AbortSignal): Promise<ToolDefinition[]>;
|
package/dist/mcp-tools.js
CHANGED
|
@@ -49,11 +49,11 @@ function normalizeMcpTool(value) {
|
|
|
49
49
|
input_schema: inputSchema,
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
|
-
export async function discoverMcpTools(baseUrl, apiKey, headers, onProgress, parentSignal) {
|
|
52
|
+
export async function discoverMcpTools(baseUrl, apiKey, headers, onProgress, parentSignal, allowInsecureHttp = false) {
|
|
53
53
|
onProgress?.("Discovering MCP tools from server...");
|
|
54
54
|
try {
|
|
55
55
|
onProgress?.("Querying MCP tools/list endpoint...");
|
|
56
|
-
const response = await fetch(`${normalizeBaseUrl(baseUrl)}/mcp-rest/tools/list`, {
|
|
56
|
+
const response = await fetch(`${normalizeBaseUrl(baseUrl, allowInsecureHttp)}/mcp-rest/tools/list`, {
|
|
57
57
|
headers: {
|
|
58
58
|
...headers,
|
|
59
59
|
Authorization: `Bearer ${apiKey}`,
|
|
@@ -80,9 +80,9 @@ export async function discoverMcpTools(baseUrl, apiKey, headers, onProgress, par
|
|
|
80
80
|
throw error;
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
-
export async function executeMcpTool(baseUrl, apiKey, serverId, toolName, args, headers) {
|
|
83
|
+
export async function executeMcpTool(baseUrl, apiKey, serverId, toolName, args, headers, allowInsecureHttp = false) {
|
|
84
84
|
for (let attempt = 0; attempt <= MCP_RETRY_ATTEMPTS; attempt++) {
|
|
85
|
-
const result = await executeMcpToolOnce(baseUrl, apiKey, serverId, toolName, args, headers);
|
|
85
|
+
const result = await executeMcpToolOnce(baseUrl, apiKey, serverId, toolName, args, headers, allowInsecureHttp);
|
|
86
86
|
if (attempt < MCP_RETRY_ATTEMPTS && result.retryable) {
|
|
87
87
|
await sleep(MCP_RETRY_DELAY_MS);
|
|
88
88
|
continue;
|
|
@@ -91,11 +91,11 @@ export async function executeMcpTool(baseUrl, apiKey, serverId, toolName, args,
|
|
|
91
91
|
}
|
|
92
92
|
return `Error calling ${toolName} on ${serverId}: retry attempts exhausted`;
|
|
93
93
|
}
|
|
94
|
-
async function executeMcpToolOnce(baseUrl, apiKey, serverId, toolName, args, headers) {
|
|
94
|
+
async function executeMcpToolOnce(baseUrl, apiKey, serverId, toolName, args, headers, allowInsecureHttp = false) {
|
|
95
95
|
try {
|
|
96
96
|
let response;
|
|
97
97
|
try {
|
|
98
|
-
response = await fetch(`${normalizeBaseUrl(baseUrl)}/mcp-rest/tools/call`, {
|
|
98
|
+
response = await fetch(`${normalizeBaseUrl(baseUrl, allowInsecureHttp)}/mcp-rest/tools/call`, {
|
|
99
99
|
method: "POST",
|
|
100
100
|
headers: {
|
|
101
101
|
...headers,
|
|
@@ -152,7 +152,7 @@ function buildParameters(inputSchema) {
|
|
|
152
152
|
}
|
|
153
153
|
export async function createMcpToolDefinitions(getAuth, onProgress, signal) {
|
|
154
154
|
const discoveryAuth = await getAuth();
|
|
155
|
-
const tools = await discoverMcpTools(discoveryAuth.baseUrl, discoveryAuth.apiKey, discoveryAuth.headers, onProgress, signal);
|
|
155
|
+
const tools = await discoverMcpTools(discoveryAuth.baseUrl, discoveryAuth.apiKey, discoveryAuth.headers, onProgress, signal, discoveryAuth.allowInsecureHttp);
|
|
156
156
|
return tools.map((mcpTool) => {
|
|
157
157
|
const safeServer = sanitizeName(mcpTool.server_name);
|
|
158
158
|
const safeTool = sanitizeName(mcpTool.name);
|
|
@@ -170,7 +170,7 @@ export async function createMcpToolDefinitions(getAuth, onProgress, signal) {
|
|
|
170
170
|
const args = Object.keys(rawParams).length === 1 && rawParams.args && typeof rawParams.args === "object"
|
|
171
171
|
? rawParams.args
|
|
172
172
|
: rawParams;
|
|
173
|
-
const text = await executeMcpTool(auth.baseUrl, auth.apiKey, mcpTool.server_id ?? mcpTool.server_name, mcpTool.name, args, auth.headers);
|
|
173
|
+
const text = await executeMcpTool(auth.baseUrl, auth.apiKey, mcpTool.server_id ?? mcpTool.server_name, mcpTool.name, args, auth.headers, auth.allowInsecureHttp);
|
|
174
174
|
return {
|
|
175
175
|
content: [{ type: "text", text }],
|
|
176
176
|
details: { server: mcpTool.server_name, serverId: mcpTool.server_id, tool: mcpTool.name },
|
package/dist/skills.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { type ExtensionContext, type ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import type { LiteLLMRuntimeAuth, LiteLLMSkill } from "./types.js";
|
|
3
|
-
export declare function listSkills(baseUrl: string, apiKey: string, headers?: Record<string, string
|
|
3
|
+
export declare function listSkills(baseUrl: string, apiKey: string, headers?: Record<string, string>, allowInsecureHttp?: boolean): Promise<LiteLLMSkill[]>;
|
|
4
4
|
export declare function createSkill(baseUrl: string, apiKey: string, input: {
|
|
5
5
|
name: string;
|
|
6
6
|
description?: string;
|
|
7
7
|
source?: Record<string, unknown>;
|
|
8
8
|
code?: string;
|
|
9
9
|
inputSchema?: Record<string, unknown>;
|
|
10
|
-
}, headers?: Record<string, string
|
|
11
|
-
export declare function deleteSkill(baseUrl: string, apiKey: string, skillId: string, headers?: Record<string, string
|
|
10
|
+
}, headers?: Record<string, string>, allowInsecureHttp?: boolean): Promise<unknown>;
|
|
11
|
+
export declare function deleteSkill(baseUrl: string, apiKey: string, skillId: string, headers?: Record<string, string>, allowInsecureHttp?: boolean): Promise<void>;
|
|
12
12
|
export declare function createSkillsPromptSection(skills: LiteLLMSkill[]): string | undefined;
|
|
13
13
|
export declare function createSkillToolDefinitions(getAuth: (ctx?: ExtensionContext) => Promise<LiteLLMRuntimeAuth>): ToolDefinition[];
|
|
14
14
|
export declare function resetSkillsCache(): void;
|
package/dist/skills.js
CHANGED
|
@@ -17,8 +17,8 @@ function getSkillsFromBody(body) {
|
|
|
17
17
|
}
|
|
18
18
|
return [];
|
|
19
19
|
}
|
|
20
|
-
export async function listSkills(baseUrl, apiKey, headers) {
|
|
21
|
-
const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
|
|
20
|
+
export async function listSkills(baseUrl, apiKey, headers, allowInsecureHttp = false) {
|
|
21
|
+
const normalizedBaseUrl = normalizeBaseUrl(baseUrl, allowInsecureHttp);
|
|
22
22
|
if (skillsCache &&
|
|
23
23
|
skillsCache.baseUrl === normalizedBaseUrl &&
|
|
24
24
|
skillsCache.apiKey === apiKey &&
|
|
@@ -46,10 +46,10 @@ export async function listSkills(baseUrl, apiKey, headers) {
|
|
|
46
46
|
skillsCache = { baseUrl: normalizedBaseUrl, apiKey, fetchedAt: Date.now(), skills };
|
|
47
47
|
return skills;
|
|
48
48
|
}
|
|
49
|
-
export async function createSkill(baseUrl, apiKey, input, headers) {
|
|
49
|
+
export async function createSkill(baseUrl, apiKey, input, headers, allowInsecureHttp = false) {
|
|
50
50
|
if (!input.source && !input.code)
|
|
51
51
|
throw new Error("code is required when source is omitted");
|
|
52
|
-
const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
|
|
52
|
+
const normalizedBaseUrl = normalizeBaseUrl(baseUrl, allowInsecureHttp);
|
|
53
53
|
let usedSkillHub = input.source !== undefined;
|
|
54
54
|
const skillHubPayload = input.source
|
|
55
55
|
? {
|
|
@@ -105,8 +105,8 @@ export async function createSkill(baseUrl, apiKey, input, headers) {
|
|
|
105
105
|
}
|
|
106
106
|
return response.json().catch(() => ({}));
|
|
107
107
|
}
|
|
108
|
-
export async function deleteSkill(baseUrl, apiKey, skillId, headers) {
|
|
109
|
-
const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
|
|
108
|
+
export async function deleteSkill(baseUrl, apiKey, skillId, headers, allowInsecureHttp = false) {
|
|
109
|
+
const normalizedBaseUrl = normalizeBaseUrl(baseUrl, allowInsecureHttp);
|
|
110
110
|
let skillHubError;
|
|
111
111
|
const skillHubResponse = await fetch(`${normalizedBaseUrl}/claude-code/plugins/${encodeURIComponent(skillId)}`, {
|
|
112
112
|
method: "DELETE",
|
|
@@ -182,7 +182,7 @@ export function createSkillToolDefinitions(getAuth) {
|
|
|
182
182
|
parameters: Type.Object({}),
|
|
183
183
|
async execute(_toolCallId, _params, _signal, _onUpdate, ctx) {
|
|
184
184
|
const auth = await getAuth(ctx);
|
|
185
|
-
const skills = await listSkills(auth.baseUrl, auth.apiKey, auth.headers);
|
|
185
|
+
const skills = await listSkills(auth.baseUrl, auth.apiKey, auth.headers, auth.allowInsecureHttp);
|
|
186
186
|
return { content: [{ type: "text", text: formatSkills(skills) }], details: { count: skills.length } };
|
|
187
187
|
},
|
|
188
188
|
}),
|
|
@@ -203,7 +203,7 @@ export function createSkillToolDefinitions(getAuth) {
|
|
|
203
203
|
source,
|
|
204
204
|
code: params.code,
|
|
205
205
|
inputSchema,
|
|
206
|
-
}, auth.headers);
|
|
206
|
+
}, auth.headers, auth.allowInsecureHttp);
|
|
207
207
|
return { content: [{ type: "text", text: "LiteLLM skill created." }], details: { result } };
|
|
208
208
|
},
|
|
209
209
|
}),
|
|
@@ -214,7 +214,7 @@ export function createSkillToolDefinitions(getAuth) {
|
|
|
214
214
|
parameters: DeleteSkillParams,
|
|
215
215
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
216
216
|
const auth = await getAuth(ctx);
|
|
217
|
-
await deleteSkill(auth.baseUrl, auth.apiKey, params.skillId, auth.headers);
|
|
217
|
+
await deleteSkill(auth.baseUrl, auth.apiKey, params.skillId, auth.headers, auth.allowInsecureHttp);
|
|
218
218
|
return { content: [{ type: "text", text: `LiteLLM skill deleted: ${params.skillId}` }], details: {} };
|
|
219
219
|
},
|
|
220
220
|
}),
|
package/dist/types.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export type LiteLLMRuntimeAuth = {
|
|
|
5
5
|
baseUrl: string;
|
|
6
6
|
apiKey: string;
|
|
7
7
|
headers?: Record<string, string>;
|
|
8
|
+
allowInsecureHttp?: boolean;
|
|
8
9
|
};
|
|
9
10
|
export type DiscoveredModel = Omit<Model<"openai-completions">, "provider" | "api" | "baseUrl"> & {
|
|
10
11
|
api?: LiteLLMApi;
|
|
@@ -17,6 +18,7 @@ export interface DiscoveryOptions {
|
|
|
17
18
|
timeoutMs?: number;
|
|
18
19
|
signal?: AbortSignal;
|
|
19
20
|
headers?: Record<string, string>;
|
|
21
|
+
allowInsecureHttp?: boolean;
|
|
20
22
|
}
|
|
21
23
|
export interface ModelInfoEntry {
|
|
22
24
|
model_name?: string;
|