opencode-pollinations-plugin 6.4.9 → 6.4.10
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.de.md +5 -4
- package/README.es.md +5 -4
- package/README.fr.md +5 -4
- package/README.it.md +5 -4
- package/README.zh.md +5 -4
- package/dist/locales/de.json +3 -0
- package/dist/locales/en.json +3 -0
- package/dist/locales/es.json +3 -0
- package/dist/locales/fr.json +3 -0
- package/dist/locales/it.json +3 -0
- package/dist/locales/zh.json +3 -0
- package/dist/server/commands.js +9 -71
- package/dist/server/config.js +1 -1
- package/dist/server/generate-config.js +2 -2
- package/dist/server/models/fetcher.js +2 -0
- package/dist/server/models/types.d.ts +2 -0
- package/dist/server/proxy.js +7 -10
- package/dist/server/scripts/pollinations_pricing.js +6 -3
- package/package.json +62 -62
package/README.de.md
CHANGED
|
@@ -97,10 +97,11 @@ Das **Pollen 🌻** ist unser zentrales Kreditsystem (1$ ≈ 1 Pollen). Verbinde
|
|
|
97
97
|
|
|
98
98
|
| Tier (Stufe) | Stündliche Aufladung ⏱️ | Schätzung Tag* | Voraussetzung |
|
|
99
99
|
| :--- | :--- | :--- | :--- |
|
|
100
|
-
| 🍄 **Spore** | **0.01 Pollen / Std.** | ~0.24 / Tag |
|
|
101
|
-
| 🌱 **Seed** | **0.15 Pollen / Std.** | ~3.6 / Tag |
|
|
102
|
-
| 🌸 **Flower** | **0.40 Pollen / Std.** | ~9.6 / Tag |
|
|
103
|
-
| 🍯 **Nectar** | **0.80 Pollen / Std.** | ~19.2 / Tag |
|
|
100
|
+
| 🍄 **Spore** | **0.01 Pollen / Std.** | ~0.24 / Tag | Neues Konto (Standard) |
|
|
101
|
+
| 🌱 **Seed** | **0.15 Pollen / Std.** | ~3.6 / Tag | Aktives Community-Mitglied |
|
|
102
|
+
| 🌸 **Flower** | **0.40 Pollen / Std.** | ~9.6 / Tag | Quests abschließen & beitragen |
|
|
103
|
+
| 🍯 **Nectar** | **0.80 Pollen / Std.** | ~19.2 / Tag | Top-Mitwirkender |
|
|
104
|
+
| 🐝 **Router** | **10 Pollen / Std.** | ~240 / Tag | Speziell / nur auf Einladung |
|
|
104
105
|
|
|
105
106
|
_*Tägliche Schätzungen sind nur Näherungswerte (~24h × Stundenrate). Das Reset findet automatisch zur vollen Stunde (XX:00) statt._
|
|
106
107
|
|
package/README.es.md
CHANGED
|
@@ -97,10 +97,11 @@ El **Pollen 🌻** dicta la ley unificada del crédito (1$ ≈ 1 Pollen). Sólo
|
|
|
97
97
|
|
|
98
98
|
| Tier | Recarga Hora ⏱️ | Aprox Diario* | Requisito a Cumplir |
|
|
99
99
|
| :--- | :--- | :--- | :--- |
|
|
100
|
-
| 🍄 **Spore** | **0.01 Pollen / hora** | ~0.24 /día |
|
|
101
|
-
| 🌱 **Seed** | **0.15 Pollen / hora** | ~3.6 /día |
|
|
102
|
-
| 🌸 **Flower** | **0.40 Pollen / hora** | ~9.6 /día |
|
|
103
|
-
| 🍯 **Nectar** | **0.80 Pollen / hora** | ~19.2 /día |
|
|
100
|
+
| 🍄 **Spore** | **0.01 Pollen / hora** | ~0.24 /día | Cuenta nueva (predeterminado) |
|
|
101
|
+
| 🌱 **Seed** | **0.15 Pollen / hora** | ~3.6 /día | Miembro activo de la comunidad |
|
|
102
|
+
| 🌸 **Flower** | **0.40 Pollen / hora** | ~9.6 /día | Completa Misiones y contribuye |
|
|
103
|
+
| 🍯 **Nectar** | **0.80 Pollen / hora** | ~19.2 /día | Principal contribuidor |
|
|
104
|
+
| 🐝 **Router** | **10 Pollen / hora** | ~240 /día | Especial / solo por invitación |
|
|
104
105
|
|
|
105
106
|
_*Los cálculos diarios solo son estimaciones teóricas (~24h × cuota/hora). El reinicio limpio sucede exacto en el minuto `:00` de las horas del reloj._
|
|
106
107
|
|
package/README.fr.md
CHANGED
|
@@ -97,10 +97,11 @@ Le **Pollen 🌻** est notre système de crédit unifié (1$ ≈ 1 Pollen). En c
|
|
|
97
97
|
|
|
98
98
|
| Tier | Recharge Horaire ⏱️ | Estimation Jour* | Condition |
|
|
99
99
|
| :--- | :--- | :--- | :--- |
|
|
100
|
-
| 🍄 **Spore** | **0.01 Pollen / heure** | ~0.24 / jour |
|
|
101
|
-
| 🌱 **Seed** | **0.15 Pollen / heure** | ~3.6 / jour |
|
|
102
|
-
| 🌸 **Flower** | **0.40 Pollen / heure** | ~9.6 / jour |
|
|
103
|
-
| 🍯 **Nectar** | **0.80 Pollen / heure** | ~19.2 / jour |
|
|
100
|
+
| 🍄 **Spore** | **0.01 Pollen / heure** | ~0.24 / jour | Nouveau compte (par défaut) |
|
|
101
|
+
| 🌱 **Seed** | **0.15 Pollen / heure** | ~3.6 / jour | Membre actif de la communauté |
|
|
102
|
+
| 🌸 **Flower** | **0.40 Pollen / heure** | ~9.6 / jour | Compléter des Quêtes et contribuer |
|
|
103
|
+
| 🍯 **Nectar** | **0.80 Pollen / heure** | ~19.2 / jour | Contributeur de premier plan |
|
|
104
|
+
| 🐝 **Router** | **10 Pollen / heure** | ~240 / jour | Spécial / sur invitation |
|
|
104
105
|
|
|
105
106
|
_*Les estimations quotidiennes sont approximatives (~24h × taux horaire). La réinitialisation réelle s'effectue automatiquement au début de chaque heure (XX:00)._
|
|
106
107
|
|
package/README.it.md
CHANGED
|
@@ -97,10 +97,11 @@ Il **Pollen 🌻** è un sistema universale (1$ ≈ 1 Pollen). Immettendo una pr
|
|
|
97
97
|
|
|
98
98
|
| Tier (Livello) | Ricarica Oraria ⏱️ | Stima Giorno* | Requisito richiesto |
|
|
99
99
|
| :--- | :--- | :--- | :--- |
|
|
100
|
-
| 🍄 **Spore** | **0.01 Pollen / ora** | ~0.24 / giorno |
|
|
101
|
-
| 🌱 **Seed** | **0.15 Pollen / ora** | ~3.6 / giorno |
|
|
102
|
-
| 🌸 **Flower** | **0.40 Pollen / ora** | ~9.6 / giorno |
|
|
103
|
-
| 🍯 **Nectar** | **0.80 Pollen / ora** | ~19.2 / giorno |
|
|
100
|
+
| 🍄 **Spore** | **0.01 Pollen / ora** | ~0.24 / giorno | Nuovo account (predefinito) |
|
|
101
|
+
| 🌱 **Seed** | **0.15 Pollen / ora** | ~3.6 / giorno | Membro attivo della community |
|
|
102
|
+
| 🌸 **Flower** | **0.40 Pollen / ora** | ~9.6 / giorno | Completa le Missioni e contribuisci |
|
|
103
|
+
| 🍯 **Nectar** | **0.80 Pollen / ora** | ~19.2 / giorno | Contributore di punta |
|
|
104
|
+
| 🐝 **Router** | **10 Pollen / ora** | ~240 / giorno | Speciale / solo su invito |
|
|
104
105
|
|
|
105
106
|
_*La stima giornaliera è puramente teorica (~24h × quota oraria). I Pollen si rinfrescano in modo corretto all'istante di ogni cambio ora (`:00`)._
|
|
106
107
|
|
package/README.zh.md
CHANGED
|
@@ -97,10 +97,11 @@
|
|
|
97
97
|
|
|
98
98
|
| Tier (称号) | 每小时获取补贴量 ⏱️ | 无限循环参考值* | 达成条件 |
|
|
99
99
|
| :--- | :--- | :--- | :--- |
|
|
100
|
-
| 🍄 **Spore (孢子)** | **0.01 Pollen / 小时** | 每天约 ~0.24 |
|
|
101
|
-
| 🌱 **Seed (树种)** | **0.15 Pollen / 小时** | 每天约 ~3.6 |
|
|
102
|
-
| 🌸 **Flower (花朵)** | **0.40 Pollen / 小时** | 每天约 ~9.6 |
|
|
103
|
-
| 🍯 **Nectar (花蜜)** | **0.80 Pollen / 小时** | 每天约 ~19.2 |
|
|
100
|
+
| 🍄 **Spore (孢子)** | **0.01 Pollen / 小时** | 每天约 ~0.24 | 新账户(默认) |
|
|
101
|
+
| 🌱 **Seed (树种)** | **0.15 Pollen / 小时** | 每天约 ~3.6 | 活跃的社区成员 |
|
|
102
|
+
| 🌸 **Flower (花朵)** | **0.40 Pollen / 小时** | 每天约 ~9.6 | 完成任务并贡献 |
|
|
103
|
+
| 🍯 **Nectar (花蜜)** | **0.80 Pollen / 小时** | 每天约 ~19.2 | 顶级贡献者 |
|
|
104
|
+
| 🐝 **Router (路由)** | **10 Pollen / 小时** | 每天约 ~240 | 特殊 / 仅限邀请 |
|
|
104
105
|
|
|
105
106
|
_*所列出每天近似最大总额建立在前置满消(~24h × hourly rate)为理论上限。真实的花粉量都会准时在零点过的一分钟 (XX:00) 统一灌满池子里。_
|
|
106
107
|
|
package/dist/locales/de.json
CHANGED
|
@@ -488,7 +488,10 @@
|
|
|
488
488
|
"condition": {
|
|
489
489
|
"signup": "Einfach registrieren!",
|
|
490
490
|
"auto_verify": "Automatische Verifizierung",
|
|
491
|
+
"under_review": "Konto wird überprüft",
|
|
492
|
+
"default": "Neues Konto (Standard)",
|
|
491
493
|
"community": "Aktives Community-Mitglied",
|
|
494
|
+
"quests": "Quests abschließen & beitragen",
|
|
492
495
|
"publish_app": "Eine App veröffentlichen",
|
|
493
496
|
"top_contributor": "Top-Mitwirkender",
|
|
494
497
|
"special": "Speziell / nur auf Einladung"
|
package/dist/locales/en.json
CHANGED
|
@@ -488,7 +488,10 @@
|
|
|
488
488
|
"condition": {
|
|
489
489
|
"signup": "Just register",
|
|
490
490
|
"auto_verify": "Automatic verification",
|
|
491
|
+
"under_review": "Account under review",
|
|
492
|
+
"default": "New account (default)",
|
|
491
493
|
"community": "Active community member",
|
|
494
|
+
"quests": "Complete Quests & contribute",
|
|
492
495
|
"publish_app": "Publish an app",
|
|
493
496
|
"top_contributor": "Top contributor",
|
|
494
497
|
"special": "Special / invite-only"
|
package/dist/locales/es.json
CHANGED
|
@@ -488,7 +488,10 @@
|
|
|
488
488
|
"condition": {
|
|
489
489
|
"signup": "¡Solo regístrate!",
|
|
490
490
|
"auto_verify": "Verificación automática",
|
|
491
|
+
"under_review": "Cuenta en revisión",
|
|
492
|
+
"default": "Cuenta nueva (predeterminado)",
|
|
491
493
|
"community": "Miembro activo de la comunidad",
|
|
494
|
+
"quests": "Completa Misiones y contribuye",
|
|
492
495
|
"publish_app": "Publica una app",
|
|
493
496
|
"top_contributor": "Principal contribuidor",
|
|
494
497
|
"special": "Especial / solo por invitación"
|
package/dist/locales/fr.json
CHANGED
|
@@ -488,7 +488,10 @@
|
|
|
488
488
|
"condition": {
|
|
489
489
|
"signup": "Inscrivez-vous, c'est tout !",
|
|
490
490
|
"auto_verify": "Vérification automatique",
|
|
491
|
+
"under_review": "Compte en cours d'examen",
|
|
492
|
+
"default": "Nouveau compte (par défaut)",
|
|
491
493
|
"community": "Membre actif de la communauté",
|
|
494
|
+
"quests": "Compléter des Quêtes et contribuer",
|
|
492
495
|
"publish_app": "Publier une app",
|
|
493
496
|
"top_contributor": "Contributeur de premier plan",
|
|
494
497
|
"special": "Spécial / sur invitation"
|
package/dist/locales/it.json
CHANGED
|
@@ -488,7 +488,10 @@
|
|
|
488
488
|
"condition": {
|
|
489
489
|
"signup": "Basta registrarsi!",
|
|
490
490
|
"auto_verify": "Verifica automatica",
|
|
491
|
+
"under_review": "Account in revisione",
|
|
492
|
+
"default": "Nuovo account (predefinito)",
|
|
491
493
|
"community": "Membro attivo della community",
|
|
494
|
+
"quests": "Completa le Missioni e contribuisci",
|
|
492
495
|
"publish_app": "Pubblica un'app",
|
|
493
496
|
"top_contributor": "Contributore di punta",
|
|
494
497
|
"special": "Speciale / solo su invito"
|
package/dist/locales/zh.json
CHANGED
|
@@ -488,7 +488,10 @@
|
|
|
488
488
|
"condition": {
|
|
489
489
|
"signup": "只需注册",
|
|
490
490
|
"auto_verify": "自动验证",
|
|
491
|
+
"under_review": "账户审核中",
|
|
492
|
+
"default": "新账户(默认)",
|
|
491
493
|
"community": "活跃的社区成员",
|
|
494
|
+
"quests": "完成任务并贡献",
|
|
492
495
|
"publish_app": "发布一个应用",
|
|
493
496
|
"top_contributor": "顶级贡献者",
|
|
494
497
|
"special": "特殊 / 仅限邀请"
|
package/dist/server/commands.js
CHANGED
|
@@ -7,27 +7,6 @@ import { ModelRegistry } from './models/index.js';
|
|
|
7
7
|
import { t } from '../locales/index.js';
|
|
8
8
|
import { formatTierTable } from './tier-info.js';
|
|
9
9
|
import { buildQuestsReport } from '../tools/pollinations/polli_quests.js';
|
|
10
|
-
// GET helper for /account/* JSON endpoints (used for quest-reward reconstruction).
|
|
11
|
-
function fetchAccountJson(path, apiKey) {
|
|
12
|
-
return new Promise((resolve, reject) => {
|
|
13
|
-
const req = https.request({
|
|
14
|
-
hostname: 'gen.pollinations.ai', path, method: 'GET',
|
|
15
|
-
headers: { 'Authorization': `Bearer ${apiKey}`, 'User-Agent': 'opencode-pollinations-plugin' },
|
|
16
|
-
}, (res) => {
|
|
17
|
-
let data = '';
|
|
18
|
-
res.on('data', c => data += c);
|
|
19
|
-
res.on('end', () => { try {
|
|
20
|
-
resolve(JSON.parse(data));
|
|
21
|
-
}
|
|
22
|
-
catch (e) {
|
|
23
|
-
reject(e);
|
|
24
|
-
} });
|
|
25
|
-
});
|
|
26
|
-
req.on('error', reject);
|
|
27
|
-
req.setTimeout(10000, () => { req.destroy(); reject(new Error('Timeout')); });
|
|
28
|
-
req.end();
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
10
|
function checkEndpoint(ep, key) {
|
|
32
11
|
return new Promise((resolve) => {
|
|
33
12
|
const req = https.request({
|
|
@@ -262,43 +241,9 @@ export async function handleUsageCommand(args) {
|
|
|
262
241
|
response += t('commands.usage.tier', { emoji: quota.tierEmoji, tier: quota.tier.toUpperCase(), limit: quota.tierLimit });
|
|
263
242
|
response += t('commands.usage.quota', { remaining: formatPollen(quota.tierLimit - quota.tierRemaining), limit: formatPollen(quota.tierLimit) });
|
|
264
243
|
response += t('commands.usage.usage_bar', { bar: progressBar(quota.tierLimit - quota.tierRemaining, quota.tierLimit) });
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
// • current-hour floor remaining (≤ tierLimit) ← quota (the only fuzzy term, ignored)
|
|
269
|
-
// Quest remaining ≈ claimedQuestTier − tierConsumedSinceClaim (+ floor); Paid = Total − Quest.
|
|
270
|
-
const total = quota.tierRemaining + quota.walletBalance; // true balance
|
|
271
|
-
let claimedQuestTier = 0;
|
|
272
|
-
let firstClaimMs = Infinity;
|
|
273
|
-
let tierConsumedSinceClaim = 0;
|
|
274
|
-
if (config.apiKey && config.keyHasAccessToProfile !== false) {
|
|
275
|
-
try {
|
|
276
|
-
const qres = await fetchAccountJson('/account/quests', config.apiKey);
|
|
277
|
-
for (const q of (qres?.quests || [])) {
|
|
278
|
-
const r = q.reward;
|
|
279
|
-
if (r && r.claimedAt && r.balanceBucket === 'tier') {
|
|
280
|
-
claimedQuestTier += (r.pollenAmount || 0);
|
|
281
|
-
const cms = new Date(r.claimedAt).getTime();
|
|
282
|
-
if (!isNaN(cms) && cms < firstClaimMs)
|
|
283
|
-
firstClaimMs = cms;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
// Sum tier-metered spend since the first claim (what actually ate the Quest stash).
|
|
287
|
-
if (claimedQuestTier > 0 && isFinite(firstClaimMs)) {
|
|
288
|
-
const ures = await fetchAccountJson('/account/usage?limit=100', config.apiKey);
|
|
289
|
-
for (const e of (ures?.usage || [])) {
|
|
290
|
-
const ts = new Date(String(e.timestamp).replace(' ', 'T') + (String(e.timestamp).includes('Z') ? '' : 'Z')).getTime();
|
|
291
|
-
if (e.meter_source === 'tier' && !isNaN(ts) && ts >= firstClaimMs) {
|
|
292
|
-
tierConsumedSinceClaim += (e.cost_usd || 0);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
catch { /* fall back gracefully if unreachable */ }
|
|
298
|
-
}
|
|
299
|
-
// Quest stash = claimed − consumed, plus the current hourly floor still available.
|
|
300
|
-
const questPollen = Math.max(0, claimedQuestTier - tierConsumedSinceClaim) + quota.tierRemaining;
|
|
301
|
-
const paidPollen = Math.max(0, total - questPollen);
|
|
244
|
+
const total = quota.tierRemaining + quota.questStash + quota.walletBalance;
|
|
245
|
+
const questPollen = quota.tierRemaining + quota.questStash;
|
|
246
|
+
const paidPollen = quota.walletBalance;
|
|
302
247
|
response += t('commands.usage.split', {
|
|
303
248
|
quest: questPollen.toFixed(2),
|
|
304
249
|
paid: paidPollen.toFixed(2),
|
|
@@ -810,12 +755,16 @@ ${t('commands.help.models_pricing')}
|
|
|
810
755
|
}
|
|
811
756
|
// === MODELS & PRICING COMMANDS ===
|
|
812
757
|
function parseNameDesc(m) {
|
|
758
|
+
const displayName = m.title || m.description || m.name;
|
|
813
759
|
const fullDesc = m.description || m.name;
|
|
814
|
-
|
|
760
|
+
if (m.title && m.description) {
|
|
761
|
+
return { nom: m.title, desc: m.description };
|
|
762
|
+
}
|
|
763
|
+
const parts = displayName.split(" - ");
|
|
815
764
|
if (parts.length > 1) {
|
|
816
765
|
return { nom: parts[0].trim(), desc: parts.slice(1).join(" - ").trim() };
|
|
817
766
|
}
|
|
818
|
-
return { nom:
|
|
767
|
+
return { nom: displayName, desc: "" };
|
|
819
768
|
}
|
|
820
769
|
export async function handleModelsCommand(args) {
|
|
821
770
|
const filter = args[0]; // optional: image, video, audio, text
|
|
@@ -956,17 +905,7 @@ function buildOutputCost(m) {
|
|
|
956
905
|
export async function handleInfosCommand() {
|
|
957
906
|
const config = loadConfig();
|
|
958
907
|
let name = "Developer";
|
|
959
|
-
let tier = "anonymous";
|
|
960
|
-
let tierEmoji = '👤';
|
|
961
908
|
if (config.apiKey) {
|
|
962
|
-
try {
|
|
963
|
-
const quota = await getQuotaStatus(true);
|
|
964
|
-
tier = quota.tier || 'anonymous';
|
|
965
|
-
tierEmoji = quota.tierEmoji || '👤';
|
|
966
|
-
}
|
|
967
|
-
catch (e) {
|
|
968
|
-
// Ignorer l'erreur réseau et garder les valeurs par défaut
|
|
969
|
-
}
|
|
970
909
|
try {
|
|
971
910
|
const res = await fetch('https://gen.pollinations.ai/account/profile', {
|
|
972
911
|
headers: { 'Authorization': `Bearer ${config.apiKey}` }
|
|
@@ -992,7 +931,6 @@ ${t('commands.infos.features_pro')}
|
|
|
992
931
|
|
|
993
932
|
${t('commands.infos.features_config')}
|
|
994
933
|
|
|
995
|
-
${t('commands.infos.tiers_title', { emoji: tierEmoji, tier: tier.toUpperCase() })}
|
|
996
934
|
${t('commands.infos.get_started')}
|
|
997
935
|
|
|
998
936
|
${t('commands.infos.about')}
|
package/dist/server/config.js
CHANGED
|
@@ -73,7 +73,7 @@ const DEFAULT_CONFIG_V5 = {
|
|
|
73
73
|
gui: { status: 'alert', logs: 'none' },
|
|
74
74
|
thresholds: { tier: 10, wallet: 5 },
|
|
75
75
|
fallbacks: {
|
|
76
|
-
free: { main: 'free/
|
|
76
|
+
free: { main: 'free/openai-fast', agent: 'free/openai-fast' },
|
|
77
77
|
enter: { agent: 'free/openai-fast' }
|
|
78
78
|
},
|
|
79
79
|
enablePaidTools: false,
|
|
@@ -71,7 +71,7 @@ export async function generatePollinationsConfig(forceApiKey, forceStrict = fals
|
|
|
71
71
|
catch (e) {
|
|
72
72
|
log(`Error fetching Free models: ${e}`);
|
|
73
73
|
// Fallback Robust (Offline support)
|
|
74
|
-
modelsOutput.push({ id: "free/
|
|
74
|
+
modelsOutput.push({ id: "free/openai-fast", name: "GPT-5 Nano (Fallback)", object: "model", variants: {} });
|
|
75
75
|
modelsOutput.push({ id: "free/openai", name: "OpenAI (Fallback)", object: "model", variants: {} });
|
|
76
76
|
modelsOutput.push({ id: "free/gemini", name: "Gemini Flash (Fallback)", object: "model", variants: {} });
|
|
77
77
|
}
|
|
@@ -152,7 +152,7 @@ function getCapabilityIcons(raw) {
|
|
|
152
152
|
function mapModel(raw, prefix, namePrefix) {
|
|
153
153
|
const rawId = raw.id || raw.name;
|
|
154
154
|
const fullId = prefix + rawId; // ex: "free/gemini" or "enter/nomnom" (prefix passed is "enter/")
|
|
155
|
-
let baseName = raw.description;
|
|
155
|
+
let baseName = raw.title || raw.description;
|
|
156
156
|
if (!baseName || baseName === rawId) {
|
|
157
157
|
baseName = formatName(rawId, raw.censored !== false);
|
|
158
158
|
}
|
|
@@ -79,6 +79,8 @@ function mapRawToModel(raw, fallbackCategory, averageCost) {
|
|
|
79
79
|
};
|
|
80
80
|
const model = {
|
|
81
81
|
name: raw.name || raw.id || 'unknown',
|
|
82
|
+
title: raw.title || undefined,
|
|
83
|
+
brand: raw.brand || undefined,
|
|
82
84
|
description: raw.description || raw.name || '',
|
|
83
85
|
category,
|
|
84
86
|
aliases: raw.aliases || [],
|
package/dist/server/proxy.js
CHANGED
|
@@ -338,13 +338,7 @@ export async function handleChatCompletion(req, res, bodyRaw) {
|
|
|
338
338
|
// Check dynamic list saved by generate-config.ts
|
|
339
339
|
if (isEnterprise) {
|
|
340
340
|
try {
|
|
341
|
-
const
|
|
342
|
-
// Wait, logic above for config path is messy. Let's use standard path logic:
|
|
343
|
-
// config.ts uses ~/.pollinations/config.json usually.
|
|
344
|
-
// generate-config uses path.join(config.gui ? path.dirname(CONFIG_FILE) : '/tmp')
|
|
345
|
-
// Let's rely on standard ~/.pollinations location if possible, or try both.
|
|
346
|
-
const homedir = process.env.HOME || '/tmp';
|
|
347
|
-
const standardPaidPath = path.join(homedir, '.pollinations', 'pollinations-paid-models.json');
|
|
341
|
+
const standardPaidPath = path.join(getConfigDir(), 'pollinations-paid-models.json');
|
|
348
342
|
if (fs.existsSync(standardPaidPath)) {
|
|
349
343
|
const paidModels = JSON.parse(fs.readFileSync(standardPaidPath, 'utf-8'));
|
|
350
344
|
if (paidModels.includes(actualModel)) {
|
|
@@ -389,8 +383,7 @@ export async function handleChatCompletion(req, res, bodyRaw) {
|
|
|
389
383
|
if (isEnterprise) {
|
|
390
384
|
// Paid Only Check: BLOCK (not fallback) in AlwaysFree mode
|
|
391
385
|
try {
|
|
392
|
-
const
|
|
393
|
-
const standardPaidPath = path.join(homedir, '.pollinations', 'pollinations-paid-models.json');
|
|
386
|
+
const standardPaidPath = path.join(getConfigDir(), 'pollinations-paid-models.json');
|
|
394
387
|
if (fs.existsSync(standardPaidPath)) {
|
|
395
388
|
const paidModels = JSON.parse(fs.readFileSync(standardPaidPath, 'utf-8'));
|
|
396
389
|
if (paidModels.includes(actualModel)) {
|
|
@@ -561,6 +554,10 @@ export async function handleChatCompletion(req, res, bodyRaw) {
|
|
|
561
554
|
if (actualModel.includes("gpt") || actualModel.includes("openai") || actualModel.includes("azure") || actualModel.includes("midijourney") || actualModel.includes("grok")) {
|
|
562
555
|
const limit = (actualModel.includes("midijourney") || actualModel.includes("grok")) ? 128 : 120;
|
|
563
556
|
proxyBody.tools = truncateTools(proxyBody.tools, limit);
|
|
557
|
+
if (proxyBody.reasoning_effort)
|
|
558
|
+
delete proxyBody.reasoning_effort;
|
|
559
|
+
if (proxyBody.reasoningEffort)
|
|
560
|
+
delete proxyBody.reasoningEffort;
|
|
564
561
|
if (proxyBody.messages) {
|
|
565
562
|
proxyBody.messages.forEach((m) => {
|
|
566
563
|
if (m.tool_calls) {
|
|
@@ -702,7 +699,7 @@ export async function handleChatCompletion(req, res, bodyRaw) {
|
|
|
702
699
|
// TRANSPARENT FALLBACK LOGIC
|
|
703
700
|
// 1. Enterprise Safety Net (Quota/Auth/RateLimit)
|
|
704
701
|
// 2. Gemini Tools Fix (Gemini + Tools -> 401 -> Fallback to OpenAI)
|
|
705
|
-
const isEnterpriseFallback = (fetchRes.status === 402 || fetchRes.status === 429 || fetchRes.status === 401 || fetchRes.status === 403) && isEnterprise;
|
|
702
|
+
const isEnterpriseFallback = (fetchRes.status === 402 || fetchRes.status === 429 || fetchRes.status === 502 || fetchRes.status === 401 || fetchRes.status === 403) && isEnterprise;
|
|
706
703
|
const isGeminiToolsFallback = fetchRes.status === 401 && actualModel.includes('gemini') && !isEnterprise && proxyBody.tools && proxyBody.tools.length > 0;
|
|
707
704
|
// STRICT MANUAL MODE: Disable "Magic" Fallbacks
|
|
708
705
|
if ((isEnterpriseFallback || isGeminiToolsFallback) && config.mode !== 'manual') {
|
|
@@ -109,12 +109,15 @@ function getCost(m, type) {
|
|
|
109
109
|
}
|
|
110
110
|
// ─── RENDU VISUEL ────────────────────────────────────────────────────────────
|
|
111
111
|
function parseNameDesc(m) {
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
if (m.title && m.description) {
|
|
113
|
+
return { nom: m.title, desc: m.description };
|
|
114
|
+
}
|
|
115
|
+
const displayName = m.title || m.description || m.name;
|
|
116
|
+
const parts = displayName.split(" - ");
|
|
114
117
|
if (parts.length > 1) {
|
|
115
118
|
return { nom: parts[0].trim(), desc: parts.slice(1).join(" - ").trim() };
|
|
116
119
|
}
|
|
117
|
-
return { nom:
|
|
120
|
+
return { nom: displayName, desc: "" };
|
|
118
121
|
}
|
|
119
122
|
function flags(m, overrides = []) {
|
|
120
123
|
const f = [];
|
package/package.json
CHANGED
|
@@ -1,65 +1,65 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"bin": {
|
|
34
|
-
"opencode-pollinations-plugin": "./bin/setup.js"
|
|
35
|
-
},
|
|
36
|
-
"main": "./dist/index.js",
|
|
37
|
-
"types": "./dist/index.d.ts",
|
|
38
|
-
"engines": {
|
|
39
|
-
"node": ">=18"
|
|
40
|
-
},
|
|
41
|
-
"scripts": {
|
|
42
|
-
"build": "tsc",
|
|
43
|
-
"test": "npm run build && node scripts/tests/test-suite.cjs",
|
|
44
|
-
"test:unit": "node scripts/tests/test-suite.cjs",
|
|
45
|
-
"test:i18n": "node scripts/tests/test-i18n.cjs",
|
|
46
|
-
"prepare": "npm run build",
|
|
47
|
-
"prepublishOnly": "npm run build && npm run test:unit && npm run test:i18n"
|
|
48
|
-
},
|
|
49
|
-
"files": [
|
|
50
|
-
"dist",
|
|
51
|
-
"bin",
|
|
52
|
-
"README.md",
|
|
53
|
-
"LICENSE.md"
|
|
54
|
-
],
|
|
55
|
-
"dependencies": {
|
|
56
|
-
"@opencode-ai/plugin": "^1.0.85",
|
|
57
|
-
"qrcode": "^1.5.4",
|
|
58
|
-
"zod": "^3.25.76"
|
|
59
|
-
},
|
|
60
|
-
"devDependencies": {
|
|
61
|
-
"@types/node": "^20.0.0",
|
|
62
|
-
"@types/qrcode": "^1.5.6",
|
|
63
|
-
"typescript": "^5.0.0"
|
|
2
|
+
"name": "opencode-pollinations-plugin",
|
|
3
|
+
"displayName": "Pollinations",
|
|
4
|
+
"version": "6.4.10",
|
|
5
|
+
"description": "Native Pollinations.ai Provider Plugin for OpenCode — free & premium AI models, media tools, quests, cost guards",
|
|
6
|
+
"author": "fkom13",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"opencode",
|
|
10
|
+
"pollinations",
|
|
11
|
+
"ai",
|
|
12
|
+
"plugin",
|
|
13
|
+
"image-generation",
|
|
14
|
+
"video-generation",
|
|
15
|
+
"llm",
|
|
16
|
+
"pollen"
|
|
17
|
+
],
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/fkom13/opencode-pollinations-plugin.git"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/fkom13/opencode-pollinations-plugin/issues"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/fkom13/opencode-pollinations-plugin#readme",
|
|
26
|
+
"type": "module",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"default": "./dist/index.js"
|
|
64
31
|
}
|
|
32
|
+
},
|
|
33
|
+
"bin": {
|
|
34
|
+
"opencode-pollinations-plugin": "./bin/setup.js"
|
|
35
|
+
},
|
|
36
|
+
"main": "./dist/index.js",
|
|
37
|
+
"types": "./dist/index.d.ts",
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsc",
|
|
43
|
+
"test": "npm run build && node scripts/tests/test-suite.cjs",
|
|
44
|
+
"test:unit": "node scripts/tests/test-suite.cjs",
|
|
45
|
+
"test:i18n": "node scripts/tests/test-i18n.cjs",
|
|
46
|
+
"prepare": "npm run build",
|
|
47
|
+
"prepublishOnly": "npm run build && npm run test:unit && npm run test:i18n"
|
|
48
|
+
},
|
|
49
|
+
"files": [
|
|
50
|
+
"dist",
|
|
51
|
+
"bin",
|
|
52
|
+
"README.md",
|
|
53
|
+
"LICENSE.md"
|
|
54
|
+
],
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@opencode-ai/plugin": "^1.0.85",
|
|
57
|
+
"qrcode": "^1.5.4",
|
|
58
|
+
"zod": "^3.25.76"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/node": "^20.0.0",
|
|
62
|
+
"@types/qrcode": "^1.5.6",
|
|
63
|
+
"typescript": "^5.0.0"
|
|
64
|
+
}
|
|
65
65
|
}
|