pi-free 1.0.8 → 2.0.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/CHANGELOG.md +107 -1
- package/README.md +95 -46
- package/config.ts +165 -120
- package/constants.ts +22 -61
- package/index.ts +186 -0
- package/lib/json-persistence.ts +11 -10
- package/lib/logger.ts +2 -2
- package/lib/model-enhancer.ts +20 -20
- package/lib/open-browser.ts +41 -0
- package/lib/provider-cache.ts +106 -0
- package/lib/registry.ts +144 -0
- package/package.json +67 -82
- package/provider-factory.ts +25 -41
- package/provider-failover/benchmark-lookup.ts +247 -0
- package/provider-failover/benchmarks-chunk-0.ts +2010 -0
- package/provider-failover/benchmarks-chunk-1.ts +1988 -0
- package/provider-failover/benchmarks-chunk-2.ts +2010 -0
- package/provider-failover/benchmarks-chunk-3.ts +2010 -0
- package/provider-failover/benchmarks-chunk-4.ts +1969 -0
- package/provider-failover/hardcoded-benchmarks.ts +22 -10025
- package/provider-helper.ts +38 -37
- package/providers/{cline-auth.ts → cline/cline-auth.ts} +2 -2
- package/providers/cline/cline-models.ts +128 -0
- package/providers/{cline.ts → cline/cline.ts} +300 -257
- package/providers/cloudflare/cloudflare.ts +368 -0
- package/providers/dynamic-built-in/index.ts +513 -0
- package/providers/{kilo-auth.ts → kilo/kilo-auth.ts} +3 -20
- package/providers/{kilo-models.ts → kilo/kilo-models.ts} +2 -2
- package/providers/kilo/kilo.ts +235 -0
- package/providers/{modal.ts → modal/modal.ts} +4 -3
- package/providers/{nvidia.ts → nvidia/nvidia.ts} +152 -113
- package/providers/ollama/ollama.ts +172 -0
- package/providers/opencode-session.ts +34 -34
- package/providers/{qwen-auth.ts → qwen/qwen-auth.ts} +24 -40
- package/providers/{qwen-models.ts → qwen/qwen-models.ts} +101 -95
- package/providers/qwen/qwen.ts +202 -0
- package/provider-failover/auto-switch.ts +0 -350
- package/provider-failover/errors.ts +0 -275
- package/provider-failover/index.ts +0 -238
- package/providers/cline-models.ts +0 -77
- package/providers/factory.ts +0 -125
- package/providers/fireworks.ts +0 -49
- package/providers/go.ts +0 -216
- package/providers/kilo.ts +0 -146
- package/providers/mistral.ts +0 -144
- package/providers/ollama.ts +0 -113
- package/providers/openrouter.ts +0 -175
- package/providers/qwen.ts +0 -127
- package/providers/zen.ts +0 -371
- package/usage/commands.ts +0 -17
- package/usage/cumulative.ts +0 -193
- package/usage/formatters.ts +0 -115
- package/usage/index.ts +0 -46
- package/usage/limits.ts +0 -148
- package/usage/metrics.ts +0 -222
- package/usage/sessions.ts +0 -355
- package/usage/store.ts +0 -99
- package/usage/tracking.ts +0 -329
- package/usage/types.ts +0 -26
- package/usage/widget.ts +0 -90
- package/widget/data.ts +0 -113
- package/widget/format.ts +0 -26
- package/widget/render.ts +0 -117
package/providers/fireworks.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fireworks AI Provider Extension
|
|
3
|
-
*
|
|
4
|
-
* Provides access to Fireworks AI hosted models via api.fireworks.ai.
|
|
5
|
-
* Uses OpenAI-compatible API - requires FIREWORKS_API_KEY.
|
|
6
|
-
* Get a key at: https://app.fireworks.ai/settings/users/api-keys
|
|
7
|
-
*
|
|
8
|
-
* All models are credit-based (no free tier).
|
|
9
|
-
* Set FIREWORKS_SHOW_PAID=true to enable.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import type { ProviderModelConfig } from "@mariozechner/pi-coding-agent";
|
|
13
|
-
import { PROVIDER_FIREWORKS } from "../config.ts";
|
|
14
|
-
import { BASE_URL_FIREWORKS } from "../constants.ts";
|
|
15
|
-
import { createProvider } from "../provider-factory.ts";
|
|
16
|
-
|
|
17
|
-
// =============================================================================
|
|
18
|
-
// Static model list (Fireworks doesn't have a models API)
|
|
19
|
-
// =============================================================================
|
|
20
|
-
|
|
21
|
-
function getFireworksModels(): ProviderModelConfig[] {
|
|
22
|
-
return [
|
|
23
|
-
{
|
|
24
|
-
id: "accounts/fireworks/routers/kimi-k2p5-turbo",
|
|
25
|
-
name: "Kimi K2.5 Turbo",
|
|
26
|
-
reasoning: true,
|
|
27
|
-
input: ["text"],
|
|
28
|
-
// Actual pricing (per 1M tokens): $0.50 input, $2.00 output
|
|
29
|
-
cost: { input: 0.0005, output: 0.002, cacheRead: 0, cacheWrite: 0 },
|
|
30
|
-
contextWindow: 262144,
|
|
31
|
-
maxTokens: 131072,
|
|
32
|
-
},
|
|
33
|
-
];
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// =============================================================================
|
|
37
|
-
// Extension Entry Point
|
|
38
|
-
// =============================================================================
|
|
39
|
-
|
|
40
|
-
export default function (pi: Parameters<typeof createProvider>[0]) {
|
|
41
|
-
return createProvider(pi, {
|
|
42
|
-
providerId: PROVIDER_FIREWORKS,
|
|
43
|
-
baseUrl: BASE_URL_FIREWORKS,
|
|
44
|
-
apiKeyEnvVar: "FIREWORKS_API_KEY",
|
|
45
|
-
apiKeyConfigKey: "fireworks_api_key",
|
|
46
|
-
showPaidFlag: "FIREWORKS_SHOW_PAID",
|
|
47
|
-
fetchModels: async () => getFireworksModels(),
|
|
48
|
-
});
|
|
49
|
-
}
|
package/providers/go.ts
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OpenCode Go Provider Extension
|
|
3
|
-
*
|
|
4
|
-
* Provides access to curated open coding models via the OpenCode Go gateway.
|
|
5
|
-
* Requires an OpenCode Go subscription ($5 first month, then $10/month).
|
|
6
|
-
* Set OPENCODE_GO_API_KEY (or opencode_go_api_key in ~/.pi/free.json) for access.
|
|
7
|
-
*
|
|
8
|
-
* Models available:
|
|
9
|
-
* - GLM-5
|
|
10
|
-
* - Kimi K2.5
|
|
11
|
-
* - MiMo-V2-Pro
|
|
12
|
-
* - MiMo-V2-Omni
|
|
13
|
-
* - MiniMax M2.7
|
|
14
|
-
* - MiniMax M2.5
|
|
15
|
-
*
|
|
16
|
-
* See: https://opencode.ai/docs/go
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import type {
|
|
20
|
-
ExtensionAPI,
|
|
21
|
-
ProviderModelConfig,
|
|
22
|
-
} from "@mariozechner/pi-coding-agent";
|
|
23
|
-
import {
|
|
24
|
-
applyHidden,
|
|
25
|
-
GO_SHOW_PAID,
|
|
26
|
-
OPENCODE_API_KEY,
|
|
27
|
-
OPENCODE_GO_API_KEY as CONFIG_API_KEY,
|
|
28
|
-
PROVIDER_GO,
|
|
29
|
-
} from "../config.ts";
|
|
30
|
-
import {
|
|
31
|
-
BASE_URL_GO,
|
|
32
|
-
URL_GO_TOS,
|
|
33
|
-
} from "../constants.ts";
|
|
34
|
-
import {
|
|
35
|
-
type StoredModels,
|
|
36
|
-
setupProvider,
|
|
37
|
-
createCtxReRegister,
|
|
38
|
-
} from "../provider-helper.ts";
|
|
39
|
-
import { createOpenCodeSessionTracker } from "./opencode-session.ts";
|
|
40
|
-
|
|
41
|
-
const GO_CONFIG = {
|
|
42
|
-
providerId: PROVIDER_GO,
|
|
43
|
-
baseUrl: BASE_URL_GO,
|
|
44
|
-
apiKey: "PI_FREE_GO_API_KEY",
|
|
45
|
-
headers: {
|
|
46
|
-
"X-Title": "Pi",
|
|
47
|
-
"HTTP-Referer": "https://opencode.ai/",
|
|
48
|
-
},
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const session = createOpenCodeSessionTracker();
|
|
52
|
-
|
|
53
|
-
// =============================================================================
|
|
54
|
-
// Static fallback models (from OpenCode Go docs)
|
|
55
|
-
// Used when /models API is unavailable
|
|
56
|
-
// =============================================================================
|
|
57
|
-
|
|
58
|
-
const STATIC_GO_MODELS: ProviderModelConfig[] = [
|
|
59
|
-
{
|
|
60
|
-
id: "glm-5",
|
|
61
|
-
name: "GLM-5",
|
|
62
|
-
reasoning: true,
|
|
63
|
-
input: ["text"],
|
|
64
|
-
cost: { input: 0.5, output: 2, cacheRead: 0, cacheWrite: 0 },
|
|
65
|
-
contextWindow: 128000,
|
|
66
|
-
maxTokens: 16384,
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
id: "kimi-k2.5",
|
|
70
|
-
name: "Kimi K2.5",
|
|
71
|
-
reasoning: true,
|
|
72
|
-
input: ["text"],
|
|
73
|
-
cost: { input: 0.3, output: 1.5, cacheRead: 0, cacheWrite: 0 },
|
|
74
|
-
contextWindow: 128000,
|
|
75
|
-
maxTokens: 16384,
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
id: "mimo-v2-pro",
|
|
79
|
-
name: "MiMo V2 Pro",
|
|
80
|
-
reasoning: false,
|
|
81
|
-
input: ["text"],
|
|
82
|
-
cost: { input: 0.4, output: 1.2, cacheRead: 0, cacheWrite: 0 },
|
|
83
|
-
contextWindow: 128000,
|
|
84
|
-
maxTokens: 16384,
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
id: "mimo-v2-omni",
|
|
88
|
-
name: "MiMo V2 Omni",
|
|
89
|
-
reasoning: false,
|
|
90
|
-
input: ["text", "image"],
|
|
91
|
-
cost: { input: 0.25, output: 0.8, cacheRead: 0, cacheWrite: 0 },
|
|
92
|
-
contextWindow: 128000,
|
|
93
|
-
maxTokens: 16384,
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
id: "minimax-m2.7",
|
|
97
|
-
name: "MiniMax M2.7",
|
|
98
|
-
reasoning: true,
|
|
99
|
-
input: ["text"],
|
|
100
|
-
cost: { input: 0.1, output: 0.4, cacheRead: 0, cacheWrite: 0 },
|
|
101
|
-
contextWindow: 200000,
|
|
102
|
-
maxTokens: 16384,
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
id: "minimax-m2.5",
|
|
106
|
-
name: "MiniMax M2.5",
|
|
107
|
-
reasoning: true,
|
|
108
|
-
input: ["text"],
|
|
109
|
-
cost: { input: 0.05, output: 0.2, cacheRead: 0, cacheWrite: 0 },
|
|
110
|
-
contextWindow: 200000,
|
|
111
|
-
maxTokens: 16384,
|
|
112
|
-
},
|
|
113
|
-
];
|
|
114
|
-
|
|
115
|
-
// =============================================================================
|
|
116
|
-
// Fetch helpers
|
|
117
|
-
// =============================================================================
|
|
118
|
-
|
|
119
|
-
// OpenCode Go does not have a /models endpoint.
|
|
120
|
-
// Models are only accessible via the chat completions API.
|
|
121
|
-
// Static models are used directly (see below).
|
|
122
|
-
|
|
123
|
-
// =============================================================================
|
|
124
|
-
// Main fetch
|
|
125
|
-
// =============================================================================
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* OpenCode Go does not have a /models endpoint.
|
|
129
|
-
* Models are only accessible via chat completions.
|
|
130
|
-
* So we use the static fallback models directly.
|
|
131
|
-
*/
|
|
132
|
-
async function fetchGoModels(_token: string): Promise<{
|
|
133
|
-
all: ProviderModelConfig[];
|
|
134
|
-
useStaticFallback: boolean;
|
|
135
|
-
}> {
|
|
136
|
-
// Go has no /models API - use static models
|
|
137
|
-
return { all: applyHidden(STATIC_GO_MODELS), useStaticFallback: true };
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// =============================================================================
|
|
141
|
-
// Extension Entry Point
|
|
142
|
-
// =============================================================================
|
|
143
|
-
|
|
144
|
-
export default async function (pi: ExtensionAPI) {
|
|
145
|
-
const token = CONFIG_API_KEY ?? OPENCODE_API_KEY ?? "";
|
|
146
|
-
const hasKey = !!token;
|
|
147
|
-
|
|
148
|
-
// Go requires an API key (no free tier)
|
|
149
|
-
if (!hasKey) {
|
|
150
|
-
pi.on("session_start", async () => {
|
|
151
|
-
// No key - don't register provider
|
|
152
|
-
});
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Use a private env var so we don't conflict with other providers
|
|
157
|
-
const GO_KEY_VAR = "PI_FREE_GO_API_KEY";
|
|
158
|
-
|
|
159
|
-
// Shared model storage
|
|
160
|
-
const stored: StoredModels = { free: [], all: [] };
|
|
161
|
-
|
|
162
|
-
// Re-registration function
|
|
163
|
-
let reRegisterFn: (models: ProviderModelConfig[]) => void = () => {};
|
|
164
|
-
|
|
165
|
-
// Wire up shared boilerplate
|
|
166
|
-
setupProvider(
|
|
167
|
-
pi,
|
|
168
|
-
{
|
|
169
|
-
providerId: PROVIDER_GO,
|
|
170
|
-
tosUrl: URL_GO_TOS,
|
|
171
|
-
hasKey,
|
|
172
|
-
initialShowPaid: GO_SHOW_PAID,
|
|
173
|
-
reRegister: (models) => reRegisterFn(models),
|
|
174
|
-
},
|
|
175
|
-
stored,
|
|
176
|
-
);
|
|
177
|
-
|
|
178
|
-
// Register provider on session start
|
|
179
|
-
pi.on("session_start", async (_event, ctx) => {
|
|
180
|
-
// Set up the env var
|
|
181
|
-
process.env[GO_KEY_VAR] = token;
|
|
182
|
-
|
|
183
|
-
// OpenCode Go has no /models endpoint - use static fallback
|
|
184
|
-
const models = applyHidden(STATIC_GO_MODELS);
|
|
185
|
-
|
|
186
|
-
stored.all = models;
|
|
187
|
-
stored.free = models; // Go has no free tier
|
|
188
|
-
|
|
189
|
-
if (models.length === 0) {
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// Generate session ID for this session (used in headers)
|
|
194
|
-
const sessionId = session.getSessionId();
|
|
195
|
-
|
|
196
|
-
// Create re-register function with session headers (same as zen)
|
|
197
|
-
const sessionConfig = {
|
|
198
|
-
...GO_CONFIG,
|
|
199
|
-
headers: {
|
|
200
|
-
...GO_CONFIG.headers,
|
|
201
|
-
"x-opencode-session": sessionId,
|
|
202
|
-
"x-session-affinity": sessionId,
|
|
203
|
-
},
|
|
204
|
-
};
|
|
205
|
-
reRegisterFn = createCtxReRegister(ctx as any, sessionConfig);
|
|
206
|
-
|
|
207
|
-
// Register our provider
|
|
208
|
-
reRegisterFn(models);
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
// Update request count before each agent turn (for request ID generation)
|
|
212
|
-
pi.on("before_agent_start", async (_event, ctx) => {
|
|
213
|
-
if (ctx.model?.provider !== PROVIDER_GO) return;
|
|
214
|
-
session.nextRequestId();
|
|
215
|
-
});
|
|
216
|
-
}
|
package/providers/kilo.ts
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Kilo Provider Extension
|
|
3
|
-
*
|
|
4
|
-
* Provides access to 300+ AI models via the Kilo Gateway (OpenRouter-compatible).
|
|
5
|
-
* Free models available immediately; /login kilo for full access.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* pi install git:github.com/apmantza/pi-free
|
|
9
|
-
* # Then /login kilo, or set KILO_API_KEY=...
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import type { Api, Model, OAuthCredentials } from "@mariozechner/pi-ai";
|
|
13
|
-
import type {
|
|
14
|
-
ExtensionAPI,
|
|
15
|
-
ProviderModelConfig,
|
|
16
|
-
} from "@mariozechner/pi-coding-agent";
|
|
17
|
-
import { KILO_FREE_ONLY, KILO_SHOW_PAID, PROVIDER_KILO } from "../config.ts";
|
|
18
|
-
import { URL_KILO_TOS } from "../constants.ts";
|
|
19
|
-
import {
|
|
20
|
-
enhanceWithCI,
|
|
21
|
-
type StoredModels,
|
|
22
|
-
setupProvider,
|
|
23
|
-
createReRegister,
|
|
24
|
-
createCtxReRegister,
|
|
25
|
-
} from "../provider-helper.ts";
|
|
26
|
-
import { cleanModelName, logWarning } from "../lib/util.ts";
|
|
27
|
-
import { loginKilo, refreshKiloToken } from "./kilo-auth.ts";
|
|
28
|
-
import { fetchKiloModels, KILO_GATEWAY_BASE } from "./kilo-models.ts";
|
|
29
|
-
|
|
30
|
-
const KILO_PROVIDER_CONFIG = {
|
|
31
|
-
providerId: PROVIDER_KILO,
|
|
32
|
-
baseUrl: KILO_GATEWAY_BASE,
|
|
33
|
-
apiKey: "KILO_API_KEY",
|
|
34
|
-
headers: {
|
|
35
|
-
"X-KILOCODE-EDITORNAME": "Pi",
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export default async function (pi: ExtensionAPI) {
|
|
40
|
-
let freeModels: ProviderModelConfig[] = [];
|
|
41
|
-
try {
|
|
42
|
-
freeModels = await fetchKiloModels({ freeOnly: true });
|
|
43
|
-
} catch (error) {
|
|
44
|
-
logWarning("kilo", "Failed to fetch free models at startup", error);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
let cachedAllModels: ProviderModelConfig[] = [];
|
|
48
|
-
let showPaidModels = KILO_SHOW_PAID;
|
|
49
|
-
|
|
50
|
-
// Shared model storage for setupProvider commands
|
|
51
|
-
const stored: StoredModels = { free: freeModels, all: [] };
|
|
52
|
-
|
|
53
|
-
// OAuth config for Kilo (shared across registrations)
|
|
54
|
-
const oauthConfig = {
|
|
55
|
-
name: "Kilo",
|
|
56
|
-
login: async (callbacks: any) => {
|
|
57
|
-
const cred = await loginKilo(callbacks);
|
|
58
|
-
try {
|
|
59
|
-
cachedAllModels = await fetchKiloModels({ token: cred.access });
|
|
60
|
-
stored.all = cachedAllModels;
|
|
61
|
-
} catch (error) {
|
|
62
|
-
logWarning("kilo", "Failed to fetch models after login", error);
|
|
63
|
-
}
|
|
64
|
-
return cred;
|
|
65
|
-
},
|
|
66
|
-
refreshToken: refreshKiloToken,
|
|
67
|
-
getApiKey: (cred: OAuthCredentials) => cred.access,
|
|
68
|
-
modifyModels: (models: Model<Api>[], _cred: OAuthCredentials) => {
|
|
69
|
-
if (!showPaidModels || KILO_FREE_ONLY || cachedAllModels.length === 0) {
|
|
70
|
-
return models;
|
|
71
|
-
}
|
|
72
|
-
const template = models.find((m) => m.provider === PROVIDER_KILO);
|
|
73
|
-
if (!template) return models;
|
|
74
|
-
const nonKilo = models.filter((m) => m.provider !== PROVIDER_KILO);
|
|
75
|
-
const fullModels = cachedAllModels.map((m) => ({
|
|
76
|
-
...template,
|
|
77
|
-
id: m.id,
|
|
78
|
-
name: cleanModelName(m.name),
|
|
79
|
-
reasoning: m.reasoning,
|
|
80
|
-
input: m.input,
|
|
81
|
-
cost: m.cost,
|
|
82
|
-
contextWindow: m.contextWindow,
|
|
83
|
-
maxTokens: m.maxTokens,
|
|
84
|
-
}));
|
|
85
|
-
return [...nonKilo, ...fullModels];
|
|
86
|
-
},
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
// Register initial provider
|
|
90
|
-
pi.registerProvider(PROVIDER_KILO, {
|
|
91
|
-
baseUrl: KILO_GATEWAY_BASE,
|
|
92
|
-
apiKey: "KILO_API_KEY",
|
|
93
|
-
api: "openai-completions" as const,
|
|
94
|
-
headers: {
|
|
95
|
-
"X-KILOCODE-EDITORNAME": "Pi",
|
|
96
|
-
"User-Agent": "pi-free-providers",
|
|
97
|
-
},
|
|
98
|
-
models: enhanceWithCI(freeModels),
|
|
99
|
-
oauth: oauthConfig,
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
// Wire up shared boilerplate (commands, model_select, turn_end, ToS)
|
|
103
|
-
const reRegister = createReRegister(pi, {
|
|
104
|
-
...KILO_PROVIDER_CONFIG,
|
|
105
|
-
oauth: oauthConfig as any,
|
|
106
|
-
});
|
|
107
|
-
setupProvider(
|
|
108
|
-
pi,
|
|
109
|
-
{
|
|
110
|
-
providerId: PROVIDER_KILO,
|
|
111
|
-
tosUrl: URL_KILO_TOS,
|
|
112
|
-
initialShowPaid: KILO_SHOW_PAID,
|
|
113
|
-
reRegister: (models) => {
|
|
114
|
-
showPaidModels = models === stored.all;
|
|
115
|
-
reRegister(models);
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
stored,
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
// Usage widget temporarily deprecated.
|
|
122
|
-
|
|
123
|
-
// ── Kilo-specific: events ────────────────────────────────────────────
|
|
124
|
-
|
|
125
|
-
pi.on("session_start", async (_event, ctx) => {
|
|
126
|
-
const cred = ctx.modelRegistry.authStorage.get(PROVIDER_KILO);
|
|
127
|
-
|
|
128
|
-
if (cred?.type === "oauth") {
|
|
129
|
-
try {
|
|
130
|
-
cachedAllModels = await fetchKiloModels({ token: cred.access });
|
|
131
|
-
stored.all = cachedAllModels;
|
|
132
|
-
if (cachedAllModels.length > 0) {
|
|
133
|
-
const ctxReRegister = createCtxReRegister(ctx as any, {
|
|
134
|
-
...KILO_PROVIDER_CONFIG,
|
|
135
|
-
oauth: oauthConfig as any,
|
|
136
|
-
});
|
|
137
|
-
const modelsToShow =
|
|
138
|
-
showPaidModels && !KILO_FREE_ONLY ? cachedAllModels : freeModels;
|
|
139
|
-
ctxReRegister(modelsToShow);
|
|
140
|
-
}
|
|
141
|
-
} catch (error) {
|
|
142
|
-
logWarning("kilo", "Failed to fetch models at session start", error);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
}
|
package/providers/mistral.ts
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Mistral AI Provider Extension
|
|
3
|
-
*
|
|
4
|
-
* Provides access to Mistral's models via api.mistral.ai.
|
|
5
|
-
* Free models available without account; paid models require MISTRAL_API_KEY.
|
|
6
|
-
* Get a key at: https://console.mistral.ai/api-keys
|
|
7
|
-
*
|
|
8
|
-
* By default only free models are shown.
|
|
9
|
-
* Set MISTRAL_SHOW_PAID=true to also include paid models.
|
|
10
|
-
*
|
|
11
|
-
* Note: Mistral has stricter field requirements than OpenAI —
|
|
12
|
-
* only whitelisted fields are sent to avoid 400 errors.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import type { ProviderModelConfig } from "@mariozechner/pi-coding-agent";
|
|
16
|
-
import { applyHidden, MISTRAL_SHOW_PAID, PROVIDER_MISTRAL } from "../config.ts";
|
|
17
|
-
import { BASE_URL_MISTRAL } from "../constants.ts";
|
|
18
|
-
import { createProvider } from "../provider-factory.ts";
|
|
19
|
-
|
|
20
|
-
// =============================================================================
|
|
21
|
-
// Static model list
|
|
22
|
-
// =============================================================================
|
|
23
|
-
|
|
24
|
-
function getMistralModels(): ProviderModelConfig[] {
|
|
25
|
-
return applyHidden([
|
|
26
|
-
// Free models
|
|
27
|
-
{
|
|
28
|
-
id: "mistral-small-latest",
|
|
29
|
-
name: "Mistral Small",
|
|
30
|
-
reasoning: false,
|
|
31
|
-
input: ["text"],
|
|
32
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
33
|
-
contextWindow: 32768,
|
|
34
|
-
maxTokens: 32768,
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
id: "open-mistral-nemo",
|
|
38
|
-
name: "Mistral Nemo (Open)",
|
|
39
|
-
reasoning: false,
|
|
40
|
-
input: ["text"],
|
|
41
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
42
|
-
contextWindow: 128000,
|
|
43
|
-
maxTokens: 128000,
|
|
44
|
-
},
|
|
45
|
-
// Paid models
|
|
46
|
-
{
|
|
47
|
-
id: "mistral-large-latest",
|
|
48
|
-
name: "Mistral Large",
|
|
49
|
-
reasoning: true,
|
|
50
|
-
input: ["text"],
|
|
51
|
-
cost: { input: 0.002, output: 0.006, cacheRead: 0, cacheWrite: 0 },
|
|
52
|
-
contextWindow: 128000,
|
|
53
|
-
maxTokens: 128000,
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
id: "ministral-3b-latest",
|
|
57
|
-
name: "Ministral 3B",
|
|
58
|
-
reasoning: false,
|
|
59
|
-
input: ["text"],
|
|
60
|
-
cost: { input: 0.00004, output: 0.00004, cacheRead: 0, cacheWrite: 0 },
|
|
61
|
-
contextWindow: 128000,
|
|
62
|
-
maxTokens: 128000,
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
id: "ministral-8b-latest",
|
|
66
|
-
name: "Ministral 8B",
|
|
67
|
-
reasoning: false,
|
|
68
|
-
input: ["text"],
|
|
69
|
-
cost: { input: 0.0001, output: 0.0001, cacheRead: 0, cacheWrite: 0 },
|
|
70
|
-
contextWindow: 128000,
|
|
71
|
-
maxTokens: 128000,
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
id: "codestral-latest",
|
|
75
|
-
name: "Codestral",
|
|
76
|
-
reasoning: false,
|
|
77
|
-
input: ["text"],
|
|
78
|
-
cost: { input: 0.0003, output: 0.0009, cacheRead: 0, cacheWrite: 0 },
|
|
79
|
-
contextWindow: 256000,
|
|
80
|
-
maxTokens: 256000,
|
|
81
|
-
},
|
|
82
|
-
]);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// =============================================================================
|
|
86
|
-
// Mistral-specific request filtering
|
|
87
|
-
// =============================================================================
|
|
88
|
-
|
|
89
|
-
const MISTRAL_ALLOWED_FIELDS = new Set([
|
|
90
|
-
"model",
|
|
91
|
-
"messages",
|
|
92
|
-
"temperature",
|
|
93
|
-
"max_tokens",
|
|
94
|
-
"stream",
|
|
95
|
-
"tools",
|
|
96
|
-
"tool_choice",
|
|
97
|
-
"stop",
|
|
98
|
-
"top_p",
|
|
99
|
-
"presence_penalty",
|
|
100
|
-
"frequency_penalty",
|
|
101
|
-
]);
|
|
102
|
-
|
|
103
|
-
function isMistralPayload(payload: Record<string, unknown>): boolean {
|
|
104
|
-
const modelId = payload.model as string | undefined;
|
|
105
|
-
return !!modelId && (modelId.includes("mistral") || modelId.includes("nemo"));
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function filterMistralPayload(
|
|
109
|
-
payload: Record<string, unknown>,
|
|
110
|
-
): Record<string, unknown> {
|
|
111
|
-
const filtered: Record<string, unknown> = {};
|
|
112
|
-
for (const [key, value] of Object.entries(payload)) {
|
|
113
|
-
if (MISTRAL_ALLOWED_FIELDS.has(key)) {
|
|
114
|
-
filtered[key] = value;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
return filtered;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// =============================================================================
|
|
121
|
-
// Extension Entry Point
|
|
122
|
-
// =============================================================================
|
|
123
|
-
|
|
124
|
-
export default function (pi: Parameters<typeof createProvider>[0]) {
|
|
125
|
-
const allModels = getMistralModels();
|
|
126
|
-
const models = MISTRAL_SHOW_PAID
|
|
127
|
-
? allModels
|
|
128
|
-
: allModels.filter((m) => (m.cost?.input ?? 0) === 0);
|
|
129
|
-
|
|
130
|
-
// Override fetchModels to use our already-fetched models
|
|
131
|
-
return createProvider(pi, {
|
|
132
|
-
providerId: PROVIDER_MISTRAL,
|
|
133
|
-
baseUrl: BASE_URL_MISTRAL,
|
|
134
|
-
apiKeyEnvVar: "MISTRAL_API_KEY",
|
|
135
|
-
apiKeyConfigKey: "mistral_api_key",
|
|
136
|
-
fetchModels: async () => models,
|
|
137
|
-
beforeProviderRequest: (payload) => {
|
|
138
|
-
if (isMistralPayload(payload)) {
|
|
139
|
-
return filterMistralPayload(payload);
|
|
140
|
-
}
|
|
141
|
-
return undefined;
|
|
142
|
-
},
|
|
143
|
-
});
|
|
144
|
-
}
|
package/providers/ollama.ts
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Ollama Cloud Provider Extension
|
|
3
|
-
*
|
|
4
|
-
* Provides access to Ollama's cloud-hosted models via ollama.com/v1.
|
|
5
|
-
* Free tier available with usage limits (resets every 5 hours + 7 days).
|
|
6
|
-
* Requires OLLAMA_API_KEY from https://ollama.com/settings/keys
|
|
7
|
-
*
|
|
8
|
-
* Set OLLAMA_SHOW_PAID=true to enable (required since Ollama has usage limits).
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import type { ProviderModelConfig } from "@mariozechner/pi-coding-agent";
|
|
12
|
-
import { OLLAMA_API_KEY, PROVIDER_OLLAMA } from "../config.ts";
|
|
13
|
-
import { BASE_URL_OLLAMA, DEFAULT_FETCH_TIMEOUT_MS } from "../constants.ts";
|
|
14
|
-
import { fetchWithRetry } from "../lib/util.ts";
|
|
15
|
-
import { createProvider } from "../provider-factory.ts";
|
|
16
|
-
|
|
17
|
-
// =============================================================================
|
|
18
|
-
// Fetch + map
|
|
19
|
-
// =============================================================================
|
|
20
|
-
|
|
21
|
-
async function fetchOllamaModels(): Promise<ProviderModelConfig[]> {
|
|
22
|
-
const apiKey = OLLAMA_API_KEY;
|
|
23
|
-
if (!apiKey) return [];
|
|
24
|
-
|
|
25
|
-
const response = await fetchWithRetry(
|
|
26
|
-
`${BASE_URL_OLLAMA}/models`,
|
|
27
|
-
{
|
|
28
|
-
headers: {
|
|
29
|
-
Authorization: `Bearer ${apiKey}`,
|
|
30
|
-
"User-Agent": "pi-free-providers",
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
3,
|
|
34
|
-
1000,
|
|
35
|
-
DEFAULT_FETCH_TIMEOUT_MS,
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
if (!response.ok) {
|
|
39
|
-
throw new Error(
|
|
40
|
-
`Failed to fetch Ollama models: ${response.status} ${response.statusText}`,
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const json = (await response.json()) as {
|
|
45
|
-
data?: Array<{
|
|
46
|
-
id: string;
|
|
47
|
-
object?: string;
|
|
48
|
-
created?: number;
|
|
49
|
-
owned_by?: string;
|
|
50
|
-
}>;
|
|
51
|
-
};
|
|
52
|
-
const models = json.data ?? [];
|
|
53
|
-
|
|
54
|
-
// Filter out small models (< 30B) to keep list focused
|
|
55
|
-
return models
|
|
56
|
-
.filter((m) => {
|
|
57
|
-
const sizeMatch = m.id.match(/:(\d+)([bmt])/i);
|
|
58
|
-
if (sizeMatch) {
|
|
59
|
-
const size = parseInt(sizeMatch[1], 10);
|
|
60
|
-
const unit = sizeMatch[2].toLowerCase();
|
|
61
|
-
if (unit === "b" && size < 30) return false;
|
|
62
|
-
}
|
|
63
|
-
return true;
|
|
64
|
-
})
|
|
65
|
-
.map(mapOllamaModel);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function mapOllamaModel(m: { id: string }): ProviderModelConfig {
|
|
69
|
-
// Extract context window from parameter size
|
|
70
|
-
let contextWindow = 131072; // Default 128k
|
|
71
|
-
const sizeMatch = m.id.match(/:(\d+)([bmt])/i);
|
|
72
|
-
if (sizeMatch) {
|
|
73
|
-
const size = parseInt(sizeMatch[1], 10);
|
|
74
|
-
const unit = sizeMatch[2].toLowerCase();
|
|
75
|
-
if (unit === "b" && size >= 100) {
|
|
76
|
-
contextWindow = 200000;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Clean up name for display
|
|
81
|
-
const displayName = m.id
|
|
82
|
-
.replace(/:/g, " ")
|
|
83
|
-
.replace(/-/g, " ")
|
|
84
|
-
.split(" ")
|
|
85
|
-
.filter((w) => w.length > 0)
|
|
86
|
-
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
87
|
-
.join(" ");
|
|
88
|
-
|
|
89
|
-
return {
|
|
90
|
-
id: m.id,
|
|
91
|
-
name: displayName,
|
|
92
|
-
reasoning: m.id.includes("deepseek") || m.id.includes("r1"),
|
|
93
|
-
input: ["text"],
|
|
94
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
95
|
-
contextWindow,
|
|
96
|
-
maxTokens: Math.min(contextWindow / 2, 131072),
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// =============================================================================
|
|
101
|
-
// Extension Entry Point
|
|
102
|
-
// =============================================================================
|
|
103
|
-
|
|
104
|
-
export default function (pi: Parameters<typeof createProvider>[0]) {
|
|
105
|
-
return createProvider(pi, {
|
|
106
|
-
providerId: PROVIDER_OLLAMA,
|
|
107
|
-
baseUrl: BASE_URL_OLLAMA,
|
|
108
|
-
apiKeyEnvVar: "OLLAMA_API_KEY",
|
|
109
|
-
apiKeyConfigKey: "ollama_api_key",
|
|
110
|
-
showPaidFlag: "OLLAMA_SHOW_PAID",
|
|
111
|
-
fetchModels: fetchOllamaModels,
|
|
112
|
-
});
|
|
113
|
-
}
|