opencode-pollinations-plugin 5.4.9 → 5.4.11
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 +5 -0
- package/dist/server/commands.js +67 -25
- package/dist/server/config.d.ts +2 -0
- package/dist/server/config.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -146,6 +146,11 @@ Just type in the chat. You are in **Manual Mode** by default.
|
|
|
146
146
|
|
|
147
147
|
### 🤖 Models
|
|
148
148
|
|
|
149
|
+
### 🔑 Types de Clés Supportés
|
|
150
|
+
- **Clés Standard (`sk-...`)**: Accès complet (Modèles + Dashboard Usage + Quota).
|
|
151
|
+
- **Clés Limitées**: Accès Génération uniquement. Le dashboard affichera une alerte de restriction (v5.4.11).
|
|
152
|
+
- **Support Legacy**: Les anciennes clés (`sk_...`) sont aussi acceptées.
|
|
153
|
+
|
|
149
154
|
## 🔗 Links
|
|
150
155
|
|
|
151
156
|
- **Pollinations Website**: [pollinations.ai](https://pollinations.ai)
|
package/dist/server/commands.js
CHANGED
|
@@ -2,6 +2,7 @@ import { loadConfig, saveConfig } from './config.js';
|
|
|
2
2
|
import { getQuotaStatus } from './quota.js';
|
|
3
3
|
import { emitStatusToast } from './toast.js';
|
|
4
4
|
import { getDetailedUsage } from './pollinations-api.js';
|
|
5
|
+
import { generatePollinationsConfig } from './generate-config.js';
|
|
5
6
|
// === CONSTANTS & PRICING ===
|
|
6
7
|
const TIER_LIMITS = {
|
|
7
8
|
spore: { pollen: 1, emoji: '🦠' },
|
|
@@ -146,21 +147,26 @@ async function handleUsageCommand(args) {
|
|
|
146
147
|
response += `- **Wallet**: $${quota.walletBalance.toFixed(2)}\n`;
|
|
147
148
|
response += `- **Reset**: ${resetDate} (dans ${durationStr})\n`;
|
|
148
149
|
if (isFull && config.apiKey) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const lastReset = calculateResetDate(quota.nextResetAt);
|
|
152
|
-
const stats = calculateCurrentPeriodStats(usageData.usage, lastReset, quota.tierLimit);
|
|
153
|
-
response += `\n### 📊 Détail Période (depuis ${lastReset.toLocaleTimeString()})\n`;
|
|
154
|
-
response += `**Total Requêtes**: ${stats.totalRequests} | **Tokens**: In ${formatTokens(stats.inputTokens)} / Out ${formatTokens(stats.outputTokens)}\n\n`;
|
|
155
|
-
response += `| Modèle | Reqs | Coût | Tokens |\n`;
|
|
156
|
-
response += `| :--- | :---: | :---: | :---: |\n`;
|
|
157
|
-
const sorted = Array.from(stats.models.entries()).sort((a, b) => b[1].cost - a[1].cost);
|
|
158
|
-
for (const [model, data] of sorted) {
|
|
159
|
-
response += `| \`${model}\` | ${data.requests} | ${formatPollen(data.cost)} | ${formatTokens(data.inputTokens + data.outputTokens)} |\n`;
|
|
160
|
-
}
|
|
150
|
+
if (config.keyHasAccessToProfile === false) {
|
|
151
|
+
response += `\n> ⚠️ *Votre clé API ne permet pas l'accès aux détails d'usage (Restriction).*`;
|
|
161
152
|
}
|
|
162
153
|
else {
|
|
163
|
-
|
|
154
|
+
const usageData = await getDetailedUsage(config.apiKey);
|
|
155
|
+
if (usageData && usageData.usage) {
|
|
156
|
+
const lastReset = calculateResetDate(quota.nextResetAt);
|
|
157
|
+
const stats = calculateCurrentPeriodStats(usageData.usage, lastReset, quota.tierLimit);
|
|
158
|
+
response += `\n### 📊 Détail Période (depuis ${lastReset.toLocaleTimeString()})\n`;
|
|
159
|
+
response += `**Total Requêtes**: ${stats.totalRequests} | **Tokens**: In ${formatTokens(stats.inputTokens)} / Out ${formatTokens(stats.outputTokens)}\n\n`;
|
|
160
|
+
response += `| Modèle | Reqs | Coût | Tokens |\n`;
|
|
161
|
+
response += `| :--- | :---: | :---: | :---: |\n`;
|
|
162
|
+
const sorted = Array.from(stats.models.entries()).sort((a, b) => b[1].cost - a[1].cost);
|
|
163
|
+
for (const [model, data] of sorted) {
|
|
164
|
+
response += `| \`${model}\` | ${data.requests} | ${formatPollen(data.cost)} | ${formatTokens(data.inputTokens + data.outputTokens)} |\n`;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
response += `\n> ⚠️ *Impossible de récupérer l'historique détaillé.*\n`;
|
|
169
|
+
}
|
|
164
170
|
}
|
|
165
171
|
}
|
|
166
172
|
else if (isFull) {
|
|
@@ -204,28 +210,64 @@ function handleFallbackCommand(args) {
|
|
|
204
210
|
response: `✅ Fallback (Free) configuré: main=${main}, agent=${agent || config.fallbacks.free.agent}`
|
|
205
211
|
};
|
|
206
212
|
}
|
|
207
|
-
function handleConnectCommand(args) {
|
|
213
|
+
async function handleConnectCommand(args) {
|
|
208
214
|
const key = args[0];
|
|
209
215
|
if (!key) {
|
|
210
216
|
return {
|
|
211
217
|
handled: true,
|
|
212
|
-
error: `Utilisation: /pollinations connect <
|
|
218
|
+
error: `Utilisation: /pollinations connect <votre_clé_api>`
|
|
213
219
|
};
|
|
214
220
|
}
|
|
215
|
-
|
|
221
|
+
// 1. Universal Validation (No Syntax Check) - Functional Check
|
|
222
|
+
emitStatusToast('info', 'Vérification de la clé...', 'Pollinations Config');
|
|
223
|
+
try {
|
|
224
|
+
const models = await generatePollinationsConfig(key);
|
|
225
|
+
// 2. Check if we got Enterprise models
|
|
226
|
+
const enterpriseModels = models.filter(m => m.id.startsWith('enter/'));
|
|
227
|
+
if (enterpriseModels.length > 0) {
|
|
228
|
+
// SUCCESS
|
|
229
|
+
saveConfig({ apiKey: key, mode: 'pro' });
|
|
230
|
+
const masked = key.substring(0, 6) + '...';
|
|
231
|
+
// Count Paid Only models found
|
|
232
|
+
const diamondCount = enterpriseModels.filter(m => m.name.includes('💎')).length;
|
|
233
|
+
emitStatusToast('success', `Clé Valide! (${enterpriseModels.length} modèles Pro débloqués)`, 'Pollinations Config');
|
|
234
|
+
return {
|
|
235
|
+
handled: true,
|
|
236
|
+
response: `✅ **Connexion Réussie!**\n- Clé: \`${masked}\`\n- Mode: **PRO** (Activé)\n- Modèles Débloqués: ${enterpriseModels.length} (dont ${diamondCount} 💎 Paid)`
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
// FAILURE (Valid JSON but no Enterprise models - likely Invalid Key or Free plan only?)
|
|
241
|
+
// If key is invalid, generatePollinationsConfig usually returns fallback free models BUT
|
|
242
|
+
// we specifically checked 'enter/'. If 0 enterprise models found for a *provided* key, it's suspicious.
|
|
243
|
+
// Actually config generator returns Free models + Enter models if key works.
|
|
244
|
+
// If key is BAD, fetchJson throws/logs error, and returns fallbacks (Enter GPT-4o Fallback).
|
|
245
|
+
// Wait, generate-config falls back to providing a list containing "[Enter] GPT-4o (Fallback)" if fetch failed.
|
|
246
|
+
// So we need to detect if it's a "REAL" fetch or a "FALLBACK" fetch.
|
|
247
|
+
// The fallback models have `variants: {}` usually, but real ones might too.
|
|
248
|
+
// A better check: The fallback list is hardcoded in generate-config.ts catch block.
|
|
249
|
+
// Let's modify generate-config to return EMPTY list on error?
|
|
250
|
+
// Or just check if the returned models work?
|
|
251
|
+
// Simplest: If `generatePollinationsConfig` returns any model starting with `enter/` that includes "(Fallback)" in name, we assume failure?
|
|
252
|
+
// "GPT-4o (Fallback)" is the name.
|
|
253
|
+
const isFallback = models.some(m => m.name.includes('(Fallback)') && m.id.startsWith('enter/'));
|
|
254
|
+
if (isFallback) {
|
|
255
|
+
throw new Error("Clé rejetée par l'API (Accès refusé ou invalide).");
|
|
256
|
+
}
|
|
257
|
+
// If we are here, we got no enter models, or empty list?
|
|
258
|
+
// If key is valid but has no access?
|
|
259
|
+
throw new Error("Aucun modèle Enterprise détecté pour cette clé.");
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
catch (e) {
|
|
263
|
+
// 3. FAILURE HANDLING - Revert to FREE
|
|
264
|
+
saveConfig({ apiKey: undefined, mode: 'manual' }); // Clear Key, Set Manual
|
|
265
|
+
emitStatusToast('error', `Clé Invalide. Retour au mode Gratuit.`, 'Pollinations Config');
|
|
216
266
|
return {
|
|
217
267
|
handled: true,
|
|
218
|
-
error:
|
|
268
|
+
error: `❌ **Échec Connexion**: ${e.message || e}\n\nLa configuration a été réinitialisée (Mode Gratuit/Manuel).`
|
|
219
269
|
};
|
|
220
270
|
}
|
|
221
|
-
// Save API Key only (User decides mode manually)
|
|
222
|
-
saveConfig({ apiKey: key });
|
|
223
|
-
// Confirm
|
|
224
|
-
emitStatusToast('success', 'API Key enregistrée', 'Pollinations Config');
|
|
225
|
-
return {
|
|
226
|
-
handled: true,
|
|
227
|
-
response: `✅ API Key connectée. (Utilisez /pollinations mode pro pour l'activer)`
|
|
228
|
-
};
|
|
229
271
|
}
|
|
230
272
|
function handleConfigCommand(args) {
|
|
231
273
|
const [key, value] = args;
|
package/dist/server/config.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export interface PollinationsConfigV5 {
|
|
|
2
2
|
version: string | number;
|
|
3
3
|
mode: 'manual' | 'alwaysfree' | 'pro';
|
|
4
4
|
apiKey?: string;
|
|
5
|
+
keyHasAccessToProfile?: boolean;
|
|
5
6
|
gui: {
|
|
6
7
|
status: 'none' | 'alert' | 'all';
|
|
7
8
|
logs: 'none' | 'error' | 'verbose';
|
|
@@ -27,6 +28,7 @@ export declare function saveConfig(updates: Partial<PollinationsConfigV5>): {
|
|
|
27
28
|
version: string;
|
|
28
29
|
mode: "manual" | "alwaysfree" | "pro";
|
|
29
30
|
apiKey?: string;
|
|
31
|
+
keyHasAccessToProfile?: boolean;
|
|
30
32
|
gui: {
|
|
31
33
|
status: "none" | "alert" | "all";
|
|
32
34
|
logs: "none" | "error" | "verbose";
|
package/dist/server/config.js
CHANGED
package/package.json
CHANGED