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 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
 
@@ -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 ? loginApiKey : undefined,
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 ? `${normalizeBaseUrl(String(credential.baseUrl))}/v1` : undefined,
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 { baseUrl, apiKey: credential.access, headers: resolveHeaders(definition) };
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) {
@@ -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>): Promise<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>): Promise<LiteLLMSkill[]>;
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>): Promise<unknown>;
11
- export declare function deleteSkill(baseUrl: string, apiKey: string, skillId: string, headers?: Record<string, string>): Promise<void>;
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-provider-litellm",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "description": "LiteLLM proxy provider extension for Pi",
5
5
  "type": "module",
6
6
  "license": "MIT",