opencode-pollinations-plugin 5.5.5 → 5.6.0-beta.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/README.md CHANGED
@@ -160,9 +160,3 @@ Just type in the chat. You are in **Manual Mode** by default.
160
160
  ## 📜 License
161
161
 
162
162
  MIT License. Created by [fkom13](https://github.com/fkom13) & The Pollinations Community.
163
- ### 🛡️ Clés API Limitées
164
-
165
- Si vous utilisez un token API restreint (ex: création d'une clé **sans** les permissions `Profile`, `Balance` ou `Usage`), le plugin passera automatiquement en mode **Manual**.
166
-
167
- - **Mode Forcé** : `Manual` (Les modes `Pro` et `AlwaysFree` sont désactivés pour ces clés car ils nécessitent l'accès au quota pour fonctionner).
168
- - **Conséquence** : Pas de Dashboard, pas de Safety Nets, mais génération fonctionnelle sur les modèles autorisés.
package/dist/index.js CHANGED
@@ -96,7 +96,7 @@ export const PollinationsPlugin = async (ctx) => {
96
96
  config.provider = {};
97
97
  config.provider['pollinations'] = {
98
98
  id: 'pollinations',
99
- name: `Pollinations V${loadConfig().version} (Native)`,
99
+ name: 'Pollinations V5.2 (Native)',
100
100
  options: { baseURL: localBaseUrl },
101
101
  models: modelsObj
102
102
  };
@@ -300,24 +300,11 @@ async function handleConnectCommand(args) {
300
300
  }
301
301
  else {
302
302
  // FAILURE (Valid JSON but no Enterprise models - likely Invalid Key or Free plan only?)
303
- // If key is invalid, generatePollinationsConfig usually returns fallback free models BUT
304
- // we specifically checked 'enter/'. If 0 enterprise models found for a *provided* key, it's suspicious.
305
- // Actually config generator returns Free models + Enter models if key works.
306
- // If key is BAD, fetchJson throws/logs error, and returns fallbacks (Enter GPT-4o Fallback).
307
- // Wait, generate-config falls back to providing a list containing "[Enter] GPT-4o (Fallback)" if fetch failed.
308
- // So we need to detect if it's a "REAL" fetch or a "FALLBACK" fetch.
309
- // The fallback models have `variants: {}` usually, but real ones might too.
310
- // A better check: The fallback list is hardcoded in generate-config.ts catch block.
311
- // Let's modify generate-config to return EMPTY list on error?
312
- // Or just check if the returned models work?
313
- // Simplest: If `generatePollinationsConfig` returns any model starting with `enter/` that includes "(Fallback)" in name, we assume failure?
314
- // "GPT-4o (Fallback)" is the name.
315
303
  const isFallback = models.some(m => m.name.includes('(Fallback)') && m.id.startsWith('enter/'));
316
304
  if (isFallback) {
317
305
  throw new Error("Clé rejetée par l'API (Accès refusé ou invalide).");
318
306
  }
319
307
  // If we are here, we got no enter models, or empty list?
320
- // If key is valid but has no access?
321
308
  throw new Error("Aucun modèle Enterprise détecté pour cette clé.");
322
309
  }
323
310
  }
@@ -341,7 +328,6 @@ function handleConfigCommand(args) {
341
328
  };
342
329
  }
343
330
  if (key === 'toast_verbosity' && value) {
344
- // BACKWARD COMPAT (Maps to Status GUI)
345
331
  if (!['none', 'alert', 'all'].includes(value)) {
346
332
  return { handled: true, error: 'Valeurs: none, alert, all' };
347
333
  }
@@ -79,8 +79,12 @@ export async function generatePollinationsConfig(forceApiKey, forceStrict = fals
79
79
  modelsOutput.push({ id: "free/gemini", name: "[Free] Gemini Flash (Fallback)", object: "model", variants: {} });
80
80
  }
81
81
  // 1.5 FORCE ENSURE CRITICAL MODELS
82
- // REMOVED: Duplicate Gemini/Flash injection.
83
- // The alias below handles standardizing the ID.
82
+ // Sometimes the API list changes or is cached weirdly. We force vital models.
83
+ const hasGemini = modelsOutput.find(m => m.id === 'free/gemini');
84
+ if (!hasGemini) {
85
+ log(`[ConfigGen] Force-injecting free/gemini.`);
86
+ modelsOutput.push({ id: "free/gemini", name: "[Free] Gemini Flash (Force)", object: "model", variants: {} });
87
+ }
84
88
  // ALIAS for Full ID matching (Fix ProviderModelNotFoundError) - ALWAYS CHECK SEPARATELY
85
89
  const hasGeminiAlias = modelsOutput.find(m => m.id === 'pollinations/free/gemini');
86
90
  if (!hasGeminiAlias) {
@@ -211,21 +211,6 @@ export async function handleChatCompletion(req, res, bodyRaw) {
211
211
  // LOAD QUOTA FOR SAFETY CHECKS
212
212
  const { getQuotaStatus, formatQuotaForToast } = await import('./quota.js');
213
213
  const quota = await getQuotaStatus(false);
214
- // RUNTIME RESTRICTION ENFORCEMENT (V5.5.3)
215
- // If we are in a Managed Mode (Pro/AlwaysFree) BUT the Quota returns 'error'
216
- // (meaning Profile/Usage access failed or network issue), we MUST downgrade to Manual
217
- // to avoid "Quota Unreachable" Fallbacks. The user wants to force Manual.
218
- if ((config.mode === 'alwaysfree' || config.mode === 'pro') && quota.tier === 'error') {
219
- log(`[SafetyNet] Runtime: Quota Access Lost (Tier=error). Forcing MANUAL Mode.`);
220
- // 1. Update In-Memory Config (stops downstream fallbacks)
221
- config.mode = 'manual';
222
- config.keyHasAccessToProfile = false;
223
- // 2. Persist
224
- const { saveConfig } = await import('./config.js');
225
- saveConfig({ mode: 'manual', keyHasAccessToProfile: false });
226
- // 3. Notify
227
- emitStatusToast('warning', "⚠️ Accès Quota Perdu -> Mode MANUAL forcé", "System");
228
- }
229
214
  // A. Resolve Base Target
230
215
  if (actualModel.startsWith('enter/')) {
231
216
  isEnterprise = true;
@@ -689,9 +674,8 @@ export async function handleChatCompletion(req, res, bodyRaw) {
689
674
  if (isFallbackActive)
690
675
  modeLabel += " (FALLBACK)";
691
676
  const fullMsg = `${dashboardMsg} | ⚙️ ${modeLabel}`;
692
- // Only emit if not silenced AND (only for Enterprise/Paid requests OR if Fallback occurred)
693
- // We want to know if our Pro request failed.
694
- if (isEnterprise || isFallbackActive) {
677
+ // Only emit if not silenced AND only for Enterprise/Paid requests
678
+ if (isEnterprise) {
695
679
  emitStatusToast('info', fullMsg, 'Pollinations Status');
696
680
  }
697
681
  }
@@ -10,7 +10,6 @@ export interface QuotaStatus {
10
10
  needsAlert: boolean;
11
11
  tier: string;
12
12
  tierEmoji: string;
13
- isLimitedKey?: boolean;
14
13
  }
15
14
  export declare function getQuotaStatus(forceRefresh?: boolean): Promise<QuotaStatus>;
16
15
  export declare function formatQuotaForToast(quota: QuotaStatus): string;
@@ -38,31 +38,13 @@ export async function getQuotaStatus(forceRefresh = false) {
38
38
  tierEmoji: '❌'
39
39
  };
40
40
  }
41
- // CHECK LIMITED KEY (v5.5)
42
- // If commands.ts detected this key has no profile access, return specific status immediately.
43
- // We do NOT attempt to fetch quota to avoid 403 spam.
44
- if (config.keyHasAccessToProfile === false) {
45
- return {
46
- tierRemaining: 0,
47
- tierUsed: 0,
48
- tierLimit: 0,
49
- walletBalance: 0,
50
- nextResetAt: new Date(),
51
- timeUntilReset: 0,
52
- canUseEnterprise: true, // GENERATION IS ALLOWED
53
- isUsingWallet: false,
54
- needsAlert: false,
55
- tier: 'limited',
56
- tierEmoji: '🗝️',
57
- isLimitedKey: true
58
- };
59
- }
60
41
  const now = Date.now();
61
42
  if (!forceRefresh && cachedQuota && (now - lastQuotaFetch) < CACHE_TTL) {
62
43
  return cachedQuota;
63
44
  }
64
45
  try {
65
46
  logQuota("Fetching Quota Data...");
47
+ // Fetch parallèle using HTTPS helper
66
48
  // SEQUENTIAL FETCH (Avoid Rate Limits)
67
49
  // We fetch one by one. If one fails, we catch and return fallback.
68
50
  const profileRes = await fetchAPI('/account/profile', config.apiKey);
@@ -216,9 +198,6 @@ function calculateCurrentPeriodUsage(usage, resetInfo) {
216
198
  }
217
199
  // === EXPORT POUR LES ALERTES ===
218
200
  export function formatQuotaForToast(quota) {
219
- if (quota.isLimitedKey) {
220
- return "⚠️ Dashboard Limitation: Clé restreinte (Activez Profile/Usage/Balance pour voir le Quota)";
221
- }
222
201
  const tierPercent = quota.tierLimit > 0
223
202
  ? Math.round((quota.tierRemaining / quota.tierLimit) * 100)
224
203
  : 0;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "opencode-pollinations-plugin",
3
3
  "displayName": "Pollinations AI (V5.1)",
4
- "version": "5.5.5",
4
+ "version": "5.6.0-beta.0",
5
5
  "description": "Native Pollinations.ai Provider Plugin for OpenCode",
6
6
  "publisher": "pollinations",
7
7
  "repository": {