pi-free 2.1.0 → 2.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/CHANGELOG.md +48 -3
- package/README.md +32 -4
- package/banner.svg +1 -1
- package/config.ts +644 -629
- package/constants.ts +4 -0
- package/index.ts +380 -378
- package/lib/built-in-toggle.ts +0 -40
- package/lib/probe-cache.ts +8 -0
- package/lib/provider-probe.ts +15 -0
- package/package.json +5 -5
- package/provider-helper.ts +1 -25
- package/providers/bai/bai.ts +232 -0
- package/providers/cline/cline-xml-bridge.ts +631 -105
- package/providers/cline/cline.ts +0 -23
- package/providers/codestral/codestral.ts +0 -11
- package/providers/dynamic-built-in/index.ts +12 -20
- package/providers/kilo/kilo.ts +2 -19
- package/providers/ollama/ollama.ts +12 -12
- package/providers/routeway/routeway.ts +10 -0
- package/providers/tokenrouter/tokenrouter.ts +634 -378
package/providers/cline/cline.ts
CHANGED
|
@@ -163,29 +163,6 @@ export default async function clineProvider(pi: ExtensionAPI) {
|
|
|
163
163
|
},
|
|
164
164
|
});
|
|
165
165
|
|
|
166
|
-
// ── Status bar for provider selection ─────────────────────────
|
|
167
|
-
|
|
168
|
-
pi.on("model_select", (_event, ctx) => {
|
|
169
|
-
if (_event.model?.provider !== PROVIDER_CLINE) {
|
|
170
|
-
ctx.ui.setStatus(`${PROVIDER_CLINE}-status`, undefined);
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const free = stored.free.length;
|
|
175
|
-
const total = stored.all.length;
|
|
176
|
-
const paid = total - free;
|
|
177
|
-
const mode = toggleState.getCurrentMode();
|
|
178
|
-
let status: string;
|
|
179
|
-
if (paid === 0) {
|
|
180
|
-
status = `cline: ${free} free models`;
|
|
181
|
-
} else if (mode === "all") {
|
|
182
|
-
status = `cline: ${total} models (free + paid)`;
|
|
183
|
-
} else {
|
|
184
|
-
status = `cline: ${free} free \u00b7 ${paid} paid`;
|
|
185
|
-
}
|
|
186
|
-
ctx.ui.setStatus(`${PROVIDER_CLINE}-status`, status);
|
|
187
|
-
});
|
|
188
|
-
|
|
189
166
|
pi.on("before_agent_start", (_event, ctx) => {
|
|
190
167
|
if (ctx.model?.provider !== PROVIDER_CLINE) return;
|
|
191
168
|
_currentTaskId = generateUlid();
|
|
@@ -125,15 +125,4 @@ export default async function codestralProvider(pi: ExtensionAPI) {
|
|
|
125
125
|
|
|
126
126
|
_logger.info(`[codestral] Registered codestral-latest via ${keySource}`);
|
|
127
127
|
|
|
128
|
-
// Status bar
|
|
129
|
-
pi.on("model_select", (_event, ctx) => {
|
|
130
|
-
if (_event.model?.provider !== PROVIDER_CODESTRAL) {
|
|
131
|
-
ctx.ui.setStatus(`${PROVIDER_CODESTRAL}-status`, undefined);
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
ctx.ui.setStatus(
|
|
135
|
-
`${PROVIDER_CODESTRAL}-status`,
|
|
136
|
-
`codestral: 1 model (free tier) 🔑`,
|
|
137
|
-
);
|
|
138
|
-
});
|
|
139
128
|
}
|
|
@@ -45,6 +45,7 @@ import { createLogger } from "../../lib/logger.ts";
|
|
|
45
45
|
import { safeEnrichModelsWithModelsDev } from "../../lib/model-metadata.ts";
|
|
46
46
|
import { getProxyModelCompat } from "../../lib/provider-compat.ts";
|
|
47
47
|
import {
|
|
48
|
+
areAllModelsFresh,
|
|
48
49
|
getModelsDueForProbe,
|
|
49
50
|
recordModelProbeResults,
|
|
50
51
|
} from "../../lib/probe-cache.ts";
|
|
@@ -563,26 +564,6 @@ async function registerProvider(
|
|
|
563
564
|
true,
|
|
564
565
|
);
|
|
565
566
|
|
|
566
|
-
// Status bar
|
|
567
|
-
const pid = config.providerId;
|
|
568
|
-
pi.on("model_select", (_event, ctx) => {
|
|
569
|
-
if (_event.model?.provider !== pid) {
|
|
570
|
-
ctx.ui.setStatus(`${pid}-status`, undefined);
|
|
571
|
-
return;
|
|
572
|
-
}
|
|
573
|
-
const f = freeModels.length;
|
|
574
|
-
const t = allModels.length;
|
|
575
|
-
const p = t - f;
|
|
576
|
-
const mode = toggleState.getCurrentMode();
|
|
577
|
-
const status =
|
|
578
|
-
p === 0
|
|
579
|
-
? `${pid}: ${f} free models`
|
|
580
|
-
: mode === "all"
|
|
581
|
-
? `${pid}: ${t} models (free + paid)`
|
|
582
|
-
: `${pid}: ${f} free \u00b7 ${p} paid`;
|
|
583
|
-
ctx.ui.setStatus(`${pid}-status`, `${status} 🔑`);
|
|
584
|
-
});
|
|
585
|
-
|
|
586
567
|
// Register models (this swaps in our discovered models over Pi's defaults)
|
|
587
568
|
toggleState.applyCurrent(reRegister);
|
|
588
569
|
|
|
@@ -625,6 +606,17 @@ async function registerProvider(
|
|
|
625
606
|
wrapSessionStartHandler(`${config.providerId}-auto-probe`, async () => {
|
|
626
607
|
if (_autoProbeDone) return;
|
|
627
608
|
_autoProbeDone = true;
|
|
609
|
+
if (
|
|
610
|
+
areAllModelsFresh(
|
|
611
|
+
config.providerId,
|
|
612
|
+
stored.free.map((m) => m.id),
|
|
613
|
+
)
|
|
614
|
+
) {
|
|
615
|
+
_logger.info(
|
|
616
|
+
`[probe] ${config.providerId}: auto-probe cache is fresh`,
|
|
617
|
+
);
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
628
620
|
_logger.info(
|
|
629
621
|
`Starting lazy auto-probe of ${config.providerId} free models...`,
|
|
630
622
|
);
|
package/providers/kilo/kilo.ts
CHANGED
|
@@ -326,27 +326,10 @@ export default async function kiloProvider(pi: ExtensionAPI) {
|
|
|
326
326
|
},
|
|
327
327
|
});
|
|
328
328
|
|
|
329
|
-
//
|
|
329
|
+
// ToS notice on provider selection
|
|
330
330
|
let tosShown = false;
|
|
331
331
|
pi.on("model_select", async (_event, ctx) => {
|
|
332
|
-
if (ctx.model?.provider !== PROVIDER_KILO)
|
|
333
|
-
ctx.ui.setStatus(`${PROVIDER_KILO}-status`, undefined);
|
|
334
|
-
return;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Build status line
|
|
338
|
-
const free = freeModels.length;
|
|
339
|
-
const total = allModels.length;
|
|
340
|
-
const paid = total - free;
|
|
341
|
-
let status: string;
|
|
342
|
-
if (paid === 0) {
|
|
343
|
-
status = `kilo: ${free} free models`;
|
|
344
|
-
} else if (showPaidModels) {
|
|
345
|
-
status = `kilo: ${total} models (free + paid)`;
|
|
346
|
-
} else {
|
|
347
|
-
status = `kilo: ${free} free \u00b7 ${paid} paid`;
|
|
348
|
-
}
|
|
349
|
-
ctx.ui.setStatus(`${PROVIDER_KILO}-status`, status);
|
|
332
|
+
if (ctx.model?.provider !== PROVIDER_KILO) return;
|
|
350
333
|
|
|
351
334
|
// ToS notice (once)
|
|
352
335
|
if (tosShown) return;
|
|
@@ -43,6 +43,7 @@ import {
|
|
|
43
43
|
} from "../../lib/provider-cache.ts";
|
|
44
44
|
import { wrapSessionStartHandler } from "../../lib/session-start-metrics.ts";
|
|
45
45
|
import {
|
|
46
|
+
areAllModelsFresh,
|
|
46
47
|
getModelsDueForProbe,
|
|
47
48
|
recordModelProbeResults,
|
|
48
49
|
} from "../../lib/probe-cache.ts";
|
|
@@ -591,20 +592,19 @@ export default async function ollamaProvider(pi: ExtensionAPI) {
|
|
|
591
592
|
},
|
|
592
593
|
});
|
|
593
594
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
if (
|
|
599
|
-
|
|
595
|
+
const runProbeInBackground = (models: ProviderModelConfig[]) => {
|
|
596
|
+
// Skip scheduling entirely if every model was probed recently.
|
|
597
|
+
// Without this check the probe runs on every session_start and
|
|
598
|
+
// only then discovers the cache is fresh inside runOllamaProbe.
|
|
599
|
+
if (
|
|
600
|
+
areAllModelsFresh(
|
|
601
|
+
PROVIDER_OLLAMA,
|
|
602
|
+
models.map((m) => m.id),
|
|
603
|
+
)
|
|
604
|
+
) {
|
|
605
|
+
_logger.info("Auto-probe: Ollama probe cache is fresh");
|
|
600
606
|
return;
|
|
601
607
|
}
|
|
602
|
-
|
|
603
|
-
const count = allModels.length;
|
|
604
|
-
ctx.ui.setStatus(`${PROVIDER_OLLAMA}-status`, `ollama: ${count} models`);
|
|
605
|
-
});
|
|
606
|
-
|
|
607
|
-
const runProbeInBackground = (models: ProviderModelConfig[]) => {
|
|
608
608
|
runOllamaProbe(apiKey, models, applyModelList, { useCache: true }).catch(
|
|
609
609
|
(error) => {
|
|
610
610
|
_logger.warn("Auto-probe failed", {
|
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
isLikelyReasoningModel,
|
|
38
38
|
} from "../../lib/provider-compat.ts";
|
|
39
39
|
import {
|
|
40
|
+
areAllModelsFresh,
|
|
40
41
|
getModelsDueForProbe,
|
|
41
42
|
recordModelProbeResults,
|
|
42
43
|
} from "../../lib/probe-cache.ts";
|
|
@@ -350,6 +351,15 @@ export default async function routewayProvider(pi: ExtensionAPI) {
|
|
|
350
351
|
wrapSessionStartHandler("routeway", async () => {
|
|
351
352
|
if (_autoProbeDone || !apiKey) return;
|
|
352
353
|
_autoProbeDone = true;
|
|
354
|
+
if (
|
|
355
|
+
areAllModelsFresh(
|
|
356
|
+
PROVIDER_ROUTEWAY,
|
|
357
|
+
allModels.map((m) => m.id),
|
|
358
|
+
)
|
|
359
|
+
) {
|
|
360
|
+
_logger.info("Auto-probe: Routeway probe cache is fresh");
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
353
363
|
_logger.info("Starting lazy auto-probe of Routeway models...");
|
|
354
364
|
runRoutewayProbe(apiKey, allModels, stored, reRegister, {
|
|
355
365
|
useCache: true,
|