npm-ai-hooks 2.0.1 โ 2.0.3
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 +14 -14
- package/Readme.md +612 -612
- package/dist/cjs/index.js +2 -1
- package/dist/cjs/providers/base/ProviderConfig.js +39 -14
- package/dist/cjs/providers/index.js +26 -0
- package/dist/cjs/providers/init.js +12 -0
- package/dist/cjs/wrap.js +61 -61
- package/dist/esm/index.js +1 -1
- package/dist/esm/providers/base/ProviderConfig.js +39 -14
- package/dist/esm/providers/index.js +26 -1
- package/dist/esm/providers/init.js +11 -0
- package/dist/esm/wrap.js +62 -62
- package/dist/index.d.ts +1 -1
- package/dist/providers/base/ProviderConfig.d.ts +9 -0
- package/dist/providers/base/SpecializedProviders.d.ts +19 -5
- package/dist/providers/index.d.ts +4 -0
- package/dist/providers/init.d.ts +9 -0
- package/package.json +94 -94
package/Readme.md
CHANGED
|
@@ -1,612 +1,612 @@
|
|
|
1
|
-
# npm-ai-hooks
|
|
2
|
-
|
|
3
|
-
**Universal AI Hook Layer for Node.js and React โ one wrapper for all AI providers.**
|
|
4
|
-
|
|
5
|
-
Inject LLM-like behavior into any JavaScript or TypeScript function with a single line, without writing prompts, handling SDKs, or locking into any provider. Works seamlessly in both Node.js (Express) and React (Vite) environments.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Features
|
|
12
|
-
|
|
13
|
-
* **Universal API:** Works with OpenAI, Claude, Gemini, DeepSeek, Groq, OpenRouter, XAI, Perplexity, and Mistral โ out of the box.
|
|
14
|
-
* **Cross-Platform:** Works in both Node.js (Express) and React (Vite) environments with dual build system.
|
|
15
|
-
* **Multimodal Support:** ๐ Images, files, and voice input support with vision-enabled models.
|
|
16
|
-
* **Plug & Play:** Wrap any function and instantly give it AI-powered behavior.
|
|
17
|
-
* **Zero Prompting:** Built-in task templates (summarize, explain, translate, sentiment, rewrite, code-review, etc.)
|
|
18
|
-
* **Explicit Configuration:** No environment variables needed - initialize providers explicitly with API keys.
|
|
19
|
-
* **Auto Provider Selection:** Smart fallback system with configurable preferences.
|
|
20
|
-
* **Type Safe:** Full TypeScript support with IntelliSense and type checking.
|
|
21
|
-
* **Error Safe:** Handles invalid keys, unauthorized models, rate limits, and more gracefully.
|
|
22
|
-
* **Dynamic Management:** Add/remove providers at runtime.
|
|
23
|
-
* **Cost Awareness:** Estimate and log token usage and cost before and after calls.
|
|
24
|
-
* **Caching:** Prevents duplicate calls and charges by caching results intelligently.
|
|
25
|
-
* **Extensible:** Add your own providers and custom tasks easily.
|
|
26
|
-
* **Debug Friendly:** Full debug logging with `DEBUG=true`.
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
## Installation
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
npm install npm-ai-hooks
|
|
34
|
-
# or
|
|
35
|
-
yarn add npm-ai-hooks
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
## Quick Start
|
|
41
|
-
|
|
42
|
-
### 1. Initialize Providers
|
|
43
|
-
|
|
44
|
-
```typescript
|
|
45
|
-
import { initAIHooks, wrap } from "npm-ai-hooks";
|
|
46
|
-
|
|
47
|
-
// Initialize with your API keys
|
|
48
|
-
initAIHooks({
|
|
49
|
-
providers: [
|
|
50
|
-
{ provider: 'openai', key: 'sk-your-openai-key-here' },
|
|
51
|
-
{ provider: 'claude', key: 'sk-ant-your-claude-key-here' },
|
|
52
|
-
{ provider: 'groq', key: 'gsk_your-groq-key-here' }
|
|
53
|
-
],
|
|
54
|
-
defaultProvider: 'openai' // optional
|
|
55
|
-
});
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### 2. Wrap Any Function
|
|
59
|
-
|
|
60
|
-
```typescript
|
|
61
|
-
// Wrap any function with AI behavior
|
|
62
|
-
const summarize = wrap((text: string) => text, { task: "summarize" });
|
|
63
|
-
|
|
64
|
-
// Use it
|
|
65
|
-
const result = await summarize("Node.js is a JavaScript runtime built on Chrome's V8...");
|
|
66
|
-
console.log(result); // "Node.js is a JS runtime for building server-side apps."
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
## ๐ง Provider Initialization
|
|
72
|
-
|
|
73
|
-
### Basic Setup
|
|
74
|
-
|
|
75
|
-
```typescript
|
|
76
|
-
import { initAIHooks } from "npm-ai-hooks";
|
|
77
|
-
|
|
78
|
-
initAIHooks({
|
|
79
|
-
providers: [
|
|
80
|
-
{ provider: 'openai', key: 'sk-...' },
|
|
81
|
-
{ provider: 'claude', key: 'sk-ant-...' }
|
|
82
|
-
]
|
|
83
|
-
});
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### Advanced Setup with Custom Models
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
initAIHooks({
|
|
90
|
-
providers: [
|
|
91
|
-
{
|
|
92
|
-
provider: 'openai',
|
|
93
|
-
key: 'sk-...',
|
|
94
|
-
defaultModel: 'gpt-4' // custom default model
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
provider: 'claude',
|
|
98
|
-
key: 'sk-ant-...',
|
|
99
|
-
defaultModel: 'claude-3-sonnet-20240229'
|
|
100
|
-
}
|
|
101
|
-
],
|
|
102
|
-
defaultProvider: 'openai' // preferred provider
|
|
103
|
-
});
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### Dynamic Provider Management
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
import { addProvider, removeProvider, getAvailableProviders } from "npm-ai-hooks";
|
|
110
|
-
|
|
111
|
-
// Add providers after initialization
|
|
112
|
-
addProvider({
|
|
113
|
-
provider: 'mistral',
|
|
114
|
-
key: '...',
|
|
115
|
-
defaultModel: 'mistral-large'
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
// Remove providers
|
|
119
|
-
removeProvider('mistral');
|
|
120
|
-
|
|
121
|
-
// Check available providers
|
|
122
|
-
console.log(getAvailableProviders()); // ['openai', 'claude', 'groq', 'mistral']
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
---
|
|
126
|
-
|
|
127
|
-
## React/Vite Support
|
|
128
|
-
|
|
129
|
-
The library works seamlessly in React applications with Vite. The dual build system automatically provides the correct module format.
|
|
130
|
-
|
|
131
|
-
### React Setup
|
|
132
|
-
|
|
133
|
-
```typescript
|
|
134
|
-
// App.tsx
|
|
135
|
-
import { useState, useEffect } from 'react';
|
|
136
|
-
import { initAIHooks, wrap } from 'npm-ai-hooks';
|
|
137
|
-
|
|
138
|
-
function App() {
|
|
139
|
-
const [isInitialized, setIsInitialized] = useState(false);
|
|
140
|
-
|
|
141
|
-
useEffect(() => {
|
|
142
|
-
// Initialize with Vite environment variables (VITE_ prefix required)
|
|
143
|
-
initAIHooks({
|
|
144
|
-
providers: [
|
|
145
|
-
{ provider: 'openai', key: import.meta.env.VITE_OPENAI_KEY },
|
|
146
|
-
{ provider: 'groq', key: import.meta.env.VITE_GROQ_KEY },
|
|
147
|
-
{ provider: 'claude', key: import.meta.env.VITE_CLAUDE_KEY }
|
|
148
|
-
],
|
|
149
|
-
defaultProvider: 'groq'
|
|
150
|
-
});
|
|
151
|
-
setIsInitialized(true);
|
|
152
|
-
}, []);
|
|
153
|
-
|
|
154
|
-
const handleSummarize = async () => {
|
|
155
|
-
const summarize = wrap((text: string) => text, { task: "summarize" });
|
|
156
|
-
const result = await summarize("Your text here...");
|
|
157
|
-
console.log(result.output);
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
return (
|
|
161
|
-
<div>
|
|
162
|
-
<button onClick={handleSummarize} disabled={!isInitialized}>
|
|
163
|
-
Summarize Text
|
|
164
|
-
</button>
|
|
165
|
-
</div>
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### Vite Configuration
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
// vite.config.ts
|
|
174
|
-
import { defineConfig } from 'vite'
|
|
175
|
-
import react from '@vitejs/plugin-react'
|
|
176
|
-
|
|
177
|
-
export default defineConfig({
|
|
178
|
-
plugins: [react()],
|
|
179
|
-
server: {
|
|
180
|
-
fs: {
|
|
181
|
-
allow: ['..', '../..'] // Allow access to parent directories for local library
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
})
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
---
|
|
188
|
-
|
|
189
|
-
## Usage Examples
|
|
190
|
-
|
|
191
|
-
### 1. Basic Tasks
|
|
192
|
-
|
|
193
|
-
```typescript
|
|
194
|
-
import { wrap } from "npm-ai-hooks";
|
|
195
|
-
|
|
196
|
-
// Summarization
|
|
197
|
-
const summarize = wrap((text: string) => text, { task: "summarize" });
|
|
198
|
-
console.log(await summarize("Long article text..."));
|
|
199
|
-
|
|
200
|
-
// Translation
|
|
201
|
-
const translate = wrap((text: string) => text, {
|
|
202
|
-
task: "translate",
|
|
203
|
-
targetLanguage: "spanish"
|
|
204
|
-
});
|
|
205
|
-
console.log(await translate("Hello world"));
|
|
206
|
-
|
|
207
|
-
// Code Review
|
|
208
|
-
const codeReview = wrap((code: string) => code, { task: "codeReview" });
|
|
209
|
-
console.log(await codeReview("function add(a, b) { return a + b; }"));
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
### 2. Provider-Specific Usage
|
|
213
|
-
|
|
214
|
-
```typescript
|
|
215
|
-
// Use specific provider
|
|
216
|
-
const explain = wrap((text: string) => text, {
|
|
217
|
-
task: "explain",
|
|
218
|
-
provider: "claude",
|
|
219
|
-
model: "claude-3-opus"
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
console.log(await explain("Explain quantum computing like I'm 10."));
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
### 3. AI Pipelines
|
|
226
|
-
|
|
227
|
-
```typescript
|
|
228
|
-
const summarize = wrap((t: string) => t, { task: "summarize" });
|
|
229
|
-
const translate = wrap((t: string) => t, { task: "translate", targetLanguage: "fr" });
|
|
230
|
-
|
|
231
|
-
// Chain operations
|
|
232
|
-
const result = await translate(await summarize("Long technical article..."));
|
|
233
|
-
console.log(result); // Rรฉsumรฉ en franรงais
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
### 4. Multimodal Support (Images, Files, Voice) ๐จ๐ค
|
|
237
|
-
|
|
238
|
-
**NEW!** npm-ai-hooks now supports multimodal inputs including images, files, and voice.
|
|
239
|
-
|
|
240
|
-
```typescript
|
|
241
|
-
import { wrap, MultimodalInput } from "npm-ai-hooks";
|
|
242
|
-
import * as fs from 'fs';
|
|
243
|
-
|
|
244
|
-
// Image Analysis
|
|
245
|
-
const analyzeImage = wrap((input: MultimodalInput) => input, {
|
|
246
|
-
provider: 'openai',
|
|
247
|
-
model: 'gpt-4o', // Vision-enabled model
|
|
248
|
-
customPrompt: 'Describe what you see in this image'
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
// Load and encode image
|
|
252
|
-
const imageBuffer = fs.readFileSync('./photo.jpg');
|
|
253
|
-
const base64Image = `data:image/jpeg;base64,${imageBuffer.toString('base64')}`;
|
|
254
|
-
|
|
255
|
-
const result = await analyzeImage({
|
|
256
|
-
text: 'What is in this image?',
|
|
257
|
-
image: base64Image
|
|
258
|
-
});
|
|
259
|
-
console.log(result.output); // Detailed image description
|
|
260
|
-
|
|
261
|
-
// OCR (Text Extraction)
|
|
262
|
-
const extractText = wrap((input: MultimodalInput) => input, {
|
|
263
|
-
provider: 'openai',
|
|
264
|
-
model: 'gpt-4o',
|
|
265
|
-
customPrompt: 'Extract all text from this image'
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
const ocrResult = await extractText({
|
|
269
|
-
text: 'Extract text from this document',
|
|
270
|
-
image: base64Image
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
// File Processing
|
|
274
|
-
const analyzeFile = wrap((input: MultimodalInput) => input, {
|
|
275
|
-
provider: 'claude',
|
|
276
|
-
model: 'claude-3-opus',
|
|
277
|
-
task: 'summarize'
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
const fileBuffer = fs.readFileSync('./document.pdf');
|
|
281
|
-
const fileResult = await analyzeFile({
|
|
282
|
-
text: 'Summarize this document',
|
|
283
|
-
file: {
|
|
284
|
-
name: 'document.pdf',
|
|
285
|
-
data: `data:application/pdf;base64,${fileBuffer.toString('base64')}`,
|
|
286
|
-
type: 'application/pdf'
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
**Browser Voice Input (Web Speech API):**
|
|
292
|
-
```typescript
|
|
293
|
-
// In browser environment
|
|
294
|
-
const SpeechRecognition = window.webkitSpeechRecognition || window.SpeechRecognition;
|
|
295
|
-
const recognition = new SpeechRecognition();
|
|
296
|
-
|
|
297
|
-
recognition.onresult = async (event) => {
|
|
298
|
-
const transcript = event.results[0][0].transcript;
|
|
299
|
-
|
|
300
|
-
// Process voice input with AI
|
|
301
|
-
const explain = wrap((text: string) => text, { task: 'explain' });
|
|
302
|
-
const result = await explain(transcript);
|
|
303
|
-
console.log(result.output);
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
recognition.start();
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
**Multimodal Interface:**
|
|
310
|
-
```typescript
|
|
311
|
-
interface MultimodalInput {
|
|
312
|
-
text?: string; // Text content
|
|
313
|
-
image?: string; // Base64 encoded image (with data URI)
|
|
314
|
-
file?: { // File attachment
|
|
315
|
-
name: string; // File name
|
|
316
|
-
data: string; // Base64 encoded (with data URI)
|
|
317
|
-
type: string; // MIME type
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
**Use Cases:**
|
|
323
|
-
- ๐ธ Image analysis and description
|
|
324
|
-
- ๐ OCR and document processing
|
|
325
|
-
- ๐ Code review from screenshots
|
|
326
|
-
- ๐ค Voice commands and transcription
|
|
327
|
-
- ๐ Chart and diagram analysis
|
|
328
|
-
- ๐ท๏ธ Product image tagging
|
|
329
|
-
|
|
330
|
-
**See full examples:**
|
|
331
|
-
- [Vision Examples](./examples/multimodal/vision-example.ts)
|
|
332
|
-
- [Voice Examples](./examples/multimodal/voice-example.ts)
|
|
333
|
-
- [React Demo with UI](
|
|
334
|
-
|
|
335
|
-
### 5. Error Handling
|
|
336
|
-
|
|
337
|
-
```typescript
|
|
338
|
-
try {
|
|
339
|
-
const result = await summarize("Some text");
|
|
340
|
-
} catch (error) {
|
|
341
|
-
console.error(error);
|
|
342
|
-
/*
|
|
343
|
-
{
|
|
344
|
-
code: "INVALID_API_KEY",
|
|
345
|
-
message: "Invalid OpenAI API key: ...",
|
|
346
|
-
provider: "openai",
|
|
347
|
-
suggestion: "Verify your API key"
|
|
348
|
-
}
|
|
349
|
-
*/
|
|
350
|
-
}
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
---
|
|
354
|
-
|
|
355
|
-
## ๐ฏ Built-in Tasks
|
|
356
|
-
|
|
357
|
-
| Task | Description | Example |
|
|
358
|
-
| ------------ | ---------------------------------------- | ------- |
|
|
359
|
-
| `summarize` | Summarize text into concise form | `wrap(fn, { task: "summarize" })` |
|
|
360
|
-
| `translate` | Translate text to a target language | `wrap(fn, { task: "translate", targetLanguage: "es" })` |
|
|
361
|
-
| `explain` | Explain complex text simply | `wrap(fn, { task: "explain" })` |
|
|
362
|
-
| `rewrite` | Rephrase text for tone/clarity | `wrap(fn, { task: "rewrite" })` |
|
|
363
|
-
| `sentiment` | Analyze emotional tone of text | `wrap(fn, { task: "sentiment" })` |
|
|
364
|
-
| `codeReview` | Review code and provide feedback | `wrap(fn, { task: "codeReview" })` |
|
|
365
|
-
|
|
366
|
-
---
|
|
367
|
-
|
|
368
|
-
## ๐ค Supported Providers
|
|
369
|
-
|
|
370
|
-
| Provider | Key Format Example | Default Model |
|
|
371
|
-
| ----------- | ------------------------- | ----------------------- |
|
|
372
|
-
| OpenRouter | `sk-or-...` | `openai/gpt-4o-mini` |
|
|
373
|
-
| Groq | `gsk_...` | `llama-3.1-70b-versatile` |
|
|
374
|
-
| OpenAI | `sk-...` | `gpt-4o` |
|
|
375
|
-
| Gemini | `AIza...` | `gemini-1.5-flash` |
|
|
376
|
-
| Claude | `sk-ant-...` | `claude-3-5-sonnet-20241022` |
|
|
377
|
-
| DeepSeek | `ds-...` | `deepseek-chat` |
|
|
378
|
-
| XAI | `xai-...` | `grok-2-1212` |
|
|
379
|
-
| Perplexity | `pplx-...` | `sonar` |
|
|
380
|
-
| Mistral | `mistral-...` | `mistral-large-latest` |
|
|
381
|
-
|
|
382
|
-
---
|
|
383
|
-
|
|
384
|
-
## โ๏ธ Provider Selection Logic
|
|
385
|
-
|
|
386
|
-
The system follows this priority order:
|
|
387
|
-
|
|
388
|
-
1. **User-specified provider** (if available)
|
|
389
|
-
2. **Default provider** (if set during initialization)
|
|
390
|
-
3. **OpenRouter** (if available)
|
|
391
|
-
4. **First provider** in the initialization list
|
|
392
|
-
|
|
393
|
-
```typescript
|
|
394
|
-
// Example: OpenRouter will be selected if available
|
|
395
|
-
initAIHooks({
|
|
396
|
-
providers: [
|
|
397
|
-
{ provider: 'groq', key: '...' },
|
|
398
|
-
{ provider: 'openrouter', key: '...' }, // This will be preferred
|
|
399
|
-
{ provider: 'openai', key: '...' }
|
|
400
|
-
]
|
|
401
|
-
});
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
---
|
|
405
|
-
|
|
406
|
-
## ๐ Advanced Configuration
|
|
407
|
-
|
|
408
|
-
### Cost Awareness
|
|
409
|
-
|
|
410
|
-
```typescript
|
|
411
|
-
const summarize = wrap((t: string) => t, { task: "summarize" });
|
|
412
|
-
const result = await summarize(longText);
|
|
413
|
-
|
|
414
|
-
console.log(result.meta);
|
|
415
|
-
/*
|
|
416
|
-
{
|
|
417
|
-
provider: "openai",
|
|
418
|
-
model: "gpt-4o",
|
|
419
|
-
cached: false,
|
|
420
|
-
estimatedCostUSD: 0.0013,
|
|
421
|
-
totalCostUSD: 0.0012,
|
|
422
|
-
inputTokens: 326,
|
|
423
|
-
outputTokens: 127,
|
|
424
|
-
latencyMs: 812
|
|
425
|
-
}
|
|
426
|
-
*/
|
|
427
|
-
```
|
|
428
|
-
|
|
429
|
-
### Caching
|
|
430
|
-
|
|
431
|
-
```typescript
|
|
432
|
-
const summarize = wrap((t: string) => t, {
|
|
433
|
-
task: "summarize",
|
|
434
|
-
cache: true // Enable caching
|
|
435
|
-
});
|
|
436
|
-
```
|
|
437
|
-
|
|
438
|
-
### Debug Mode
|
|
439
|
-
|
|
440
|
-
```bash
|
|
441
|
-
DEBUG=true
|
|
442
|
-
```
|
|
443
|
-
|
|
444
|
-
Output:
|
|
445
|
-
```
|
|
446
|
-
[ai-hooks] Using provider: OpenAI (gpt-4o)
|
|
447
|
-
[ai-hooks] Estimated cost: $0.0012
|
|
448
|
-
[ai-hooks] Cache: MISS
|
|
449
|
-
[ai-hooks] Response received in 812ms
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
---
|
|
453
|
-
|
|
454
|
-
## ๐ Migration from v1.x
|
|
455
|
-
|
|
456
|
-
### Old Way (v1.x)
|
|
457
|
-
```typescript
|
|
458
|
-
// Set environment variables
|
|
459
|
-
process.env.OPENAI_KEY = 'sk-...';
|
|
460
|
-
|
|
461
|
-
// Use providers
|
|
462
|
-
import { getProvider } from 'npm-ai-hooks';
|
|
463
|
-
const { fn } = getProvider();
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
### New Way (v2.0)
|
|
467
|
-
```typescript
|
|
468
|
-
// Initialize providers explicitly
|
|
469
|
-
import { initAIHooks, getProvider } from 'npm-ai-hooks';
|
|
470
|
-
|
|
471
|
-
initAIHooks({
|
|
472
|
-
providers: [
|
|
473
|
-
{ provider: 'openai', key: 'sk-...' }
|
|
474
|
-
]
|
|
475
|
-
});
|
|
476
|
-
|
|
477
|
-
// Use providers (same API)
|
|
478
|
-
const { fn } = getProvider();
|
|
479
|
-
```
|
|
480
|
-
|
|
481
|
-
### Benefits of Migration
|
|
482
|
-
|
|
483
|
-
- โ
**No Environment Dependencies** - Cleaner, more explicit configuration
|
|
484
|
-
- โ
**Better Security** - No accidental exposure of environment variables
|
|
485
|
-
- โ
**Type Safety** - Full TypeScript support for provider configuration
|
|
486
|
-
- โ
**Dynamic Management** - Add/remove providers at runtime
|
|
487
|
-
- โ
**Custom Models** - Specify default models per provider
|
|
488
|
-
- โ
**Smaller Bundle** - 77% reduction in code size
|
|
489
|
-
|
|
490
|
-
---
|
|
491
|
-
|
|
492
|
-
## ๐งช Development Setup
|
|
493
|
-
|
|
494
|
-
For contributors and developers:
|
|
495
|
-
|
|
496
|
-
```bash
|
|
497
|
-
# Clone the repository
|
|
498
|
-
git clone https://github.com/iTeebot/npm-ai-hooks.git
|
|
499
|
-
cd npm-ai-hooks
|
|
500
|
-
|
|
501
|
-
# Setup development environment
|
|
502
|
-
npm run setup:dev
|
|
503
|
-
|
|
504
|
-
# Or on Windows (PowerShell - recommended)
|
|
505
|
-
npm run setup:dev:ps
|
|
506
|
-
|
|
507
|
-
# Or on Windows (Command Prompt)
|
|
508
|
-
npm run setup:dev:win
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
The setup script will:
|
|
512
|
-
- Use the correct Node.js version from `.nvmrc`
|
|
513
|
-
- Apply npm configuration from `.npmrc`
|
|
514
|
-
- Install dependencies
|
|
515
|
-
- Run tests to verify everything works
|
|
516
|
-
|
|
517
|
-
### Testing with Real API Keys
|
|
518
|
-
|
|
519
|
-
To test with real API keys (optional):
|
|
520
|
-
|
|
521
|
-
```bash
|
|
522
|
-
# 1. Copy the example environment file
|
|
523
|
-
cp .env.example .env
|
|
524
|
-
|
|
525
|
-
# 2. Add your API keys to .env
|
|
526
|
-
# Edit .env and add your actual API keys
|
|
527
|
-
|
|
528
|
-
# 3. Run tests with real API keys
|
|
529
|
-
npm run test:env
|
|
530
|
-
|
|
531
|
-
# 4. Or run all tests (includes both mock and real API tests)
|
|
532
|
-
npm test
|
|
533
|
-
```
|
|
534
|
-
|
|
535
|
-
### Testing Commands
|
|
536
|
-
|
|
537
|
-
```bash
|
|
538
|
-
# Run all tests (mock + real API if available)
|
|
539
|
-
npm test
|
|
540
|
-
|
|
541
|
-
# Run only mock tests (no API keys needed)
|
|
542
|
-
npm run test:mock
|
|
543
|
-
|
|
544
|
-
# Run only real API tests (requires API keys in .env)
|
|
545
|
-
npm run test:env
|
|
546
|
-
|
|
547
|
-
# Run specific test suites
|
|
548
|
-
npm run test:providers
|
|
549
|
-
npm run test:tasks
|
|
550
|
-
npm run test:errors
|
|
551
|
-
npm run test:integration
|
|
552
|
-
npm run test:performance
|
|
553
|
-
```
|
|
554
|
-
|
|
555
|
-
---
|
|
556
|
-
|
|
557
|
-
## ๐๏ธ Project Structure
|
|
558
|
-
|
|
559
|
-
```
|
|
560
|
-
npm-ai-hooks/
|
|
561
|
-
โโ src/
|
|
562
|
-
โ โโ index.ts # Main exports
|
|
563
|
-
โ โโ wrap.ts # Core wrapping functionality
|
|
564
|
-
โ โโ errors.ts # Error handling
|
|
565
|
-
โ โโ providers/
|
|
566
|
-
โ โ โโ base/ # Base provider system
|
|
567
|
-
โ โ โ โโ BaseProvider.ts # Abstract base class
|
|
568
|
-
โ โ โ โโ ProviderConfig.ts # Provider configuration
|
|
569
|
-
โ โ โ โโ ProviderRegistry.ts # Provider management
|
|
570
|
-
โ โ โ โโ ProviderConfigs.ts # Provider definitions
|
|
571
|
-
โ โ โโ index.ts # Provider exports
|
|
572
|
-
โ โโ types/ # TypeScript definitions
|
|
573
|
-
โโ examples/ # Usage examples
|
|
574
|
-
โโ tests/ # Test suite
|
|
575
|
-
โโ package.json
|
|
576
|
-
โโ README.md
|
|
577
|
-
โโ LICENSE
|
|
578
|
-
```
|
|
579
|
-
|
|
580
|
-
---
|
|
581
|
-
|
|
582
|
-
## ๐ฃ๏ธ Roadmap
|
|
583
|
-
|
|
584
|
-
* [ ] Streaming output support
|
|
585
|
-
* [ ] Cost ceiling + auto-fallbacks
|
|
586
|
-
* [ ] Rate limiter
|
|
587
|
-
* [ ] Multi-turn conversation API
|
|
588
|
-
* [ ] Local model support (llama.cpp, Ollama)
|
|
589
|
-
* [ ] VSCode extension for code-gen
|
|
590
|
-
* [ ] Custom provider registration
|
|
591
|
-
* [ ] Advanced caching strategies
|
|
592
|
-
|
|
593
|
-
---
|
|
594
|
-
|
|
595
|
-
## ๐ค Contributing
|
|
596
|
-
|
|
597
|
-
Contributions, ideas, and feedback are welcome! Please open an issue or submit a pull request.
|
|
598
|
-
|
|
599
|
-
---
|
|
600
|
-
|
|
601
|
-
## ๐ License
|
|
602
|
-
|
|
603
|
-
MIT ยฉ 2025 `npm-ai-hooks` Team
|
|
604
|
-
|
|
605
|
-
---
|
|
606
|
-
|
|
607
|
-
## ๐ Links
|
|
608
|
-
|
|
609
|
-
- [GitHub Repository](https://github.com/iTeebot/npm-ai-hooks)
|
|
610
|
-
- [NPM Package](https://www.npmjs.com/package/npm-ai-hooks)
|
|
611
|
-
- [Documentation](https://
|
|
612
|
-
- [Changelog](CHANGELOG.md)
|
|
1
|
+
# npm-ai-hooks
|
|
2
|
+
|
|
3
|
+
**Universal AI Hook Layer for Node.js and React โ one wrapper for all AI providers.**
|
|
4
|
+
|
|
5
|
+
Inject LLM-like behavior into any JavaScript or TypeScript function with a single line, without writing prompts, handling SDKs, or locking into any provider. Works seamlessly in both Node.js (Express) and React (Vite) environments.
|
|
6
|
+
|
|
7
|
+
๐ป **[Node.js Example](./examples/demo.ts)**
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
* **Universal API:** Works with OpenAI, Claude, Gemini, DeepSeek, Groq, OpenRouter, XAI, Perplexity, and Mistral โ out of the box.
|
|
14
|
+
* **Cross-Platform:** Works in both Node.js (Express) and React (Vite) environments with dual build system.
|
|
15
|
+
* **Multimodal Support:** ๐ Images, files, and voice input support with vision-enabled models.
|
|
16
|
+
* **Plug & Play:** Wrap any function and instantly give it AI-powered behavior.
|
|
17
|
+
* **Zero Prompting:** Built-in task templates (summarize, explain, translate, sentiment, rewrite, code-review, etc.)
|
|
18
|
+
* **Explicit Configuration:** No environment variables needed - initialize providers explicitly with API keys.
|
|
19
|
+
* **Auto Provider Selection:** Smart fallback system with configurable preferences.
|
|
20
|
+
* **Type Safe:** Full TypeScript support with IntelliSense and type checking.
|
|
21
|
+
* **Error Safe:** Handles invalid keys, unauthorized models, rate limits, and more gracefully.
|
|
22
|
+
* **Dynamic Management:** Add/remove providers at runtime.
|
|
23
|
+
* **Cost Awareness:** Estimate and log token usage and cost before and after calls.
|
|
24
|
+
* **Caching:** Prevents duplicate calls and charges by caching results intelligently.
|
|
25
|
+
* **Extensible:** Add your own providers and custom tasks easily.
|
|
26
|
+
* **Debug Friendly:** Full debug logging with `DEBUG=true`.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install npm-ai-hooks
|
|
34
|
+
# or
|
|
35
|
+
yarn add npm-ai-hooks
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
### 1. Initialize Providers
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { initAIHooks, wrap } from "npm-ai-hooks";
|
|
46
|
+
|
|
47
|
+
// Initialize with your API keys
|
|
48
|
+
initAIHooks({
|
|
49
|
+
providers: [
|
|
50
|
+
{ provider: 'openai', key: 'sk-your-openai-key-here' },
|
|
51
|
+
{ provider: 'claude', key: 'sk-ant-your-claude-key-here' },
|
|
52
|
+
{ provider: 'groq', key: 'gsk_your-groq-key-here' }
|
|
53
|
+
],
|
|
54
|
+
defaultProvider: 'openai' // optional
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 2. Wrap Any Function
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// Wrap any function with AI behavior
|
|
62
|
+
const summarize = wrap((text: string) => text, { task: "summarize" });
|
|
63
|
+
|
|
64
|
+
// Use it
|
|
65
|
+
const result = await summarize("Node.js is a JavaScript runtime built on Chrome's V8...");
|
|
66
|
+
console.log(result); // "Node.js is a JS runtime for building server-side apps."
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## ๐ง Provider Initialization
|
|
72
|
+
|
|
73
|
+
### Basic Setup
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { initAIHooks } from "npm-ai-hooks";
|
|
77
|
+
|
|
78
|
+
initAIHooks({
|
|
79
|
+
providers: [
|
|
80
|
+
{ provider: 'openai', key: 'sk-...' },
|
|
81
|
+
{ provider: 'claude', key: 'sk-ant-...' }
|
|
82
|
+
]
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Advanced Setup with Custom Models
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
initAIHooks({
|
|
90
|
+
providers: [
|
|
91
|
+
{
|
|
92
|
+
provider: 'openai',
|
|
93
|
+
key: 'sk-...',
|
|
94
|
+
defaultModel: 'gpt-4' // custom default model
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
provider: 'claude',
|
|
98
|
+
key: 'sk-ant-...',
|
|
99
|
+
defaultModel: 'claude-3-sonnet-20240229'
|
|
100
|
+
}
|
|
101
|
+
],
|
|
102
|
+
defaultProvider: 'openai' // preferred provider
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Dynamic Provider Management
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import { addProvider, removeProvider, getAvailableProviders } from "npm-ai-hooks";
|
|
110
|
+
|
|
111
|
+
// Add providers after initialization
|
|
112
|
+
addProvider({
|
|
113
|
+
provider: 'mistral',
|
|
114
|
+
key: '...',
|
|
115
|
+
defaultModel: 'mistral-large'
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// Remove providers
|
|
119
|
+
removeProvider('mistral');
|
|
120
|
+
|
|
121
|
+
// Check available providers
|
|
122
|
+
console.log(getAvailableProviders()); // ['openai', 'claude', 'groq', 'mistral']
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## React/Vite Support
|
|
128
|
+
|
|
129
|
+
The library works seamlessly in React applications with Vite. The dual build system automatically provides the correct module format.
|
|
130
|
+
|
|
131
|
+
### React Setup
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
// App.tsx
|
|
135
|
+
import { useState, useEffect } from 'react';
|
|
136
|
+
import { initAIHooks, wrap } from 'npm-ai-hooks';
|
|
137
|
+
|
|
138
|
+
function App() {
|
|
139
|
+
const [isInitialized, setIsInitialized] = useState(false);
|
|
140
|
+
|
|
141
|
+
useEffect(() => {
|
|
142
|
+
// Initialize with Vite environment variables (VITE_ prefix required)
|
|
143
|
+
initAIHooks({
|
|
144
|
+
providers: [
|
|
145
|
+
{ provider: 'openai', key: import.meta.env.VITE_OPENAI_KEY },
|
|
146
|
+
{ provider: 'groq', key: import.meta.env.VITE_GROQ_KEY },
|
|
147
|
+
{ provider: 'claude', key: import.meta.env.VITE_CLAUDE_KEY }
|
|
148
|
+
],
|
|
149
|
+
defaultProvider: 'groq'
|
|
150
|
+
});
|
|
151
|
+
setIsInitialized(true);
|
|
152
|
+
}, []);
|
|
153
|
+
|
|
154
|
+
const handleSummarize = async () => {
|
|
155
|
+
const summarize = wrap((text: string) => text, { task: "summarize" });
|
|
156
|
+
const result = await summarize("Your text here...");
|
|
157
|
+
console.log(result.output);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
return (
|
|
161
|
+
<div>
|
|
162
|
+
<button onClick={handleSummarize} disabled={!isInitialized}>
|
|
163
|
+
Summarize Text
|
|
164
|
+
</button>
|
|
165
|
+
</div>
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Vite Configuration
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
// vite.config.ts
|
|
174
|
+
import { defineConfig } from 'vite'
|
|
175
|
+
import react from '@vitejs/plugin-react'
|
|
176
|
+
|
|
177
|
+
export default defineConfig({
|
|
178
|
+
plugins: [react()],
|
|
179
|
+
server: {
|
|
180
|
+
fs: {
|
|
181
|
+
allow: ['..', '../..'] // Allow access to parent directories for local library
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
})
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Usage Examples
|
|
190
|
+
|
|
191
|
+
### 1. Basic Tasks
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
import { wrap } from "npm-ai-hooks";
|
|
195
|
+
|
|
196
|
+
// Summarization
|
|
197
|
+
const summarize = wrap((text: string) => text, { task: "summarize" });
|
|
198
|
+
console.log(await summarize("Long article text..."));
|
|
199
|
+
|
|
200
|
+
// Translation
|
|
201
|
+
const translate = wrap((text: string) => text, {
|
|
202
|
+
task: "translate",
|
|
203
|
+
targetLanguage: "spanish"
|
|
204
|
+
});
|
|
205
|
+
console.log(await translate("Hello world"));
|
|
206
|
+
|
|
207
|
+
// Code Review
|
|
208
|
+
const codeReview = wrap((code: string) => code, { task: "codeReview" });
|
|
209
|
+
console.log(await codeReview("function add(a, b) { return a + b; }"));
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### 2. Provider-Specific Usage
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
// Use specific provider
|
|
216
|
+
const explain = wrap((text: string) => text, {
|
|
217
|
+
task: "explain",
|
|
218
|
+
provider: "claude",
|
|
219
|
+
model: "claude-3-opus"
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
console.log(await explain("Explain quantum computing like I'm 10."));
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### 3. AI Pipelines
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
const summarize = wrap((t: string) => t, { task: "summarize" });
|
|
229
|
+
const translate = wrap((t: string) => t, { task: "translate", targetLanguage: "fr" });
|
|
230
|
+
|
|
231
|
+
// Chain operations
|
|
232
|
+
const result = await translate(await summarize("Long technical article..."));
|
|
233
|
+
console.log(result); // Rรฉsumรฉ en franรงais
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### 4. Multimodal Support (Images, Files, Voice) ๐จ๐ค
|
|
237
|
+
|
|
238
|
+
**NEW!** npm-ai-hooks now supports multimodal inputs including images, files, and voice.
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
import { wrap, MultimodalInput } from "npm-ai-hooks";
|
|
242
|
+
import * as fs from 'fs';
|
|
243
|
+
|
|
244
|
+
// Image Analysis
|
|
245
|
+
const analyzeImage = wrap((input: MultimodalInput) => input, {
|
|
246
|
+
provider: 'openai',
|
|
247
|
+
model: 'gpt-4o', // Vision-enabled model
|
|
248
|
+
customPrompt: 'Describe what you see in this image'
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// Load and encode image
|
|
252
|
+
const imageBuffer = fs.readFileSync('./photo.jpg');
|
|
253
|
+
const base64Image = `data:image/jpeg;base64,${imageBuffer.toString('base64')}`;
|
|
254
|
+
|
|
255
|
+
const result = await analyzeImage({
|
|
256
|
+
text: 'What is in this image?',
|
|
257
|
+
image: base64Image
|
|
258
|
+
});
|
|
259
|
+
console.log(result.output); // Detailed image description
|
|
260
|
+
|
|
261
|
+
// OCR (Text Extraction)
|
|
262
|
+
const extractText = wrap((input: MultimodalInput) => input, {
|
|
263
|
+
provider: 'openai',
|
|
264
|
+
model: 'gpt-4o',
|
|
265
|
+
customPrompt: 'Extract all text from this image'
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
const ocrResult = await extractText({
|
|
269
|
+
text: 'Extract text from this document',
|
|
270
|
+
image: base64Image
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// File Processing
|
|
274
|
+
const analyzeFile = wrap((input: MultimodalInput) => input, {
|
|
275
|
+
provider: 'claude',
|
|
276
|
+
model: 'claude-3-opus',
|
|
277
|
+
task: 'summarize'
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
const fileBuffer = fs.readFileSync('./document.pdf');
|
|
281
|
+
const fileResult = await analyzeFile({
|
|
282
|
+
text: 'Summarize this document',
|
|
283
|
+
file: {
|
|
284
|
+
name: 'document.pdf',
|
|
285
|
+
data: `data:application/pdf;base64,${fileBuffer.toString('base64')}`,
|
|
286
|
+
type: 'application/pdf'
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
**Browser Voice Input (Web Speech API):**
|
|
292
|
+
```typescript
|
|
293
|
+
// In browser environment
|
|
294
|
+
const SpeechRecognition = window.webkitSpeechRecognition || window.SpeechRecognition;
|
|
295
|
+
const recognition = new SpeechRecognition();
|
|
296
|
+
|
|
297
|
+
recognition.onresult = async (event) => {
|
|
298
|
+
const transcript = event.results[0][0].transcript;
|
|
299
|
+
|
|
300
|
+
// Process voice input with AI
|
|
301
|
+
const explain = wrap((text: string) => text, { task: 'explain' });
|
|
302
|
+
const result = await explain(transcript);
|
|
303
|
+
console.log(result.output);
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
recognition.start();
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**Multimodal Interface:**
|
|
310
|
+
```typescript
|
|
311
|
+
interface MultimodalInput {
|
|
312
|
+
text?: string; // Text content
|
|
313
|
+
image?: string; // Base64 encoded image (with data URI)
|
|
314
|
+
file?: { // File attachment
|
|
315
|
+
name: string; // File name
|
|
316
|
+
data: string; // Base64 encoded (with data URI)
|
|
317
|
+
type: string; // MIME type
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**Use Cases:**
|
|
323
|
+
- ๐ธ Image analysis and description
|
|
324
|
+
- ๐ OCR and document processing
|
|
325
|
+
- ๐ Code review from screenshots
|
|
326
|
+
- ๐ค Voice commands and transcription
|
|
327
|
+
- ๐ Chart and diagram analysis
|
|
328
|
+
- ๐ท๏ธ Product image tagging
|
|
329
|
+
|
|
330
|
+
**See full examples:**
|
|
331
|
+
- [Vision Examples](./examples/multimodal/vision-example.ts)
|
|
332
|
+
- [Voice Examples](./examples/multimodal/voice-example.ts)
|
|
333
|
+
- [React Demo with UI](https://labs.iteebot.com/npm-packages/npm-ai-hooks/demo)
|
|
334
|
+
|
|
335
|
+
### 5. Error Handling
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
try {
|
|
339
|
+
const result = await summarize("Some text");
|
|
340
|
+
} catch (error) {
|
|
341
|
+
console.error(error);
|
|
342
|
+
/*
|
|
343
|
+
{
|
|
344
|
+
code: "INVALID_API_KEY",
|
|
345
|
+
message: "Invalid OpenAI API key: ...",
|
|
346
|
+
provider: "openai",
|
|
347
|
+
suggestion: "Verify your API key"
|
|
348
|
+
}
|
|
349
|
+
*/
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## ๐ฏ Built-in Tasks
|
|
356
|
+
|
|
357
|
+
| Task | Description | Example |
|
|
358
|
+
| ------------ | ---------------------------------------- | ------- |
|
|
359
|
+
| `summarize` | Summarize text into concise form | `wrap(fn, { task: "summarize" })` |
|
|
360
|
+
| `translate` | Translate text to a target language | `wrap(fn, { task: "translate", targetLanguage: "es" })` |
|
|
361
|
+
| `explain` | Explain complex text simply | `wrap(fn, { task: "explain" })` |
|
|
362
|
+
| `rewrite` | Rephrase text for tone/clarity | `wrap(fn, { task: "rewrite" })` |
|
|
363
|
+
| `sentiment` | Analyze emotional tone of text | `wrap(fn, { task: "sentiment" })` |
|
|
364
|
+
| `codeReview` | Review code and provide feedback | `wrap(fn, { task: "codeReview" })` |
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## ๐ค Supported Providers
|
|
369
|
+
|
|
370
|
+
| Provider | Key Format Example | Default Model |
|
|
371
|
+
| ----------- | ------------------------- | ----------------------- |
|
|
372
|
+
| OpenRouter | `sk-or-...` | `openai/gpt-4o-mini` |
|
|
373
|
+
| Groq | `gsk_...` | `llama-3.1-70b-versatile` |
|
|
374
|
+
| OpenAI | `sk-...` | `gpt-4o` |
|
|
375
|
+
| Gemini | `AIza...` | `gemini-1.5-flash` |
|
|
376
|
+
| Claude | `sk-ant-...` | `claude-3-5-sonnet-20241022` |
|
|
377
|
+
| DeepSeek | `ds-...` | `deepseek-chat` |
|
|
378
|
+
| XAI | `xai-...` | `grok-2-1212` |
|
|
379
|
+
| Perplexity | `pplx-...` | `sonar` |
|
|
380
|
+
| Mistral | `mistral-...` | `mistral-large-latest` |
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## โ๏ธ Provider Selection Logic
|
|
385
|
+
|
|
386
|
+
The system follows this priority order:
|
|
387
|
+
|
|
388
|
+
1. **User-specified provider** (if available)
|
|
389
|
+
2. **Default provider** (if set during initialization)
|
|
390
|
+
3. **OpenRouter** (if available)
|
|
391
|
+
4. **First provider** in the initialization list
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
// Example: OpenRouter will be selected if available
|
|
395
|
+
initAIHooks({
|
|
396
|
+
providers: [
|
|
397
|
+
{ provider: 'groq', key: '...' },
|
|
398
|
+
{ provider: 'openrouter', key: '...' }, // This will be preferred
|
|
399
|
+
{ provider: 'openai', key: '...' }
|
|
400
|
+
]
|
|
401
|
+
});
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## ๐ Advanced Configuration
|
|
407
|
+
|
|
408
|
+
### Cost Awareness
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
const summarize = wrap((t: string) => t, { task: "summarize" });
|
|
412
|
+
const result = await summarize(longText);
|
|
413
|
+
|
|
414
|
+
console.log(result.meta);
|
|
415
|
+
/*
|
|
416
|
+
{
|
|
417
|
+
provider: "openai",
|
|
418
|
+
model: "gpt-4o",
|
|
419
|
+
cached: false,
|
|
420
|
+
estimatedCostUSD: 0.0013,
|
|
421
|
+
totalCostUSD: 0.0012,
|
|
422
|
+
inputTokens: 326,
|
|
423
|
+
outputTokens: 127,
|
|
424
|
+
latencyMs: 812
|
|
425
|
+
}
|
|
426
|
+
*/
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### Caching
|
|
430
|
+
|
|
431
|
+
```typescript
|
|
432
|
+
const summarize = wrap((t: string) => t, {
|
|
433
|
+
task: "summarize",
|
|
434
|
+
cache: true // Enable caching
|
|
435
|
+
});
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
### Debug Mode
|
|
439
|
+
|
|
440
|
+
```bash
|
|
441
|
+
DEBUG=true
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
Output:
|
|
445
|
+
```
|
|
446
|
+
[ai-hooks] Using provider: OpenAI (gpt-4o)
|
|
447
|
+
[ai-hooks] Estimated cost: $0.0012
|
|
448
|
+
[ai-hooks] Cache: MISS
|
|
449
|
+
[ai-hooks] Response received in 812ms
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
## ๐ Migration from v1.x
|
|
455
|
+
|
|
456
|
+
### Old Way (v1.x)
|
|
457
|
+
```typescript
|
|
458
|
+
// Set environment variables
|
|
459
|
+
process.env.OPENAI_KEY = 'sk-...';
|
|
460
|
+
|
|
461
|
+
// Use providers
|
|
462
|
+
import { getProvider } from 'npm-ai-hooks';
|
|
463
|
+
const { fn } = getProvider();
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
### New Way (v2.0)
|
|
467
|
+
```typescript
|
|
468
|
+
// Initialize providers explicitly
|
|
469
|
+
import { initAIHooks, getProvider } from 'npm-ai-hooks';
|
|
470
|
+
|
|
471
|
+
initAIHooks({
|
|
472
|
+
providers: [
|
|
473
|
+
{ provider: 'openai', key: 'sk-...' }
|
|
474
|
+
]
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
// Use providers (same API)
|
|
478
|
+
const { fn } = getProvider();
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
### Benefits of Migration
|
|
482
|
+
|
|
483
|
+
- โ
**No Environment Dependencies** - Cleaner, more explicit configuration
|
|
484
|
+
- โ
**Better Security** - No accidental exposure of environment variables
|
|
485
|
+
- โ
**Type Safety** - Full TypeScript support for provider configuration
|
|
486
|
+
- โ
**Dynamic Management** - Add/remove providers at runtime
|
|
487
|
+
- โ
**Custom Models** - Specify default models per provider
|
|
488
|
+
- โ
**Smaller Bundle** - 77% reduction in code size
|
|
489
|
+
|
|
490
|
+
---
|
|
491
|
+
|
|
492
|
+
## ๐งช Development Setup
|
|
493
|
+
|
|
494
|
+
For contributors and developers:
|
|
495
|
+
|
|
496
|
+
```bash
|
|
497
|
+
# Clone the repository
|
|
498
|
+
git clone https://github.com/iTeebot/npm-ai-hooks.git
|
|
499
|
+
cd npm-ai-hooks
|
|
500
|
+
|
|
501
|
+
# Setup development environment
|
|
502
|
+
npm run setup:dev
|
|
503
|
+
|
|
504
|
+
# Or on Windows (PowerShell - recommended)
|
|
505
|
+
npm run setup:dev:ps
|
|
506
|
+
|
|
507
|
+
# Or on Windows (Command Prompt)
|
|
508
|
+
npm run setup:dev:win
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
The setup script will:
|
|
512
|
+
- Use the correct Node.js version from `.nvmrc`
|
|
513
|
+
- Apply npm configuration from `.npmrc`
|
|
514
|
+
- Install dependencies
|
|
515
|
+
- Run tests to verify everything works
|
|
516
|
+
|
|
517
|
+
### Testing with Real API Keys
|
|
518
|
+
|
|
519
|
+
To test with real API keys (optional):
|
|
520
|
+
|
|
521
|
+
```bash
|
|
522
|
+
# 1. Copy the example environment file
|
|
523
|
+
cp .env.example .env
|
|
524
|
+
|
|
525
|
+
# 2. Add your API keys to .env
|
|
526
|
+
# Edit .env and add your actual API keys
|
|
527
|
+
|
|
528
|
+
# 3. Run tests with real API keys
|
|
529
|
+
npm run test:env
|
|
530
|
+
|
|
531
|
+
# 4. Or run all tests (includes both mock and real API tests)
|
|
532
|
+
npm test
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
### Testing Commands
|
|
536
|
+
|
|
537
|
+
```bash
|
|
538
|
+
# Run all tests (mock + real API if available)
|
|
539
|
+
npm test
|
|
540
|
+
|
|
541
|
+
# Run only mock tests (no API keys needed)
|
|
542
|
+
npm run test:mock
|
|
543
|
+
|
|
544
|
+
# Run only real API tests (requires API keys in .env)
|
|
545
|
+
npm run test:env
|
|
546
|
+
|
|
547
|
+
# Run specific test suites
|
|
548
|
+
npm run test:providers
|
|
549
|
+
npm run test:tasks
|
|
550
|
+
npm run test:errors
|
|
551
|
+
npm run test:integration
|
|
552
|
+
npm run test:performance
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
557
|
+
## ๐๏ธ Project Structure
|
|
558
|
+
|
|
559
|
+
```
|
|
560
|
+
npm-ai-hooks/
|
|
561
|
+
โโ src/
|
|
562
|
+
โ โโ index.ts # Main exports
|
|
563
|
+
โ โโ wrap.ts # Core wrapping functionality
|
|
564
|
+
โ โโ errors.ts # Error handling
|
|
565
|
+
โ โโ providers/
|
|
566
|
+
โ โ โโ base/ # Base provider system
|
|
567
|
+
โ โ โ โโ BaseProvider.ts # Abstract base class
|
|
568
|
+
โ โ โ โโ ProviderConfig.ts # Provider configuration
|
|
569
|
+
โ โ โ โโ ProviderRegistry.ts # Provider management
|
|
570
|
+
โ โ โ โโ ProviderConfigs.ts # Provider definitions
|
|
571
|
+
โ โ โโ index.ts # Provider exports
|
|
572
|
+
โ โโ types/ # TypeScript definitions
|
|
573
|
+
โโ examples/ # Usage examples
|
|
574
|
+
โโ tests/ # Test suite
|
|
575
|
+
โโ package.json
|
|
576
|
+
โโ README.md
|
|
577
|
+
โโ LICENSE
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
---
|
|
581
|
+
|
|
582
|
+
## ๐ฃ๏ธ Roadmap
|
|
583
|
+
|
|
584
|
+
* [ ] Streaming output support
|
|
585
|
+
* [ ] Cost ceiling + auto-fallbacks
|
|
586
|
+
* [ ] Rate limiter
|
|
587
|
+
* [ ] Multi-turn conversation API
|
|
588
|
+
* [ ] Local model support (llama.cpp, Ollama)
|
|
589
|
+
* [ ] VSCode extension for code-gen
|
|
590
|
+
* [ ] Custom provider registration
|
|
591
|
+
* [ ] Advanced caching strategies
|
|
592
|
+
|
|
593
|
+
---
|
|
594
|
+
|
|
595
|
+
## ๐ค Contributing
|
|
596
|
+
|
|
597
|
+
Contributions, ideas, and feedback are welcome! Please open an issue or submit a pull request.
|
|
598
|
+
|
|
599
|
+
---
|
|
600
|
+
|
|
601
|
+
## ๐ License
|
|
602
|
+
|
|
603
|
+
MIT ยฉ 2025 `npm-ai-hooks` Team
|
|
604
|
+
|
|
605
|
+
---
|
|
606
|
+
|
|
607
|
+
## ๐ Links
|
|
608
|
+
|
|
609
|
+
- [GitHub Repository](https://github.com/iTeebot/npm-ai-hooks)
|
|
610
|
+
- [NPM Package](https://www.npmjs.com/package/npm-ai-hooks)
|
|
611
|
+
- [Documentation](https://labs.iteebot.com/npm-packages/npm-ai-hooks)
|
|
612
|
+
- [Changelog](CHANGELOG.md)
|