opencode-pollinations-plugin 6.1.0-beta.3 → 6.1.0-beta.5

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.
@@ -2,7 +2,7 @@ import * as https from 'https';
2
2
  import { loadConfig, saveConfig } from './config.js';
3
3
  import { getQuotaStatus } from './quota.js';
4
4
  import { emitStatusToast } from './toast.js';
5
- import { getDetailedUsage } from './pollinations-api.js';
5
+ import { getDetailedUsage, getAggregatedModels } from './pollinations-api.js';
6
6
  import { generatePollinationsConfig } from './generate-config.js';
7
7
  function checkEndpoint(ep, key) {
8
8
  return new Promise((resolve) => {
@@ -145,7 +145,7 @@ export async function handleCommand(command) {
145
145
  case 'connect':
146
146
  return await handleConnectCommand(args);
147
147
  case 'fallback':
148
- return handleFallbackCommand(args);
148
+ return await handleFallbackCommand(args);
149
149
  case 'config':
150
150
  return handleConfigCommand(args);
151
151
  case 'help':
@@ -159,7 +159,7 @@ export async function handleCommand(command) {
159
159
  }
160
160
  // === SUB-COMMANDS ===
161
161
  async function handleModeCommand(args) {
162
- const mode = args[0];
162
+ let mode = args[0];
163
163
  if (!mode) {
164
164
  const config = loadConfig();
165
165
  return {
@@ -167,15 +167,17 @@ async function handleModeCommand(args) {
167
167
  response: `Mode actuel: ${config.mode}`
168
168
  };
169
169
  }
170
- if (!['manual', 'alwaysfree', 'pro'].includes(mode)) {
170
+ if (mode === 'alwaysfree')
171
+ mode = 'economy'; // Alias support
172
+ if (!['manual', 'economy', 'pro'].includes(mode)) {
171
173
  return {
172
174
  handled: true,
173
- error: `Mode invalide: ${mode}. Valeurs: manual, alwaysfree, pro`
175
+ error: `❌ Mode invalide: ${mode}. Valeurs: manual, economy, pro`
174
176
  };
175
177
  }
176
178
  const checkConfig = loadConfig();
177
- // JIT VERIFICATION for PRO and ALWAYSFREE Mode
178
- if (mode === 'pro' || mode === 'alwaysfree') {
179
+ // JIT VERIFICATION for PRO and ECONOMY Mode
180
+ if (mode === 'pro' || mode === 'economy') {
179
181
  const checkConfig = loadConfig(); // Reload to be sure
180
182
  const key = checkConfig.apiKey;
181
183
  if (!key) {
@@ -263,37 +265,44 @@ async function handleUsageCommand(args) {
263
265
  return { handled: true, error: `Erreur: ${e}` };
264
266
  }
265
267
  }
266
- function handleFallbackCommand(args) {
267
- const [mode, model] = args;
268
- if (!mode) {
269
- const config = loadConfig();
268
+ async function handleFallbackCommand(args) {
269
+ let targetMode = args[0];
270
+ const targetModel = args[1];
271
+ if (!targetMode || !targetModel) {
270
272
  return {
271
273
  handled: true,
272
- response: `Fallbacks actuels:\n- Economy: ${config.fallbacks.economy}\n- Pro: ${config.fallbacks.pro}`
274
+ error: `Usage: /pollinations fallback [economy|pro] <modèle>`
273
275
  };
274
276
  }
275
- const config = loadConfig();
276
- if (mode === 'economy' && model) {
277
- saveConfig({
278
- fallbacks: { ...config.fallbacks, economy: model }
279
- });
280
- return {
281
- handled: true,
282
- response: `✅ Fallback Economy configuré: ${model}`
283
- };
277
+ // Alias support
278
+ if (targetMode === 'alwaysfree')
279
+ targetMode = 'economy';
280
+ if (targetMode !== 'economy' && targetMode !== 'pro') {
281
+ return { handled: true, error: 'Target mode invalide (economy ou pro)' };
284
282
  }
285
- if (mode === 'pro' && model) {
286
- saveConfig({
287
- fallbacks: { ...config.fallbacks, pro: model }
288
- });
289
- return {
290
- handled: true,
291
- response: `✅ Fallback Pro configuré: ${model}`
292
- };
283
+ // DYNAMIC MODEL VALIDATION (BUG 2 FIX)
284
+ try {
285
+ const { data: models } = await getAggregatedModels();
286
+ const validIds = models.map(m => m.id.replace(/^pollinations\/(free|enter)\//, ''));
287
+ if (!validIds.includes(targetModel)) {
288
+ const suggestions = validIds.slice(0, 10).join(', ');
289
+ return {
290
+ handled: true,
291
+ error: `⚠️ Modèle inconnu: "${targetModel}".\nExemples valides: ${suggestions}...`
292
+ };
293
+ }
293
294
  }
295
+ catch (e) {
296
+ // Fail-open si API down
297
+ console.warn('[Fallback] Model validation failed, allowing:', e);
298
+ }
299
+ const config = loadConfig();
300
+ const updates = { fallbacks: { ...config.fallbacks } };
301
+ updates.fallbacks[targetMode] = targetModel;
302
+ saveConfig(updates);
294
303
  return {
295
304
  handled: true,
296
- error: `Usage: /pollinations fallback [economy|pro] <modèle>`
305
+ response: `✅ Fallback ${targetMode.charAt(0).toUpperCase() + targetMode.slice(1)} configuré: ${targetModel}`
297
306
  };
298
307
  }
299
308
  async function handleConnectCommand(args) {
@@ -639,6 +639,23 @@ export async function handleChatCompletion(req, res, bodyRaw) {
639
639
  const retryHeaders = { ...headers };
640
640
  // Keep Authorization for gen.pollinations.ai
641
641
  const retryBody = { ...proxyBody, model: actualModel };
642
+ // LIMIT MAX_TOKENS for lightweight fallback models (e.g. nova-fast limits)
643
+ if (actualModel.includes('nova') || actualModel.includes('fast')) {
644
+ // Force max_tokens down if missing or too high
645
+ if (!retryBody.max_tokens || retryBody.max_tokens > 4000) {
646
+ retryBody.max_tokens = 4000;
647
+ log(`[SafetyNet] Adjusted max_tokens to 4000 for ${actualModel}`);
648
+ }
649
+ }
650
+ // BEDROCK COMPATIBILITY FIX (BUG 1)
651
+ const isBedrockModel = actualModel.includes('nova') ||
652
+ actualModel.includes('amazon') ||
653
+ actualModel.includes('chickytutor');
654
+ if (isBedrockModel && retryBody.tools) {
655
+ delete retryBody.tools;
656
+ log(`[SafetyNet] Tools removed for Bedrock model: ${actualModel}`);
657
+ emitStatusToast('warning', '⚠️ Tools désactivés (Bedrock incompatible)', 'Fallback');
658
+ }
642
659
  // 4. Retry Fetch
643
660
  const retryRes = await fetchWithRetry(targetUrl, {
644
661
  method: 'POST',
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "opencode-pollinations-plugin",
3
3
  "displayName": "Pollinations AI (V5.6)",
4
- "version": "6.1.0-beta.3",
4
+ "version": "6.1.0-beta.5",
5
5
  "description": "Native Pollinations.ai Provider Plugin for OpenCode",
6
6
  "publisher": "pollinations",
7
7
  "repository": {