npm-ai-hooks 1.0.0-beta.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/.env.example +14 -0
- package/CODE_OF_CONDUCT.md +35 -0
- package/CONTRIBUTING.md +88 -0
- package/EXAMPLES.md +53 -0
- package/LICENSE +15 -0
- package/ROADMAP.md +22 -0
- package/Readme.md +268 -0
- package/SECURITY.md +30 -0
- package/examples/basic/explain.ts +18 -0
- package/examples/basic/rewrite.ts +10 -0
- package/examples/basic/sentiment.ts +10 -0
- package/examples/basic/summarize.ts +10 -0
- package/examples/basic/translate.ts +10 -0
- package/examples/demo.ts +16 -0
- package/examples/model-switch/groq-default.ts +10 -0
- package/examples/model-switch/groq-text2.ts +10 -0
- package/examples/model-switch/openrouter-default.ts +10 -0
- package/examples/model-switch/openrouter-gpt5.ts +10 -0
- package/examples/model-switch/wrong-models.ts +21 -0
- package/examples/openrouter/summarize-switch-model-demo.ts +25 -0
- package/examples/openrouter/translate-switch-model-demo.ts +24 -0
- package/examples/openrouter/translate-to-urdu-demo.ts +19 -0
- package/examples/openrouter-openai/gpt5-demo.ts +25 -0
- package/jest.config.js +11 -0
- package/package.json +32 -0
- package/src/errors.ts +23 -0
- package/src/index.ts +2 -0
- package/src/providers/groq.ts +98 -0
- package/src/providers/index.ts +54 -0
- package/src/providers/openai.ts +19 -0
- package/src/providers/openrouter.ts +100 -0
- package/src/types/core/providers.ts +13 -0
- package/src/types/groq.ts +20 -0
- package/src/types/index.ts +37 -0
- package/src/types/openai.ts +3 -0
- package/src/types/openrouter.ts +52 -0
- package/src/wrap.ts +93 -0
- package/tsconfig.json +11 -0
package/.env.example
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# OpenAI API key (for OpenRouter OpenAI models or standalone OpenAI)
|
|
2
|
+
AI_HOOK_OPENAI_KEY=your_openai_api_key_here
|
|
3
|
+
|
|
4
|
+
# OpenRouter API key
|
|
5
|
+
AI_HOOK_OPENROUTER_KEY=your_openrouter_api_key_here
|
|
6
|
+
|
|
7
|
+
# Groq API key
|
|
8
|
+
AI_HOOK_GROQ_KEY=your_groq_api_key_here
|
|
9
|
+
|
|
10
|
+
# Default provider (optional)
|
|
11
|
+
# AI_HOOK_DEFAULT_PROVIDER=openrouter
|
|
12
|
+
|
|
13
|
+
# Default model is handled by code, so no need to set it here
|
|
14
|
+
# AI_HOOK_DEFAULT_MODEL=
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
---
|
|
3
|
+
|
|
4
|
+
## 3. `CODE_OF_CONDUCT.md`
|
|
5
|
+
|
|
6
|
+
```md
|
|
7
|
+
# Contributor Covenant Code of Conduct
|
|
8
|
+
|
|
9
|
+
## Our Pledge
|
|
10
|
+
|
|
11
|
+
We as members, contributors, and maintainers pledge to make participation in this project a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
|
12
|
+
|
|
13
|
+
## Our Standards
|
|
14
|
+
|
|
15
|
+
Examples of behavior that contributes to a positive environment include:
|
|
16
|
+
|
|
17
|
+
- Using welcoming and inclusive language
|
|
18
|
+
- Being respectful of differing viewpoints and experiences
|
|
19
|
+
- Gracefully accepting constructive criticism
|
|
20
|
+
- Focusing on what is best for the community
|
|
21
|
+
- Showing empathy towards other community members
|
|
22
|
+
|
|
23
|
+
Examples of unacceptable behavior include:
|
|
24
|
+
|
|
25
|
+
- Harassment of public or private forms
|
|
26
|
+
- Trolling, insulting/derogatory comments
|
|
27
|
+
- Publishing othersβ private information without permission
|
|
28
|
+
- Other conduct which could reasonably be considered inappropriate
|
|
29
|
+
|
|
30
|
+
## Enforcement
|
|
31
|
+
|
|
32
|
+
Instances of abusive behavior may be reported to the maintainers via [issues](https://github.com/RealTeebot/npm-ai-hooks/issues).
|
|
33
|
+
All complaints will be reviewed and addressed appropriately.
|
|
34
|
+
|
|
35
|
+
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/).
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Contributing to npm-ai-hooks
|
|
2
|
+
|
|
3
|
+
π Thanks for your interest in contributing to **npm-ai-hooks**!
|
|
4
|
+
This project is maintained by the [RealTeebot](https://github.com/RealTeebot) organization and welcomes community involvement at all levels β from bug fixes and documentation to major feature development.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## π οΈ Development Setup
|
|
9
|
+
|
|
10
|
+
1. **Fork** the repository and clone your fork:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
git clone https://github.com/your-username/npm-ai-hooks.git
|
|
14
|
+
cd npm-ai-hooks
|
|
15
|
+
|
|
16
|
+
npm install
|
|
17
|
+
|
|
18
|
+
npm run dev
|
|
19
|
+
|
|
20
|
+
npm run test
|
|
21
|
+
|
|
22
|
+
npm-ai-hooks/
|
|
23
|
+
ββ src/
|
|
24
|
+
β ββ index.ts # Main entry
|
|
25
|
+
β ββ wrap.ts # Core hook wrapper logic
|
|
26
|
+
β ββ cache.ts # Caching engine
|
|
27
|
+
β ββ cost.ts # Cost estimation utilities
|
|
28
|
+
β ββ errors.ts # Unified error handling
|
|
29
|
+
β ββ providers/ # Provider adapters
|
|
30
|
+
β β ββ openai.ts
|
|
31
|
+
β β ββ claude.ts
|
|
32
|
+
β β ββ ...
|
|
33
|
+
ββ examples/
|
|
34
|
+
β ββ node-basic/
|
|
35
|
+
β ββ react-basic/
|
|
36
|
+
ββ tests/
|
|
37
|
+
ββ ...
|
|
38
|
+
|
|
39
|
+
β¨ Contributing Guidelines
|
|
40
|
+
|
|
41
|
+
TypeScript Only: All code must be written in TypeScript with strict typing enabled.
|
|
42
|
+
|
|
43
|
+
Linting: Run npm run lint before committing.
|
|
44
|
+
|
|
45
|
+
Formatting: Code must pass Prettier formatting checks.
|
|
46
|
+
|
|
47
|
+
Commit Style: Use Conventional Commits
|
|
48
|
+
(e.g., feat: add caching to DeepSeek provider).
|
|
49
|
+
|
|
50
|
+
Tests: Add unit/integration tests for any new features or bug fixes.
|
|
51
|
+
|
|
52
|
+
π¦ Adding a New Provider
|
|
53
|
+
|
|
54
|
+
Create a new file in src/providers/ (e.g., mistral.ts)
|
|
55
|
+
|
|
56
|
+
Implement the required interface:
|
|
57
|
+
|
|
58
|
+
export const mistralProvider: Provider = {
|
|
59
|
+
name: "mistral",
|
|
60
|
+
isAvailable: () => !!process.env.AI_HOOK_MISTRAL_KEY,
|
|
61
|
+
generate: async (prompt, options) => { /* API call logic */ },
|
|
62
|
+
models: ["mistral-medium", "mistral-large"]
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
Register the provider in providers/index.ts
|
|
67
|
+
|
|
68
|
+
Add documentation and tests.
|
|
69
|
+
|
|
70
|
+
π§ͺ Testing
|
|
71
|
+
|
|
72
|
+
We use Jest for unit testing and Playwright for integration tests where relevant.
|
|
73
|
+
|
|
74
|
+
npm run test
|
|
75
|
+
npm run test:watch
|
|
76
|
+
|
|
77
|
+
π£ Communication
|
|
78
|
+
|
|
79
|
+
Issues: GitHub Issues
|
|
80
|
+
|
|
81
|
+
Discussions: GitHub Discussions
|
|
82
|
+
|
|
83
|
+
Pull Requests: Always create a PR to the main branch
|
|
84
|
+
|
|
85
|
+
π Credits
|
|
86
|
+
|
|
87
|
+
Maintained with β€οΈ by RealTeebot
|
|
88
|
+
and contributors.
|
package/EXAMPLES.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
7. EXAMPLES.md
|
|
2
|
+
# Usage Examples β npm-ai-hooks
|
|
3
|
+
|
|
4
|
+
## π§ In a React Frontend
|
|
5
|
+
|
|
6
|
+
Install:
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install npm-ai-hooks
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
Example:
|
|
13
|
+
|
|
14
|
+
import { wrap } from "npm-ai-hooks";
|
|
15
|
+
|
|
16
|
+
const summarize = wrap((text: string) => text, { task: "summarize" });
|
|
17
|
+
|
|
18
|
+
export function App() {
|
|
19
|
+
const [result, setResult] = useState("");
|
|
20
|
+
|
|
21
|
+
const handleClick = async () => {
|
|
22
|
+
const res = await summarize("Explain server components in React.");
|
|
23
|
+
setResult(res.output);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<div>
|
|
28
|
+
<button onClick={handleClick}>Summarize</button>
|
|
29
|
+
<p>{result}</p>
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
βοΈ In a Node.js Backend
|
|
35
|
+
import { wrap } from "npm-ai-hooks";
|
|
36
|
+
|
|
37
|
+
const explain = wrap((input: string) => input, { task: "explain" });
|
|
38
|
+
|
|
39
|
+
app.post("/explain", async (req, res) => {
|
|
40
|
+
const result = await explain(req.body.text);
|
|
41
|
+
res.json(result);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
This works with Express, NestJS, Fastify, Next.js API routes β anything Node-compatible.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
β
**With these files in place**, your repository will be structured like a professional, enterprise-ready open-source project:
|
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 RealTeebot
|
|
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
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND...
|
package/ROADMAP.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Roadmap β npm-ai-hooks
|
|
2
|
+
|
|
3
|
+
β
v0.1.0 (MVP)
|
|
4
|
+
- [x] Basic `wrap()` functionality
|
|
5
|
+
- [x] OpenAI + Claude support
|
|
6
|
+
- [x] Error handling and cost estimation
|
|
7
|
+
- [x] Caching layer
|
|
8
|
+
|
|
9
|
+
π v0.2.0
|
|
10
|
+
- [ ] Provider auto-discovery CLI
|
|
11
|
+
- [ ] More built-in tasks (e.g., classify, code explain)
|
|
12
|
+
- [ ] React hook wrapper (`useAI`)
|
|
13
|
+
|
|
14
|
+
π‘ v0.3.0
|
|
15
|
+
- [ ] Streaming support
|
|
16
|
+
- [ ] Local model support (Ollama / Llama.cpp)
|
|
17
|
+
- [ ] SDK for Python (bridge)
|
|
18
|
+
|
|
19
|
+
π§ Long-Term Vision
|
|
20
|
+
- Unified dashboard for usage + cost
|
|
21
|
+
- Plugin ecosystem (community providers, custom tasks)
|
|
22
|
+
- Serverless deployment starter template
|
package/Readme.md
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# npm-ai-hooks π§
|
|
2
|
+
|
|
3
|
+
**Universal AI Hook Layer for Node.js β one wrapper for all AI providers.**
|
|
4
|
+
Inject LLM-like behavior into any JavaScript or TypeScript function with a single line, without writing prompts, handling SDKs, or locking into any provider.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## π Features
|
|
9
|
+
|
|
10
|
+
* β¨ **Universal API:** Works with OpenAI, Claude, Gemini, DeepSeek, Groq, and more β out of the box.
|
|
11
|
+
* π **Plug & Play:** Wrap any function and instantly give it AI-powered behavior.
|
|
12
|
+
* π¦ **Zero Prompting:** Built-in task templates (summarize, explain, translate, sentiment, rewrite, code-review, etc.)
|
|
13
|
+
* π **Auto Provider Selection:** Detects available providers automatically from environment variables.
|
|
14
|
+
* βοΈ **Configurable:** Choose provider, model, temperature, and more per call.
|
|
15
|
+
* π **Error Safe:** Handles invalid keys, unauthorized models, rate limits, and more gracefully.
|
|
16
|
+
* π° **Cost Awareness:** Estimate and log token usage and cost before and after calls.
|
|
17
|
+
* π§ **Caching:** Prevents duplicate calls and charges by caching results intelligently.
|
|
18
|
+
* π **Extensible:** Add your own providers and custom tasks easily.
|
|
19
|
+
* π οΈ **Debug Friendly:** Full debug logging with `AI_HOOK_DEBUG=true`.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## π¦ Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install npm-ai-hooks
|
|
27
|
+
# or
|
|
28
|
+
yarn add npm-ai-hooks
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## π§ͺ Quick Start
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
const ai = require("npm-ai-hooks");
|
|
37
|
+
|
|
38
|
+
// Wrap any function
|
|
39
|
+
const summarize = ai.wrap(text => text, { task: "summarize" });
|
|
40
|
+
|
|
41
|
+
(async () => {
|
|
42
|
+
const result = await summarize("Node.js is a JavaScript runtime built on Chrome's V8...");
|
|
43
|
+
console.log(result.output); // "Node.js is a JS runtime for building server-side apps."
|
|
44
|
+
})();
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## π Environment Setup
|
|
50
|
+
|
|
51
|
+
Set one or more API keys in your `.env` file (or system environment):
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
AI_HOOK_OPENAI_KEY=sk-...
|
|
55
|
+
AI_HOOK_CLAUDE_KEY=sk-...
|
|
56
|
+
AI_HOOK_GEMINI_KEY=AIza...
|
|
57
|
+
AI_HOOK_DEEPSEEK_KEY=ds-...
|
|
58
|
+
AI_HOOK_GROQ_KEY=gr-...
|
|
59
|
+
|
|
60
|
+
AI_HOOK_DEFAULT_PROVIDER=openai
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If no provider is explicitly set, `npm-ai-hooks` will:
|
|
64
|
+
|
|
65
|
+
1. Use `AI_HOOK_DEFAULT_PROVIDER` if defined.
|
|
66
|
+
2. Auto-detect the first available provider.
|
|
67
|
+
3. Throw an error if none are available.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## π Usage Examples
|
|
72
|
+
|
|
73
|
+
### 1. Basic Summarization
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
const summarize = ai.wrap(text => text, { task: "summarize" });
|
|
77
|
+
console.log(await summarize("Long article text..."));
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
### 2. Custom Provider + Model
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
const explain = ai.wrap(t => t, {
|
|
86
|
+
task: "explain",
|
|
87
|
+
provider: "claude",
|
|
88
|
+
model: "claude-3-opus"
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
console.log(await explain("Explain quantum computing like I'm 10."));
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### 3. AI Pipelines
|
|
97
|
+
|
|
98
|
+
```js
|
|
99
|
+
const summarize = ai.wrap(t => t, { task: "summarize" });
|
|
100
|
+
const translate = ai.wrap(t => t, { task: "translate", lang: "fr" });
|
|
101
|
+
|
|
102
|
+
const result = await translate(await summarize("Long technical article..."));
|
|
103
|
+
console.log(result.output); // RΓ©sumΓ© en franΓ§ais
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
### 4. Built-in Tasks
|
|
109
|
+
|
|
110
|
+
| Task | Description |
|
|
111
|
+
| ------------ | ---------------------------------------- |
|
|
112
|
+
| `summarize` | Summarize text into concise form |
|
|
113
|
+
| `translate` | Translate text to a target language |
|
|
114
|
+
| `explain` | Explain complex text simply |
|
|
115
|
+
| `rewrite` | Rephrase text for tone/clarity |
|
|
116
|
+
| `sentiment` | Analyze emotional tone of text |
|
|
117
|
+
| `codeReview` | Review code and provide feedback |
|
|
118
|
+
| `docstring` | Generate function documentation comments |
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## βοΈ Advanced Configuration
|
|
123
|
+
|
|
124
|
+
### Caching
|
|
125
|
+
|
|
126
|
+
```js
|
|
127
|
+
const summarize = ai.wrap(t => t, { task: "summarize", cache: true });
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
* Cache keys are based on task + input + model.
|
|
131
|
+
* TTL defaults to 24h (configurable).
|
|
132
|
+
* Clear manually with:
|
|
133
|
+
|
|
134
|
+
```js
|
|
135
|
+
await ai.clearCache();
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
### Cost Awareness
|
|
141
|
+
|
|
142
|
+
Get detailed cost + token usage metadata:
|
|
143
|
+
|
|
144
|
+
```js
|
|
145
|
+
const summarize = ai.wrap(t => t, { task: "summarize" });
|
|
146
|
+
const result = await summarize(longText);
|
|
147
|
+
|
|
148
|
+
console.log(result.meta);
|
|
149
|
+
/*
|
|
150
|
+
{
|
|
151
|
+
provider: "openai",
|
|
152
|
+
model: "gpt-4o",
|
|
153
|
+
cached: false,
|
|
154
|
+
estimatedCostUSD: 0.0013,
|
|
155
|
+
totalCostUSD: 0.0012,
|
|
156
|
+
inputTokens: 326,
|
|
157
|
+
outputTokens: 127,
|
|
158
|
+
latencyMs: 812
|
|
159
|
+
}
|
|
160
|
+
*/
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
### Error Handling
|
|
166
|
+
|
|
167
|
+
All errors follow a unified structure:
|
|
168
|
+
|
|
169
|
+
```js
|
|
170
|
+
try {
|
|
171
|
+
await summarize("...");
|
|
172
|
+
} catch (err) {
|
|
173
|
+
console.error(err);
|
|
174
|
+
/*
|
|
175
|
+
{
|
|
176
|
+
code: "MODEL_NOT_ALLOWED",
|
|
177
|
+
message: "Your API key does not have access to gpt-4o",
|
|
178
|
+
provider: "openai",
|
|
179
|
+
suggestion: "Upgrade your plan or choose another model."
|
|
180
|
+
}
|
|
181
|
+
*/
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
### Debugging
|
|
188
|
+
|
|
189
|
+
Enable verbose logs:
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
AI_HOOK_DEBUG=true
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Output example:
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
[ai-hooks] Using provider: OpenAI (gpt-4o)
|
|
199
|
+
[ai-hooks] Estimated cost: $0.0012
|
|
200
|
+
[ai-hooks] Cache: MISS
|
|
201
|
+
[ai-hooks] Response received in 812ms
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## π§© Extending with Custom Providers
|
|
207
|
+
|
|
208
|
+
You can add support for any model/service:
|
|
209
|
+
|
|
210
|
+
```js
|
|
211
|
+
ai.registerProvider({
|
|
212
|
+
name: "my-llm",
|
|
213
|
+
isAvailable: () => !!process.env.MY_LLM_KEY,
|
|
214
|
+
generate: async (prompt, options) => {
|
|
215
|
+
const res = await fetch("https://my-llm.com/api", { ... });
|
|
216
|
+
return await res.text();
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## π§ Roadmap
|
|
224
|
+
|
|
225
|
+
* [ ] Streaming output support
|
|
226
|
+
* [ ] Cost ceiling + auto-fallbacks
|
|
227
|
+
* [ ] Rate limiter
|
|
228
|
+
* [ ] Multi-turn conversation API
|
|
229
|
+
* [ ] Local model support (llama.cpp, Ollama)
|
|
230
|
+
* [ ] VSCode extension for code-gen
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## π οΈ Project Structure (Planned)
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
npm-ai-hooks/
|
|
238
|
+
ββ src/
|
|
239
|
+
β ββ index.js
|
|
240
|
+
β ββ wrap.js
|
|
241
|
+
β ββ cache.js
|
|
242
|
+
β ββ cost.js
|
|
243
|
+
β ββ errors.js
|
|
244
|
+
β ββ providers/
|
|
245
|
+
β β ββ openai.js
|
|
246
|
+
β β ββ claude.js
|
|
247
|
+
β β ββ gemini.js
|
|
248
|
+
β β ββ deepseek.js
|
|
249
|
+
β β ββ groq.js
|
|
250
|
+
β β ββ index.js
|
|
251
|
+
ββ tests/
|
|
252
|
+
ββ package.json
|
|
253
|
+
ββ README.md
|
|
254
|
+
ββ LICENSE
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## π€ Contributing
|
|
260
|
+
|
|
261
|
+
Contributions, ideas, and feedback are welcome!
|
|
262
|
+
Please open an issue or submit a pull request.
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## π License
|
|
267
|
+
|
|
268
|
+
MIT Β© 2025 `npm-ai-hooks` Team
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
We actively support the latest major release and security patches for the previous one.
|
|
6
|
+
|
|
7
|
+
| Version | Supported |
|
|
8
|
+
|--------|-----------|
|
|
9
|
+
| 1.x.x | β
|
|
|
10
|
+
| 0.x.x | β |
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Reporting a Vulnerability
|
|
15
|
+
|
|
16
|
+
If you discover a security vulnerability, **DO NOT** open a public GitHub issue.
|
|
17
|
+
|
|
18
|
+
Instead, please report it privately by emailing:
|
|
19
|
+
**security@realteebot.dev**
|
|
20
|
+
|
|
21
|
+
We take all security issues seriously and will respond within 48 hours.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Disclosure Process
|
|
26
|
+
|
|
27
|
+
1. We confirm and investigate the vulnerability.
|
|
28
|
+
2. We create a patch and test the fix.
|
|
29
|
+
3. We coordinate a release and notify users.
|
|
30
|
+
4. We credit the reporter (if they wish).
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { wrap } from "../../src/wrap";
|
|
2
|
+
|
|
3
|
+
const explain = wrap((text: string) => text, { task: "explain" });
|
|
4
|
+
|
|
5
|
+
async function run() {
|
|
6
|
+
try {
|
|
7
|
+
const result = await explain("Quantum computing is complex.");
|
|
8
|
+
console.log(result.output);
|
|
9
|
+
} catch (err: any) {
|
|
10
|
+
if (err && typeof err.pretty === "function") {
|
|
11
|
+
err.pretty();
|
|
12
|
+
} else {
|
|
13
|
+
console.error(err.message || err);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
run();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { wrap } from "../../src/wrap";
|
|
2
|
+
|
|
3
|
+
const sentiment = wrap((text: string) => text, { task: "sentiment" });
|
|
4
|
+
|
|
5
|
+
async function run() {
|
|
6
|
+
const result = await sentiment("I love using AI-Hooks for my projects!");
|
|
7
|
+
console.log(result.output);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
run();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { wrap } from "../../src/wrap";
|
|
2
|
+
|
|
3
|
+
const summarize = wrap((text: string) => text, { task: "summarize" });
|
|
4
|
+
|
|
5
|
+
async function run() {
|
|
6
|
+
const result = await summarize("OpenRouter is a powerful AI integration tool.");
|
|
7
|
+
console.log(result.output);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
run();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { wrap } from "../../src/wrap";
|
|
2
|
+
|
|
3
|
+
const translate = wrap((text: string) => text, { task: "translate", targetLanguage: "Urdu" });
|
|
4
|
+
|
|
5
|
+
async function run() {
|
|
6
|
+
const result = await translate("Hello everyone! Welcome to AI demos.");
|
|
7
|
+
console.log(result.output);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
run();
|
package/examples/demo.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { wrap } from "../src";
|
|
2
|
+
|
|
3
|
+
const summarize = wrap((text: string) => text, { task: "summarize" });
|
|
4
|
+
|
|
5
|
+
(async () => {
|
|
6
|
+
try {
|
|
7
|
+
const result = await summarize("OpenRouter is a great tool for AI integration...");
|
|
8
|
+
console.log(result.output);
|
|
9
|
+
} catch (err: any) {
|
|
10
|
+
if (err.pretty) {
|
|
11
|
+
err.pretty(); // prints nice error with suggestions
|
|
12
|
+
} else {
|
|
13
|
+
console.error(err);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
})();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { wrap } from "../../src/wrap";
|
|
2
|
+
|
|
3
|
+
const explain = wrap((text: string) => text, { task: "explain", provider: "groq" });
|
|
4
|
+
|
|
5
|
+
async function run() {
|
|
6
|
+
const result = await explain("Groq provides fast text AI models.");
|
|
7
|
+
console.log(result.output);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
run();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { wrap } from "../../src/wrap";
|
|
2
|
+
|
|
3
|
+
const explain = wrap((text: string) => text, { task: "explain", provider: "groq", model: "allam-2-7b" });
|
|
4
|
+
|
|
5
|
+
async function run() {
|
|
6
|
+
const result = await explain("Groq's text-2 model is versatile for many tasks.");
|
|
7
|
+
console.log(result.output);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
run();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { wrap } from "../../src/wrap";
|
|
2
|
+
|
|
3
|
+
const summarize = wrap((text: string) => text, { task: "summarize", provider: "openrouter" });
|
|
4
|
+
|
|
5
|
+
async function run() {
|
|
6
|
+
const result = await summarize("OpenRouter makes AI integration seamless.");
|
|
7
|
+
console.log(result.output);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
run();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { wrap } from "../../src/wrap";
|
|
2
|
+
|
|
3
|
+
const summarize = wrap((text: string) => text, { task: "summarize", provider: "openrouter", model: "openai/gpt-5-pro" });
|
|
4
|
+
|
|
5
|
+
async function run() {
|
|
6
|
+
const result = await summarize("OpenRouter supports multiple models including GPT-5.");
|
|
7
|
+
console.log(result.output);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
run();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { wrap } from "../../src/wrap";
|
|
2
|
+
|
|
3
|
+
async function run() {
|
|
4
|
+
// Wrong OpenRouter model
|
|
5
|
+
try {
|
|
6
|
+
const wrongOpenRouter = wrap((text: string) => text, { task: "summarize", provider: "openrouter", model: "invalid-model" as any });
|
|
7
|
+
await wrongOpenRouter("Test text");
|
|
8
|
+
} catch (err: unknown) {
|
|
9
|
+
console.error("β OpenRouter error:", err);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Wrong Groq model
|
|
13
|
+
try {
|
|
14
|
+
const wrongGroq = wrap((text: string) => text, { task: "explain", provider: "groq", model: "invalid-groq-model" as any });
|
|
15
|
+
await wrongGroq("Test text");
|
|
16
|
+
} catch (err: unknown) {
|
|
17
|
+
console.error("β Groq error:", err);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
run();
|