opencode-pollinations-plugin 6.4.10 → 6.5.1
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 +67 -55
- package/README.es.md +79 -67
- package/README.fr.md +70 -58
- package/README.it.md +78 -66
- package/README.md +33 -29
- package/README.zh.md +77 -65
- package/dist/locales/de.json +82 -50
- package/dist/locales/en.json +84 -52
- package/dist/locales/es.json +82 -50
- package/dist/locales/fr.json +81 -49
- package/dist/locales/it.json +82 -50
- package/dist/locales/zh.json +82 -50
- package/dist/server/commands.js +112 -110
- package/dist/server/config.d.ts +24 -6
- package/dist/server/config.js +45 -4
- package/dist/server/connect-response.js +7 -7
- package/dist/server/generate-config.d.ts +7 -0
- package/dist/server/generate-config.js +22 -16
- package/dist/server/models/cache.d.ts +23 -10
- package/dist/server/models/cache.js +46 -24
- package/dist/server/models/fetcher.js +9 -0
- package/dist/server/models/types.d.ts +8 -0
- package/dist/server/models/worker.js +32 -8
- package/dist/server/proxy.d.ts +6 -0
- package/dist/server/proxy.js +297 -210
- package/dist/server/quota.d.ts +23 -32
- package/dist/server/quota.js +45 -185
- package/dist/server/status.js +1 -2
- package/dist/server/toast.js +1 -1
- package/dist/tools/index.d.ts +2 -1
- package/dist/tools/index.js +8 -3
- package/dist/tools/pollinations/artifact-core.d.ts +53 -0
- package/dist/tools/pollinations/artifact-core.js +159 -0
- package/dist/tools/pollinations/beta_discovery.js +2 -1
- package/dist/tools/pollinations/cost-guard.d.ts +2 -2
- package/dist/tools/pollinations/error-parser.d.ts +38 -0
- package/dist/tools/pollinations/error-parser.js +112 -0
- package/dist/tools/pollinations/gen_3d.d.ts +17 -0
- package/dist/tools/pollinations/gen_3d.js +207 -0
- package/dist/tools/pollinations/gen_image.js +29 -10
- package/dist/tools/pollinations/gen_music.js +3 -2
- package/dist/tools/pollinations/gen_video.js +13 -2
- package/dist/tools/pollinations/polli_config.js +18 -21
- package/dist/tools/pollinations/polli_gen_confirm.js +2 -0
- package/dist/tools/pollinations/shared.d.ts +1 -1
- package/dist/tools/pollinations/shared.js +53 -142
- package/dist/tools/pollinations/timeout-policy.d.ts +80 -0
- package/dist/tools/pollinations/timeout-policy.js +124 -0
- package/dist/tools/pollinations/tool-capability-registry.d.ts +51 -0
- package/dist/tools/pollinations/tool-capability-registry.js +215 -0
- package/dist/tools/pollinations/transcribe_audio.js +5 -24
- package/package.json +6 -4
- package/dist/server/tier-info.d.ts +0 -36
- package/dist/server/tier-info.js +0 -107
|
@@ -3,33 +3,46 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Central access point for all model metadata. Backed by the fetcher
|
|
5
5
|
* with a configurable TTL. Falls back to static data if fetch fails.
|
|
6
|
+
*
|
|
7
|
+
* v6.5: every read path (get/list/all) triggers a coalesced, non-blocking
|
|
8
|
+
* freshness check, so long sessions always converge to the live catalog.
|
|
6
9
|
*/
|
|
7
10
|
import type { PollinationsModel, ModelCategory, ModelRegistryInterface } from './types.js';
|
|
8
|
-
|
|
11
|
+
export type RegistryFetcher = (apiKey?: string) => Promise<PollinationsModel[]>;
|
|
12
|
+
export interface RegistryOptions {
|
|
13
|
+
ttlMs?: number;
|
|
14
|
+
fetcher?: RegistryFetcher;
|
|
15
|
+
diskCache?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare class ModelRegistryImpl implements ModelRegistryInterface {
|
|
9
18
|
private models;
|
|
10
19
|
private lastRefresh;
|
|
11
20
|
private ttl;
|
|
12
21
|
private ready;
|
|
13
22
|
private refreshing;
|
|
14
|
-
|
|
15
|
-
|
|
23
|
+
private fetcher;
|
|
24
|
+
private useDiskCache;
|
|
25
|
+
constructor(options?: RegistryOptions);
|
|
26
|
+
/** Get a single model by category and name. Triggers lazy freshness check. */
|
|
16
27
|
get(category: ModelCategory, name: string): PollinationsModel | undefined;
|
|
17
|
-
/** Also search by alias */
|
|
28
|
+
/** Also search by alias. Triggers lazy freshness check. */
|
|
18
29
|
getByNameOrAlias(category: ModelCategory, name: string): PollinationsModel | undefined;
|
|
19
|
-
/** List all models in a category */
|
|
30
|
+
/** List all models in a category. Triggers lazy freshness check. */
|
|
20
31
|
list(category: ModelCategory): PollinationsModel[];
|
|
21
32
|
/** Check if registry has been populated */
|
|
22
33
|
isReady(): boolean;
|
|
23
34
|
/** Check if cache is stale */
|
|
24
35
|
isStale(): boolean;
|
|
25
|
-
/**
|
|
36
|
+
/** Timestamp of last successful refresh (for tests/diagnostics). */
|
|
37
|
+
lastRefreshAt(): number;
|
|
38
|
+
/** Force refresh from API. Concurrent calls are coalesced on one fetch. */
|
|
26
39
|
refresh(apiKey?: string): Promise<void>;
|
|
27
|
-
|
|
40
|
+
private performRefresh;
|
|
41
|
+
/** Get all models across all categories. Triggers lazy freshness check. */
|
|
28
42
|
all(): PollinationsModel[];
|
|
29
|
-
/** Auto-refresh if stale (non-blocking) */
|
|
30
|
-
ensureFresh(): void
|
|
43
|
+
/** Auto-refresh if stale (non-blocking). Returns the refresh promise for tests. */
|
|
44
|
+
ensureFresh(): Promise<void>;
|
|
31
45
|
/** Get count per category (for logging) */
|
|
32
46
|
stats(): Record<ModelCategory, number>;
|
|
33
47
|
}
|
|
34
48
|
export declare const ModelRegistry: ModelRegistryImpl;
|
|
35
|
-
export {};
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Central access point for all model metadata. Backed by the fetcher
|
|
5
5
|
* with a configurable TTL. Falls back to static data if fetch fails.
|
|
6
|
+
*
|
|
7
|
+
* v6.5: every read path (get/list/all) triggers a coalesced, non-blocking
|
|
8
|
+
* freshness check, so long sessions always converge to the live catalog.
|
|
6
9
|
*/
|
|
7
10
|
import * as fs from 'fs';
|
|
8
11
|
import * as path from 'path';
|
|
@@ -60,31 +63,41 @@ function saveCacheToDisk(models, timestamp) {
|
|
|
60
63
|
}
|
|
61
64
|
}
|
|
62
65
|
// ─── Registry Implementation ─────────────────────────────────────────────
|
|
63
|
-
class ModelRegistryImpl {
|
|
66
|
+
export class ModelRegistryImpl {
|
|
64
67
|
models = [];
|
|
65
68
|
lastRefresh = 0;
|
|
66
69
|
ttl = DEFAULT_TTL;
|
|
67
70
|
ready = false;
|
|
68
|
-
refreshing =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
refreshing = null;
|
|
72
|
+
fetcher;
|
|
73
|
+
useDiskCache;
|
|
74
|
+
constructor(options = {}) {
|
|
75
|
+
this.ttl = options.ttlMs ?? DEFAULT_TTL;
|
|
76
|
+
this.fetcher = options.fetcher ?? ((apiKey) => fetchAllModels(apiKey));
|
|
77
|
+
this.useDiskCache = options.diskCache ?? true;
|
|
78
|
+
if (this.useDiskCache) {
|
|
79
|
+
const diskCache = loadCacheFromDisk();
|
|
80
|
+
if (diskCache && (Date.now() - diskCache.timestamp) < this.ttl) {
|
|
81
|
+
this.models = diskCache.models;
|
|
82
|
+
this.lastRefresh = diskCache.timestamp;
|
|
83
|
+
this.ready = true;
|
|
84
|
+
log(`[ModelRegistry] Loaded ${this.models.length} models from disk cache.`);
|
|
85
|
+
}
|
|
76
86
|
}
|
|
77
87
|
}
|
|
78
|
-
/** Get a single model by category and name */
|
|
88
|
+
/** Get a single model by category and name. Triggers lazy freshness check. */
|
|
79
89
|
get(category, name) {
|
|
90
|
+
this.ensureFresh().catch(() => { });
|
|
80
91
|
return this.models.find(m => m.category === category && m.name === name);
|
|
81
92
|
}
|
|
82
|
-
/** Also search by alias */
|
|
93
|
+
/** Also search by alias. Triggers lazy freshness check. */
|
|
83
94
|
getByNameOrAlias(category, name) {
|
|
95
|
+
this.ensureFresh().catch(() => { });
|
|
84
96
|
return this.models.find(m => m.category === category && (m.name === name || m.aliases.includes(name)));
|
|
85
97
|
}
|
|
86
|
-
/** List all models in a category */
|
|
98
|
+
/** List all models in a category. Triggers lazy freshness check. */
|
|
87
99
|
list(category) {
|
|
100
|
+
this.ensureFresh().catch(() => { });
|
|
88
101
|
return this.models.filter(m => m.category === category);
|
|
89
102
|
}
|
|
90
103
|
/** Check if registry has been populated */
|
|
@@ -95,19 +108,29 @@ class ModelRegistryImpl {
|
|
|
95
108
|
isStale() {
|
|
96
109
|
return Date.now() - this.lastRefresh > this.ttl;
|
|
97
110
|
}
|
|
98
|
-
/**
|
|
99
|
-
|
|
111
|
+
/** Timestamp of last successful refresh (for tests/diagnostics). */
|
|
112
|
+
lastRefreshAt() {
|
|
113
|
+
return this.lastRefresh;
|
|
114
|
+
}
|
|
115
|
+
/** Force refresh from API. Concurrent calls are coalesced on one fetch. */
|
|
116
|
+
refresh(apiKey) {
|
|
100
117
|
if (this.refreshing)
|
|
101
|
-
return; //
|
|
102
|
-
this.refreshing =
|
|
118
|
+
return this.refreshing; // coalesce concurrent refreshes
|
|
119
|
+
this.refreshing = this.performRefresh(apiKey).finally(() => {
|
|
120
|
+
this.refreshing = null;
|
|
121
|
+
});
|
|
122
|
+
return this.refreshing;
|
|
123
|
+
}
|
|
124
|
+
async performRefresh(apiKey) {
|
|
103
125
|
try {
|
|
104
126
|
const key = apiKey || loadConfig().apiKey;
|
|
105
|
-
const fetched = await
|
|
127
|
+
const fetched = await this.fetcher(key);
|
|
106
128
|
if (fetched.length > 0) {
|
|
107
129
|
this.models = fetched;
|
|
108
130
|
this.lastRefresh = Date.now();
|
|
109
131
|
this.ready = true;
|
|
110
|
-
|
|
132
|
+
if (this.useDiskCache)
|
|
133
|
+
saveCacheToDisk(this.models, this.lastRefresh);
|
|
111
134
|
log(`[ModelRegistry] Refreshed: ${this.models.length} models cached to disk.`);
|
|
112
135
|
}
|
|
113
136
|
else {
|
|
@@ -132,19 +155,18 @@ class ModelRegistryImpl {
|
|
|
132
155
|
log(`[ModelRegistry] Refresh failed, keeping cache: ${e}`);
|
|
133
156
|
}
|
|
134
157
|
}
|
|
135
|
-
finally {
|
|
136
|
-
this.refreshing = false;
|
|
137
|
-
}
|
|
138
158
|
}
|
|
139
|
-
/** Get all models across all categories */
|
|
159
|
+
/** Get all models across all categories. Triggers lazy freshness check. */
|
|
140
160
|
all() {
|
|
161
|
+
this.ensureFresh().catch(() => { });
|
|
141
162
|
return [...this.models];
|
|
142
163
|
}
|
|
143
|
-
/** Auto-refresh if stale (non-blocking) */
|
|
164
|
+
/** Auto-refresh if stale (non-blocking). Returns the refresh promise for tests. */
|
|
144
165
|
ensureFresh() {
|
|
145
166
|
if (this.isStale()) {
|
|
146
|
-
this.refresh()
|
|
167
|
+
return this.refresh(); // coalesced; refresh() never rejects (handles offline)
|
|
147
168
|
}
|
|
169
|
+
return Promise.resolve();
|
|
148
170
|
}
|
|
149
171
|
/** Get count per category (for logging) */
|
|
150
172
|
stats() {
|
|
@@ -93,6 +93,9 @@ function mapRawToModel(raw, fallbackCategory, averageCost) {
|
|
|
93
93
|
voices: raw.voices,
|
|
94
94
|
tools: raw.tools,
|
|
95
95
|
reasoning: raw.reasoning,
|
|
96
|
+
reasoning_options: raw.reasoning_options,
|
|
97
|
+
interleaved: raw.interleaved,
|
|
98
|
+
capabilities: raw.capabilities,
|
|
96
99
|
is_specialized: raw.is_specialized,
|
|
97
100
|
context_window: raw.context_window || raw.context_length,
|
|
98
101
|
averageCost: averageCost !== undefined && !isNaN(averageCost) ? averageCost : undefined,
|
|
@@ -179,6 +182,12 @@ export async function fetchAllModels(apiKey) {
|
|
|
179
182
|
item.tools = v1Item.tools;
|
|
180
183
|
if (v1Item.reasoning !== undefined)
|
|
181
184
|
item.reasoning = v1Item.reasoning;
|
|
185
|
+
if (v1Item.reasoning_options !== undefined)
|
|
186
|
+
item.reasoning_options = v1Item.reasoning_options;
|
|
187
|
+
if (v1Item.interleaved !== undefined)
|
|
188
|
+
item.interleaved = v1Item.interleaved;
|
|
189
|
+
if (v1Item.capabilities !== undefined)
|
|
190
|
+
item.capabilities = v1Item.capabilities;
|
|
182
191
|
}
|
|
183
192
|
const model = mapRawToModel(item, res.fallbackCategory, avgCost);
|
|
184
193
|
const uniqueId = model.name;
|
|
@@ -33,6 +33,14 @@ export interface PollinationsModel {
|
|
|
33
33
|
voices?: string[];
|
|
34
34
|
tools?: boolean;
|
|
35
35
|
reasoning?: boolean;
|
|
36
|
+
reasoning_options?: Array<{
|
|
37
|
+
type: 'effort' | 'toggle';
|
|
38
|
+
values?: string[];
|
|
39
|
+
}>;
|
|
40
|
+
interleaved?: {
|
|
41
|
+
field: 'reasoning' | 'reasoning_content' | 'reasoning_details';
|
|
42
|
+
};
|
|
43
|
+
capabilities?: string[];
|
|
36
44
|
is_specialized?: boolean;
|
|
37
45
|
context_window?: number;
|
|
38
46
|
input_modalities: string[];
|
|
@@ -2,6 +2,7 @@ import { polliGenImageTool } from '../../tools/pollinations/gen_image.js';
|
|
|
2
2
|
import { polliGenVideoTool } from '../../tools/pollinations/gen_video.js';
|
|
3
3
|
import { polliGenAudioTool } from '../../tools/pollinations/gen_audio.js';
|
|
4
4
|
import { polliGenMusicTool } from '../../tools/pollinations/gen_music.js';
|
|
5
|
+
import { polliGen3dTool } from '../../tools/pollinations/gen_3d.js';
|
|
5
6
|
import { polliWebSearchTool } from '../../tools/pollinations/polli_web_search.js';
|
|
6
7
|
import { ModelRegistry } from './index.js';
|
|
7
8
|
import { log } from '../logger.js';
|
|
@@ -54,7 +55,7 @@ export class ToolRegistryWorker {
|
|
|
54
55
|
const videoModels = ModelRegistry.list('video');
|
|
55
56
|
if (videoModels.length > 0 && polliGenVideoTool.description) {
|
|
56
57
|
let videoTable = `\n\n**🎬 Modèles Vidéo Détectés (${videoModels.length}) :**\n`;
|
|
57
|
-
videoTable += `*(Légende: [💎 Paid] =
|
|
58
|
+
videoTable += `*(Légende: [💎 Paid] = Pollen acheté (consomme le Wallet USD), [🌿 Quest] = appel éligible au Quest; en mode quest_only, fallback Free avant le plancher Quest)*\n`;
|
|
58
59
|
videoTable += `| Modèle | Source I/O | Audio | 1 pollen ≈ | Specs |\n`;
|
|
59
60
|
videoTable += `|--------|------------|-------|------------|-------|\n`;
|
|
60
61
|
for (const m of videoModels) {
|
|
@@ -62,7 +63,7 @@ export class ToolRegistryWorker {
|
|
|
62
63
|
const price = cost ? `${per1pollen(cost)} vidéos` : 'inconnu';
|
|
63
64
|
const specs = `${m.durationRange ? m.durationRange.join('-') + 's' : '?s'} / ${m.aspectRatios ? m.aspectRatios.length : '?'} ratios`;
|
|
64
65
|
const isCommunity = m.community === true || m.name.includes('/');
|
|
65
|
-
const badge = isCommunity ? '[👥]' : (m.paid_only ? '[💎 Paid]' : '[🌿
|
|
66
|
+
const badge = isCommunity ? '[👥]' : (m.paid_only ? '[💎 Paid]' : '[🌿 Quest]');
|
|
66
67
|
videoTable += `| \`${m.name}\` ${badge} | ${m.supportsI2X ? 'T2V/I2V' : 'T2V'} | ${m.output_modalities?.includes('audio') || m.name === 'grok-video' ? '✅' : '❌'} | ${price} | ${specs} |\n`;
|
|
67
68
|
}
|
|
68
69
|
if (!polliGenVideoTool.description.includes('**🎬 Modèles Vidéo Détectés')) {
|
|
@@ -76,7 +77,7 @@ export class ToolRegistryWorker {
|
|
|
76
77
|
const imageModels = ModelRegistry.list('image');
|
|
77
78
|
if (imageModels.length > 0 && polliGenImageTool.description) {
|
|
78
79
|
let imageTable = `\n\n**🎨 Modèles Image Détectés (${imageModels.length}) :**\n`;
|
|
79
|
-
imageTable += `*(Légende: [💎 Paid] =
|
|
80
|
+
imageTable += `*(Légende: [💎 Paid] = Pollen acheté (consomme le Wallet USD), [🌿 Quest] = appel éligible au Quest; en mode quest_only, fallback Free avant le plancher Quest)*\n`;
|
|
80
81
|
imageTable += `| Modèle | I2I | Qualité | 1 pollen ≈ |\n`;
|
|
81
82
|
imageTable += `|--------|-----|---------|------------|\n`;
|
|
82
83
|
// Afficher max 20 modèles pour éviter de saturer le prompt LLM
|
|
@@ -84,7 +85,7 @@ export class ToolRegistryWorker {
|
|
|
84
85
|
const cost = estimateImageCost(m.name);
|
|
85
86
|
const price = cost ? `${per1pollen(cost)} images` : 'inconnu';
|
|
86
87
|
const isCommunity = m.community === true || m.name.includes('/');
|
|
87
|
-
const badge = isCommunity ? '[👥]' : (m.paid_only ? '[💎 Paid]' : '[🌿
|
|
88
|
+
const badge = isCommunity ? '[👥]' : (m.paid_only ? '[💎 Paid]' : '[🌿 Quest]');
|
|
88
89
|
imageTable += `| \`${m.name}\` ${badge} | ${m.supportsI2X ? '✅' : '❌'} | Standard | ${price} |\n`;
|
|
89
90
|
}
|
|
90
91
|
if (imageModels.length > 20) {
|
|
@@ -101,12 +102,12 @@ export class ToolRegistryWorker {
|
|
|
101
102
|
const audioModels = ModelRegistry.list('audio');
|
|
102
103
|
if (audioModels.length > 0 && polliGenAudioTool.description && polliGenMusicTool.description) {
|
|
103
104
|
let audioTable = `\n\n**🎵 Modèles Audio/Music Détectés (${audioModels.length}) :**\n`;
|
|
104
|
-
audioTable += `*(Légende: [💎 Paid] =
|
|
105
|
+
audioTable += `*(Légende: [💎 Paid] = Pollen acheté (consomme le Wallet USD), [🌿 Quest] = appel éligible au Quest; en mode quest_only, fallback Free avant le plancher Quest)*\n`;
|
|
105
106
|
audioTable += `| Modèle | Durée max | Qualité |\n`;
|
|
106
107
|
audioTable += `|--------|-----------|---------|\n`;
|
|
107
108
|
for (const m of audioModels) {
|
|
108
109
|
const isCommunity = m.community === true || m.name.includes('/');
|
|
109
|
-
const badge = isCommunity ? '[👥]' : (m.paid_only ? '[💎 Paid]' : '[🌿
|
|
110
|
+
const badge = isCommunity ? '[👥]' : (m.paid_only ? '[💎 Paid]' : '[🌿 Quest]');
|
|
110
111
|
const duration = m.durationRange ? `${m.durationRange.join('-')}s` : 'Standard';
|
|
111
112
|
audioTable += `| \`${m.name}\` ${badge} | ${duration} | Standard |\n`;
|
|
112
113
|
}
|
|
@@ -123,6 +124,29 @@ export class ToolRegistryWorker {
|
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
126
|
}
|
|
127
|
+
// -- Patch 3D Tool (fully dynamic from ModelRegistry) --
|
|
128
|
+
const threeDModels = ModelRegistry.list('3d');
|
|
129
|
+
if (threeDModels.length > 0 && polliGen3dTool.description) {
|
|
130
|
+
let threeDTable = `\n\n**🧊 Live 3D models (${threeDModels.length})**\n`;
|
|
131
|
+
threeDTable += `| Model | Access | Inputs | Output | Estimated cost |\n`;
|
|
132
|
+
threeDTable += `|-------|--------|--------|--------|----------------|\n`;
|
|
133
|
+
for (const m of threeDModels) {
|
|
134
|
+
const access = m.paid_only ? 'Paid only' : 'Quest eligible';
|
|
135
|
+
const inputs = m.input_modalities.join(', ') || 'text';
|
|
136
|
+
const cost = m.averageCost
|
|
137
|
+
?? m.pricing.completionImageTokens
|
|
138
|
+
?? m.pricing.completionTextTokens;
|
|
139
|
+
const costText = typeof cost === 'number' ? `${cost.toFixed(4)} pollen` : 'live pricing';
|
|
140
|
+
threeDTable += `| \`${m.name}\` | ${access} | ${inputs} | GLB | ${costText} |\n`;
|
|
141
|
+
}
|
|
142
|
+
const sectionMarker = '**🧊 Live 3D models';
|
|
143
|
+
if (!polliGen3dTool.description.includes(sectionMarker)) {
|
|
144
|
+
polliGen3dTool.description += threeDTable;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
polliGen3dTool.description = polliGen3dTool.description.split(sectionMarker)[0] + threeDTable;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
126
150
|
// -- Patch WEB SEARCH Tool --
|
|
127
151
|
const textModels = ModelRegistry.list('text');
|
|
128
152
|
if (textModels.length > 0 && polliWebSearchTool.description) {
|
|
@@ -134,12 +158,12 @@ export class ToolRegistryWorker {
|
|
|
134
158
|
});
|
|
135
159
|
if (searchModels.length > 0) {
|
|
136
160
|
let searchTable = `\n\n**🌍 Modèles de Recherche & Grounding Détectés (${searchModels.length}) :**\n`;
|
|
137
|
-
searchTable += `*(Légende: [💎 Paid] =
|
|
161
|
+
searchTable += `*(Légende: [💎 Paid] = Pollen acheté, [🌿 Quest] = appel éligible au Quest; quest_only protège le wallet Paid. Obligatoire de choisir un modèle exact au lieu de 'deep' ou 'rapid' !)*\n`;
|
|
138
162
|
searchTable += `| Modèle | Description / Specs |\n`;
|
|
139
163
|
searchTable += `|--------|---------------------|\n`;
|
|
140
164
|
for (const m of searchModels) {
|
|
141
165
|
const isCommunity = m.community === true || m.name.includes('/');
|
|
142
|
-
const badge = isCommunity ? '[👥]' : (m.paid_only ? '[💎 Paid]' : '[🌿
|
|
166
|
+
const badge = isCommunity ? '[👥]' : (m.paid_only ? '[💎 Paid]' : '[🌿 Quest]');
|
|
143
167
|
// Clean markdown piping conflicts
|
|
144
168
|
let cleanDesc = m.description.replace(/\|/g, '-');
|
|
145
169
|
// Adding "Specialized" hint
|
package/dist/server/proxy.d.ts
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
import * as http from 'http';
|
|
2
|
+
type RetrySignal = 'abort' | 'network' | number;
|
|
3
|
+
export declare function classifyRetry(signal: RetrySignal): 'RETRY' | 'NO_RETRY';
|
|
4
|
+
export declare function fetchWithRetry(url: string, options: any, retries?: number): Promise<Response>;
|
|
5
|
+
/** Normalize a single raw SSE `data:` payload line (JSON). Non-JSON passes through. */
|
|
6
|
+
export declare function normalizeChunkLine(payload: string): string;
|
|
2
7
|
export declare function handleChatCompletion(req: http.IncomingMessage, res: http.ServerResponse, bodyRaw: string): Promise<void>;
|
|
8
|
+
export {};
|