@ooneex/ai 0.0.4

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ooneex
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,405 @@
1
+ # @ooneex/ai
2
+
3
+ A unified AI client library for TypeScript applications with support for OpenAI, Anthropic, Google Gemini, and Ollama providers. This package provides a consistent interface for text generation, content transformation, and streaming responses across multiple AI backends.
4
+
5
+ ![Bun](https://img.shields.io/badge/Bun-Compatible-orange?style=flat-square&logo=bun)
6
+ ![Deno](https://img.shields.io/badge/Deno-Compatible-blue?style=flat-square&logo=deno)
7
+ ![Node.js](https://img.shields.io/badge/Node.js-Compatible-green?style=flat-square&logo=node.js)
8
+ ![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue?style=flat-square&logo=typescript)
9
+ ![MIT License](https://img.shields.io/badge/License-MIT-yellow?style=flat-square)
10
+
11
+ ## Features
12
+
13
+ ✅ **Multiple Providers** - Support for OpenAI, Anthropic Claude, Google Gemini, and Ollama
14
+
15
+ ✅ **Unified Interface** - Consistent API across all AI providers
16
+
17
+ ✅ **Text Transformations** - Built-in methods for summarizing, rephrasing, translating, and more
18
+
19
+ ✅ **Streaming Support** - Real-time response streaming with async generators
20
+
21
+ ✅ **Output Validation** - Validate AI responses against schemas using ArkType
22
+
23
+ ✅ **Configurable Tone** - 15 different tone options for content generation
24
+
25
+ ✅ **Multi-language** - Translate and generate content in multiple languages
26
+
27
+ ✅ **Type-Safe** - Full TypeScript support with proper type definitions
28
+
29
+ ## Installation
30
+
31
+ ### Bun
32
+ ```bash
33
+ bun add @ooneex/ai
34
+ ```
35
+
36
+ ### pnpm
37
+ ```bash
38
+ pnpm add @ooneex/ai
39
+ ```
40
+
41
+ ### Yarn
42
+ ```bash
43
+ yarn add @ooneex/ai
44
+ ```
45
+
46
+ ### npm
47
+ ```bash
48
+ npm install @ooneex/ai
49
+ ```
50
+
51
+ ## Usage
52
+
53
+ ### Basic Usage with OpenAI
54
+
55
+ ```typescript
56
+ import { OpenAi } from '@ooneex/ai';
57
+
58
+ const ai = new OpenAi();
59
+
60
+ // Run a simple prompt
61
+ const result = await ai.run<string>('What is the capital of France?');
62
+ console.log(result); // "Paris"
63
+ ```
64
+
65
+ ### Text Transformations
66
+
67
+ ```typescript
68
+ import { AnthropicAi } from '@ooneex/ai';
69
+
70
+ const ai = new AnthropicAi();
71
+
72
+ // Summarize content
73
+ const summary = await ai.summarize('Your long text here...');
74
+
75
+ // Make text shorter
76
+ const shorter = await ai.makeShorter('Your verbose text here...');
77
+
78
+ // Simplify complex text
79
+ const simplified = await ai.simplify('Complex technical jargon...');
80
+
81
+ // Change tone
82
+ const formal = await ai.changeTone('Hey, what\'s up?', 'formal');
83
+
84
+ // Translate content
85
+ const translated = await ai.translate('Hello, world!', { language: 'fr' });
86
+ ```
87
+
88
+ ### Streaming Responses
89
+
90
+ ```typescript
91
+ import { OpenAi } from '@ooneex/ai';
92
+
93
+ const ai = new OpenAi();
94
+
95
+ // Stream the response chunk by chunk
96
+ for await (const chunk of ai.runStream('Explain quantum computing')) {
97
+ process.stdout.write(chunk);
98
+ }
99
+ ```
100
+
101
+ ### With Configuration
102
+
103
+ ```typescript
104
+ import { GeminiAi, type GeminiConfigType } from '@ooneex/ai';
105
+
106
+ const ai = new GeminiAi();
107
+
108
+ const config: GeminiConfigType = {
109
+ model: 'gemini-1.5-pro',
110
+ wordCount: 200,
111
+ tone: 'professional',
112
+ language: 'en',
113
+ context: 'You are a technical writer.'
114
+ };
115
+
116
+ const result = await ai.run<string>('Explain microservices', config);
117
+ ```
118
+
119
+ ### Output Validation
120
+
121
+ ```typescript
122
+ import { OpenAi } from '@ooneex/ai';
123
+ import { type } from 'arktype';
124
+
125
+ const ai = new OpenAi();
126
+
127
+ // Define expected output schema
128
+ const ProductSchema = type({
129
+ name: 'string',
130
+ price: 'number',
131
+ description: 'string'
132
+ });
133
+
134
+ const product = await ai.run<{ name: string; price: number; description: string }>(
135
+ 'Generate a product for an e-commerce store',
136
+ { output: ProductSchema }
137
+ );
138
+
139
+ console.log(product.name, product.price);
140
+ ```
141
+
142
+ ### Using Ollama (Local Models)
143
+
144
+ ```typescript
145
+ import { OllamaAi } from '@ooneex/ai';
146
+
147
+ const ai = new OllamaAi();
148
+
149
+ const result = await ai.run<string>('Write a haiku about coding', {
150
+ host: 'http://localhost:11434',
151
+ model: 'llama2'
152
+ });
153
+ ```
154
+
155
+ ## API Reference
156
+
157
+ ### Classes
158
+
159
+ #### `OpenAi`
160
+
161
+ OpenAI provider implementation with GPT models.
162
+
163
+ **Constructor:**
164
+ ```typescript
165
+ new OpenAi()
166
+ ```
167
+
168
+ **Environment Variables:**
169
+ - `OPENAI_API_KEY` - Your OpenAI API key
170
+
171
+ #### `AnthropicAi`
172
+
173
+ Anthropic provider implementation with Claude models.
174
+
175
+ **Constructor:**
176
+ ```typescript
177
+ new AnthropicAi()
178
+ ```
179
+
180
+ **Environment Variables:**
181
+ - `ANTHROPIC_API_KEY` - Your Anthropic API key
182
+
183
+ #### `GeminiAi`
184
+
185
+ Google Gemini provider implementation.
186
+
187
+ **Constructor:**
188
+ ```typescript
189
+ new GeminiAi()
190
+ ```
191
+
192
+ **Environment Variables:**
193
+ - `GEMINI_API_KEY` - Your Google Gemini API key
194
+
195
+ #### `OllamaAi`
196
+
197
+ Ollama provider for local AI models.
198
+
199
+ **Constructor:**
200
+ ```typescript
201
+ new OllamaAi()
202
+ ```
203
+
204
+ **Configuration:**
205
+ - `host` - Ollama server URL (default: `http://localhost:11434`)
206
+
207
+ ### Common Methods
208
+
209
+ All AI classes implement the `IAiChat` interface with these methods:
210
+
211
+ ##### `run<T>(prompt: string, config?: ConfigType): Promise<T>`
212
+
213
+ Execute a prompt and return the response.
214
+
215
+ ##### `runStream(prompt: string, config?: ConfigType): AsyncGenerator<string>`
216
+
217
+ Stream the response chunk by chunk.
218
+
219
+ ##### `summarize(content: string, config?: ConfigType): Promise<string>`
220
+
221
+ Summarize the provided content.
222
+
223
+ ##### `makeShorter(content: string, config?: ConfigType): Promise<string>`
224
+
225
+ Condense text while preserving meaning.
226
+
227
+ ##### `makeLonger(content: string, config?: ConfigType): Promise<string>`
228
+
229
+ Expand text with additional details.
230
+
231
+ ##### `simplify(content: string, config?: ConfigType): Promise<string>`
232
+
233
+ Simplify complex text for general audiences.
234
+
235
+ ##### `rephrase(content: string, config?: ConfigType): Promise<string>`
236
+
237
+ Rephrase using different words and structures.
238
+
239
+ ##### `changeTone(content: string, tone: AiToneType, config?: ConfigType): Promise<string>`
240
+
241
+ Rewrite content with a different tone.
242
+
243
+ ##### `translate(content: string, config?: ConfigType): Promise<string>`
244
+
245
+ Translate content to the specified language.
246
+
247
+ ##### `proofread(content: string, config?: ConfigType): Promise<string>`
248
+
249
+ Correct grammar, spelling, and punctuation.
250
+
251
+ ##### `extractKeywords(content: string, config?: ConfigType): Promise<string[]>`
252
+
253
+ Extract important keywords from content.
254
+
255
+ ##### `extractCategories(content: string, config?: ConfigType): Promise<string[]>`
256
+
257
+ Identify relevant categories for content.
258
+
259
+ ##### `generateTitle(content: string, config?: ConfigType): Promise<string>`
260
+
261
+ Generate a compelling title for content.
262
+
263
+ ### Types
264
+
265
+ #### `AiConfigType`
266
+
267
+ ```typescript
268
+ type AiConfigType = {
269
+ apiKey?: string;
270
+ model?: string;
271
+ wordCount?: number;
272
+ stream?: boolean;
273
+ language?: LocaleType;
274
+ tone?: AiToneType;
275
+ messages?: AiMessageType[];
276
+ context?: string;
277
+ prompt?: string;
278
+ output?: AssertType;
279
+ };
280
+ ```
281
+
282
+ #### `AiToneType`
283
+
284
+ ```typescript
285
+ type AiToneType =
286
+ | "professional"
287
+ | "casual"
288
+ | "formal"
289
+ | "friendly"
290
+ | "confident"
291
+ | "empathetic"
292
+ | "persuasive"
293
+ | "informative"
294
+ | "enthusiastic"
295
+ | "neutral"
296
+ | "humorous"
297
+ | "serious"
298
+ | "inspirational"
299
+ | "conversational"
300
+ | "authoritative";
301
+ ```
302
+
303
+ #### `AiMessageType`
304
+
305
+ ```typescript
306
+ type AiMessageType = {
307
+ role: "user" | "assistant" | "system" | "tool";
308
+ content: string;
309
+ };
310
+ ```
311
+
312
+ ## Advanced Usage
313
+
314
+ ### Conversation History
315
+
316
+ ```typescript
317
+ import { OpenAi, type AiMessageType } from '@ooneex/ai';
318
+
319
+ const ai = new OpenAi();
320
+
321
+ const messages: AiMessageType[] = [
322
+ { role: 'user', content: 'My name is Alice.' },
323
+ { role: 'assistant', content: 'Hello Alice! How can I help you today?' }
324
+ ];
325
+
326
+ const response = await ai.run<string>('What is my name?', { messages });
327
+ // "Your name is Alice."
328
+ ```
329
+
330
+ ### Custom Context
331
+
332
+ ```typescript
333
+ import { AnthropicAi } from '@ooneex/ai';
334
+
335
+ const ai = new AnthropicAi();
336
+
337
+ const response = await ai.run<string>('Summarize the project status', {
338
+ context: `
339
+ Project: E-commerce Platform
340
+ Status: In development
341
+ Progress: 75% complete
342
+ Team: 5 developers
343
+ Deadline: December 2024
344
+ `
345
+ });
346
+ ```
347
+
348
+ ### Error Handling
349
+
350
+ ```typescript
351
+ import { OpenAi, AiException } from '@ooneex/ai';
352
+
353
+ const ai = new OpenAi();
354
+
355
+ try {
356
+ const result = await ai.run<string>('Generate content');
357
+ } catch (error) {
358
+ if (error instanceof AiException) {
359
+ console.error('AI Error:', error.message);
360
+ console.error('Status:', error.status);
361
+ }
362
+ }
363
+ ```
364
+
365
+ ### Integration with Dependency Injection
366
+
367
+ ```typescript
368
+ import { container } from '@ooneex/container';
369
+ import { OpenAi, decorator } from '@ooneex/ai';
370
+
371
+ // The decorator registers the class with the container
372
+ @decorator.ai()
373
+ class MyAiService extends OpenAi {
374
+ // Custom implementation
375
+ }
376
+
377
+ // Resolve from container
378
+ const aiService = container.get(MyAiService);
379
+ ```
380
+
381
+ ## License
382
+
383
+ This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
384
+
385
+ ## Contributing
386
+
387
+ Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
388
+
389
+ ### Development Setup
390
+
391
+ 1. Clone the repository
392
+ 2. Install dependencies: `bun install`
393
+ 3. Run tests: `bun run test`
394
+ 4. Build the project: `bun run build`
395
+
396
+ ### Guidelines
397
+
398
+ - Write tests for new features
399
+ - Follow the existing code style
400
+ - Update documentation for API changes
401
+ - Ensure all tests pass before submitting PR
402
+
403
+ ---
404
+
405
+ Made with ❤️ by the Ooneex team
@@ -0,0 +1,227 @@
1
+ import { Exception } from "@ooneex/exception";
2
+ declare class AiException extends Exception {
3
+ constructor(message: string, data?: Record<string, unknown>);
4
+ }
5
+ import { LocaleType } from "@ooneex/translation";
6
+ import { AssertType } from "@ooneex/validation";
7
+ import { anthropicText } from "@tanstack/ai-anthropic";
8
+ import { geminiText } from "@tanstack/ai-gemini";
9
+ import { ollamaText } from "@tanstack/ai-ollama";
10
+ import { openaiText } from "@tanstack/ai-openai";
11
+ type AiClassType = new (...args: any[]) => IAiChat<any>;
12
+ type OpenAiModelType = Parameters<typeof openaiText>[0];
13
+ type AnthropicModelType = Parameters<typeof anthropicText>[0];
14
+ type GeminiModelType = Parameters<typeof geminiText>[0];
15
+ type OllamaModelType = Parameters<typeof ollamaText>[0];
16
+ type AiToneType = "professional" | "casual" | "formal" | "friendly" | "confident" | "empathetic" | "persuasive" | "informative" | "enthusiastic" | "neutral" | "humorous" | "serious" | "inspirational" | "conversational" | "authoritative";
17
+ type AiMessageType = {
18
+ role: "user" | "assistant" | "system" | "tool";
19
+ content: string;
20
+ };
21
+ type AiConfigType = {
22
+ apiKey?: string;
23
+ model?: OpenAiModelType | AnthropicModelType | GeminiModelType | OllamaModelType;
24
+ wordCount?: number;
25
+ stream?: boolean;
26
+ language?: LocaleType;
27
+ tone?: AiToneType;
28
+ messages?: AiMessageType[];
29
+ context?: string;
30
+ prompt?: string;
31
+ output?: AssertType;
32
+ };
33
+ type OpenAiConfigType = Omit<AiConfigType, "model"> & {
34
+ model?: OpenAiModelType;
35
+ };
36
+ type AnthropicConfigType = Omit<AiConfigType, "model"> & {
37
+ model?: AnthropicModelType;
38
+ };
39
+ type GeminiConfigType = Omit<AiConfigType, "model"> & {
40
+ model?: GeminiModelType;
41
+ };
42
+ type OllamaConfigType = Omit<AiConfigType, "model" | "apiKey"> & {
43
+ host?: string;
44
+ model?: OllamaModelType;
45
+ };
46
+ interface IAiChat<TConfig extends AiConfigType = AiConfigType> {
47
+ makeShorter?: (content: string, config?: TConfig) => Promise<string>;
48
+ makeLonger?: (content: string, config?: TConfig) => Promise<string>;
49
+ summarize?: (content: string, config?: TConfig) => Promise<string>;
50
+ concise?: (content: string, config?: TConfig) => Promise<string>;
51
+ paragraph?: (content: string, config?: TConfig) => Promise<string>;
52
+ bulletPoints?: (content: string, config?: TConfig) => Promise<string>;
53
+ rephrase?: (content: string, config?: TConfig) => Promise<string>;
54
+ simplify?: (content: string, config?: TConfig) => Promise<string>;
55
+ changeTone?: (content: string, tone: AiToneType, config?: Omit<TConfig, "tone">) => Promise<string>;
56
+ proofread?: (content: string, config?: TConfig) => Promise<string>;
57
+ translate?: (content: string, config?: TConfig) => Promise<string>;
58
+ explain?: (content: string, config?: TConfig) => Promise<string>;
59
+ expandIdeas?: (content: string, config?: TConfig) => Promise<string>;
60
+ fixGrammar?: (content: string, config?: TConfig) => Promise<string>;
61
+ generateTitle?: (content: string, config?: TConfig) => Promise<string>;
62
+ extractKeywords?: (content: string, config?: TConfig) => Promise<string[]>;
63
+ extractCategories?: (content: string, config?: TConfig) => Promise<string[]>;
64
+ run: <T>(content: string, config?: TConfig) => Promise<T>;
65
+ runStream: (content: string, config?: TConfig) => AsyncGenerator<string, void, unknown>;
66
+ }
67
+ declare class AnthropicAi implements IAiChat<AnthropicConfigType> {
68
+ private getApiKey;
69
+ private getAdapter;
70
+ private buildPrompt;
71
+ private toMessages;
72
+ private executeChat;
73
+ makeShorter(content: string, config?: Omit<AnthropicConfigType, "output">): Promise<string>;
74
+ makeLonger(content: string, config?: Omit<AnthropicConfigType, "output">): Promise<string>;
75
+ summarize(content: string, config?: Omit<AnthropicConfigType, "output">): Promise<string>;
76
+ concise(content: string, config?: Omit<AnthropicConfigType, "output">): Promise<string>;
77
+ paragraph(content: string, config?: Omit<AnthropicConfigType, "output">): Promise<string>;
78
+ bulletPoints(content: string, config?: Omit<AnthropicConfigType, "output">): Promise<string>;
79
+ rephrase(content: string, config?: Omit<AnthropicConfigType, "output">): Promise<string>;
80
+ simplify(content: string, config?: Omit<AnthropicConfigType, "output">): Promise<string>;
81
+ changeTone(content: string, tone: AiToneType, config?: Omit<AnthropicConfigType, "tone" | "output">): Promise<string>;
82
+ proofread(content: string, config?: Omit<AnthropicConfigType, "output">): Promise<string>;
83
+ translate(content: string, config?: Omit<AnthropicConfigType, "output">): Promise<string>;
84
+ explain(content: string, config?: Omit<AnthropicConfigType, "output">): Promise<string>;
85
+ expandIdeas(content: string, config?: Omit<AnthropicConfigType, "output">): Promise<string>;
86
+ fixGrammar(content: string, config?: Omit<AnthropicConfigType, "output">): Promise<string>;
87
+ generateTitle(content: string, config?: Omit<AnthropicConfigType, "output">): Promise<string>;
88
+ extractKeywords(content: string, config?: Omit<AnthropicConfigType, "output">): Promise<string[]>;
89
+ extractCategories(content: string, config?: Omit<AnthropicConfigType, "output">): Promise<string[]>;
90
+ run<T>(prompt: string, config?: Omit<AnthropicConfigType, "prompt">): Promise<T>;
91
+ /**
92
+ * Streams the AI response chunk by chunk as an async generator.
93
+ *
94
+ * @example
95
+ * ```ts
96
+ * const adapter = new AnthropicChatAdapter();
97
+ *
98
+ * // Stream the response chunk by chunk
99
+ * for await (const chunk of adapter.runStream("Explain quantum computing")) {
100
+ * process.stdout.write(chunk); // Print each chunk as it arrives
101
+ * }
102
+ * ```
103
+ */
104
+ runStream(prompt: string, config?: Omit<AnthropicConfigType, "prompt" | "output">): AsyncGenerator<string, void, unknown>;
105
+ }
106
+ import { EContainerScope } from "@ooneex/container";
107
+ declare const decorator: {
108
+ ai: (scope?: EContainerScope) => (target: AiClassType) => void;
109
+ };
110
+ declare class GeminiAi implements IAiChat<GeminiConfigType> {
111
+ private getApiKey;
112
+ private getAdapter;
113
+ private buildPrompt;
114
+ private toMessages;
115
+ private executeChat;
116
+ makeShorter(content: string, config?: Omit<GeminiConfigType, "output">): Promise<string>;
117
+ makeLonger(content: string, config?: Omit<GeminiConfigType, "output">): Promise<string>;
118
+ summarize(content: string, config?: Omit<GeminiConfigType, "output">): Promise<string>;
119
+ concise(content: string, config?: Omit<GeminiConfigType, "output">): Promise<string>;
120
+ paragraph(content: string, config?: Omit<GeminiConfigType, "output">): Promise<string>;
121
+ bulletPoints(content: string, config?: Omit<GeminiConfigType, "output">): Promise<string>;
122
+ rephrase(content: string, config?: Omit<GeminiConfigType, "output">): Promise<string>;
123
+ simplify(content: string, config?: Omit<GeminiConfigType, "output">): Promise<string>;
124
+ changeTone(content: string, tone: AiToneType, config?: Omit<GeminiConfigType, "tone" | "output">): Promise<string>;
125
+ proofread(content: string, config?: Omit<GeminiConfigType, "output">): Promise<string>;
126
+ translate(content: string, config?: Omit<GeminiConfigType, "output">): Promise<string>;
127
+ explain(content: string, config?: Omit<GeminiConfigType, "output">): Promise<string>;
128
+ expandIdeas(content: string, config?: Omit<GeminiConfigType, "output">): Promise<string>;
129
+ fixGrammar(content: string, config?: Omit<GeminiConfigType, "output">): Promise<string>;
130
+ generateTitle(content: string, config?: Omit<GeminiConfigType, "output">): Promise<string>;
131
+ extractKeywords(content: string, config?: Omit<GeminiConfigType, "output">): Promise<string[]>;
132
+ extractCategories(content: string, config?: Omit<GeminiConfigType, "output">): Promise<string[]>;
133
+ run<T>(prompt: string, config?: Omit<GeminiConfigType, "prompt">): Promise<T>;
134
+ /**
135
+ * Streams the AI response chunk by chunk as an async generator.
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * const adapter = new GeminiChatAdapter();
140
+ *
141
+ * // Stream the response chunk by chunk
142
+ * for await (const chunk of adapter.runStream("Explain quantum computing")) {
143
+ * process.stdout.write(chunk); // Print each chunk as it arrives
144
+ * }
145
+ * ```
146
+ */
147
+ runStream(prompt: string, config?: Omit<GeminiConfigType, "prompt" | "output">): AsyncGenerator<string, void, unknown>;
148
+ }
149
+ declare class OllamaAi implements IAiChat<OllamaConfigType> {
150
+ private getHost;
151
+ private getAdapter;
152
+ private buildPrompt;
153
+ private toMessages;
154
+ private executeChat;
155
+ makeShorter(content: string, config?: Omit<OllamaConfigType, "output">): Promise<string>;
156
+ makeLonger(content: string, config?: Omit<OllamaConfigType, "output">): Promise<string>;
157
+ summarize(content: string, config?: Omit<OllamaConfigType, "output">): Promise<string>;
158
+ concise(content: string, config?: Omit<OllamaConfigType, "output">): Promise<string>;
159
+ paragraph(content: string, config?: Omit<OllamaConfigType, "output">): Promise<string>;
160
+ bulletPoints(content: string, config?: Omit<OllamaConfigType, "output">): Promise<string>;
161
+ rephrase(content: string, config?: Omit<OllamaConfigType, "output">): Promise<string>;
162
+ simplify(content: string, config?: Omit<OllamaConfigType, "output">): Promise<string>;
163
+ changeTone(content: string, tone: AiToneType, config?: Omit<OllamaConfigType, "tone" | "output">): Promise<string>;
164
+ proofread(content: string, config?: Omit<OllamaConfigType, "output">): Promise<string>;
165
+ translate(content: string, config?: Omit<OllamaConfigType, "output">): Promise<string>;
166
+ explain(content: string, config?: Omit<OllamaConfigType, "output">): Promise<string>;
167
+ expandIdeas(content: string, config?: Omit<OllamaConfigType, "output">): Promise<string>;
168
+ fixGrammar(content: string, config?: Omit<OllamaConfigType, "output">): Promise<string>;
169
+ generateTitle(content: string, config?: Omit<OllamaConfigType, "output">): Promise<string>;
170
+ extractKeywords(content: string, config?: Omit<OllamaConfigType, "output">): Promise<string[]>;
171
+ extractCategories(content: string, config?: Omit<OllamaConfigType, "output">): Promise<string[]>;
172
+ run<T>(prompt: string, config?: Omit<OllamaConfigType, "prompt">): Promise<T>;
173
+ /**
174
+ * Streams the AI response chunk by chunk as an async generator.
175
+ *
176
+ * @example
177
+ * ```ts
178
+ * const adapter = new OllamaChatAdapter();
179
+ *
180
+ * // Stream the response chunk by chunk
181
+ * for await (const chunk of adapter.runStream("Explain quantum computing")) {
182
+ * process.stdout.write(chunk); // Print each chunk as it arrives
183
+ * }
184
+ * ```
185
+ */
186
+ runStream(prompt: string, config?: Omit<OllamaConfigType, "prompt" | "output">): AsyncGenerator<string, void, unknown>;
187
+ }
188
+ declare class OpenAi implements IAiChat<OpenAiConfigType> {
189
+ private getApiKey;
190
+ private getAdapter;
191
+ private buildPrompt;
192
+ private toMessages;
193
+ private executeChat;
194
+ makeShorter(content: string, config?: Omit<OpenAiConfigType, "output">): Promise<string>;
195
+ makeLonger(content: string, config?: Omit<OpenAiConfigType, "output">): Promise<string>;
196
+ summarize(content: string, config?: Omit<OpenAiConfigType, "output">): Promise<string>;
197
+ concise(content: string, config?: Omit<OpenAiConfigType, "output">): Promise<string>;
198
+ paragraph(content: string, config?: Omit<OpenAiConfigType, "output">): Promise<string>;
199
+ bulletPoints(content: string, config?: Omit<OpenAiConfigType, "output">): Promise<string>;
200
+ rephrase(content: string, config?: Omit<OpenAiConfigType, "output">): Promise<string>;
201
+ simplify(content: string, config?: Omit<OpenAiConfigType, "output">): Promise<string>;
202
+ changeTone(content: string, tone: AiToneType, config?: Omit<OpenAiConfigType, "tone" | "output">): Promise<string>;
203
+ proofread(content: string, config?: Omit<OpenAiConfigType, "output">): Promise<string>;
204
+ translate(content: string, config?: Omit<OpenAiConfigType, "output">): Promise<string>;
205
+ explain(content: string, config?: Omit<OpenAiConfigType, "output">): Promise<string>;
206
+ expandIdeas(content: string, config?: Omit<OpenAiConfigType, "output">): Promise<string>;
207
+ fixGrammar(content: string, config?: Omit<OpenAiConfigType, "output">): Promise<string>;
208
+ generateTitle(content: string, config?: Omit<OpenAiConfigType, "output">): Promise<string>;
209
+ extractKeywords(content: string, config?: Omit<OpenAiConfigType, "output">): Promise<string[]>;
210
+ extractCategories(content: string, config?: Omit<OpenAiConfigType, "output">): Promise<string[]>;
211
+ run<T>(prompt: string, config?: Omit<OpenAiConfigType, "prompt">): Promise<T>;
212
+ /**
213
+ * Streams the AI response chunk by chunk as an async generator.
214
+ *
215
+ * @example
216
+ * ```ts
217
+ * const adapter = new OpenAiAdapter();
218
+ *
219
+ * // Stream the response chunk by chunk
220
+ * for await (const chunk of adapter.runStream("Explain quantum computing")) {
221
+ * process.stdout.write(chunk); // Print each chunk as it arrives
222
+ * }
223
+ * ```
224
+ */
225
+ runStream(prompt: string, config?: Omit<OpenAiConfigType, "prompt" | "output">): AsyncGenerator<string, void, unknown>;
226
+ }
227
+ export { decorator, OpenAiModelType, OpenAiConfigType, OpenAi, OllamaModelType, OllamaConfigType, OllamaAi, IAiChat, GeminiModelType, GeminiConfigType, GeminiAi, AnthropicModelType, AnthropicConfigType, AnthropicAi, AiToneType, AiMessageType, AiException, AiConfigType, AiClassType };
package/dist/index.js ADDED
@@ -0,0 +1,55 @@
1
+ var $=function(z,H,R,D){var B=arguments.length,F=B<3?H:D===null?D=Object.getOwnPropertyDescriptor(H,R):D,J;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")F=Reflect.decorate(z,H,R,D);else for(var N=z.length-1;N>=0;N--)if(J=z[N])F=(B<3?J(F):B>3?J(H,R,F):J(H,R))||F;return B>3&&F&&Object.defineProperty(H,R,F),F};import{Exception as T}from"@ooneex/exception";import{HttpStatus as v}from"@ooneex/http-status";class Y extends T{constructor(z,H={}){super(z,{status:v.Code.InternalServerError,data:H});this.name="AiException"}}import{jsonSchemaToTypeString as M}from"@ooneex/validation";import{chat as G}from"@tanstack/ai";import{createAnthropicChat as b}from"@tanstack/ai-anthropic";import{type as P}from"arktype";import{container as S,EContainerScope as K}from"@ooneex/container";var _={ai:(z=K.Singleton)=>{return(H)=>{S.add(H,z)}}};class I{getApiKey(z){let H=z?.apiKey||Bun.env.ANTHROPIC_API_KEY||"";if(!H)throw new Y("Anthropic API key is required. Provide an API key through config options or set the ANTHROPIC_API_KEY environment variable.");return H}getAdapter(z,H){return b(H,z)}buildPrompt(z,H){let R=[H?.prompt||z];if(H?.context)R.push(`Context:
2
+ ${H.context}`);if(H?.wordCount)R.push(`Target approximately ${H.wordCount} words.`);if(H?.tone)R.push(`Use a ${H.tone} tone.`);if(H?.language)R.push(`Respond in ${H.language} language.`);return R.push(`${H?.context?"Use the provided context to inform your response. ":""}Respond with only the transformed text. Do not include explanations or additional commentary.`),R.join(`
3
+ `)}toMessages(z){return z.map((H)=>({role:H.role,content:H.content}))}async executeChat(z,H,R){let D=this.getApiKey(R),B=R?.model??"claude-sonnet-4-5",F=this.getAdapter(D,B),J=R?.messages?this.toMessages(R.messages):[],N={role:"user",content:`${H}
4
+
5
+ Text to process:
6
+ ${z}`},U=[...J,N];return(await G({adapter:F,messages:U,stream:!1})).trim()}async makeShorter(z,H){let R=this.buildPrompt("Condense the following text while preserving its core meaning and key information. Remove redundancies and unnecessary details.",H);return this.executeChat(z,R,H)}async makeLonger(z,H){let R=this.buildPrompt("Expand the following text by adding relevant details, examples, and explanations while maintaining coherence and the original message.",H);return this.executeChat(z,R,H)}async summarize(z,H){let R=this.buildPrompt("Provide a clear and comprehensive summary of the following text, capturing all essential points and main ideas.",H);return this.executeChat(z,R,H)}async concise(z,H){let R=this.buildPrompt("Rewrite the following text in the most concise form possible without losing essential meaning.",H);return this.executeChat(z,R,H)}async paragraph(z,H){let R=this.buildPrompt("Transform the following text into well-structured paragraph format with clear topic sentences and logical flow.",H);return this.executeChat(z,R,H)}async bulletPoints(z,H){let R=this.buildPrompt("Convert the following text into a clear, organized list of bullet points highlighting the key information.",H);return this.executeChat(z,R,H)}async rephrase(z,H){let R=this.buildPrompt("Rephrase the following text using different words and sentence structures while preserving the original meaning.",H);return this.executeChat(z,R,H)}async simplify(z,H){let R=this.buildPrompt("Simplify the following text by using plain language, shorter sentences, and avoiding jargon. Make it accessible to a general audience.",H);return this.executeChat(z,R,H)}async changeTone(z,H,R){let D=this.buildPrompt(`Rewrite the following text in a ${H} tone while maintaining clarity.`,R);return this.executeChat(z,D,R)}async proofread(z,H){let R=this.buildPrompt("Proofread and correct the following text for grammar, spelling, punctuation, and clarity issues. Return the corrected version.",H);return this.executeChat(z,R,H)}async translate(z,H){let R=H?.language??"en",D=this.buildPrompt(`Translate the following text accurately into ${R}, preserving the original meaning, tone, and nuance.`,H);return this.executeChat(z,D,H)}async explain(z,H){let R=this.buildPrompt("Provide a clear explanation of the following text, breaking down complex concepts and clarifying the meaning.",H);return this.executeChat(z,R,H)}async expandIdeas(z,H){let R=this.buildPrompt("Expand on the ideas presented in the following text by exploring related concepts, implications, and additional perspectives.",H);return this.executeChat(z,R,H)}async fixGrammar(z,H){let R=this.buildPrompt("Fix all grammatical errors in the following text, including subject-verb agreement, tense consistency, and sentence structure.",H);return this.executeChat(z,R,H)}async generateTitle(z,H){let R=this.buildPrompt("Generate a compelling, descriptive title for the following text that captures its main theme and engages readers.",H);return this.executeChat(z,R,H)}async extractKeywords(z,H){let R=this.buildPrompt("Extract the most important keywords and key phrases from the following text. Return only the keywords as a comma-separated list without numbering, brackets, or additional formatting.",H);return(await this.executeChat(z,R,H)).split(",").map((B)=>B.trim()).filter((B)=>B.length>0)}async extractCategories(z,H){let R=this.buildPrompt("Identify the most relevant categories or topics that best describe the following text. Return only the categories as a comma-separated list without numbering, brackets, or additional formatting.",H);return(await this.executeChat(z,R,H)).split(",").map((B)=>B.trim()).filter((B)=>B.length>0)}async run(z,H){let R=this.getApiKey(H),D=H?.model??"claude-sonnet-4-5",B=this.getAdapter(R,D),F="Process the following request and respond appropriately. If the request asks for structured data, return valid JSON.";if(H?.output){let Q=H.output.toJsonSchema(),C=M(Q);F+=`
7
+
8
+ Output Type: ${C}`}let J=this.buildPrompt(F,H),N=H?.messages?this.toMessages(H.messages):[],U={role:"user",content:`${J}
9
+
10
+ Request:
11
+ ${z}`},W=[...N,U],V=(await G({adapter:B,messages:W,stream:!1})).trim(),X;try{let Q=V.replace(/```json\n?|\n?```/g,"").trim();X=JSON.parse(Q)}catch{X=V}if(H?.output){let Q=H.output(X);if(Q instanceof P.errors)throw new Y(`Output validation failed: ${Q.summary}`)}return X}async*runStream(z,H){let R=this.getApiKey(H),D=H?.model??"claude-sonnet-4-5",B=this.getAdapter(R,D),F="Process the following request and respond appropriately.",J=this.buildPrompt("Process the following request and respond appropriately.",H),N=H?.messages?this.toMessages(H.messages):[],U={role:"user",content:`${J}
12
+
13
+ Request:
14
+ ${z}`},W=[...N,U],Z=G({adapter:B,messages:W,stream:!0});for await(let V of Z)if(V.type==="content")yield V.content}}I=$([_.ai()],I);import{jsonSchemaToTypeString as w}from"@ooneex/validation";import{chat as E}from"@tanstack/ai";import{createGeminiChat as A}from"@tanstack/ai-gemini";import{type as l}from"arktype";class j{getApiKey(z){let H=z?.apiKey||Bun.env.GEMINI_API_KEY||"";if(!H)throw new Y("Gemini API key is required. Provide an API key through config options or set the GEMINI_API_KEY environment variable.");return H}getAdapter(z,H="gemini-2.0-flash"){return A(H,z)}buildPrompt(z,H){let R=[H?.prompt||z];if(H?.context)R.push(`Context:
15
+ ${H.context}`);if(H?.wordCount)R.push(`Target approximately ${H.wordCount} words.`);if(H?.tone)R.push(`Use a ${H.tone} tone.`);if(H?.language)R.push(`Respond in ${H.language} language.`);return R.push(`${H?.context?"Use the provided context to inform your response. ":""}Respond with only the transformed text. Do not include explanations or additional commentary.`),R.join(`
16
+ `)}toMessages(z){return z.map((H)=>({role:H.role,content:H.content}))}async executeChat(z,H,R){let D=this.getApiKey(R),B=R?.model??"gemini-2.0-flash",F=this.getAdapter(D,B),J=R?.messages?this.toMessages(R.messages):[],N={role:"user",content:`${H}
17
+
18
+ Text to process:
19
+ ${z}`},U=[...J,N];return(await E({adapter:F,messages:U,stream:!1})).trim()}async makeShorter(z,H){let R=this.buildPrompt("Condense the following text while preserving its core meaning and key information. Remove redundancies and unnecessary details.",H);return this.executeChat(z,R,H)}async makeLonger(z,H){let R=this.buildPrompt("Expand the following text by adding relevant details, examples, and explanations while maintaining coherence and the original message.",H);return this.executeChat(z,R,H)}async summarize(z,H){let R=this.buildPrompt("Provide a clear and comprehensive summary of the following text, capturing all essential points and main ideas.",H);return this.executeChat(z,R,H)}async concise(z,H){let R=this.buildPrompt("Rewrite the following text in the most concise form possible without losing essential meaning.",H);return this.executeChat(z,R,H)}async paragraph(z,H){let R=this.buildPrompt("Transform the following text into well-structured paragraph format with clear topic sentences and logical flow.",H);return this.executeChat(z,R,H)}async bulletPoints(z,H){let R=this.buildPrompt("Convert the following text into a clear, organized list of bullet points highlighting the key information.",H);return this.executeChat(z,R,H)}async rephrase(z,H){let R=this.buildPrompt("Rephrase the following text using different words and sentence structures while preserving the original meaning.",H);return this.executeChat(z,R,H)}async simplify(z,H){let R=this.buildPrompt("Simplify the following text by using plain language, shorter sentences, and avoiding jargon. Make it accessible to a general audience.",H);return this.executeChat(z,R,H)}async changeTone(z,H,R){let D=this.buildPrompt(`Rewrite the following text in a ${H} tone while maintaining clarity.`,R);return this.executeChat(z,D,R)}async proofread(z,H){let R=this.buildPrompt("Proofread and correct the following text for grammar, spelling, punctuation, and clarity issues. Return the corrected version.",H);return this.executeChat(z,R,H)}async translate(z,H){let R=H?.language??"en",D=this.buildPrompt(`Translate the following text accurately into ${R}, preserving the original meaning, tone, and nuance.`,H);return this.executeChat(z,D,H)}async explain(z,H){let R=this.buildPrompt("Provide a clear explanation of the following text, breaking down complex concepts and clarifying the meaning.",H);return this.executeChat(z,R,H)}async expandIdeas(z,H){let R=this.buildPrompt("Expand on the ideas presented in the following text by exploring related concepts, implications, and additional perspectives.",H);return this.executeChat(z,R,H)}async fixGrammar(z,H){let R=this.buildPrompt("Fix all grammatical errors in the following text, including subject-verb agreement, tense consistency, and sentence structure.",H);return this.executeChat(z,R,H)}async generateTitle(z,H){let R=this.buildPrompt("Generate a compelling, descriptive title for the following text that captures its main theme and engages readers.",H);return this.executeChat(z,R,H)}async extractKeywords(z,H){let R=this.buildPrompt("Extract the most important keywords and key phrases from the following text. Return only the keywords as a comma-separated list without numbering, brackets, or additional formatting.",H);return(await this.executeChat(z,R,H)).split(",").map((B)=>B.trim()).filter((B)=>B.length>0)}async extractCategories(z,H){let R=this.buildPrompt("Identify the most relevant categories or topics that best describe the following text. Return only the categories as a comma-separated list without numbering, brackets, or additional formatting.",H);return(await this.executeChat(z,R,H)).split(",").map((B)=>B.trim()).filter((B)=>B.length>0)}async run(z,H){let R=this.getApiKey(H),D=H?.model??"gemini-2.5-pro",B=this.getAdapter(R,D),F="Process the following request and respond appropriately. If the request asks for structured data, return valid JSON.";if(H?.output){let Q=H.output.toJsonSchema(),C=w(Q);F+=`
20
+
21
+ Output Type: ${C}`}let J=this.buildPrompt(F,H),N=H?.messages?this.toMessages(H.messages):[],U={role:"user",content:`${J}
22
+
23
+ Request:
24
+ ${z}`},W=[...N,U],V=(await E({adapter:B,messages:W,stream:!1})).trim(),X;try{let Q=V.replace(/```json\n?|\n?```/g,"").trim();X=JSON.parse(Q)}catch{X=V}if(H?.output){let Q=H.output(X);if(Q instanceof l.errors)throw new Y(`Output validation failed: ${Q.summary}`)}return X}async*runStream(z,H){let R=this.getApiKey(H),D=H?.model??"gemini-2.5-pro",B=this.getAdapter(R,D),F="Process the following request and respond appropriately.",J=this.buildPrompt("Process the following request and respond appropriately.",H),N=H?.messages?this.toMessages(H.messages):[],U={role:"user",content:`${J}
25
+
26
+ Request:
27
+ ${z}`},W=[...N,U],Z=E({adapter:B,messages:W,stream:!0});for await(let V of Z)if(V.type==="content")yield V.content}}j=$([_.ai()],j);import{jsonSchemaToTypeString as k}from"@ooneex/validation";import{chat as x}from"@tanstack/ai";import{createOllamaChat as h}from"@tanstack/ai-ollama";import{type as y}from"arktype";class q{getHost(z){return z?.host||Bun.env.OLLAMA_HOST||"http://localhost:11434"}getAdapter(z="llama3",H){return h(z,H)}buildPrompt(z,H){let R=[H?.prompt||z];if(H?.context)R.push(`Context:
28
+ ${H.context}`);if(H?.wordCount)R.push(`Target approximately ${H.wordCount} words.`);if(H?.tone)R.push(`Use a ${H.tone} tone.`);if(H?.language)R.push(`Respond in ${H.language} language.`);return R.push(`${H?.context?"Use the provided context to inform your response. ":""}Respond with only the transformed text. Do not include explanations or additional commentary.`),R.join(`
29
+ `)}toMessages(z){return z.map((H)=>({role:H.role,content:H.content}))}async executeChat(z,H,R){let D=this.getHost(R),B=R?.model??"llama3",F=this.getAdapter(B,D),J=R?.messages?this.toMessages(R.messages):[],N={role:"user",content:`${H}
30
+
31
+ Text to process:
32
+ ${z}`},U=[...J,N];return(await x({adapter:F,messages:U,stream:!1})).trim()}async makeShorter(z,H){let R=this.buildPrompt("Condense the following text while preserving its core meaning and key information. Remove redundancies and unnecessary details.",H);return this.executeChat(z,R,H)}async makeLonger(z,H){let R=this.buildPrompt("Expand the following text by adding relevant details, examples, and explanations while maintaining coherence and the original message.",H);return this.executeChat(z,R,H)}async summarize(z,H){let R=this.buildPrompt("Provide a clear and comprehensive summary of the following text, capturing all essential points and main ideas.",H);return this.executeChat(z,R,H)}async concise(z,H){let R=this.buildPrompt("Rewrite the following text in the most concise form possible without losing essential meaning.",H);return this.executeChat(z,R,H)}async paragraph(z,H){let R=this.buildPrompt("Transform the following text into well-structured paragraph format with clear topic sentences and logical flow.",H);return this.executeChat(z,R,H)}async bulletPoints(z,H){let R=this.buildPrompt("Convert the following text into a clear, organized list of bullet points highlighting the key information.",H);return this.executeChat(z,R,H)}async rephrase(z,H){let R=this.buildPrompt("Rephrase the following text using different words and sentence structures while preserving the original meaning.",H);return this.executeChat(z,R,H)}async simplify(z,H){let R=this.buildPrompt("Simplify the following text by using plain language, shorter sentences, and avoiding jargon. Make it accessible to a general audience.",H);return this.executeChat(z,R,H)}async changeTone(z,H,R){let D=this.buildPrompt(`Rewrite the following text in a ${H} tone while maintaining clarity.`,R);return this.executeChat(z,D,R)}async proofread(z,H){let R=this.buildPrompt("Proofread and correct the following text for grammar, spelling, punctuation, and clarity issues. Return the corrected version.",H);return this.executeChat(z,R,H)}async translate(z,H){let R=H?.language??"en",D=this.buildPrompt(`Translate the following text accurately into ${R}, preserving the original meaning, tone, and nuance.`,H);return this.executeChat(z,D,H)}async explain(z,H){let R=this.buildPrompt("Provide a clear explanation of the following text, breaking down complex concepts and clarifying the meaning.",H);return this.executeChat(z,R,H)}async expandIdeas(z,H){let R=this.buildPrompt("Expand on the ideas presented in the following text by exploring related concepts, implications, and additional perspectives.",H);return this.executeChat(z,R,H)}async fixGrammar(z,H){let R=this.buildPrompt("Fix all grammatical errors in the following text, including subject-verb agreement, tense consistency, and sentence structure.",H);return this.executeChat(z,R,H)}async generateTitle(z,H){let R=this.buildPrompt("Generate a compelling, descriptive title for the following text that captures its main theme and engages readers.",H);return this.executeChat(z,R,H)}async extractKeywords(z,H){let R=this.buildPrompt("Extract the most important keywords and key phrases from the following text. Return only the keywords as a comma-separated list without numbering, brackets, or additional formatting.",H);return(await this.executeChat(z,R,H)).split(",").map((B)=>B.trim()).filter((B)=>B.length>0)}async extractCategories(z,H){let R=this.buildPrompt("Identify the most relevant categories or topics that best describe the following text. Return only the categories as a comma-separated list without numbering, brackets, or additional formatting.",H);return(await this.executeChat(z,R,H)).split(",").map((B)=>B.trim()).filter((B)=>B.length>0)}async run(z,H){let R=this.getHost(H),D=H?.model??"llama3",B=this.getAdapter(D,R),F="Process the following request and respond appropriately. If the request asks for structured data, return valid JSON.";if(H?.output){let Q=H.output.toJsonSchema(),C=k(Q);F+=`
33
+
34
+ Output Type: ${C}`}let J=this.buildPrompt(F,H),N=H?.messages?this.toMessages(H.messages):[],U={role:"user",content:`${J}
35
+
36
+ Request:
37
+ ${z}`},W=[...N,U],V=(await x({adapter:B,messages:W,stream:!1})).trim(),X;try{let Q=V.replace(/```json\n?|\n?```/g,"").trim();X=JSON.parse(Q)}catch{X=V}if(H?.output){let Q=H.output(X);if(Q instanceof y.errors)throw new Y(`Output validation failed: ${Q.summary}`)}return X}async*runStream(z,H){let R=this.getHost(H),D=H?.model??"llama3",B=this.getAdapter(D,R),F="Process the following request and respond appropriately.",J=this.buildPrompt("Process the following request and respond appropriately.",H),N=H?.messages?this.toMessages(H.messages):[],U={role:"user",content:`${J}
38
+
39
+ Request:
40
+ ${z}`},W=[...N,U],Z=x({adapter:B,messages:W,stream:!0});for await(let V of Z)if(V.type==="content")yield V.content}}q=$([_.ai()],q);import{jsonSchemaToTypeString as u}from"@ooneex/validation";import{chat as O}from"@tanstack/ai";import{createOpenaiChat as d}from"@tanstack/ai-openai";import{type as m}from"arktype";class L{getApiKey(z){let H=z?.apiKey||Bun.env.OPENAI_API_KEY||"";if(!H)throw new Y("OpenAI API key is required. Provide an API key through config options or set the OPENAI_API_KEY environment variable.");return H}getAdapter(z,H="gpt-4o-mini"){return d(H,z)}buildPrompt(z,H){let R=[H?.prompt||z];if(H?.context)R.push(`Context:
41
+ ${H.context}`);if(H?.wordCount)R.push(`Target approximately ${H.wordCount} words.`);if(H?.tone)R.push(`Use a ${H.tone} tone.`);if(H?.language)R.push(`Respond in ${H.language} language.`);return R.push(`${H?.context?"Use the provided context to inform your response. ":""}Respond with only the transformed text. Do not include explanations or additional commentary.`),R.join(`
42
+ `)}toMessages(z){return z.map((H)=>({role:H.role,content:H.content}))}async executeChat(z,H,R){let D=this.getApiKey(R),B=R?.model??"gpt-4o-mini",F=this.getAdapter(D,B),J=R?.messages?this.toMessages(R.messages):[],N={role:"user",content:`${H}
43
+
44
+ Text to process:
45
+ ${z}`},U=[...J,N];return(await O({adapter:F,messages:U,stream:!1})).trim()}async makeShorter(z,H){let R=this.buildPrompt("Condense the following text while preserving its core meaning and key information. Remove redundancies and unnecessary details.",H);return this.executeChat(z,R,H)}async makeLonger(z,H){let R=this.buildPrompt("Expand the following text by adding relevant details, examples, and explanations while maintaining coherence and the original message.",H);return this.executeChat(z,R,H)}async summarize(z,H){let R=this.buildPrompt("Provide a clear and comprehensive summary of the following text, capturing all essential points and main ideas.",H);return this.executeChat(z,R,H)}async concise(z,H){let R=this.buildPrompt("Rewrite the following text in the most concise form possible without losing essential meaning.",H);return this.executeChat(z,R,H)}async paragraph(z,H){let R=this.buildPrompt("Transform the following text into well-structured paragraph format with clear topic sentences and logical flow.",H);return this.executeChat(z,R,H)}async bulletPoints(z,H){let R=this.buildPrompt("Convert the following text into a clear, organized list of bullet points highlighting the key information.",H);return this.executeChat(z,R,H)}async rephrase(z,H){let R=this.buildPrompt("Rephrase the following text using different words and sentence structures while preserving the original meaning.",H);return this.executeChat(z,R,H)}async simplify(z,H){let R=this.buildPrompt("Simplify the following text by using plain language, shorter sentences, and avoiding jargon. Make it accessible to a general audience.",H);return this.executeChat(z,R,H)}async changeTone(z,H,R){let D=this.buildPrompt(`Rewrite the following text in a ${H} tone while maintaining clarity.`,R);return this.executeChat(z,D,R)}async proofread(z,H){let R=this.buildPrompt("Proofread and correct the following text for grammar, spelling, punctuation, and clarity issues. Return the corrected version.",H);return this.executeChat(z,R,H)}async translate(z,H){let R=H?.language??"en",D=this.buildPrompt(`Translate the following text accurately into ${R}, preserving the original meaning, tone, and nuance.`,H);return this.executeChat(z,D,H)}async explain(z,H){let R=this.buildPrompt("Provide a clear explanation of the following text, breaking down complex concepts and clarifying the meaning.",H);return this.executeChat(z,R,H)}async expandIdeas(z,H){let R=this.buildPrompt("Expand on the ideas presented in the following text by exploring related concepts, implications, and additional perspectives.",H);return this.executeChat(z,R,H)}async fixGrammar(z,H){let R=this.buildPrompt("Fix all grammatical errors in the following text, including subject-verb agreement, tense consistency, and sentence structure.",H);return this.executeChat(z,R,H)}async generateTitle(z,H){let R=this.buildPrompt("Generate a compelling, descriptive title for the following text that captures its main theme and engages readers.",H);return this.executeChat(z,R,H)}async extractKeywords(z,H){let R=this.buildPrompt("Extract the most important keywords and key phrases from the following text. Return only the keywords as a comma-separated list without numbering, brackets, or additional formatting.",H);return(await this.executeChat(z,R,H)).split(",").map((B)=>B.trim()).filter((B)=>B.length>0)}async extractCategories(z,H){let R=this.buildPrompt("Identify the most relevant categories or topics that best describe the following text. Return only the categories as a comma-separated list without numbering, brackets, or additional formatting.",H);return(await this.executeChat(z,R,H)).split(",").map((B)=>B.trim()).filter((B)=>B.length>0)}async run(z,H){let R=this.getApiKey(H),D=H?.model??"gpt-4o",B=this.getAdapter(R,D),F="Process the following request and respond appropriately. If the request asks for structured data, return valid JSON.";if(H?.output){let Q=H.output.toJsonSchema(),C=u(Q);F+=`
46
+
47
+ Output Type: ${C}`}let J=this.buildPrompt(F,H),N=H?.messages?this.toMessages(H.messages):[],U={role:"user",content:`${J}
48
+
49
+ Request:
50
+ ${z}`},W=[...N,U],V=(await O({adapter:B,messages:W,stream:!1})).trim(),X;try{let Q=V.replace(/```json\n?|\n?```/g,"").trim();X=JSON.parse(Q)}catch{X=V}if(H?.output){let Q=H.output(X);if(Q instanceof m.errors)throw new Y(`Output validation failed: ${Q.summary}`)}return X}async*runStream(z,H){let R=this.getApiKey(H),D=H?.model??"gpt-4o",B=this.getAdapter(R,D),F="Process the following request and respond appropriately.",J=this.buildPrompt("Process the following request and respond appropriately.",H),N=H?.messages?this.toMessages(H.messages):[],U={role:"user",content:`${J}
51
+
52
+ Request:
53
+ ${z}`},W=[...N,U],Z=O({adapter:B,messages:W,stream:!0});for await(let V of Z)if(V.type==="content")yield V.content}}L=$([_.ai()],L);export{_ as decorator,L as OpenAi,q as OllamaAi,j as GeminiAi,I as AnthropicAi,Y as AiException};
54
+
55
+ //# debugId=66CB2B945DCDCB8864756E2164756E21
@@ -0,0 +1,15 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["src/AiException.ts", "src/AnthropicAi.ts", "src/decorators.ts", "src/GeminiAi.ts", "src/OllamaAi.ts", "src/OpenAi.ts"],
4
+ "sourcesContent": [
5
+ "import { Exception } from \"@ooneex/exception\";\nimport { HttpStatus } from \"@ooneex/http-status\";\n\nexport class AiException extends Exception {\n constructor(message: string, data: Record<string, unknown> = {}) {\n super(message, {\n status: HttpStatus.Code.InternalServerError,\n data,\n });\n this.name = \"AiException\";\n }\n}\n",
6
+ "import { jsonSchemaToTypeString } from \"@ooneex/validation\";\nimport { chat, type ModelMessage } from \"@tanstack/ai\";\nimport { createAnthropicChat } from \"@tanstack/ai-anthropic\";\nimport { type } from \"arktype\";\nimport { AiException } from \"./AiException\";\nimport { decorator } from \"./decorators\";\nimport type { AiMessageType, AiToneType, AnthropicConfigType, AnthropicModelType, IAiChat } from \"./types\";\n\n@decorator.ai()\nexport class AnthropicAi implements IAiChat<AnthropicConfigType> {\n private getApiKey(config?: AnthropicConfigType): string {\n const apiKey = config?.apiKey || Bun.env.ANTHROPIC_API_KEY || \"\";\n\n if (!apiKey) {\n throw new AiException(\n \"Anthropic API key is required. Provide an API key through config options or set the ANTHROPIC_API_KEY environment variable.\",\n );\n }\n\n return apiKey;\n }\n\n private getAdapter(apiKey: string, model: AnthropicModelType) {\n return createAnthropicChat(model, apiKey);\n }\n\n private buildPrompt(instruction: string, config?: AnthropicConfigType): string {\n const parts: string[] = [config?.prompt || instruction];\n\n if (config?.context) {\n parts.push(`Context:\\n${config.context}`);\n }\n\n if (config?.wordCount) {\n parts.push(`Target approximately ${config.wordCount} words.`);\n }\n\n if (config?.tone) {\n parts.push(`Use a ${config.tone} tone.`);\n }\n\n if (config?.language) {\n parts.push(`Respond in ${config.language} language.`);\n }\n\n parts.push(\n `${config?.context ? \"Use the provided context to inform your response. \" : \"\"}Respond with only the transformed text. Do not include explanations or additional commentary.`,\n );\n\n return parts.join(\"\\n\");\n }\n\n private toMessages(messages: AiMessageType[]): ModelMessage[] {\n return messages.map((msg) => ({ role: msg.role as \"user\" | \"assistant\" | \"tool\", content: msg.content }));\n }\n\n private async executeChat(content: string, systemPrompt: string, config?: AnthropicConfigType): Promise<string> {\n const apiKey = this.getApiKey(config);\n const model = (config?.model ?? (\"claude-sonnet-4-5\" as const)) as AnthropicModelType;\n const adapter = this.getAdapter(apiKey, model);\n\n const baseMessages: ModelMessage[] = config?.messages ? this.toMessages(config.messages) : [];\n const userMessage: ModelMessage = { role: \"user\", content: `${systemPrompt}\\n\\nText to process:\\n${content}` };\n\n const messages = [...baseMessages, userMessage];\n const result = await chat({\n adapter,\n messages: messages as unknown as NonNullable<\n Parameters<typeof chat<typeof adapter, undefined, false>>[0][\"messages\"]\n >,\n stream: false,\n });\n\n return result.trim();\n }\n\n public async makeShorter(content: string, config?: Omit<AnthropicConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Condense the following text while preserving its core meaning and key information. Remove redundancies and unnecessary details.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async makeLonger(content: string, config?: Omit<AnthropicConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Expand the following text by adding relevant details, examples, and explanations while maintaining coherence and the original message.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async summarize(content: string, config?: Omit<AnthropicConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Provide a clear and comprehensive summary of the following text, capturing all essential points and main ideas.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async concise(content: string, config?: Omit<AnthropicConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Rewrite the following text in the most concise form possible without losing essential meaning.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async paragraph(content: string, config?: Omit<AnthropicConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Transform the following text into well-structured paragraph format with clear topic sentences and logical flow.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async bulletPoints(content: string, config?: Omit<AnthropicConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Convert the following text into a clear, organized list of bullet points highlighting the key information.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async rephrase(content: string, config?: Omit<AnthropicConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Rephrase the following text using different words and sentence structures while preserving the original meaning.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async simplify(content: string, config?: Omit<AnthropicConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Simplify the following text by using plain language, shorter sentences, and avoiding jargon. Make it accessible to a general audience.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async changeTone(\n content: string,\n tone: AiToneType,\n config?: Omit<AnthropicConfigType, \"tone\" | \"output\">,\n ): Promise<string> {\n const prompt = this.buildPrompt(`Rewrite the following text in a ${tone} tone while maintaining clarity.`, config);\n return this.executeChat(content, prompt, config);\n }\n\n public async proofread(content: string, config?: Omit<AnthropicConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Proofread and correct the following text for grammar, spelling, punctuation, and clarity issues. Return the corrected version.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async translate(content: string, config?: Omit<AnthropicConfigType, \"output\">): Promise<string> {\n const targetLanguage = config?.language ?? \"en\";\n const prompt = this.buildPrompt(\n `Translate the following text accurately into ${targetLanguage}, preserving the original meaning, tone, and nuance.`,\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async explain(content: string, config?: Omit<AnthropicConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Provide a clear explanation of the following text, breaking down complex concepts and clarifying the meaning.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async expandIdeas(content: string, config?: Omit<AnthropicConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Expand on the ideas presented in the following text by exploring related concepts, implications, and additional perspectives.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async fixGrammar(content: string, config?: Omit<AnthropicConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Fix all grammatical errors in the following text, including subject-verb agreement, tense consistency, and sentence structure.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async generateTitle(content: string, config?: Omit<AnthropicConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Generate a compelling, descriptive title for the following text that captures its main theme and engages readers.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async extractKeywords(content: string, config?: Omit<AnthropicConfigType, \"output\">): Promise<string[]> {\n const prompt = this.buildPrompt(\n \"Extract the most important keywords and key phrases from the following text. Return only the keywords as a comma-separated list without numbering, brackets, or additional formatting.\",\n config,\n );\n\n const result = await this.executeChat(content, prompt, config);\n\n return result\n .split(\",\")\n .map((keyword) => keyword.trim())\n .filter((keyword) => keyword.length > 0);\n }\n\n public async extractCategories(content: string, config?: Omit<AnthropicConfigType, \"output\">): Promise<string[]> {\n const prompt = this.buildPrompt(\n \"Identify the most relevant categories or topics that best describe the following text. Return only the categories as a comma-separated list without numbering, brackets, or additional formatting.\",\n config,\n );\n\n const result = await this.executeChat(content, prompt, config);\n\n return result\n .split(\",\")\n .map((category) => category.trim())\n .filter((category) => category.length > 0);\n }\n\n public async run<T>(prompt: string, config?: Omit<AnthropicConfigType, \"prompt\">): Promise<T> {\n const apiKey = this.getApiKey(config);\n const model = (config?.model ?? (\"claude-sonnet-4-5\" as const)) as AnthropicModelType;\n const adapter = this.getAdapter(apiKey, model);\n\n let defaultPrompt =\n \"Process the following request and respond appropriately. If the request asks for structured data, return valid JSON.\";\n\n if (config?.output) {\n const schema = config.output.toJsonSchema();\n const outputType = jsonSchemaToTypeString(schema);\n defaultPrompt += `\\n\\nOutput Type: ${outputType}`;\n }\n\n const systemPrompt = this.buildPrompt(defaultPrompt, config);\n\n const baseMessages = config?.messages ? this.toMessages(config.messages) : [];\n const userMessage: ModelMessage = { role: \"user\", content: `${systemPrompt}\\n\\nRequest:\\n${prompt}` };\n\n const messages = [...baseMessages, userMessage];\n const result = await chat({\n adapter,\n messages: messages as unknown as NonNullable<\n Parameters<typeof chat<typeof adapter, undefined, false>>[0][\"messages\"]\n >,\n stream: false,\n });\n\n const trimmed = result.trim();\n\n let parsed: T;\n try {\n const cleaned = trimmed.replace(/```json\\n?|\\n?```/g, \"\").trim();\n parsed = JSON.parse(cleaned) as T;\n } catch {\n parsed = trimmed as T;\n }\n\n if (config?.output) {\n const validation = config.output(parsed);\n if (validation instanceof type.errors) {\n throw new AiException(`Output validation failed: ${validation.summary}`);\n }\n }\n\n return parsed;\n }\n\n /**\n * Streams the AI response chunk by chunk as an async generator.\n *\n * @example\n * ```ts\n * const adapter = new AnthropicChatAdapter();\n *\n * // Stream the response chunk by chunk\n * for await (const chunk of adapter.runStream(\"Explain quantum computing\")) {\n * process.stdout.write(chunk); // Print each chunk as it arrives\n * }\n * ```\n */\n public async *runStream(\n prompt: string,\n config?: Omit<AnthropicConfigType, \"prompt\" | \"output\">,\n ): AsyncGenerator<string, void, unknown> {\n const apiKey = this.getApiKey(config);\n const model = (config?.model ?? (\"claude-sonnet-4-5\" as const)) as AnthropicModelType;\n const adapter = this.getAdapter(apiKey, model);\n\n const defaultPrompt = \"Process the following request and respond appropriately.\";\n const systemPrompt = this.buildPrompt(defaultPrompt, config);\n\n const baseMessages: ModelMessage[] = config?.messages ? this.toMessages(config.messages) : [];\n const userMessage: ModelMessage = { role: \"user\", content: `${systemPrompt}\\n\\nRequest:\\n${prompt}` };\n\n const messages = [...baseMessages, userMessage];\n const stream = chat({\n adapter,\n messages: messages as unknown as NonNullable<\n Parameters<typeof chat<typeof adapter, undefined, true>>[0][\"messages\"]\n >,\n stream: true,\n });\n\n for await (const chunk of stream) {\n if (chunk.type === \"content\") {\n yield chunk.content;\n }\n }\n }\n}\n",
7
+ "import { container, EContainerScope } from \"@ooneex/container\";\nimport type { AiClassType } from \"./types\";\n\nexport const decorator = {\n ai: (scope: EContainerScope = EContainerScope.Singleton) => {\n return (target: AiClassType): void => {\n container.add(target, scope);\n };\n },\n};\n",
8
+ "import { jsonSchemaToTypeString } from \"@ooneex/validation\";\nimport { chat, type ModelMessage } from \"@tanstack/ai\";\nimport { createGeminiChat } from \"@tanstack/ai-gemini\";\nimport { type } from \"arktype\";\nimport { AiException } from \"./AiException\";\nimport { decorator } from \"./decorators\";\nimport type { AiMessageType, AiToneType, GeminiConfigType, GeminiModelType, IAiChat } from \"./types\";\n\n@decorator.ai()\nexport class GeminiAi implements IAiChat<GeminiConfigType> {\n private getApiKey(config?: GeminiConfigType): string {\n const apiKey = config?.apiKey || Bun.env.GEMINI_API_KEY || \"\";\n\n if (!apiKey) {\n throw new AiException(\n \"Gemini API key is required. Provide an API key through config options or set the GEMINI_API_KEY environment variable.\",\n );\n }\n\n return apiKey;\n }\n\n private getAdapter(apiKey: string, model: GeminiModelType = \"gemini-2.0-flash\") {\n return createGeminiChat(model, apiKey);\n }\n\n private buildPrompt(instruction: string, config?: GeminiConfigType): string {\n const parts: string[] = [config?.prompt || instruction];\n\n if (config?.context) {\n parts.push(`Context:\\n${config.context}`);\n }\n\n if (config?.wordCount) {\n parts.push(`Target approximately ${config.wordCount} words.`);\n }\n\n if (config?.tone) {\n parts.push(`Use a ${config.tone} tone.`);\n }\n\n if (config?.language) {\n parts.push(`Respond in ${config.language} language.`);\n }\n\n parts.push(\n `${config?.context ? \"Use the provided context to inform your response. \" : \"\"}Respond with only the transformed text. Do not include explanations or additional commentary.`,\n );\n\n return parts.join(\"\\n\");\n }\n\n private toMessages(messages: AiMessageType[]): ModelMessage[] {\n return messages.map((msg) => ({ role: msg.role as \"user\" | \"assistant\" | \"tool\", content: msg.content }));\n }\n\n private async executeChat(content: string, systemPrompt: string, config?: GeminiConfigType): Promise<string> {\n const apiKey = this.getApiKey(config);\n const model = config?.model ?? \"gemini-2.0-flash\";\n const adapter = this.getAdapter(apiKey, model);\n\n const baseMessages: ModelMessage[] = config?.messages ? this.toMessages(config.messages) : [];\n const userMessage: ModelMessage = { role: \"user\", content: `${systemPrompt}\\n\\nText to process:\\n${content}` };\n\n const messages = [...baseMessages, userMessage];\n const result = await chat({\n adapter,\n messages: messages as unknown as NonNullable<\n Parameters<typeof chat<typeof adapter, undefined, false>>[0][\"messages\"]\n >,\n stream: false,\n });\n\n return result.trim();\n }\n\n public async makeShorter(content: string, config?: Omit<GeminiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Condense the following text while preserving its core meaning and key information. Remove redundancies and unnecessary details.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async makeLonger(content: string, config?: Omit<GeminiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Expand the following text by adding relevant details, examples, and explanations while maintaining coherence and the original message.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async summarize(content: string, config?: Omit<GeminiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Provide a clear and comprehensive summary of the following text, capturing all essential points and main ideas.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async concise(content: string, config?: Omit<GeminiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Rewrite the following text in the most concise form possible without losing essential meaning.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async paragraph(content: string, config?: Omit<GeminiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Transform the following text into well-structured paragraph format with clear topic sentences and logical flow.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async bulletPoints(content: string, config?: Omit<GeminiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Convert the following text into a clear, organized list of bullet points highlighting the key information.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async rephrase(content: string, config?: Omit<GeminiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Rephrase the following text using different words and sentence structures while preserving the original meaning.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async simplify(content: string, config?: Omit<GeminiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Simplify the following text by using plain language, shorter sentences, and avoiding jargon. Make it accessible to a general audience.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async changeTone(\n content: string,\n tone: AiToneType,\n config?: Omit<GeminiConfigType, \"tone\" | \"output\">,\n ): Promise<string> {\n const prompt = this.buildPrompt(`Rewrite the following text in a ${tone} tone while maintaining clarity.`, config);\n return this.executeChat(content, prompt, config);\n }\n\n public async proofread(content: string, config?: Omit<GeminiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Proofread and correct the following text for grammar, spelling, punctuation, and clarity issues. Return the corrected version.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async translate(content: string, config?: Omit<GeminiConfigType, \"output\">): Promise<string> {\n const targetLanguage = config?.language ?? \"en\";\n const prompt = this.buildPrompt(\n `Translate the following text accurately into ${targetLanguage}, preserving the original meaning, tone, and nuance.`,\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async explain(content: string, config?: Omit<GeminiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Provide a clear explanation of the following text, breaking down complex concepts and clarifying the meaning.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async expandIdeas(content: string, config?: Omit<GeminiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Expand on the ideas presented in the following text by exploring related concepts, implications, and additional perspectives.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async fixGrammar(content: string, config?: Omit<GeminiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Fix all grammatical errors in the following text, including subject-verb agreement, tense consistency, and sentence structure.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async generateTitle(content: string, config?: Omit<GeminiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Generate a compelling, descriptive title for the following text that captures its main theme and engages readers.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async extractKeywords(content: string, config?: Omit<GeminiConfigType, \"output\">): Promise<string[]> {\n const prompt = this.buildPrompt(\n \"Extract the most important keywords and key phrases from the following text. Return only the keywords as a comma-separated list without numbering, brackets, or additional formatting.\",\n config,\n );\n\n const result = await this.executeChat(content, prompt, config);\n\n return result\n .split(\",\")\n .map((keyword) => keyword.trim())\n .filter((keyword) => keyword.length > 0);\n }\n\n public async extractCategories(content: string, config?: Omit<GeminiConfigType, \"output\">): Promise<string[]> {\n const prompt = this.buildPrompt(\n \"Identify the most relevant categories or topics that best describe the following text. Return only the categories as a comma-separated list without numbering, brackets, or additional formatting.\",\n config,\n );\n\n const result = await this.executeChat(content, prompt, config);\n\n return result\n .split(\",\")\n .map((category) => category.trim())\n .filter((category) => category.length > 0);\n }\n\n public async run<T>(prompt: string, config?: Omit<GeminiConfigType, \"prompt\">): Promise<T> {\n const apiKey = this.getApiKey(config);\n const model = config?.model ?? \"gemini-2.5-pro\";\n const adapter = this.getAdapter(apiKey, model);\n\n let defaultPrompt =\n \"Process the following request and respond appropriately. If the request asks for structured data, return valid JSON.\";\n\n if (config?.output) {\n const schema = config.output.toJsonSchema();\n const outputType = jsonSchemaToTypeString(schema);\n defaultPrompt += `\\n\\nOutput Type: ${outputType}`;\n }\n\n const systemPrompt = this.buildPrompt(defaultPrompt, config);\n\n const baseMessages = config?.messages ? this.toMessages(config.messages) : [];\n const userMessage: ModelMessage = { role: \"user\", content: `${systemPrompt}\\n\\nRequest:\\n${prompt}` };\n\n const messages = [...baseMessages, userMessage];\n const result = await chat({\n adapter,\n messages: messages as unknown as NonNullable<\n Parameters<typeof chat<typeof adapter, undefined, false>>[0][\"messages\"]\n >,\n stream: false,\n });\n\n const trimmed = result.trim();\n\n let parsed: T;\n try {\n const cleaned = trimmed.replace(/```json\\n?|\\n?```/g, \"\").trim();\n parsed = JSON.parse(cleaned) as T;\n } catch {\n parsed = trimmed as T;\n }\n\n if (config?.output) {\n const validation = config.output(parsed);\n if (validation instanceof type.errors) {\n throw new AiException(`Output validation failed: ${validation.summary}`);\n }\n }\n\n return parsed;\n }\n\n /**\n * Streams the AI response chunk by chunk as an async generator.\n *\n * @example\n * ```ts\n * const adapter = new GeminiChatAdapter();\n *\n * // Stream the response chunk by chunk\n * for await (const chunk of adapter.runStream(\"Explain quantum computing\")) {\n * process.stdout.write(chunk); // Print each chunk as it arrives\n * }\n * ```\n */\n public async *runStream(\n prompt: string,\n config?: Omit<GeminiConfigType, \"prompt\" | \"output\">,\n ): AsyncGenerator<string, void, unknown> {\n const apiKey = this.getApiKey(config);\n const model = config?.model ?? \"gemini-2.5-pro\";\n const adapter = this.getAdapter(apiKey, model);\n\n const defaultPrompt = \"Process the following request and respond appropriately.\";\n const systemPrompt = this.buildPrompt(defaultPrompt, config);\n\n const baseMessages: ModelMessage[] = config?.messages ? this.toMessages(config.messages) : [];\n const userMessage: ModelMessage = { role: \"user\", content: `${systemPrompt}\\n\\nRequest:\\n${prompt}` };\n\n const messages = [...baseMessages, userMessage];\n const stream = chat({\n adapter,\n messages: messages as unknown as NonNullable<\n Parameters<typeof chat<typeof adapter, undefined, true>>[0][\"messages\"]\n >,\n stream: true,\n });\n\n for await (const chunk of stream) {\n if (chunk.type === \"content\") {\n yield chunk.content;\n }\n }\n }\n}\n",
9
+ "import { jsonSchemaToTypeString } from \"@ooneex/validation\";\nimport { chat, type ModelMessage } from \"@tanstack/ai\";\nimport { createOllamaChat } from \"@tanstack/ai-ollama\";\nimport { type } from \"arktype\";\nimport { AiException } from \"./AiException\";\nimport { decorator } from \"./decorators\";\nimport type { AiMessageType, AiToneType, IAiChat, OllamaConfigType, OllamaModelType } from \"./types\";\n\n@decorator.ai()\nexport class OllamaAi implements IAiChat<OllamaConfigType> {\n private getHost(config?: OllamaConfigType): string {\n return config?.host || Bun.env.OLLAMA_HOST || \"http://localhost:11434\";\n }\n\n private getAdapter(model: OllamaModelType = \"llama3\", host?: string) {\n return createOllamaChat(model, host);\n }\n\n private buildPrompt(instruction: string, config?: OllamaConfigType): string {\n const parts: string[] = [config?.prompt || instruction];\n\n if (config?.context) {\n parts.push(`Context:\\n${config.context}`);\n }\n\n if (config?.wordCount) {\n parts.push(`Target approximately ${config.wordCount} words.`);\n }\n\n if (config?.tone) {\n parts.push(`Use a ${config.tone} tone.`);\n }\n\n if (config?.language) {\n parts.push(`Respond in ${config.language} language.`);\n }\n\n parts.push(\n `${config?.context ? \"Use the provided context to inform your response. \" : \"\"}Respond with only the transformed text. Do not include explanations or additional commentary.`,\n );\n\n return parts.join(\"\\n\");\n }\n\n private toMessages(messages: AiMessageType[]): ModelMessage[] {\n return messages.map((msg) => ({ role: msg.role as \"user\" | \"assistant\" | \"tool\", content: msg.content }));\n }\n\n private async executeChat(content: string, systemPrompt: string, config?: OllamaConfigType): Promise<string> {\n const host = this.getHost(config);\n const model = config?.model ?? \"llama3\";\n const adapter = this.getAdapter(model, host);\n\n const baseMessages: ModelMessage[] = config?.messages ? this.toMessages(config.messages) : [];\n const userMessage: ModelMessage = { role: \"user\", content: `${systemPrompt}\\n\\nText to process:\\n${content}` };\n\n const messages = [...baseMessages, userMessage];\n const result = await chat({\n adapter,\n messages: messages as unknown as NonNullable<\n Parameters<typeof chat<typeof adapter, undefined, false>>[0][\"messages\"]\n >,\n stream: false,\n });\n\n return result.trim();\n }\n\n public async makeShorter(content: string, config?: Omit<OllamaConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Condense the following text while preserving its core meaning and key information. Remove redundancies and unnecessary details.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async makeLonger(content: string, config?: Omit<OllamaConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Expand the following text by adding relevant details, examples, and explanations while maintaining coherence and the original message.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async summarize(content: string, config?: Omit<OllamaConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Provide a clear and comprehensive summary of the following text, capturing all essential points and main ideas.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async concise(content: string, config?: Omit<OllamaConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Rewrite the following text in the most concise form possible without losing essential meaning.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async paragraph(content: string, config?: Omit<OllamaConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Transform the following text into well-structured paragraph format with clear topic sentences and logical flow.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async bulletPoints(content: string, config?: Omit<OllamaConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Convert the following text into a clear, organized list of bullet points highlighting the key information.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async rephrase(content: string, config?: Omit<OllamaConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Rephrase the following text using different words and sentence structures while preserving the original meaning.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async simplify(content: string, config?: Omit<OllamaConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Simplify the following text by using plain language, shorter sentences, and avoiding jargon. Make it accessible to a general audience.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async changeTone(\n content: string,\n tone: AiToneType,\n config?: Omit<OllamaConfigType, \"tone\" | \"output\">,\n ): Promise<string> {\n const prompt = this.buildPrompt(`Rewrite the following text in a ${tone} tone while maintaining clarity.`, config);\n return this.executeChat(content, prompt, config);\n }\n\n public async proofread(content: string, config?: Omit<OllamaConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Proofread and correct the following text for grammar, spelling, punctuation, and clarity issues. Return the corrected version.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async translate(content: string, config?: Omit<OllamaConfigType, \"output\">): Promise<string> {\n const targetLanguage = config?.language ?? \"en\";\n const prompt = this.buildPrompt(\n `Translate the following text accurately into ${targetLanguage}, preserving the original meaning, tone, and nuance.`,\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async explain(content: string, config?: Omit<OllamaConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Provide a clear explanation of the following text, breaking down complex concepts and clarifying the meaning.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async expandIdeas(content: string, config?: Omit<OllamaConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Expand on the ideas presented in the following text by exploring related concepts, implications, and additional perspectives.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async fixGrammar(content: string, config?: Omit<OllamaConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Fix all grammatical errors in the following text, including subject-verb agreement, tense consistency, and sentence structure.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async generateTitle(content: string, config?: Omit<OllamaConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Generate a compelling, descriptive title for the following text that captures its main theme and engages readers.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async extractKeywords(content: string, config?: Omit<OllamaConfigType, \"output\">): Promise<string[]> {\n const prompt = this.buildPrompt(\n \"Extract the most important keywords and key phrases from the following text. Return only the keywords as a comma-separated list without numbering, brackets, or additional formatting.\",\n config,\n );\n\n const result = await this.executeChat(content, prompt, config);\n\n return result\n .split(\",\")\n .map((keyword) => keyword.trim())\n .filter((keyword) => keyword.length > 0);\n }\n\n public async extractCategories(content: string, config?: Omit<OllamaConfigType, \"output\">): Promise<string[]> {\n const prompt = this.buildPrompt(\n \"Identify the most relevant categories or topics that best describe the following text. Return only the categories as a comma-separated list without numbering, brackets, or additional formatting.\",\n config,\n );\n\n const result = await this.executeChat(content, prompt, config);\n\n return result\n .split(\",\")\n .map((category) => category.trim())\n .filter((category) => category.length > 0);\n }\n\n public async run<T>(prompt: string, config?: Omit<OllamaConfigType, \"prompt\">): Promise<T> {\n const host = this.getHost(config);\n const model = config?.model ?? \"llama3\";\n const adapter = this.getAdapter(model, host);\n\n let defaultPrompt =\n \"Process the following request and respond appropriately. If the request asks for structured data, return valid JSON.\";\n\n if (config?.output) {\n const schema = config.output.toJsonSchema();\n const outputType = jsonSchemaToTypeString(schema);\n defaultPrompt += `\\n\\nOutput Type: ${outputType}`;\n }\n\n const systemPrompt = this.buildPrompt(defaultPrompt, config);\n\n const baseMessages = config?.messages ? this.toMessages(config.messages) : [];\n const userMessage: ModelMessage = { role: \"user\", content: `${systemPrompt}\\n\\nRequest:\\n${prompt}` };\n\n const messages = [...baseMessages, userMessage];\n const result = await chat({\n adapter,\n messages: messages as unknown as NonNullable<\n Parameters<typeof chat<typeof adapter, undefined, false>>[0][\"messages\"]\n >,\n stream: false,\n });\n\n const trimmed = result.trim();\n\n let parsed: T;\n try {\n const cleaned = trimmed.replace(/```json\\n?|\\n?```/g, \"\").trim();\n parsed = JSON.parse(cleaned) as T;\n } catch {\n parsed = trimmed as T;\n }\n\n if (config?.output) {\n const validation = config.output(parsed);\n if (validation instanceof type.errors) {\n throw new AiException(`Output validation failed: ${validation.summary}`);\n }\n }\n\n return parsed;\n }\n\n /**\n * Streams the AI response chunk by chunk as an async generator.\n *\n * @example\n * ```ts\n * const adapter = new OllamaChatAdapter();\n *\n * // Stream the response chunk by chunk\n * for await (const chunk of adapter.runStream(\"Explain quantum computing\")) {\n * process.stdout.write(chunk); // Print each chunk as it arrives\n * }\n * ```\n */\n public async *runStream(\n prompt: string,\n config?: Omit<OllamaConfigType, \"prompt\" | \"output\">,\n ): AsyncGenerator<string, void, unknown> {\n const host = this.getHost(config);\n const model = config?.model ?? \"llama3\";\n const adapter = this.getAdapter(model, host);\n\n const defaultPrompt = \"Process the following request and respond appropriately.\";\n const systemPrompt = this.buildPrompt(defaultPrompt, config);\n\n const baseMessages: ModelMessage[] = config?.messages ? this.toMessages(config.messages) : [];\n const userMessage: ModelMessage = { role: \"user\", content: `${systemPrompt}\\n\\nRequest:\\n${prompt}` };\n\n const messages = [...baseMessages, userMessage];\n const stream = chat({\n adapter,\n messages: messages as unknown as NonNullable<\n Parameters<typeof chat<typeof adapter, undefined, true>>[0][\"messages\"]\n >,\n stream: true,\n });\n\n for await (const chunk of stream) {\n if (chunk.type === \"content\") {\n yield chunk.content;\n }\n }\n }\n}\n",
10
+ "import { jsonSchemaToTypeString } from \"@ooneex/validation\";\nimport { chat, type ModelMessage } from \"@tanstack/ai\";\nimport { createOpenaiChat } from \"@tanstack/ai-openai\";\nimport { type } from \"arktype\";\nimport { AiException } from \"./AiException\";\nimport { decorator } from \"./decorators\";\nimport type { AiMessageType, AiToneType, IAiChat, OpenAiConfigType, OpenAiModelType } from \"./types\";\n\n@decorator.ai()\nexport class OpenAi implements IAiChat<OpenAiConfigType> {\n private getApiKey(config?: OpenAiConfigType): string {\n const apiKey = config?.apiKey || Bun.env.OPENAI_API_KEY || \"\";\n\n if (!apiKey) {\n throw new AiException(\n \"OpenAI API key is required. Provide an API key through config options or set the OPENAI_API_KEY environment variable.\",\n );\n }\n\n return apiKey;\n }\n\n private getAdapter(apiKey: string, model: OpenAiModelType = \"gpt-4o-mini\") {\n return createOpenaiChat(model, apiKey);\n }\n\n private buildPrompt(instruction: string, config?: OpenAiConfigType): string {\n const parts: string[] = [config?.prompt || instruction];\n\n if (config?.context) {\n parts.push(`Context:\\n${config.context}`);\n }\n\n if (config?.wordCount) {\n parts.push(`Target approximately ${config.wordCount} words.`);\n }\n\n if (config?.tone) {\n parts.push(`Use a ${config.tone} tone.`);\n }\n\n if (config?.language) {\n parts.push(`Respond in ${config.language} language.`);\n }\n\n parts.push(\n `${config?.context ? \"Use the provided context to inform your response. \" : \"\"}Respond with only the transformed text. Do not include explanations or additional commentary.`,\n );\n\n return parts.join(\"\\n\");\n }\n\n private toMessages(messages: AiMessageType[]): ModelMessage[] {\n return messages.map((msg) => ({ role: msg.role as \"user\" | \"assistant\" | \"tool\", content: msg.content }));\n }\n\n private async executeChat(content: string, systemPrompt: string, config?: OpenAiConfigType): Promise<string> {\n const apiKey = this.getApiKey(config);\n const model = config?.model ?? \"gpt-4o-mini\";\n const adapter = this.getAdapter(apiKey, model);\n\n const baseMessages: ModelMessage[] = config?.messages ? this.toMessages(config.messages) : [];\n const userMessage: ModelMessage = { role: \"user\", content: `${systemPrompt}\\n\\nText to process:\\n${content}` };\n\n const messages = [...baseMessages, userMessage];\n const result = await chat({\n adapter,\n messages: messages as unknown as NonNullable<\n Parameters<typeof chat<typeof adapter, undefined, false>>[0][\"messages\"]\n >,\n stream: false,\n });\n\n return result.trim();\n }\n\n public async makeShorter(content: string, config?: Omit<OpenAiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Condense the following text while preserving its core meaning and key information. Remove redundancies and unnecessary details.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async makeLonger(content: string, config?: Omit<OpenAiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Expand the following text by adding relevant details, examples, and explanations while maintaining coherence and the original message.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async summarize(content: string, config?: Omit<OpenAiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Provide a clear and comprehensive summary of the following text, capturing all essential points and main ideas.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async concise(content: string, config?: Omit<OpenAiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Rewrite the following text in the most concise form possible without losing essential meaning.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async paragraph(content: string, config?: Omit<OpenAiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Transform the following text into well-structured paragraph format with clear topic sentences and logical flow.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async bulletPoints(content: string, config?: Omit<OpenAiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Convert the following text into a clear, organized list of bullet points highlighting the key information.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async rephrase(content: string, config?: Omit<OpenAiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Rephrase the following text using different words and sentence structures while preserving the original meaning.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async simplify(content: string, config?: Omit<OpenAiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Simplify the following text by using plain language, shorter sentences, and avoiding jargon. Make it accessible to a general audience.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async changeTone(\n content: string,\n tone: AiToneType,\n config?: Omit<OpenAiConfigType, \"tone\" | \"output\">,\n ): Promise<string> {\n const prompt = this.buildPrompt(`Rewrite the following text in a ${tone} tone while maintaining clarity.`, config);\n return this.executeChat(content, prompt, config);\n }\n\n public async proofread(content: string, config?: Omit<OpenAiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Proofread and correct the following text for grammar, spelling, punctuation, and clarity issues. Return the corrected version.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async translate(content: string, config?: Omit<OpenAiConfigType, \"output\">): Promise<string> {\n const targetLanguage = config?.language ?? \"en\";\n const prompt = this.buildPrompt(\n `Translate the following text accurately into ${targetLanguage}, preserving the original meaning, tone, and nuance.`,\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async explain(content: string, config?: Omit<OpenAiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Provide a clear explanation of the following text, breaking down complex concepts and clarifying the meaning.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async expandIdeas(content: string, config?: Omit<OpenAiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Expand on the ideas presented in the following text by exploring related concepts, implications, and additional perspectives.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async fixGrammar(content: string, config?: Omit<OpenAiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Fix all grammatical errors in the following text, including subject-verb agreement, tense consistency, and sentence structure.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async generateTitle(content: string, config?: Omit<OpenAiConfigType, \"output\">): Promise<string> {\n const prompt = this.buildPrompt(\n \"Generate a compelling, descriptive title for the following text that captures its main theme and engages readers.\",\n config,\n );\n return this.executeChat(content, prompt, config);\n }\n\n public async extractKeywords(content: string, config?: Omit<OpenAiConfigType, \"output\">): Promise<string[]> {\n const prompt = this.buildPrompt(\n \"Extract the most important keywords and key phrases from the following text. Return only the keywords as a comma-separated list without numbering, brackets, or additional formatting.\",\n config,\n );\n\n const result = await this.executeChat(content, prompt, config);\n\n return result\n .split(\",\")\n .map((keyword) => keyword.trim())\n .filter((keyword) => keyword.length > 0);\n }\n\n public async extractCategories(content: string, config?: Omit<OpenAiConfigType, \"output\">): Promise<string[]> {\n const prompt = this.buildPrompt(\n \"Identify the most relevant categories or topics that best describe the following text. Return only the categories as a comma-separated list without numbering, brackets, or additional formatting.\",\n config,\n );\n\n const result = await this.executeChat(content, prompt, config);\n\n return result\n .split(\",\")\n .map((category) => category.trim())\n .filter((category) => category.length > 0);\n }\n\n public async run<T>(prompt: string, config?: Omit<OpenAiConfigType, \"prompt\">): Promise<T> {\n const apiKey = this.getApiKey(config);\n const model = config?.model ?? \"gpt-4o\";\n const adapter = this.getAdapter(apiKey, model);\n\n let defaultPrompt =\n \"Process the following request and respond appropriately. If the request asks for structured data, return valid JSON.\";\n\n if (config?.output) {\n const schema = config.output.toJsonSchema();\n const outputType = jsonSchemaToTypeString(schema);\n defaultPrompt += `\\n\\nOutput Type: ${outputType}`;\n }\n\n const systemPrompt = this.buildPrompt(defaultPrompt, config);\n\n const baseMessages = config?.messages ? this.toMessages(config.messages) : [];\n const userMessage: ModelMessage = { role: \"user\", content: `${systemPrompt}\\n\\nRequest:\\n${prompt}` };\n\n const messages = [...baseMessages, userMessage];\n const result = await chat({\n adapter,\n messages: messages as unknown as NonNullable<\n Parameters<typeof chat<typeof adapter, undefined, false>>[0][\"messages\"]\n >,\n stream: false,\n });\n\n const trimmed = result.trim();\n\n let parsed: T;\n try {\n const cleaned = trimmed.replace(/```json\\n?|\\n?```/g, \"\").trim();\n parsed = JSON.parse(cleaned) as T;\n } catch {\n parsed = trimmed as T;\n }\n\n if (config?.output) {\n const validation = config.output(parsed);\n if (validation instanceof type.errors) {\n throw new AiException(`Output validation failed: ${validation.summary}`);\n }\n }\n\n return parsed;\n }\n\n /**\n * Streams the AI response chunk by chunk as an async generator.\n *\n * @example\n * ```ts\n * const adapter = new OpenAiAdapter();\n *\n * // Stream the response chunk by chunk\n * for await (const chunk of adapter.runStream(\"Explain quantum computing\")) {\n * process.stdout.write(chunk); // Print each chunk as it arrives\n * }\n * ```\n */\n public async *runStream(\n prompt: string,\n config?: Omit<OpenAiConfigType, \"prompt\" | \"output\">,\n ): AsyncGenerator<string, void, unknown> {\n const apiKey = this.getApiKey(config);\n const model = config?.model ?? \"gpt-4o\";\n const adapter = this.getAdapter(apiKey, model);\n\n const defaultPrompt = \"Process the following request and respond appropriately.\";\n const systemPrompt = this.buildPrompt(defaultPrompt, config);\n\n const baseMessages: ModelMessage[] = config?.messages ? this.toMessages(config.messages) : [];\n const userMessage: ModelMessage = { role: \"user\", content: `${systemPrompt}\\n\\nRequest:\\n${prompt}` };\n\n const messages = [...baseMessages, userMessage];\n const stream = chat({\n adapter,\n messages: messages as unknown as NonNullable<\n Parameters<typeof chat<typeof adapter, undefined, true>>[0][\"messages\"]\n >,\n stream: true,\n });\n\n for await (const chunk of stream) {\n if (chunk.type === \"content\") {\n yield chunk.content;\n }\n }\n }\n}\n"
11
+ ],
12
+ "mappings": "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",
13
+ "debugId": "66CB2B945DCDCB8864756E2164756E21",
14
+ "names": []
15
+ }
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@ooneex/ai",
3
+ "description": "Unified AI client library with support for OpenAI, Anthropic, Google Gemini, and Ollama providers",
4
+ "version": "0.0.4",
5
+ "type": "module",
6
+ "files": [
7
+ "dist",
8
+ "LICENSE",
9
+ "README.md",
10
+ "package.json"
11
+ ],
12
+ "module": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "import": {
17
+ "types": "./dist/index.d.ts",
18
+ "default": "./dist/index.js"
19
+ }
20
+ },
21
+ "./package.json": "./package.json"
22
+ },
23
+ "license": "MIT",
24
+ "scripts": {
25
+ "build": "bunup",
26
+ "lint": "tsgo --noEmit && bunx biome lint",
27
+ "publish": "bun publish --access public || true",
28
+ "test": "bun test tests"
29
+ },
30
+ "dependencies": {
31
+ "@ooneex/container": "0.0.2",
32
+ "@ooneex/exception": "0.0.1",
33
+ "@ooneex/http-status": "0.0.1",
34
+ "@ooneex/validation": "0.0.1",
35
+ "@tanstack/ai": "^0.2.0",
36
+ "@tanstack/ai-anthropic": "^0.2.0",
37
+ "@tanstack/ai-gemini": "^0.2.0",
38
+ "@tanstack/ai-ollama": "^0.2.0",
39
+ "@tanstack/ai-openai": "^0.2.0"
40
+ },
41
+ "devDependencies": {
42
+ "@ooneex/translation": "0.0.1"
43
+ },
44
+ "keywords": [
45
+ "ai",
46
+ "anthropic",
47
+ "artificial-intelligence",
48
+ "bun",
49
+ "gemini",
50
+ "llm",
51
+ "machine-learning",
52
+ "ollama",
53
+ "ooneex",
54
+ "openai",
55
+ "typescript"
56
+ ]
57
+ }