pi-free 2.2.3 → 2.2.4
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 +16 -49
- package/README.md +41 -532
- package/banner.svg +23 -20
- package/config.ts +82 -10
- package/constants.ts +11 -1
- package/index.ts +15 -1
- package/lib/model-detection.ts +296 -296
- package/lib/model-metadata.ts +10 -3
- package/lib/telemetry.ts +36 -44
- package/package.json +3 -2
- package/provider-failover/benchmark-lookup.ts +30 -15
- package/provider-helper.ts +27 -8
- package/providers/bai/bai.ts +2 -7
- package/providers/cline/cline-xml-bridge.ts +31 -25
- package/providers/cline/cline.ts +17 -8
- package/providers/kilo/kilo.ts +11 -6
- package/providers/model-fetcher.ts +1 -1
- package/providers/opencode-session.ts +2 -2
- package/providers/openmodel/openmodel.ts +525 -0
- package/providers/qoder/auth.ts +548 -0
- package/providers/qoder/cosy.ts +236 -0
- package/providers/qoder/encoding.ts +48 -0
- package/providers/qoder/models.ts +321 -0
- package/providers/qoder/qoder.ts +154 -0
- package/providers/qoder/stream.ts +677 -0
- package/providers/qoder/thinking-parser.ts +251 -0
- package/providers/qoder/transform.ts +189 -0
- package/providers/tokenrouter/tokenrouter.ts +3 -6
package/banner.svg
CHANGED
|
@@ -88,28 +88,31 @@
|
|
|
88
88
|
</g>
|
|
89
89
|
|
|
90
90
|
<!-- Provider cards (right side) -->
|
|
91
|
-
<g transform="translate(700,
|
|
92
|
-
<rect x="0" y="0" width="250" height="
|
|
93
|
-
<rect x="0" y="0" width="250" height="
|
|
94
|
-
<text x="20" y="
|
|
95
|
-
<text x="20" y="
|
|
96
|
-
<text x="20" y="
|
|
97
|
-
<text x="20" y="
|
|
98
|
-
<text x="20" y="
|
|
99
|
-
<text x="20" y="
|
|
91
|
+
<g transform="translate(700, 45)">
|
|
92
|
+
<rect x="0" y="0" width="250" height="200" rx="12" fill="url(#card1)" stroke="#7c3aed" stroke-width="0.5" stroke-opacity="0.2" filter="url(#shadow)"/>
|
|
93
|
+
<rect x="0" y="0" width="250" height="200" rx="12" fill="none" stroke="url(#accent)" stroke-width="0.5" opacity="0.1"/>
|
|
94
|
+
<text x="20" y="26" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#c4b5fd">Providers</text>
|
|
95
|
+
<text x="20" y="46" font-family="system-ui, sans-serif" font-size="11" fill="#8b9aaa">Kilo · Cline · OpenCode</text>
|
|
96
|
+
<text x="20" y="66" font-family="system-ui, sans-serif" font-size="11" fill="#a78bfa">OpenModel · AgentRouter</text>
|
|
97
|
+
<text x="20" y="86" font-family="system-ui, sans-serif" font-size="11" fill="#8b9aaa">Ollama Cloud · SambaNova</text>
|
|
98
|
+
<text x="20" y="106" font-family="system-ui, sans-serif" font-size="11" fill="#8b9aaa">Codestral · LLM7 · Novita</text>
|
|
99
|
+
<text x="20" y="126" font-family="system-ui, sans-serif" font-size="11" fill="#8b9aaa">ZenMux · CrofAI · DeepInfra</text>
|
|
100
|
+
<text x="20" y="146" font-family="system-ui, sans-serif" font-size="11" fill="#8b9aaa">Together · TokenRouter · FastRouter</text>
|
|
101
|
+
<text x="20" y="166" font-family="system-ui, sans-serif" font-size="11" fill="#8b9aaa">+ dynamic (Mistral, Groq, …)</text>
|
|
100
102
|
</g>
|
|
101
103
|
|
|
102
|
-
<g transform="translate(970,
|
|
103
|
-
<rect x="0" y="0" width="250" height="
|
|
104
|
-
<rect x="0" y="0" width="250" height="
|
|
105
|
-
<text x="20" y="
|
|
106
|
-
<text x="20" y="
|
|
107
|
-
<text x="20" y="
|
|
108
|
-
<text x="20" y="
|
|
109
|
-
<text x="20" y="
|
|
110
|
-
<text x="20" y="
|
|
111
|
-
<text x="20" y="
|
|
112
|
-
<text x="20" y="
|
|
104
|
+
<g transform="translate(970, 45)">
|
|
105
|
+
<rect x="0" y="0" width="250" height="200" rx="12" fill="url(#card2)" stroke="#06b6d4" stroke-width="0.5" stroke-opacity="0.2" filter="url(#shadow)"/>
|
|
106
|
+
<rect x="0" y="0" width="250" height="200" rx="12" fill="none" stroke="url(#accent2)" stroke-width="0.5" opacity="0.1"/>
|
|
107
|
+
<text x="20" y="26" font-family="system-ui, sans-serif" font-size="13" font-weight="700" fill="#67e8f9">Features</text>
|
|
108
|
+
<text x="20" y="46" font-family="system-ui, sans-serif" font-size="11" fill="#8b9aaa">Free model auto-detection</text>
|
|
109
|
+
<text x="20" y="64" font-family="system-ui, sans-serif" font-size="11" fill="#8b9aaa">Per-provider toggles</text>
|
|
110
|
+
<text x="20" y="82" font-family="system-ui, sans-serif" font-size="11" fill="#8b9aaa">OAuth flows (Kilo, Cline)</text>
|
|
111
|
+
<text x="20" y="100" font-family="system-ui, sans-serif" font-size="11" fill="#8b9aaa">Coding Index (CI) scores</text>
|
|
112
|
+
<text x="20" y="118" font-family="system-ui, sans-serif" font-size="11" fill="#8b9aaa">Model health probes</text>
|
|
113
|
+
<text x="20" y="136" font-family="system-ui, sans-serif" font-size="11" fill="#8b9aaa">Thinking level maps</text>
|
|
114
|
+
<text x="20" y="154" font-family="system-ui, sans-serif" font-size="11" fill="#8b9aaa">404/403 auto-hide on probe</text>
|
|
115
|
+
<text x="20" y="172" font-family="system-ui, sans-serif" font-size="11" fill="#8b9aaa">+ dynamic built-in fetch</text>
|
|
113
116
|
</g>
|
|
114
117
|
|
|
115
118
|
<!-- Bottom tagline -->
|
package/config.ts
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
PROVIDER_KILO,
|
|
19
19
|
PROVIDER_OLLAMA,
|
|
20
20
|
PROVIDER_OPENCODE,
|
|
21
|
+
PROVIDER_OPENMODEL,
|
|
21
22
|
PROVIDER_OPENROUTER,
|
|
22
23
|
PROVIDER_ROUTEWAY,
|
|
23
24
|
PROVIDER_TOKENROUTER,
|
|
@@ -72,6 +73,9 @@ interface PiFreeConfig {
|
|
|
72
73
|
fastrouter_api_key?: string;
|
|
73
74
|
tokenrouter_api_key?: string;
|
|
74
75
|
bai_api_key?: string;
|
|
76
|
+
openmodel_api_key?: string;
|
|
77
|
+
kilo_api_key?: string;
|
|
78
|
+
cline_api_key?: string;
|
|
75
79
|
kilo_free_only?: boolean;
|
|
76
80
|
hidden_models?: string[];
|
|
77
81
|
free_only?: boolean;
|
|
@@ -90,6 +94,7 @@ interface PiFreeConfig {
|
|
|
90
94
|
fastrouter_show_paid?: boolean;
|
|
91
95
|
tokenrouter_show_paid?: boolean;
|
|
92
96
|
bai_show_paid?: boolean;
|
|
97
|
+
openmodel_show_paid?: boolean;
|
|
93
98
|
openrouter_show_paid?: boolean;
|
|
94
99
|
opencode_show_paid?: boolean;
|
|
95
100
|
}
|
|
@@ -109,6 +114,9 @@ const CONFIG_TEMPLATE: PiFreeConfig = {
|
|
|
109
114
|
fastrouter_api_key: "",
|
|
110
115
|
tokenrouter_api_key: "",
|
|
111
116
|
bai_api_key: "",
|
|
117
|
+
openmodel_api_key: "",
|
|
118
|
+
kilo_api_key: "",
|
|
119
|
+
cline_api_key: "",
|
|
112
120
|
|
|
113
121
|
kilo_free_only: false,
|
|
114
122
|
hidden_models: [],
|
|
@@ -128,6 +136,7 @@ const CONFIG_TEMPLATE: PiFreeConfig = {
|
|
|
128
136
|
fastrouter_show_paid: false,
|
|
129
137
|
tokenrouter_show_paid: false,
|
|
130
138
|
bai_show_paid: false,
|
|
139
|
+
openmodel_show_paid: false,
|
|
131
140
|
openrouter_show_paid: false,
|
|
132
141
|
opencode_show_paid: false,
|
|
133
142
|
};
|
|
@@ -262,19 +271,60 @@ const PROVIDER_META: readonly ProviderMeta[] = [
|
|
|
262
271
|
{ id: PROVIDER_CLINE, prefix: "CLINE", showPaidKey: "cline_show_paid" },
|
|
263
272
|
{ id: PROVIDER_ZENMUX, prefix: "ZENMUX", showPaidKey: "zenmux_show_paid" },
|
|
264
273
|
{ id: PROVIDER_CROFAI, prefix: "CROFAI", showPaidKey: "crofai_show_paid" },
|
|
265
|
-
{
|
|
274
|
+
{
|
|
275
|
+
id: PROVIDER_CODESTRAL,
|
|
276
|
+
prefix: "CODESTRAL",
|
|
277
|
+
showPaidKey: "codestral_show_paid",
|
|
278
|
+
},
|
|
266
279
|
{ id: PROVIDER_LLM7, prefix: "LLM7", showPaidKey: "llm7_show_paid" },
|
|
267
|
-
{
|
|
268
|
-
|
|
269
|
-
|
|
280
|
+
{
|
|
281
|
+
id: PROVIDER_DEEPINFRA,
|
|
282
|
+
prefix: "DEEPINFRA",
|
|
283
|
+
showPaidKey: "deepinfra_show_paid",
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
id: PROVIDER_SAMBANOVA,
|
|
287
|
+
prefix: "SAMBANOVA",
|
|
288
|
+
showPaidKey: "sambanova_show_paid",
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
id: PROVIDER_TOGETHER,
|
|
292
|
+
prefix: "TOGETHER",
|
|
293
|
+
showPaidKey: "together_show_paid",
|
|
294
|
+
},
|
|
270
295
|
{ id: PROVIDER_NOVITA, prefix: "NOVITA", showPaidKey: "novita_show_paid" },
|
|
271
|
-
{
|
|
272
|
-
|
|
296
|
+
{
|
|
297
|
+
id: PROVIDER_ROUTEWAY,
|
|
298
|
+
prefix: "ROUTEWAY",
|
|
299
|
+
showPaidKey: "routeway_show_paid",
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
id: PROVIDER_TOKENROUTER,
|
|
303
|
+
prefix: "TOKENROUTER",
|
|
304
|
+
showPaidKey: "tokenrouter_show_paid",
|
|
305
|
+
},
|
|
273
306
|
{ id: PROVIDER_BAI, prefix: "BAI", showPaidKey: "bai_show_paid" },
|
|
274
|
-
{
|
|
307
|
+
{
|
|
308
|
+
id: PROVIDER_OPENMODEL,
|
|
309
|
+
prefix: "OPENMODEL",
|
|
310
|
+
showPaidKey: "openmodel_show_paid",
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
id: PROVIDER_FASTROUTER,
|
|
314
|
+
prefix: "FASTROUTER",
|
|
315
|
+
showPaidKey: "fastrouter_show_paid",
|
|
316
|
+
},
|
|
275
317
|
{ id: PROVIDER_OLLAMA, prefix: "OLLAMA", showPaidKey: "ollama_show_paid" },
|
|
276
|
-
{
|
|
277
|
-
|
|
318
|
+
{
|
|
319
|
+
id: PROVIDER_OPENROUTER,
|
|
320
|
+
prefix: "OPENROUTER",
|
|
321
|
+
showPaidKey: "openrouter_show_paid",
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
id: PROVIDER_OPENCODE,
|
|
325
|
+
prefix: "OPENCODE",
|
|
326
|
+
showPaidKey: "opencode_show_paid",
|
|
327
|
+
},
|
|
278
328
|
];
|
|
279
329
|
|
|
280
330
|
const PROVIDER_META_BY_ID = new Map(PROVIDER_META.map((m) => [m.id, m]));
|
|
@@ -288,7 +338,10 @@ function resolveShowPaidForProvider(providerId: string): boolean {
|
|
|
288
338
|
if (!meta) return false;
|
|
289
339
|
const cfg = loadConfigFile();
|
|
290
340
|
const fileVal = cfg[meta.showPaidKey];
|
|
291
|
-
return resolveBool(
|
|
341
|
+
return resolveBool(
|
|
342
|
+
`${meta.prefix}_SHOW_PAID`,
|
|
343
|
+
fileVal as boolean | undefined,
|
|
344
|
+
);
|
|
292
345
|
}
|
|
293
346
|
|
|
294
347
|
// =============================================================================
|
|
@@ -359,6 +412,13 @@ export function getBaiShowPaid(): boolean {
|
|
|
359
412
|
return resolveBool("BAI_SHOW_PAID", loadConfigFile().bai_show_paid);
|
|
360
413
|
}
|
|
361
414
|
|
|
415
|
+
export function getOpenmodelShowPaid(): boolean {
|
|
416
|
+
return resolveBool(
|
|
417
|
+
"OPENMODEL_SHOW_PAID",
|
|
418
|
+
loadConfigFile().openmodel_show_paid,
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
|
|
362
422
|
export function getFastrouterShowPaid(): boolean {
|
|
363
423
|
return resolveBool(
|
|
364
424
|
"FASTROUTER_SHOW_PAID",
|
|
@@ -453,6 +513,18 @@ export function getBaiApiKey(): string | undefined {
|
|
|
453
513
|
return resolve("BAI_API_KEY", loadConfigFile().bai_api_key);
|
|
454
514
|
}
|
|
455
515
|
|
|
516
|
+
export function getOpenmodelApiKey(): string | undefined {
|
|
517
|
+
return resolve("OPENMODEL_API_KEY", loadConfigFile().openmodel_api_key);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
export function getKiloApiKey(): string | undefined {
|
|
521
|
+
return resolve("KILO_API_KEY", loadConfigFile().kilo_api_key);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
export function getClineApiKey(): string | undefined {
|
|
525
|
+
return resolve("CLINE_API_KEY", loadConfigFile().cline_api_key);
|
|
526
|
+
}
|
|
527
|
+
|
|
456
528
|
export function getOllamaApiKey(): string | undefined {
|
|
457
529
|
return resolve("OLLAMA_API_KEY", loadConfigFile().ollama_api_key);
|
|
458
530
|
}
|
package/constants.ts
CHANGED
|
@@ -25,6 +25,8 @@ export const PROVIDER_NOVITA = "novita";
|
|
|
25
25
|
export const PROVIDER_ROUTEWAY = "routeway";
|
|
26
26
|
export const PROVIDER_TOKENROUTER = "tokenrouter";
|
|
27
27
|
export const PROVIDER_BAI = "bai";
|
|
28
|
+
export const PROVIDER_OPENMODEL = "openmodel";
|
|
29
|
+
export const PROVIDER_QODER = "qoder";
|
|
28
30
|
|
|
29
31
|
// Built-in pi providers that pi-free wraps with toggles
|
|
30
32
|
export const PROVIDER_OPENROUTER = "openrouter";
|
|
@@ -49,6 +51,8 @@ export const ALL_UNIQUE_PROVIDERS = [
|
|
|
49
51
|
PROVIDER_ROUTEWAY,
|
|
50
52
|
PROVIDER_TOKENROUTER,
|
|
51
53
|
PROVIDER_BAI,
|
|
54
|
+
PROVIDER_OPENMODEL,
|
|
55
|
+
PROVIDER_QODER,
|
|
52
56
|
] as const;
|
|
53
57
|
|
|
54
58
|
// =============================================================================
|
|
@@ -73,7 +77,13 @@ export const BASE_URL_NOVITA = "https://api.novita.ai/openai/v1";
|
|
|
73
77
|
export const BASE_URL_ROUTEWAY = "https://api.routeway.ai/v1";
|
|
74
78
|
export const BASE_URL_TOKENROUTER = "https://api.tokenrouter.com/v1";
|
|
75
79
|
export const BASE_URL_BAI = "https://api.b.ai/v1";
|
|
76
|
-
|
|
80
|
+
/**
|
|
81
|
+
* OpenModel is registered with `api: "anthropic-messages"`. The pi-ai
|
|
82
|
+
* Anthropic SDK appends `/v1/messages` to `baseURL`, so the base must
|
|
83
|
+
* NOT include `/v1`. See {@link PROVIDER_OPENMODEL}.
|
|
84
|
+
*/
|
|
85
|
+
export const BASE_URL_OPENMODEL = "https://api.openmodel.ai";
|
|
86
|
+
export const BASE_URL_QODER = "https://api3.qoder.sh";
|
|
77
87
|
|
|
78
88
|
/** Cline fetches free models from OpenRouter */
|
|
79
89
|
export const BASE_URL_OPENROUTER = "https://openrouter.ai/api/v1";
|
package/index.ts
CHANGED
|
@@ -44,6 +44,8 @@ import tokenRouter from "./providers/tokenrouter/tokenrouter.ts";
|
|
|
44
44
|
import ollama from "./providers/ollama/ollama.ts";
|
|
45
45
|
import zenmux from "./providers/zenmux/zenmux.ts";
|
|
46
46
|
import bai from "./providers/bai/bai.ts";
|
|
47
|
+
import openmodel from "./providers/openmodel/openmodel.ts";
|
|
48
|
+
import qoder from "./providers/qoder/qoder.ts";
|
|
47
49
|
|
|
48
50
|
/**
|
|
49
51
|
* Single source of truth for unique provider extensions (providers NOT
|
|
@@ -68,6 +70,8 @@ const UNIQUE_PROVIDERS: ReadonlyArray<(pi: ExtensionAPI) => Promise<void>> = [
|
|
|
68
70
|
routeway,
|
|
69
71
|
tokenRouter,
|
|
70
72
|
bai,
|
|
73
|
+
openmodel,
|
|
74
|
+
qoder,
|
|
71
75
|
];
|
|
72
76
|
|
|
73
77
|
const _logger = createLogger("pi-free");
|
|
@@ -188,7 +192,17 @@ function setupGlobalCommands(pi: ExtensionAPI) {
|
|
|
188
192
|
|
|
189
193
|
const lines = ["📊 Model Telemetry:", ""];
|
|
190
194
|
lines.push(
|
|
191
|
-
|
|
195
|
+
"Model".padEnd(40) +
|
|
196
|
+
" " +
|
|
197
|
+
"Calls".padEnd(6) +
|
|
198
|
+
" " +
|
|
199
|
+
"OK%".padEnd(6) +
|
|
200
|
+
" " +
|
|
201
|
+
"Lat".padEnd(7) +
|
|
202
|
+
" " +
|
|
203
|
+
"tok/s".padEnd(7) +
|
|
204
|
+
" " +
|
|
205
|
+
"Cost",
|
|
192
206
|
);
|
|
193
207
|
lines.push(`─`.repeat(75));
|
|
194
208
|
|