noosphere 0.1.0 → 0.1.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/LICENSE +21 -0
- package/README.md +346 -0
- package/dist/index.cjs +1318 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +257 -0
- package/package.json +23 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 0xJesus
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
# noosphere
|
|
2
|
+
|
|
3
|
+
Unified AI creation engine — text, image, video, and audio generation across all providers through a single interface.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Multi-modal** — LLM chat, image generation, video generation, and text-to-speech
|
|
8
|
+
- **Multi-provider** — OpenAI, Anthropic, Google, Groq, Mistral, xAI, OpenRouter, FAL, Hugging Face
|
|
9
|
+
- **Local-first** — Auto-detects ComfyUI, Ollama, Piper, and Kokoro running on your machine
|
|
10
|
+
- **Failover & retry** — Automatic retries with exponential backoff and cross-provider failover
|
|
11
|
+
- **Usage tracking** — Track costs, latency, and token counts across all providers
|
|
12
|
+
- **TypeScript-first** — Full type definitions with ESM and CommonJS support
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install noosphere
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { Noosphere } from 'noosphere';
|
|
24
|
+
|
|
25
|
+
const ai = new Noosphere();
|
|
26
|
+
|
|
27
|
+
// Chat with any LLM
|
|
28
|
+
const response = await ai.chat({
|
|
29
|
+
messages: [{ role: 'user', content: 'Hello!' }],
|
|
30
|
+
});
|
|
31
|
+
console.log(response.content);
|
|
32
|
+
|
|
33
|
+
// Generate an image
|
|
34
|
+
const image = await ai.image({
|
|
35
|
+
prompt: 'A sunset over mountains',
|
|
36
|
+
width: 1024,
|
|
37
|
+
height: 1024,
|
|
38
|
+
});
|
|
39
|
+
console.log(image.url);
|
|
40
|
+
|
|
41
|
+
// Generate a video
|
|
42
|
+
const video = await ai.video({
|
|
43
|
+
prompt: 'Ocean waves crashing on rocks',
|
|
44
|
+
duration: 5,
|
|
45
|
+
});
|
|
46
|
+
console.log(video.url);
|
|
47
|
+
|
|
48
|
+
// Text-to-speech
|
|
49
|
+
const audio = await ai.speak({
|
|
50
|
+
text: 'Welcome to Noosphere',
|
|
51
|
+
voice: 'alloy',
|
|
52
|
+
format: 'mp3',
|
|
53
|
+
});
|
|
54
|
+
// audio.buffer contains the audio data
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Configuration
|
|
58
|
+
|
|
59
|
+
API keys are resolved from the constructor or environment variables:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
const ai = new Noosphere({
|
|
63
|
+
keys: {
|
|
64
|
+
openai: 'sk-...',
|
|
65
|
+
anthropic: 'sk-ant-...',
|
|
66
|
+
google: 'AIza...',
|
|
67
|
+
fal: 'fal-...',
|
|
68
|
+
huggingface: 'hf_...',
|
|
69
|
+
groq: 'gsk_...',
|
|
70
|
+
mistral: '...',
|
|
71
|
+
xai: '...',
|
|
72
|
+
openrouter: 'sk-or-...',
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Or set environment variables:
|
|
78
|
+
|
|
79
|
+
| Variable | Provider |
|
|
80
|
+
|---|---|
|
|
81
|
+
| `OPENAI_API_KEY` | OpenAI |
|
|
82
|
+
| `ANTHROPIC_API_KEY` | Anthropic |
|
|
83
|
+
| `GEMINI_API_KEY` | Google |
|
|
84
|
+
| `FAL_KEY` | FAL |
|
|
85
|
+
| `HUGGINGFACE_TOKEN` | Hugging Face |
|
|
86
|
+
| `GROQ_API_KEY` | Groq |
|
|
87
|
+
| `MISTRAL_API_KEY` | Mistral |
|
|
88
|
+
| `XAI_API_KEY` | xAI |
|
|
89
|
+
| `OPENROUTER_API_KEY` | OpenRouter |
|
|
90
|
+
|
|
91
|
+
## API
|
|
92
|
+
|
|
93
|
+
### `new Noosphere(config?)`
|
|
94
|
+
|
|
95
|
+
Creates a new instance. Providers are initialized lazily on first use.
|
|
96
|
+
|
|
97
|
+
### Generation
|
|
98
|
+
|
|
99
|
+
#### `ai.chat(options): Promise<NoosphereResult>`
|
|
100
|
+
|
|
101
|
+
Generate text with an LLM.
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
const result = await ai.chat({
|
|
105
|
+
provider: 'anthropic', // optional — auto-resolved if omitted
|
|
106
|
+
model: 'claude-sonnet-4-20250514', // optional
|
|
107
|
+
messages: [
|
|
108
|
+
{ role: 'system', content: 'You are helpful.' },
|
|
109
|
+
{ role: 'user', content: 'Explain quantum computing' },
|
|
110
|
+
],
|
|
111
|
+
temperature: 0.7, // optional
|
|
112
|
+
maxTokens: 1024, // optional
|
|
113
|
+
jsonMode: false, // optional
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
console.log(result.content); // response text
|
|
117
|
+
console.log(result.thinking); // reasoning (if supported)
|
|
118
|
+
console.log(result.usage.cost); // cost in USD
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### `ai.stream(options): NoosphereStream`
|
|
122
|
+
|
|
123
|
+
Stream LLM responses.
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
const stream = ai.stream({
|
|
127
|
+
messages: [{ role: 'user', content: 'Write a story' }],
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
for await (const event of stream) {
|
|
131
|
+
if (event.type === 'text_delta') process.stdout.write(event.delta!);
|
|
132
|
+
if (event.type === 'thinking_delta') console.log('[thinking]', event.delta);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Or get the full result after streaming
|
|
136
|
+
const result = await stream.result();
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### `ai.image(options): Promise<NoosphereResult>`
|
|
140
|
+
|
|
141
|
+
Generate images.
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
const result = await ai.image({
|
|
145
|
+
prompt: 'A futuristic cityscape',
|
|
146
|
+
negativePrompt: 'blurry, low quality', // optional
|
|
147
|
+
width: 1024, // optional
|
|
148
|
+
height: 768, // optional
|
|
149
|
+
seed: 42, // optional
|
|
150
|
+
steps: 30, // optional
|
|
151
|
+
guidanceScale: 7.5, // optional
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
console.log(result.url); // image URL
|
|
155
|
+
console.log(result.media?.width); // dimensions
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
#### `ai.video(options): Promise<NoosphereResult>`
|
|
159
|
+
|
|
160
|
+
Generate videos.
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
const result = await ai.video({
|
|
164
|
+
prompt: 'A bird flying through clouds',
|
|
165
|
+
imageUrl: 'https://...', // optional — image-to-video
|
|
166
|
+
duration: 5, // optional — seconds
|
|
167
|
+
fps: 24, // optional
|
|
168
|
+
width: 1280, // optional
|
|
169
|
+
height: 720, // optional
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
console.log(result.url);
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
#### `ai.speak(options): Promise<NoosphereResult>`
|
|
176
|
+
|
|
177
|
+
Text-to-speech synthesis.
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
const result = await ai.speak({
|
|
181
|
+
text: 'Hello world',
|
|
182
|
+
voice: 'alloy', // optional
|
|
183
|
+
language: 'en', // optional
|
|
184
|
+
speed: 1.0, // optional
|
|
185
|
+
format: 'mp3', // optional — 'mp3' | 'wav' | 'ogg'
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// result.buffer contains the audio data
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Discovery
|
|
192
|
+
|
|
193
|
+
#### `ai.getProviders(modality?): Promise<ProviderInfo[]>`
|
|
194
|
+
|
|
195
|
+
List available providers, optionally filtered by modality.
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
const providers = await ai.getProviders('llm');
|
|
199
|
+
// [{ id: 'pi-ai', name: 'Pi-AI', modalities: ['llm'], local: false, status: 'online', modelCount: 42 }]
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### `ai.getModels(modality?): Promise<ModelInfo[]>`
|
|
203
|
+
|
|
204
|
+
List all available models.
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
const models = await ai.getModels('image');
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
#### `ai.getModel(provider, modelId): Promise<ModelInfo | null>`
|
|
211
|
+
|
|
212
|
+
Get details about a specific model.
|
|
213
|
+
|
|
214
|
+
#### `ai.syncModels(): Promise<SyncResult>`
|
|
215
|
+
|
|
216
|
+
Refresh model lists from all providers.
|
|
217
|
+
|
|
218
|
+
### Usage Tracking
|
|
219
|
+
|
|
220
|
+
#### `ai.getUsage(options?): UsageSummary`
|
|
221
|
+
|
|
222
|
+
Get aggregated usage statistics.
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
const usage = ai.getUsage({ since: '2024-01-01', provider: 'openai' });
|
|
226
|
+
console.log(usage.totalCost); // total USD spent
|
|
227
|
+
console.log(usage.totalRequests); // number of requests
|
|
228
|
+
console.log(usage.byProvider); // { openai: 2.50, anthropic: 1.20 }
|
|
229
|
+
console.log(usage.byModality); // { llm: 3.00, image: 0.70 }
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Real-time usage callback:
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
const ai = new Noosphere({
|
|
236
|
+
onUsage: (event) => {
|
|
237
|
+
console.log(`${event.provider}/${event.model}: $${event.cost} (${event.latencyMs}ms)`);
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Custom Providers
|
|
243
|
+
|
|
244
|
+
Register your own provider by implementing the `NoosphereProvider` interface:
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
import type { NoosphereProvider } from 'noosphere';
|
|
248
|
+
|
|
249
|
+
const myProvider: NoosphereProvider = {
|
|
250
|
+
id: 'my-provider',
|
|
251
|
+
name: 'My Provider',
|
|
252
|
+
modalities: ['llm'],
|
|
253
|
+
isLocal: false,
|
|
254
|
+
|
|
255
|
+
async ping() { return true; },
|
|
256
|
+
async listModels() { return [/* ... */]; },
|
|
257
|
+
|
|
258
|
+
async chat(options) {
|
|
259
|
+
// your implementation
|
|
260
|
+
return { content: '...', provider: 'my-provider', model: '...', modality: 'llm', latencyMs: 100, usage: { cost: 0 } };
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
ai.registerProvider(myProvider);
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Error Handling
|
|
268
|
+
|
|
269
|
+
All errors are instances of `NoosphereError`:
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
import { NoosphereError } from 'noosphere';
|
|
273
|
+
|
|
274
|
+
try {
|
|
275
|
+
await ai.chat({ messages: [{ role: 'user', content: 'Hello' }] });
|
|
276
|
+
} catch (err) {
|
|
277
|
+
if (err instanceof NoosphereError) {
|
|
278
|
+
console.log(err.code); // 'RATE_LIMITED' | 'TIMEOUT' | 'AUTH_FAILED' | ...
|
|
279
|
+
console.log(err.provider); // which provider failed
|
|
280
|
+
console.log(err.modality); // 'llm' | 'image' | 'video' | 'tts'
|
|
281
|
+
console.log(err.isRetryable());
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Error codes: `PROVIDER_UNAVAILABLE`, `MODEL_NOT_FOUND`, `AUTH_FAILED`, `RATE_LIMITED`, `TIMEOUT`, `GENERATION_FAILED`, `INVALID_INPUT`, `NO_PROVIDER`
|
|
287
|
+
|
|
288
|
+
### Retry & Failover
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
const ai = new Noosphere({
|
|
292
|
+
retry: {
|
|
293
|
+
maxRetries: 3, // default: 2
|
|
294
|
+
backoffMs: 2000, // default: 1000
|
|
295
|
+
failover: true, // default: true — try other providers on failure
|
|
296
|
+
retryableErrors: ['RATE_LIMITED', 'TIMEOUT', 'PROVIDER_UNAVAILABLE'],
|
|
297
|
+
},
|
|
298
|
+
timeout: {
|
|
299
|
+
llm: 30000, // 30s (default)
|
|
300
|
+
image: 120000, // 2min (default)
|
|
301
|
+
video: 300000, // 5min (default)
|
|
302
|
+
tts: 60000, // 1min (default)
|
|
303
|
+
},
|
|
304
|
+
});
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Local Services
|
|
308
|
+
|
|
309
|
+
Noosphere auto-detects local AI services on startup. Configure via constructor or environment variables:
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
const ai = new Noosphere({
|
|
313
|
+
autoDetectLocal: true, // default
|
|
314
|
+
local: {
|
|
315
|
+
comfyui: { enabled: true, host: 'http://localhost', port: 8188 },
|
|
316
|
+
piper: { enabled: true, host: 'http://localhost', port: 5500 },
|
|
317
|
+
kokoro: { enabled: true, host: 'http://localhost', port: 5501 },
|
|
318
|
+
},
|
|
319
|
+
});
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Environment variables: `COMFYUI_HOST`, `COMFYUI_PORT`, `PIPER_HOST`, `PIPER_PORT`, `KOKORO_HOST`, `KOKORO_PORT`, `NOOSPHERE_AUTO_DETECT_LOCAL`
|
|
323
|
+
|
|
324
|
+
### Cleanup
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
await ai.dispose();
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## Providers
|
|
331
|
+
|
|
332
|
+
| Provider | Modalities | Type |
|
|
333
|
+
|---|---|---|
|
|
334
|
+
| Pi-AI (OpenAI, Anthropic, Google, Groq, Mistral, xAI, OpenRouter) | LLM | Cloud |
|
|
335
|
+
| FAL | Image, Video, TTS | Cloud |
|
|
336
|
+
| Hugging Face | LLM, Image, TTS | Cloud |
|
|
337
|
+
| ComfyUI | Image, Video | Local |
|
|
338
|
+
| Piper / Kokoro | TTS | Local |
|
|
339
|
+
|
|
340
|
+
## Requirements
|
|
341
|
+
|
|
342
|
+
- Node.js >= 18.0.0
|
|
343
|
+
|
|
344
|
+
## License
|
|
345
|
+
|
|
346
|
+
MIT
|