noosphere 0.2.1 → 0.3.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 +50 -0
- package/dist/index.cjs +230 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -1
- package/dist/index.d.ts +22 -1
- package/dist/index.js +234 -67
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -70,6 +70,10 @@ interface NoosphereStream extends AsyncIterable<StreamEvent> {
|
|
|
70
70
|
result(): Promise<NoosphereResult>;
|
|
71
71
|
abort(): void;
|
|
72
72
|
}
|
|
73
|
+
interface ProviderLogo$1 {
|
|
74
|
+
svg?: string;
|
|
75
|
+
png?: string;
|
|
76
|
+
}
|
|
73
77
|
interface ModelInfo {
|
|
74
78
|
id: string;
|
|
75
79
|
provider: string;
|
|
@@ -80,6 +84,7 @@ interface ModelInfo {
|
|
|
80
84
|
price: number;
|
|
81
85
|
unit: string;
|
|
82
86
|
};
|
|
87
|
+
logo?: ProviderLogo$1;
|
|
83
88
|
capabilities?: {
|
|
84
89
|
contextWindow?: number;
|
|
85
90
|
maxTokens?: number;
|
|
@@ -104,6 +109,7 @@ interface ProviderInfo {
|
|
|
104
109
|
local: boolean;
|
|
105
110
|
status: 'online' | 'offline' | 'degraded';
|
|
106
111
|
modelCount: number;
|
|
112
|
+
logo?: ProviderLogo$1;
|
|
107
113
|
}
|
|
108
114
|
interface UsageEvent {
|
|
109
115
|
modality: Modality;
|
|
@@ -254,4 +260,19 @@ declare class NoosphereError extends Error {
|
|
|
254
260
|
isRetryable(): boolean;
|
|
255
261
|
}
|
|
256
262
|
|
|
257
|
-
|
|
263
|
+
interface ProviderLogo {
|
|
264
|
+
svg?: string;
|
|
265
|
+
png?: string;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Known provider logos from official brand assets and CDNs.
|
|
269
|
+
* Keys match provider IDs used throughout noosphere.
|
|
270
|
+
*/
|
|
271
|
+
declare const PROVIDER_LOGOS: Record<string, ProviderLogo>;
|
|
272
|
+
/**
|
|
273
|
+
* Get logo for a provider by its ID.
|
|
274
|
+
* Tries exact match first, then case-insensitive partial match.
|
|
275
|
+
*/
|
|
276
|
+
declare function getProviderLogo(providerId: string | undefined | null): ProviderLogo | undefined;
|
|
277
|
+
|
|
278
|
+
export { type BaseOptions, type ChatOptions, type ImageOptions, type LocalServiceConfig, type Modality, type ModelInfo, Noosphere, type NoosphereConfig, NoosphereError, type NoosphereErrorCode, type NoosphereProvider, type NoosphereResult, type NoosphereStream, PROVIDER_LOGOS, type ProviderInfo, type ProviderLogo$1 as ProviderLogo, type SpeakOptions, type StreamEvent, type SyncResult, type UsageEvent, type UsageQueryOptions, type UsageSummary, type VideoOptions, getProviderLogo };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
1
8
|
// src/errors.ts
|
|
2
9
|
var RETRYABLE_CODES = /* @__PURE__ */ new Set([
|
|
3
10
|
"PROVIDER_UNAVAILABLE",
|
|
@@ -26,6 +33,16 @@ var NoosphereError = class extends Error {
|
|
|
26
33
|
};
|
|
27
34
|
|
|
28
35
|
// src/config.ts
|
|
36
|
+
var _envLoaded = false;
|
|
37
|
+
function loadEnv() {
|
|
38
|
+
if (_envLoaded) return;
|
|
39
|
+
_envLoaded = true;
|
|
40
|
+
try {
|
|
41
|
+
const dotenvx = __require("@dotenvx/dotenvx");
|
|
42
|
+
dotenvx.config({ quiet: true });
|
|
43
|
+
} catch {
|
|
44
|
+
}
|
|
45
|
+
}
|
|
29
46
|
var ENV_KEY_MAP = {
|
|
30
47
|
openai: "OPENAI_API_KEY",
|
|
31
48
|
anthropic: "ANTHROPIC_API_KEY",
|
|
@@ -49,6 +66,7 @@ var DEFAULT_RETRYABLE = [
|
|
|
49
66
|
"TIMEOUT"
|
|
50
67
|
];
|
|
51
68
|
function resolveConfig(input) {
|
|
69
|
+
loadEnv();
|
|
52
70
|
const keys = {};
|
|
53
71
|
for (const [name, envVar] of Object.entries(ENV_KEY_MAP)) {
|
|
54
72
|
keys[name] = input.keys?.[name] ?? process.env[envVar];
|
|
@@ -90,6 +108,132 @@ function resolveConfig(input) {
|
|
|
90
108
|
};
|
|
91
109
|
}
|
|
92
110
|
|
|
111
|
+
// src/logos.ts
|
|
112
|
+
var PROVIDER_LOGOS = {
|
|
113
|
+
// --- Cloud LLM Providers ---
|
|
114
|
+
openai: {
|
|
115
|
+
svg: "https://cdn.simpleicons.org/openai",
|
|
116
|
+
png: "https://cdn.brandfetch.io/idR3duQxYl/w/512/h/512/theme/dark/icon.png"
|
|
117
|
+
},
|
|
118
|
+
anthropic: {
|
|
119
|
+
svg: "https://cdn.simpleicons.org/anthropic",
|
|
120
|
+
png: "https://cdn.brandfetch.io/id2S-kXbuM/w/512/h/512/theme/dark/icon.png"
|
|
121
|
+
},
|
|
122
|
+
google: {
|
|
123
|
+
svg: "https://cdn.simpleicons.org/google",
|
|
124
|
+
png: "https://cdn.brandfetch.io/id6O2oGzv-/w/512/h/512/theme/dark/icon.png"
|
|
125
|
+
},
|
|
126
|
+
groq: {
|
|
127
|
+
svg: "https://cdn.simpleicons.org/groq",
|
|
128
|
+
png: "https://cdn.brandfetch.io/idTEBPz5KO/w/512/h/512/theme/dark/icon.png"
|
|
129
|
+
},
|
|
130
|
+
mistral: {
|
|
131
|
+
svg: "https://cdn.simpleicons.org/mistral",
|
|
132
|
+
png: "https://cdn.brandfetch.io/idnBOFq5eF/w/512/h/512/theme/dark/icon.png"
|
|
133
|
+
},
|
|
134
|
+
xai: {
|
|
135
|
+
svg: "https://cdn.simpleicons.org/x",
|
|
136
|
+
png: "https://cdn.brandfetch.io/idS5WhqBbM/w/512/h/512/theme/dark/icon.png"
|
|
137
|
+
},
|
|
138
|
+
openrouter: {
|
|
139
|
+
svg: "https://openrouter.ai/favicon.svg",
|
|
140
|
+
png: "https://openrouter.ai/favicon.png"
|
|
141
|
+
},
|
|
142
|
+
cerebras: {
|
|
143
|
+
svg: "https://cdn.simpleicons.org/cerebras",
|
|
144
|
+
png: "https://cdn.brandfetch.io/idGa4PRFP0/w/512/h/512/theme/dark/icon.png"
|
|
145
|
+
},
|
|
146
|
+
// --- Media Providers ---
|
|
147
|
+
fal: {
|
|
148
|
+
svg: "https://fal.ai/favicon.svg",
|
|
149
|
+
png: "https://fal.ai/favicon.png"
|
|
150
|
+
},
|
|
151
|
+
huggingface: {
|
|
152
|
+
svg: "https://cdn.simpleicons.org/huggingface",
|
|
153
|
+
png: "https://cdn.brandfetch.io/idnrPPHe87/w/512/h/512/theme/dark/icon.png"
|
|
154
|
+
},
|
|
155
|
+
// --- Local Providers ---
|
|
156
|
+
comfyui: {
|
|
157
|
+
svg: "https://raw.githubusercontent.com/comfyanonymous/ComfyUI/master/web/assets/icon.svg",
|
|
158
|
+
png: "https://raw.githubusercontent.com/comfyanonymous/ComfyUI/master/web/assets/icon.png"
|
|
159
|
+
},
|
|
160
|
+
piper: {
|
|
161
|
+
png: "https://raw.githubusercontent.com/rhasspy/piper/master/logo.png"
|
|
162
|
+
},
|
|
163
|
+
kokoro: {
|
|
164
|
+
png: "https://raw.githubusercontent.com/hexgrad/kokoro/main/assets/icon.png"
|
|
165
|
+
},
|
|
166
|
+
ollama: {
|
|
167
|
+
svg: "https://cdn.simpleicons.org/ollama",
|
|
168
|
+
png: "https://cdn.brandfetch.io/idtesMoSFj/w/512/h/512/theme/dark/icon.png"
|
|
169
|
+
},
|
|
170
|
+
// --- Model Org Providers (from OpenRouter model prefixes) ---
|
|
171
|
+
meta: {
|
|
172
|
+
svg: "https://cdn.simpleicons.org/meta",
|
|
173
|
+
png: "https://cdn.brandfetch.io/idmKk_rq7Y/w/512/h/512/theme/dark/icon.png"
|
|
174
|
+
},
|
|
175
|
+
deepseek: {
|
|
176
|
+
png: "https://cdn.brandfetch.io/id1BWKUVWI/w/512/h/512/theme/dark/icon.png"
|
|
177
|
+
},
|
|
178
|
+
microsoft: {
|
|
179
|
+
svg: "https://cdn.simpleicons.org/microsoft",
|
|
180
|
+
png: "https://cdn.brandfetch.io/idchmboHEZ/w/512/h/512/theme/dark/icon.png"
|
|
181
|
+
},
|
|
182
|
+
nvidia: {
|
|
183
|
+
svg: "https://cdn.simpleicons.org/nvidia",
|
|
184
|
+
png: "https://cdn.brandfetch.io/id1JcGHuZN/w/512/h/512/theme/dark/icon.png"
|
|
185
|
+
},
|
|
186
|
+
qwen: {
|
|
187
|
+
png: "https://img.alicdn.com/imgextra/i1/O1CN01BUp2gU1sRZigvazUo_!!6000000005764-2-tps-228-228.png"
|
|
188
|
+
},
|
|
189
|
+
cohere: {
|
|
190
|
+
svg: "https://cdn.simpleicons.org/cohere",
|
|
191
|
+
png: "https://cdn.brandfetch.io/idiDnz1fvB/w/512/h/512/theme/dark/icon.png"
|
|
192
|
+
},
|
|
193
|
+
perplexity: {
|
|
194
|
+
svg: "https://cdn.simpleicons.org/perplexity",
|
|
195
|
+
png: "https://cdn.brandfetch.io/idwWX3Neii/w/512/h/512/theme/dark/icon.png"
|
|
196
|
+
},
|
|
197
|
+
amazon: {
|
|
198
|
+
svg: "https://cdn.simpleicons.org/amazonaws",
|
|
199
|
+
png: "https://cdn.brandfetch.io/idawORoPJZ/w/512/h/512/theme/dark/icon.png"
|
|
200
|
+
},
|
|
201
|
+
// --- HuggingFace Inference Providers ---
|
|
202
|
+
"hf-inference": {
|
|
203
|
+
svg: "https://cdn.simpleicons.org/huggingface",
|
|
204
|
+
png: "https://cdn.brandfetch.io/idnrPPHe87/w/512/h/512/theme/dark/icon.png"
|
|
205
|
+
},
|
|
206
|
+
"sambanova": {
|
|
207
|
+
png: "https://cdn.brandfetch.io/id__2e5yMY/w/512/h/512/theme/dark/icon.png"
|
|
208
|
+
},
|
|
209
|
+
"together": {
|
|
210
|
+
svg: "https://cdn.simpleicons.org/togetherai",
|
|
211
|
+
png: "https://cdn.brandfetch.io/idH5EoFVaH/w/512/h/512/theme/dark/icon.png"
|
|
212
|
+
},
|
|
213
|
+
"fireworks-ai": {
|
|
214
|
+
png: "https://cdn.brandfetch.io/idj1VQ2O4C/w/512/h/512/theme/dark/icon.png"
|
|
215
|
+
},
|
|
216
|
+
"replicate": {
|
|
217
|
+
svg: "https://cdn.simpleicons.org/replicate",
|
|
218
|
+
png: "https://cdn.brandfetch.io/idWKE4rRaH/w/512/h/512/theme/dark/icon.png"
|
|
219
|
+
},
|
|
220
|
+
"nebius": {
|
|
221
|
+
png: "https://cdn.brandfetch.io/idiUqSQ52b/w/512/h/512/theme/dark/icon.png"
|
|
222
|
+
},
|
|
223
|
+
"novita": {
|
|
224
|
+
png: "https://novita.ai/favicon.png"
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
function getProviderLogo(providerId) {
|
|
228
|
+
if (!providerId) return void 0;
|
|
229
|
+
if (PROVIDER_LOGOS[providerId]) return PROVIDER_LOGOS[providerId];
|
|
230
|
+
const normalized = providerId.toLowerCase().replace(/[-_\s]/g, "");
|
|
231
|
+
for (const [key, logo] of Object.entries(PROVIDER_LOGOS)) {
|
|
232
|
+
if (key.replace(/[-_\s]/g, "") === normalized) return logo;
|
|
233
|
+
}
|
|
234
|
+
return void 0;
|
|
235
|
+
}
|
|
236
|
+
|
|
93
237
|
// src/registry.ts
|
|
94
238
|
var Registry = class {
|
|
95
239
|
providers = /* @__PURE__ */ new Map();
|
|
@@ -193,7 +337,8 @@ var Registry = class {
|
|
|
193
337
|
local: provider.isLocal,
|
|
194
338
|
status: "online",
|
|
195
339
|
// ping-based status is set externally
|
|
196
|
-
modelCount: cached?.models.length ?? 0
|
|
340
|
+
modelCount: cached?.models.length ?? 0,
|
|
341
|
+
logo: getProviderLogo(provider.id)
|
|
197
342
|
});
|
|
198
343
|
}
|
|
199
344
|
return infos;
|
|
@@ -252,7 +397,6 @@ var UsageTracker = class {
|
|
|
252
397
|
// src/providers/pi-ai.ts
|
|
253
398
|
import { getModels, getProviders, complete, stream, setApiKey } from "@mariozechner/pi-ai";
|
|
254
399
|
var KNOWN_PROVIDERS = ["anthropic", "google", "openai", "xai", "groq", "cerebras", "openrouter", "zai"];
|
|
255
|
-
var LOCAL_PROVIDERS = /* @__PURE__ */ new Set(["ollama"]);
|
|
256
400
|
var FETCH_TIMEOUT_MS = 8e3;
|
|
257
401
|
var OPENAI_CHAT_PREFIXES = ["gpt-", "o1", "o3", "o4", "chatgpt-", "codex-"];
|
|
258
402
|
var OPENAI_REASONING_PREFIXES = ["o1", "o3", "o4"];
|
|
@@ -393,35 +537,9 @@ var PiAiProvider = class {
|
|
|
393
537
|
if (modality && modality !== "llm") return [];
|
|
394
538
|
await this.ensureDynamicModels();
|
|
395
539
|
const models = [];
|
|
396
|
-
const
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
const providerModels = getModels(provider);
|
|
400
|
-
for (const m of providerModels) {
|
|
401
|
-
seenIds.add(m.id);
|
|
402
|
-
models.push({
|
|
403
|
-
id: m.id,
|
|
404
|
-
provider: "pi-ai",
|
|
405
|
-
name: m.name || m.id,
|
|
406
|
-
modality: "llm",
|
|
407
|
-
local: LOCAL_PROVIDERS.has(String(m.provider)),
|
|
408
|
-
cost: {
|
|
409
|
-
price: m.cost.input ?? 0,
|
|
410
|
-
unit: m.cost.input > 0 ? "per_1m_tokens" : "free"
|
|
411
|
-
},
|
|
412
|
-
capabilities: {
|
|
413
|
-
contextWindow: m.contextWindow,
|
|
414
|
-
maxTokens: m.maxTokens,
|
|
415
|
-
supportsVision: m.input.includes("image"),
|
|
416
|
-
supportsStreaming: true
|
|
417
|
-
}
|
|
418
|
-
});
|
|
419
|
-
}
|
|
420
|
-
} catch {
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
for (const [id, m] of this.dynamicModels) {
|
|
424
|
-
if (seenIds.has(id)) continue;
|
|
540
|
+
for (const [, m] of this.dynamicModels) {
|
|
541
|
+
const providerName = String(m.provider);
|
|
542
|
+
const logoProvider = this.inferLogoProvider(m.id, providerName);
|
|
425
543
|
models.push({
|
|
426
544
|
id: m.id,
|
|
427
545
|
provider: "pi-ai",
|
|
@@ -432,6 +550,7 @@ var PiAiProvider = class {
|
|
|
432
550
|
price: m.cost.input ?? 0,
|
|
433
551
|
unit: m.cost.input > 0 ? "per_1m_tokens" : "free"
|
|
434
552
|
},
|
|
553
|
+
logo: getProviderLogo(logoProvider),
|
|
435
554
|
capabilities: {
|
|
436
555
|
contextWindow: m.contextWindow,
|
|
437
556
|
maxTokens: m.maxTokens,
|
|
@@ -556,24 +675,15 @@ var PiAiProvider = class {
|
|
|
556
675
|
async ensureDynamicModels() {
|
|
557
676
|
if (this.dynamicModelsFetched) return;
|
|
558
677
|
this.dynamicModelsFetched = true;
|
|
559
|
-
const staticIds = /* @__PURE__ */ new Set();
|
|
560
|
-
for (const provider of KNOWN_PROVIDERS) {
|
|
561
|
-
try {
|
|
562
|
-
for (const m of getModels(provider)) {
|
|
563
|
-
staticIds.add(m.id);
|
|
564
|
-
}
|
|
565
|
-
} catch {
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
678
|
const fetchPromises = [];
|
|
569
679
|
for (const [providerKey, configFactory] of Object.entries(PROVIDER_APIS)) {
|
|
570
680
|
const apiKey = this.keys[providerKey];
|
|
571
681
|
if (!apiKey) continue;
|
|
572
|
-
fetchPromises.push(this.fetchProviderModels(configFactory(apiKey), apiKey
|
|
682
|
+
fetchPromises.push(this.fetchProviderModels(configFactory(apiKey), apiKey));
|
|
573
683
|
}
|
|
574
684
|
await Promise.allSettled(fetchPromises);
|
|
575
685
|
}
|
|
576
|
-
async fetchProviderModels(config, apiKey
|
|
686
|
+
async fetchProviderModels(config, apiKey) {
|
|
577
687
|
try {
|
|
578
688
|
const controller = new AbortController();
|
|
579
689
|
const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
@@ -586,11 +696,11 @@ var PiAiProvider = class {
|
|
|
586
696
|
if (!res.ok) return;
|
|
587
697
|
const data = await res.json();
|
|
588
698
|
const entries = config.extractEntries(data);
|
|
589
|
-
const
|
|
699
|
+
const staticTemplate = this.findStaticTemplate(config.providerName);
|
|
590
700
|
for (const entry of entries) {
|
|
591
701
|
const id = entry.id;
|
|
592
702
|
if (!config.filterChat(id)) continue;
|
|
593
|
-
|
|
703
|
+
const staticMatch = this.findStaticModel(config.providerName, id);
|
|
594
704
|
this.dynamicModels.set(id, {
|
|
595
705
|
id,
|
|
596
706
|
name: entry.name ?? id,
|
|
@@ -598,10 +708,10 @@ var PiAiProvider = class {
|
|
|
598
708
|
provider: config.providerName,
|
|
599
709
|
baseUrl: config.piBaseUrl,
|
|
600
710
|
reasoning: config.isReasoning(id),
|
|
601
|
-
input: ["text", "image"],
|
|
602
|
-
cost:
|
|
603
|
-
contextWindow: entry.contextWindow ??
|
|
604
|
-
maxTokens: entry.maxTokens ??
|
|
711
|
+
input: staticMatch?.input ?? ["text", "image"],
|
|
712
|
+
cost: staticMatch?.cost ?? staticTemplate?.cost ?? { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
713
|
+
contextWindow: entry.contextWindow ?? staticMatch?.contextWindow ?? staticTemplate?.contextWindow ?? 128e3,
|
|
714
|
+
maxTokens: entry.maxTokens ?? staticMatch?.maxTokens ?? staticTemplate?.maxTokens ?? 16384
|
|
605
715
|
});
|
|
606
716
|
}
|
|
607
717
|
} finally {
|
|
@@ -618,25 +728,75 @@ var PiAiProvider = class {
|
|
|
618
728
|
return null;
|
|
619
729
|
}
|
|
620
730
|
}
|
|
731
|
+
findStaticModel(providerName, modelId) {
|
|
732
|
+
try {
|
|
733
|
+
const models = getModels(providerName);
|
|
734
|
+
return models.find((m) => m.id === modelId) ?? null;
|
|
735
|
+
} catch {
|
|
736
|
+
return null;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
621
739
|
/** Force re-fetch of dynamic models from provider APIs */
|
|
622
740
|
async refreshDynamicModels() {
|
|
623
741
|
this.dynamicModelsFetched = false;
|
|
624
742
|
this.dynamicModels.clear();
|
|
625
743
|
await this.ensureDynamicModels();
|
|
626
744
|
}
|
|
745
|
+
/**
|
|
746
|
+
* Infer the real provider from model ID for logo resolution.
|
|
747
|
+
* e.g. "x-ai/grok-4" → "xai", "anthropic/claude-4" → "anthropic"
|
|
748
|
+
*/
|
|
749
|
+
inferLogoProvider(modelId, fallback) {
|
|
750
|
+
const MODEL_PREFIX_TO_PROVIDER = {
|
|
751
|
+
"openai/": "openai",
|
|
752
|
+
"gpt-": "openai",
|
|
753
|
+
"o1-": "openai",
|
|
754
|
+
"o3-": "openai",
|
|
755
|
+
"o4-": "openai",
|
|
756
|
+
"chatgpt-": "openai",
|
|
757
|
+
"anthropic/": "anthropic",
|
|
758
|
+
"claude-": "anthropic",
|
|
759
|
+
"google/": "google",
|
|
760
|
+
"gemini-": "google",
|
|
761
|
+
"gemma-": "google",
|
|
762
|
+
"x-ai/": "xai",
|
|
763
|
+
"grok-": "xai",
|
|
764
|
+
"meta-llama/": "meta",
|
|
765
|
+
"mistralai/": "mistral",
|
|
766
|
+
"mistral-": "mistral",
|
|
767
|
+
"deepseek/": "deepseek",
|
|
768
|
+
"microsoft/": "microsoft",
|
|
769
|
+
"nvidia/": "nvidia",
|
|
770
|
+
"qwen/": "qwen",
|
|
771
|
+
"cohere/": "cohere",
|
|
772
|
+
"perplexity/": "perplexity",
|
|
773
|
+
"amazon/": "amazon"
|
|
774
|
+
};
|
|
775
|
+
const lower = modelId.toLowerCase();
|
|
776
|
+
for (const [prefix, provider] of Object.entries(MODEL_PREFIX_TO_PROVIDER)) {
|
|
777
|
+
if (lower.startsWith(prefix)) return provider;
|
|
778
|
+
}
|
|
779
|
+
return fallback;
|
|
780
|
+
}
|
|
627
781
|
findModel(modelId) {
|
|
782
|
+
if (modelId) {
|
|
783
|
+
const dynamic = this.dynamicModels.get(modelId);
|
|
784
|
+
if (dynamic) return { model: dynamic, provider: String(dynamic.provider) };
|
|
785
|
+
}
|
|
786
|
+
if (!modelId) {
|
|
787
|
+
const first = this.dynamicModels.values().next();
|
|
788
|
+
if (!first.done && first.value) {
|
|
789
|
+
return { model: first.value, provider: String(first.value.provider) };
|
|
790
|
+
}
|
|
791
|
+
}
|
|
628
792
|
for (const provider of KNOWN_PROVIDERS) {
|
|
629
793
|
try {
|
|
630
794
|
const models = getModels(provider);
|
|
631
|
-
const found = modelId ? models.find((m) => m.id === modelId) :
|
|
795
|
+
const found = modelId ? models.find((m) => m.id === modelId) : void 0;
|
|
632
796
|
if (found) return { model: found, provider };
|
|
633
797
|
} catch {
|
|
634
798
|
}
|
|
635
799
|
}
|
|
636
|
-
if (modelId) {
|
|
637
|
-
const dynamic = this.dynamicModels.get(modelId);
|
|
638
|
-
if (dynamic) return { model: dynamic, provider: String(dynamic.provider) };
|
|
639
|
-
}
|
|
640
800
|
return { model: null, provider: null };
|
|
641
801
|
}
|
|
642
802
|
};
|
|
@@ -677,7 +837,8 @@ var FalProvider = class {
|
|
|
677
837
|
name: entry.modelId.replace("fal-ai/", ""),
|
|
678
838
|
modality: inferredModality,
|
|
679
839
|
local: false,
|
|
680
|
-
cost: { price: entry.price, unit: entry.unit }
|
|
840
|
+
cost: { price: entry.price, unit: entry.unit },
|
|
841
|
+
logo: getProviderLogo("fal")
|
|
681
842
|
});
|
|
682
843
|
}
|
|
683
844
|
return models;
|
|
@@ -830,6 +991,7 @@ var ComfyUIProvider = class {
|
|
|
830
991
|
const res = await fetch(`${this.baseUrl}/object_info`);
|
|
831
992
|
if (!res.ok) return [];
|
|
832
993
|
const models = [];
|
|
994
|
+
const logo = getProviderLogo("comfyui");
|
|
833
995
|
if (!modality || modality === "image") {
|
|
834
996
|
models.push({
|
|
835
997
|
id: "comfyui-txt2img",
|
|
@@ -838,6 +1000,7 @@ var ComfyUIProvider = class {
|
|
|
838
1000
|
modality: "image",
|
|
839
1001
|
local: true,
|
|
840
1002
|
cost: { price: 0, unit: "free" },
|
|
1003
|
+
logo,
|
|
841
1004
|
capabilities: { maxWidth: 2048, maxHeight: 2048, supportsNegativePrompt: true }
|
|
842
1005
|
});
|
|
843
1006
|
}
|
|
@@ -849,6 +1012,7 @@ var ComfyUIProvider = class {
|
|
|
849
1012
|
modality: "video",
|
|
850
1013
|
local: true,
|
|
851
1014
|
cost: { price: 0, unit: "free" },
|
|
1015
|
+
logo,
|
|
852
1016
|
capabilities: { maxDuration: 10, supportsImageToVideo: true }
|
|
853
1017
|
});
|
|
854
1018
|
}
|
|
@@ -960,6 +1124,7 @@ var LocalTTSProvider = class {
|
|
|
960
1124
|
voices = data.data ?? [];
|
|
961
1125
|
}
|
|
962
1126
|
}
|
|
1127
|
+
const logo = getProviderLogo(this.id);
|
|
963
1128
|
return voices.map((v) => ({
|
|
964
1129
|
id: v.id,
|
|
965
1130
|
provider: this.id,
|
|
@@ -967,6 +1132,7 @@ var LocalTTSProvider = class {
|
|
|
967
1132
|
modality: "tts",
|
|
968
1133
|
local: true,
|
|
969
1134
|
cost: { price: 0, unit: "free" },
|
|
1135
|
+
logo,
|
|
970
1136
|
capabilities: { voices: voices.map((vv) => vv.id) }
|
|
971
1137
|
}));
|
|
972
1138
|
} catch {
|
|
@@ -1017,11 +1183,6 @@ var PIPELINE_TAG_MAP = {
|
|
|
1017
1183
|
"text-to-image": { modality: "image", limit: 50 },
|
|
1018
1184
|
"text-to-speech": { modality: "tts", limit: 30 }
|
|
1019
1185
|
};
|
|
1020
|
-
var DEFAULT_MODELS = [
|
|
1021
|
-
{ id: "stabilityai/stable-diffusion-xl-base-1.0", provider: "huggingface", name: "SDXL Base", modality: "image", local: false, cost: { price: 0, unit: "free" } },
|
|
1022
|
-
{ id: "facebook/mms-tts-eng", provider: "huggingface", name: "MMS TTS English", modality: "tts", local: false, cost: { price: 0, unit: "free" } },
|
|
1023
|
-
{ id: "meta-llama/Llama-3.1-8B-Instruct", provider: "huggingface", name: "Llama 3.1 8B", modality: "llm", local: false, cost: { price: 0, unit: "free" } }
|
|
1024
|
-
];
|
|
1025
1186
|
var HuggingFaceProvider = class {
|
|
1026
1187
|
id = "huggingface";
|
|
1027
1188
|
name = "HuggingFace Inference";
|
|
@@ -1041,17 +1202,13 @@ var HuggingFaceProvider = class {
|
|
|
1041
1202
|
if (!this.dynamicModels) {
|
|
1042
1203
|
await this.fetchHubModels();
|
|
1043
1204
|
}
|
|
1044
|
-
const all = this.dynamicModels ??
|
|
1205
|
+
const all = this.dynamicModels ?? [];
|
|
1045
1206
|
if (modality) return all.filter((m) => m.modality === modality);
|
|
1046
1207
|
return all;
|
|
1047
1208
|
}
|
|
1048
1209
|
async fetchHubModels() {
|
|
1049
1210
|
const seenIds = /* @__PURE__ */ new Set();
|
|
1050
1211
|
const models = [];
|
|
1051
|
-
for (const d of DEFAULT_MODELS) {
|
|
1052
|
-
seenIds.add(d.id);
|
|
1053
|
-
models.push(d);
|
|
1054
|
-
}
|
|
1055
1212
|
const fetches = Object.entries(PIPELINE_TAG_MAP).map(
|
|
1056
1213
|
([tag, { modality, limit }]) => this.fetchByPipelineTag(tag, modality, limit)
|
|
1057
1214
|
);
|
|
@@ -1086,7 +1243,13 @@ var HuggingFaceProvider = class {
|
|
|
1086
1243
|
const data = await res.json();
|
|
1087
1244
|
return data.filter((entry) => entry.id || entry.modelId).map((entry) => {
|
|
1088
1245
|
const id = entry.id ?? entry.modelId;
|
|
1089
|
-
const
|
|
1246
|
+
const liveProviders = (entry.inferenceProviderMapping ?? []).filter((p) => p.status === "live");
|
|
1247
|
+
const providers = liveProviders.map((p) => p.provider);
|
|
1248
|
+
const inferenceProviderLogos = {};
|
|
1249
|
+
for (const p of liveProviders) {
|
|
1250
|
+
const pLogo = getProviderLogo(p.provider);
|
|
1251
|
+
if (pLogo) inferenceProviderLogos[p.provider] = pLogo;
|
|
1252
|
+
}
|
|
1090
1253
|
const pricingProvider = (entry.inferenceProviderMapping ?? []).find((p) => p.providerDetails?.pricing);
|
|
1091
1254
|
const pricing = pricingProvider?.providerDetails?.pricing;
|
|
1092
1255
|
const contextLength = (entry.inferenceProviderMapping ?? []).find((p) => p.providerDetails?.context_length)?.providerDetails?.context_length;
|
|
@@ -1100,12 +1263,14 @@ var HuggingFaceProvider = class {
|
|
|
1100
1263
|
price: pricing?.input ?? 0,
|
|
1101
1264
|
unit: pricing ? "per_1m_tokens" : "free"
|
|
1102
1265
|
},
|
|
1266
|
+
logo: getProviderLogo("huggingface"),
|
|
1103
1267
|
capabilities: {
|
|
1104
1268
|
...modality === "llm" ? {
|
|
1105
1269
|
contextWindow: contextLength,
|
|
1106
1270
|
supportsStreaming: true
|
|
1107
1271
|
} : {},
|
|
1108
|
-
...providers.length > 0 ? { inferenceProviders: providers } : {}
|
|
1272
|
+
...providers.length > 0 ? { inferenceProviders: providers } : {},
|
|
1273
|
+
...Object.keys(inferenceProviderLogos).length > 0 ? { inferenceProviderLogos } : {}
|
|
1109
1274
|
}
|
|
1110
1275
|
};
|
|
1111
1276
|
});
|
|
@@ -1556,6 +1721,8 @@ var Noosphere = class {
|
|
|
1556
1721
|
};
|
|
1557
1722
|
export {
|
|
1558
1723
|
Noosphere,
|
|
1559
|
-
NoosphereError
|
|
1724
|
+
NoosphereError,
|
|
1725
|
+
PROVIDER_LOGOS,
|
|
1726
|
+
getProviderLogo
|
|
1560
1727
|
};
|
|
1561
1728
|
//# sourceMappingURL=index.js.map
|