@ooneex/ai 0.0.18 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,16 +1,14 @@
1
1
  # @ooneex/ai
2
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.
3
+ Multi-provider AI toolkit for TypeScript seamlessly integrate OpenAI, Anthropic Claude, Google Gemini, Groq, and Ollama with a unified API for text generation, streaming, and content transformation.
4
4
 
5
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
6
  ![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue?style=flat-square&logo=typescript)
9
7
  ![MIT License](https://img.shields.io/badge/License-MIT-yellow?style=flat-square)
10
8
 
11
9
  ## Features
12
10
 
13
- ✅ **Multiple Providers** - Support for OpenAI, Anthropic Claude, Google Gemini, and Ollama
11
+ ✅ **Multiple Providers** - Support for OpenAI, Anthropic Claude, Google Gemini, Groq, and Ollama
14
12
 
15
13
  ✅ **Unified Interface** - Consistent API across all AI providers
16
14
 
@@ -22,32 +20,18 @@ A unified AI client library for TypeScript applications with support for OpenAI,
22
20
 
23
21
  ✅ **Configurable Tone** - 15 different tone options for content generation
24
22
 
23
+ ✅ **Text-to-Speech** - Groq-powered text-to-speech with configurable voices and formats
24
+
25
25
  ✅ **Multi-language** - Translate and generate content in multiple languages
26
26
 
27
27
  ✅ **Type-Safe** - Full TypeScript support with proper type definitions
28
28
 
29
29
  ## Installation
30
30
 
31
- ### Bun
32
31
  ```bash
33
32
  bun add @ooneex/ai
34
33
  ```
35
34
 
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
35
  ## Usage
52
36
 
53
37
  ### Basic Usage with OpenAI
@@ -120,18 +104,18 @@ const result = await ai.run<string>('Explain microservices', config);
120
104
 
121
105
  ```typescript
122
106
  import { OpenAi } from '@ooneex/ai';
123
- import { type } from 'arktype';
107
+ import { Assert } from '@ooneex/validation';
124
108
 
125
109
  const ai = new OpenAi();
126
110
 
127
111
  // Define expected output schema
128
- const ProductSchema = type({
112
+ const ProductSchema = Assert({
129
113
  name: 'string',
130
114
  price: 'number',
131
115
  description: 'string'
132
116
  });
133
117
 
134
- const product = await ai.run<{ name: string; price: number; description: string }>(
118
+ const product = await ai.run<typeof ProductSchema.infer>(
135
119
  'Generate a product for an e-commerce store',
136
120
  { output: ProductSchema }
137
121
  );
package/dist/index.d.ts CHANGED
@@ -2,25 +2,87 @@ import { Exception } from "@ooneex/exception";
2
2
  declare class AiException extends Exception {
3
3
  constructor(message: string, data?: Record<string, unknown>);
4
4
  }
5
+ import { ModelMessage } from "@tanstack/ai";
5
6
  import { LocaleType } from "@ooneex/translation";
6
7
  import { AssertType } from "@ooneex/validation";
8
+ import { ImageGenerationResult, TTSResult } from "@tanstack/ai";
7
9
  import { anthropicText } from "@tanstack/ai-anthropic";
8
- import { geminiText } from "@tanstack/ai-gemini";
10
+ import { GeminiAspectRatio, GeminiImageProviderOptions, GeminiTTSVoice, geminiText } from "@tanstack/ai-gemini";
11
+ import { groqText } from "@tanstack/ai-groq";
9
12
  import { ollamaText } from "@tanstack/ai-ollama";
10
- import { openaiText } from "@tanstack/ai-openai";
13
+ import { OpenAITranscriptionProviderOptions, OpenAITTSFormat, OpenAITTSVoice, openaiText } from "@tanstack/ai-openai";
14
+ import { TranscriptionResult, TranscriptionSegment, TranscriptionWord } from "@tanstack/ai";
11
15
  type AiClassType = new (...args: any[]) => IAiChat<any>;
12
16
  type OpenAiModelType = Parameters<typeof openaiText>[0];
13
17
  type AnthropicModelType = Parameters<typeof anthropicText>[0];
14
18
  type GeminiModelType = Parameters<typeof geminiText>[0];
19
+ type GroqModelType = Parameters<typeof groqText>[0];
15
20
  type OllamaModelType = Parameters<typeof ollamaText>[0];
21
+ type OpenAiTTSModelType = "tts-1" | "tts-1-hd" | "gpt-4o-audio-preview";
22
+ type OpenAiSTTModelType = "whisper-1" | "gpt-4o-transcribe" | "gpt-4o-mini-transcribe" | "gpt-4o-transcribe-diarize";
23
+ type GeminiTTSModelType = "gemini-2.5-flash-preview-tts" | "gemini-2.5-pro-preview-tts";
24
+ type OpenAiImageModelType = "gpt-image-1" | "gpt-image-1-mini" | "dall-e-3" | "dall-e-2";
25
+ type OpenAiImageSizeType = "1024x1024" | "1536x1024" | "1024x1536" | "1792x1024" | "1024x1792" | "256x256" | "512x512" | "auto";
26
+ type GeminiImageModelType = "gemini-2.5-flash-image" | "gemini-2.0-flash-preview-image-generation" | "imagen-3.0-generate-002" | "imagen-4.0-generate-001" | "imagen-4.0-fast-generate-001" | "imagen-4.0-ultra-generate-001";
27
+ type GeminiImageSizeType = "1024x1024" | "512x512" | "1024x768" | "1536x1024" | "1792x1024" | "1920x1080" | "768x1024" | "1024x1536" | "1024x1792" | "1080x1920";
28
+ type GenerateQuestionOptionsType = {
29
+ choiceCount?: number;
30
+ correctChoiceCount?: number;
31
+ difficulty?: number;
32
+ similarQuestion?: string;
33
+ };
34
+ type GenerateQuestionChoiceType = {
35
+ text: string;
36
+ isCorrect: boolean;
37
+ explanation: string;
38
+ };
39
+ type GenerateQuestionResultType = {
40
+ question: string;
41
+ choices: GenerateQuestionChoiceType[];
42
+ };
43
+ type GenerateFlashcardOptionsType = {
44
+ difficulty?: number;
45
+ similarFlashcard?: string;
46
+ };
47
+ type GenerateFlashcardResultType = {
48
+ front: string;
49
+ back: string;
50
+ explanation: string;
51
+ };
52
+ type GenerateCaseQuestionOptionsType = {
53
+ questionCount?: number;
54
+ choiceCount?: number;
55
+ difficulty?: number;
56
+ similarCase?: string;
57
+ };
58
+ type CaseQuestionChoiceType = {
59
+ text: string;
60
+ isCorrect: boolean;
61
+ explanation: string;
62
+ };
63
+ type CaseQuestionType = {
64
+ text: string;
65
+ answer: string;
66
+ explanation: string;
67
+ choices?: CaseQuestionChoiceType[];
68
+ };
69
+ type GenerateCaseQuestionResultType = {
70
+ title: string;
71
+ presentation: string;
72
+ questions: CaseQuestionType[];
73
+ };
16
74
  type AiToneType = "professional" | "casual" | "formal" | "friendly" | "confident" | "empathetic" | "persuasive" | "informative" | "enthusiastic" | "neutral" | "humorous" | "serious" | "inspirational" | "conversational" | "authoritative";
75
+ type AiImageSourceType = {
76
+ type: "url" | "data";
77
+ value: string;
78
+ };
17
79
  type AiMessageType = {
18
80
  role: "user" | "assistant" | "system" | "tool";
19
81
  content: string;
20
82
  };
21
83
  type AiConfigType = {
22
84
  apiKey?: string;
23
- model?: OpenAiModelType | AnthropicModelType | GeminiModelType | OllamaModelType;
85
+ model?: OpenAiModelType | AnthropicModelType | GeminiModelType | GroqModelType | OllamaModelType;
24
86
  wordCount?: number;
25
87
  stream?: boolean;
26
88
  language?: LocaleType;
@@ -28,6 +90,7 @@ type AiConfigType = {
28
90
  messages?: AiMessageType[];
29
91
  context?: string;
30
92
  prompt?: string;
93
+ count?: number;
31
94
  output?: AssertType;
32
95
  };
33
96
  type OpenAiConfigType = Omit<AiConfigType, "model"> & {
@@ -39,10 +102,71 @@ type AnthropicConfigType = Omit<AiConfigType, "model"> & {
39
102
  type GeminiConfigType = Omit<AiConfigType, "model"> & {
40
103
  model?: GeminiModelType;
41
104
  };
105
+ type GroqConfigType = Omit<AiConfigType, "model"> & {
106
+ model?: GroqModelType;
107
+ };
42
108
  type OllamaConfigType = Omit<AiConfigType, "model" | "apiKey"> & {
43
109
  host?: string;
44
110
  model?: OllamaModelType;
45
111
  };
112
+ type OpenAiTextToSpeechOptionsType = {
113
+ apiKey?: string;
114
+ model?: OpenAiTTSModelType;
115
+ voice?: OpenAITTSVoice;
116
+ format?: OpenAITTSFormat;
117
+ speed?: number;
118
+ language?: string;
119
+ instructions?: string;
120
+ };
121
+ type OpenAiSpeechToTextOptionsType = {
122
+ apiKey?: string;
123
+ model?: OpenAiSTTModelType;
124
+ language?: string;
125
+ prompt?: string;
126
+ responseFormat?: "json" | "text" | "srt" | "verbose_json" | "vtt";
127
+ modelOptions?: OpenAITranscriptionProviderOptions;
128
+ };
129
+ type GroqTTSModelType = "canopylabs/orpheus-v1-english" | "canopylabs/orpheus-arabic-saudi";
130
+ type GroqTTSVoiceType = "autumn" | "diana" | "hannah" | "austin" | "daniel" | "troy" | "fahad" | "sultan" | "lulwa" | "noura";
131
+ type GroqTTSFormatType = "wav" | "mp3" | "flac" | "ogg" | "mulaw";
132
+ type GroqTextToSpeechOptionsType = {
133
+ apiKey?: string;
134
+ model?: GroqTTSModelType;
135
+ voice?: GroqTTSVoiceType;
136
+ format?: GroqTTSFormatType;
137
+ sampleRate?: number;
138
+ };
139
+ type GeminiTextToSpeechOptionsType = {
140
+ apiKey?: string;
141
+ model?: GeminiTTSModelType;
142
+ voice?: GeminiTTSVoice;
143
+ format?: "mp3" | "opus" | "aac" | "flac" | "wav" | "pcm";
144
+ speed?: number;
145
+ instructions?: string;
146
+ language?: string;
147
+ };
148
+ type OpenAiGenerateImageOptionsType = {
149
+ apiKey?: string;
150
+ model?: OpenAiImageModelType;
151
+ numberOfImages?: number;
152
+ size?: OpenAiImageSizeType;
153
+ quality?: "high" | "medium" | "low" | "auto" | "hd" | "standard";
154
+ background?: "transparent" | "opaque" | "auto";
155
+ outputFormat?: "png" | "jpeg" | "webp";
156
+ moderation?: "low" | "auto";
157
+ style?: "vivid" | "natural";
158
+ };
159
+ type GeminiGenerateImageOptionsType = {
160
+ apiKey?: string;
161
+ model?: GeminiImageModelType;
162
+ numberOfImages?: number;
163
+ size?: GeminiImageSizeType;
164
+ aspectRatio?: GeminiAspectRatio;
165
+ personGeneration?: "DONT_ALLOW" | "ALLOW_ADULT" | "ALLOW_ALL";
166
+ negativePrompt?: string;
167
+ addWatermark?: boolean;
168
+ outputMimeType?: "image/png" | "image/jpeg" | "image/webp";
169
+ };
46
170
  interface IAiChat<TConfig extends AiConfigType = AiConfigType> {
47
171
  makeShorter?: (content: string, config?: TConfig) => Promise<string>;
48
172
  makeLonger?: (content: string, config?: TConfig) => Promise<string>;
@@ -52,7 +176,7 @@ interface IAiChat<TConfig extends AiConfigType = AiConfigType> {
52
176
  bulletPoints?: (content: string, config?: TConfig) => Promise<string>;
53
177
  rephrase?: (content: string, config?: TConfig) => Promise<string>;
54
178
  simplify?: (content: string, config?: TConfig) => Promise<string>;
55
- changeTone?: (content: string, tone: AiToneType, config?: Omit<TConfig, "tone">) => Promise<string>;
179
+ changeTone?: (content: string, tone: AiToneType, config?: Omit<TConfig, "tone" | "output">) => Promise<string>;
56
180
  proofread?: (content: string, config?: TConfig) => Promise<string>;
57
181
  translate?: (content: string, config?: TConfig) => Promise<string>;
58
182
  explain?: (content: string, config?: TConfig) => Promise<string>;
@@ -61,167 +185,81 @@ interface IAiChat<TConfig extends AiConfigType = AiConfigType> {
61
185
  generateTitle?: (content: string, config?: TConfig) => Promise<string>;
62
186
  extractKeywords?: (content: string, config?: TConfig) => Promise<string[]>;
63
187
  extractCategories?: (content: string, config?: TConfig) => Promise<string[]>;
188
+ extractTopics?: (content: string, config?: TConfig) => Promise<string[]>;
189
+ generateCaseQuestion?: (subject: string, options?: GenerateCaseQuestionOptionsType, config?: TConfig) => Promise<GenerateCaseQuestionResultType>;
190
+ generateFlashcard?: (subject: string, options?: GenerateFlashcardOptionsType, config?: TConfig) => Promise<GenerateFlashcardResultType>;
191
+ generateQuestion?: (subject: string, options?: GenerateQuestionOptionsType, config?: TConfig) => Promise<GenerateQuestionResultType>;
192
+ imageToMarkdown?: (source: AiImageSourceType, config?: Omit<TConfig, "output">) => Promise<string>;
64
193
  run: <T>(content: string, config?: TConfig) => Promise<T>;
65
194
  runStream: (content: string, config?: TConfig) => AsyncGenerator<string, void, unknown>;
66
195
  }
67
- declare class AnthropicAi implements IAiChat<AnthropicConfigType> {
196
+ declare abstract class BaseAi<TConfig extends AiConfigType> implements IAiChat<TConfig> {
197
+ protected abstract createChatAdapter(config?: TConfig): any;
198
+ protected abstract createRunAdapter(config?: TConfig): any;
199
+ protected buildPrompt(instruction: string, config?: TConfig): string;
200
+ protected toMessages(messages: AiMessageType[]): ModelMessage[];
201
+ protected executeChat(content: string, systemPrompt: string, config?: TConfig): Promise<string>;
202
+ makeShorter(content: string, config?: Omit<TConfig, "output">): Promise<string>;
203
+ makeLonger(content: string, config?: Omit<TConfig, "output">): Promise<string>;
204
+ summarize(content: string, config?: Omit<TConfig, "output">): Promise<string>;
205
+ concise(content: string, config?: Omit<TConfig, "output">): Promise<string>;
206
+ paragraph(content: string, config?: Omit<TConfig, "output">): Promise<string>;
207
+ bulletPoints(content: string, config?: Omit<TConfig, "output">): Promise<string>;
208
+ rephrase(content: string, config?: Omit<TConfig, "output">): Promise<string>;
209
+ simplify(content: string, config?: Omit<TConfig, "output">): Promise<string>;
210
+ changeTone(content: string, tone: AiToneType, config?: Omit<TConfig, "tone" | "output">): Promise<string>;
211
+ proofread(content: string, config?: Omit<TConfig, "output">): Promise<string>;
212
+ translate(content: string, config?: Omit<TConfig, "output">): Promise<string>;
213
+ explain(content: string, config?: Omit<TConfig, "output">): Promise<string>;
214
+ expandIdeas(content: string, config?: Omit<TConfig, "output">): Promise<string>;
215
+ fixGrammar(content: string, config?: Omit<TConfig, "output">): Promise<string>;
216
+ generateTitle(content: string, config?: Omit<TConfig, "output">): Promise<string>;
217
+ extractKeywords(content: string, config?: Omit<TConfig, "output">): Promise<string[]>;
218
+ extractCategories(content: string, config?: Omit<TConfig, "output">): Promise<string[]>;
219
+ extractTopics(content: string, config?: Omit<TConfig, "output">): Promise<string[]>;
220
+ generateCaseQuestion(subject: string, options?: GenerateCaseQuestionOptionsType, config?: TConfig): Promise<GenerateCaseQuestionResultType>;
221
+ generateFlashcard(subject: string, options?: GenerateFlashcardOptionsType, config?: TConfig): Promise<GenerateFlashcardResultType>;
222
+ generateQuestion(subject: string, options?: GenerateQuestionOptionsType, config?: TConfig): Promise<GenerateQuestionResultType>;
223
+ imageToMarkdown(source: AiImageSourceType, config?: Omit<TConfig, "output">): Promise<string>;
224
+ run<T>(prompt: string, config?: Omit<TConfig, "prompt">): Promise<T>;
225
+ runStream(prompt: string, config?: Omit<TConfig, "prompt" | "output">): AsyncGenerator<string, void, unknown>;
226
+ }
227
+ declare class AnthropicAi extends BaseAi<AnthropicConfigType> {
68
228
  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>;
229
+ protected createChatAdapter(config?: AnthropicConfigType);
230
+ protected createRunAdapter(config?: AnthropicConfigType);
105
231
  }
106
232
  import { EContainerScope } from "@ooneex/container";
107
233
  declare const decorator: {
108
234
  ai: (scope?: EContainerScope) => (target: AiClassType) => void;
109
235
  };
110
- declare class GeminiAi implements IAiChat<GeminiConfigType> {
236
+ import { ImageGenerationResult as ImageGenerationResult2, TTSResult as TTSResult2 } from "@tanstack/ai";
237
+ declare class GeminiAi extends BaseAi<GeminiConfigType> {
238
+ private getApiKey;
239
+ protected createChatAdapter(config?: GeminiConfigType);
240
+ protected createRunAdapter(config?: GeminiConfigType);
241
+ textToSpeech(text: string, options?: GeminiTextToSpeechOptionsType): Promise<TTSResult2>;
242
+ generateImage(prompt: string, options?: GeminiGenerateImageOptionsType): Promise<ImageGenerationResult2>;
243
+ }
244
+ import { TTSResult as TTSResult3 } from "@tanstack/ai";
245
+ declare class GroqAi extends BaseAi<GroqConfigType> {
111
246
  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>;
247
+ protected createChatAdapter(config?: GroqConfigType);
248
+ protected createRunAdapter(config?: GroqConfigType);
249
+ textToSpeech(text: string, options?: GroqTextToSpeechOptionsType): Promise<TTSResult3>;
148
250
  }
149
- declare class OllamaAi implements IAiChat<OllamaConfigType> {
251
+ declare class OllamaAi extends BaseAi<OllamaConfigType> {
150
252
  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>;
253
+ protected createChatAdapter(config?: OllamaConfigType);
254
+ protected createRunAdapter(config?: OllamaConfigType);
187
255
  }
188
- declare class OpenAi implements IAiChat<OpenAiConfigType> {
256
+ import { ImageGenerationResult as ImageGenerationResult3, TranscriptionResult as TranscriptionResult2, TTSResult as TTSResult4 } from "@tanstack/ai";
257
+ declare class OpenAi extends BaseAi<OpenAiConfigType> {
189
258
  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>;
259
+ protected createChatAdapter(config?: OpenAiConfigType);
260
+ protected createRunAdapter(config?: OpenAiConfigType);
261
+ textToSpeech(text: string, options?: OpenAiTextToSpeechOptionsType): Promise<TTSResult4>;
262
+ speechToText(audio: string | File | Blob | ArrayBuffer, options?: OpenAiSpeechToTextOptionsType): Promise<TranscriptionResult2>;
263
+ generateImage(prompt: string, options?: OpenAiGenerateImageOptionsType): Promise<ImageGenerationResult3>;
226
264
  }
227
- export { decorator, OpenAiModelType, OpenAiConfigType, OpenAi, OllamaModelType, OllamaConfigType, OllamaAi, IAiChat, GeminiModelType, GeminiConfigType, GeminiAi, AnthropicModelType, AnthropicConfigType, AnthropicAi, AiToneType, AiMessageType, AiException, AiConfigType, AiClassType };
265
+ export { decorator, TranscriptionWord, TranscriptionSegment, TranscriptionResult, TTSResult, OpenAiTextToSpeechOptionsType, OpenAiTTSModelType, OpenAiSpeechToTextOptionsType, OpenAiSTTModelType, OpenAiModelType, OpenAiImageSizeType, OpenAiImageModelType, OpenAiGenerateImageOptionsType, OpenAiConfigType, OpenAi, OpenAITranscriptionProviderOptions, OpenAITTSVoice, OpenAITTSFormat, OllamaModelType, OllamaConfigType, OllamaAi, ImageGenerationResult, IAiChat, GroqTextToSpeechOptionsType, GroqTTSVoiceType, GroqTTSModelType, GroqTTSFormatType, GroqModelType, GroqConfigType, GroqAi, GenerateQuestionResultType, GenerateQuestionOptionsType, GenerateQuestionChoiceType, GenerateFlashcardResultType, GenerateFlashcardOptionsType, GenerateCaseQuestionResultType, GenerateCaseQuestionOptionsType, GeminiTextToSpeechOptionsType, GeminiTTSVoice, GeminiTTSModelType, GeminiModelType, GeminiImageSizeType, GeminiImageProviderOptions, GeminiImageModelType, GeminiGenerateImageOptionsType, GeminiConfigType, GeminiAspectRatio, GeminiAi, CaseQuestionType, CaseQuestionChoiceType, BaseAi, AnthropicModelType, AnthropicConfigType, AnthropicAi, AiToneType, AiMessageType, AiImageSourceType, AiException, AiConfigType, AiClassType };
package/dist/index.js CHANGED
@@ -1,55 +1,20 @@
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}
1
+ // @bun
2
+ var J=function(T,C,H,v){var N=arguments.length,_=N<3?C:v===null?v=Object.getOwnPropertyDescriptor(C,H):v,R;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")_=Reflect.decorate(T,C,H,v);else for(var Y=T.length-1;Y>=0;Y--)if(R=T[Y])_=(N<3?R(_):N>3?R(C,H,_):R(C,H))||_;return N>3&&_&&Object.defineProperty(C,H,_),_};import{Exception as x}from"@ooneex/exception";import{HttpStatus as E}from"@ooneex/http-status";class L extends x{constructor(T,C={}){super(T,{status:E.Code.InternalServerError,data:C});this.name="AiException"}}import{createAnthropicChat as q}from"@tanstack/ai-anthropic";import{jsonSchemaToTypeString as w}from"@ooneex/validation";import{chat as W}from"@tanstack/ai";import{type as P}from"arktype";class z{buildPrompt(T,C){let H=[C?.prompt||T];if(C?.context)H.push(`Context:
3
+ ${C.context}`);if(C?.wordCount)H.push(`Target approximately ${C.wordCount} words.`);if(C?.tone)H.push(`Use a ${C.tone} tone.`);if(C?.language)H.push(`Respond in ${C.language} language.`);return H.push(`${C?.context?"Use the provided context to inform your response. ":""}Respond with only the transformed text. Do not include explanations or additional commentary.`),H.join(`
4
+ `)}toMessages(T){return T.map((C)=>({role:C.role,content:C.content}))}async executeChat(T,C,H){let v=this.createChatAdapter(H),N=H?.messages?this.toMessages(H.messages):[],_={role:"user",content:`${C}
4
5
 
5
6
  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
+ ${T}`},R=[...N,_];return(await W({adapter:v,messages:R,stream:!1})).trim()}async makeShorter(T,C){let H=this.buildPrompt("Condense the following text while preserving its core meaning and key information. Remove redundancies and unnecessary details.",C);return this.executeChat(T,H,C)}async makeLonger(T,C){let H=this.buildPrompt("Expand the following text by adding relevant details, examples, and explanations while maintaining coherence and the original message.",C);return this.executeChat(T,H,C)}async summarize(T,C){let H=this.buildPrompt("Provide a clear and comprehensive summary of the following text, capturing all essential points and main ideas.",C);return this.executeChat(T,H,C)}async concise(T,C){let H=this.buildPrompt("Rewrite the following text in the most concise form possible without losing essential meaning.",C);return this.executeChat(T,H,C)}async paragraph(T,C){let H=this.buildPrompt("Transform the following text into well-structured paragraph format with clear topic sentences and logical flow.",C);return this.executeChat(T,H,C)}async bulletPoints(T,C){let H=this.buildPrompt("Convert the following text into a clear, organized list of bullet points highlighting the key information.",C);return this.executeChat(T,H,C)}async rephrase(T,C){let H=this.buildPrompt("Rephrase the following text using different words and sentence structures while preserving the original meaning.",C);return this.executeChat(T,H,C)}async simplify(T,C){let H=this.buildPrompt("Simplify the following text by using plain language, shorter sentences, and avoiding jargon. Make it accessible to a general audience.",C);return this.executeChat(T,H,C)}async changeTone(T,C,H){let v=this.buildPrompt(`Rewrite the following text in a ${C} tone while maintaining clarity.`,H);return this.executeChat(T,v,H)}async proofread(T,C){let H=this.buildPrompt("Proofread and correct the following text for grammar, spelling, punctuation, and clarity issues. Return the corrected version.",C);return this.executeChat(T,H,C)}async translate(T,C){let H=C?.language??"en",v=this.buildPrompt(`Translate the following text accurately into ${H}, preserving the original meaning, tone, and nuance.`,C);return this.executeChat(T,v,C)}async explain(T,C){let H=this.buildPrompt("Provide a clear explanation of the following text, breaking down complex concepts and clarifying the meaning.",C);return this.executeChat(T,H,C)}async expandIdeas(T,C){let H=this.buildPrompt("Expand on the ideas presented in the following text by exploring related concepts, implications, and additional perspectives.",C);return this.executeChat(T,H,C)}async fixGrammar(T,C){let H=this.buildPrompt("Fix all grammatical errors in the following text, including subject-verb agreement, tense consistency, and sentence structure.",C);return this.executeChat(T,H,C)}async generateTitle(T,C){let H=this.buildPrompt("Generate a compelling, descriptive title for the following text that captures its main theme and engages readers.",C);return this.executeChat(T,H,C)}async extractKeywords(T,C){let H=C?.count,v=H?` Return exactly ${H} keywords.`:"",N=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.${v}`,C),R=(await this.executeChat(T,N,C)).split(",").map((Y)=>Y.trim()).filter((Y)=>Y.length>0);return H?R.slice(0,H):R}async extractCategories(T,C){let H=C?.count,v=H?` Return exactly ${H} categories.`:"",N=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.${v}`,C),R=(await this.executeChat(T,N,C)).split(",").map((Y)=>Y.trim()).filter((Y)=>Y.length>0);return H?R.slice(0,H):R}async extractTopics(T,C){let H=C?.count,v=H?` Return at most ${H} topics.`:"",N=this.buildPrompt(`Extract the main topics discussed in the following text. Return only the topics as a comma-separated list without numbering, brackets, or additional formatting.${v}`,C),R=(await this.executeChat(T,N,C)).split(",").map((Y)=>Y.trim()).filter((Y)=>Y.length>0);return H?R.slice(0,H):R}async generateCaseQuestion(T,C,H){let v=C?.questionCount??3,N=C?.choiceCount,_=Math.min(100,Math.max(1,C?.difficulty??50)),R=N?[`Each question must have exactly ${N} choices.`,"Exactly 1 of the choices must be correct.","For each choice (both correct and wrong), provide an explanation in approximately 50 words."]:[],Y=N?'{"title":"...","presentation":"...","questions":[{"text":"...","answer":"...","explanation":"...","choices":[{"text":"...","isCorrect":true/false,"explanation":"..."},...]},...]}':'{"title":"...","presentation":"...","questions":[{"text":"...","answer":"...","explanation":"..."},...]}',S=this.buildPrompt(["Generate a clinical case study with questions about the following subject.",`Difficulty level: ${_}/100. At easy difficulty (1-25), present straightforward cases with classic presentations. At medium difficulty (26-50), include cases requiring differential diagnosis and standard management. At hard difficulty (51-75), present atypical presentations or cases with complicating factors. At expert difficulty (76-100), present rare conditions, complex multi-system cases, or cases requiring nuanced clinical reasoning.`,...C?.similarCase?[`Generate a case similar in style and topic to: "${C.similarCase}". The new case must be different but cover a closely related clinical scenario.`]:[],"Create a detailed clinical presentation with patient demographics, symptoms, history, and relevant findings.",`Generate exactly ${v} questions about the case, numbered sequentially.`,"Each question must have a direct answer and a detailed explanation.",...R,"Respond ONLY with valid JSON in this exact format:",Y].join(`
8
+ `),H),U=(await this.executeChat(T,S,H)).replace(/```json\n?|\n?```/g,"").trim();return JSON.parse(U)}async generateFlashcard(T,C,H){let v=Math.min(100,Math.max(1,C?.difficulty??50)),N=this.buildPrompt(["Generate a flashcard about the following subject.",`Difficulty level: ${v}/100. At easy difficulty (1-25), cover basic definitions and simple facts. At medium difficulty (26-50), cover concepts requiring understanding and application. At hard difficulty (51-75), cover analysis and connections between concepts. At expert difficulty (76-100), cover nuanced details, edge cases, and advanced reasoning.`,...C?.similarFlashcard?[`Generate a flashcard similar in style and topic to: "${C.similarFlashcard}". The new flashcard must be different but cover a closely related concept.`]:[],"The front should be a clear, concise question or prompt.","The back should be a direct answer.","The explanation should provide additional context in approximately 50 words.","Respond ONLY with valid JSON in this exact format:",'{"front":"...","back":"...","explanation":"..."}'].join(`
9
+ `),H),R=(await this.executeChat(T,N,H)).replace(/```json\n?|\n?```/g,"").trim();return JSON.parse(R)}async generateQuestion(T,C,H){let v=C?.choiceCount??5,N=C?.correctChoiceCount??1,_=Math.min(100,Math.max(1,C?.difficulty??50)),R=this.buildPrompt(["Generate a multiple-choice question (MCQ) about the following subject.",`Difficulty level: ${_}/100. At easy difficulty (1-25), ask basic recall questions with obviously wrong distractors. At medium difficulty (26-50), require understanding and application with plausible distractors. At hard difficulty (51-75), test analysis and synthesis with closely related distractors that require careful reasoning. At expert difficulty (76-100), test deep analysis, edge cases, and subtle distinctions where wrong choices are very close to being correct.`,`The question must have exactly ${v} choices.`,`Exactly ${N} of the choices must be correct.`,...C?.similarQuestion?[`Generate a question similar in style and topic to: "${C.similarQuestion}". The new question must be different but cover a closely related concept.`]:[],"For each choice (both correct and wrong), provide an explanation in approximately 50 words.","Respond ONLY with valid JSON in this exact format:",'{"question":"...","choices":[{"text":"...","isCorrect":true/false,"explanation":"..."},...]}'].join(`
10
+ `),H),S=(await this.executeChat(T,R,H)).replace(/```json\n?|\n?```/g,"").trim();return JSON.parse(S)}async imageToMarkdown(T,C){let H=this.createChatAdapter(C),v=this.buildPrompt("Convert the content of the provided image into well-structured Markdown. Preserve the document structure including headings, lists, tables, code blocks, and formatting. Transcribe all visible text accurately.",C),N=C?.messages?this.toMessages(C.messages):[],_={role:"user",content:[{type:"text",content:v},{type:"image",source:{type:T.type,value:T.value}}]},R=[...N,_];return(await W({adapter:H,messages:R,stream:!1})).trim()}async run(T,C){let H=this.createRunAdapter(C),v="Process the following request and respond appropriately. If the request asks for structured data, return valid JSON.";if(C?.output){let V=C.output.toJsonSchema(),M=w(V);v+=`
7
11
 
8
- Output Type: ${C}`}let J=this.buildPrompt(F,H),N=H?.messages?this.toMessages(H.messages):[],U={role:"user",content:`${J}
12
+ Output Type: ${M}`}let N=this.buildPrompt(v,C),_=C?.messages?this.toMessages(C.messages):[],R={role:"user",content:`${N}
9
13
 
10
14
  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}
15
+ ${T}`},Y=[..._,R],Q=(await W({adapter:H,messages:Y,stream:!1})).trim(),U;try{let V=Q.replace(/```json\n?|\n?```/g,"").trim();U=JSON.parse(V)}catch{U=Q}if(C?.output){let V=C.output(U);if(V instanceof P.errors)throw new L(`Output validation failed: ${V.summary}`)}return U}async*runStream(T,C){let H=this.createRunAdapter(C),v="Process the following request and respond appropriately.",N=this.buildPrompt("Process the following request and respond appropriately.",C),_=C?.messages?this.toMessages(C.messages):[],R={role:"user",content:`${N}
12
16
 
13
17
  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}
18
+ ${T}`},Y=[..._,R],S=W({adapter:H,messages:Y,stream:!0});for await(let Q of S)if(Q.type==="content")yield Q.content}}import{container as h,EContainerScope as j}from"@ooneex/container";var D={ai:(T=j.Singleton)=>{return(C)=>{h.add(C,T)}}};class X extends z{getApiKey(T){let C=T?.apiKey||Bun.env.ANTHROPIC_API_KEY;if(!C)throw new L("Anthropic API key is required. Provide an API key through config options or set the ANTHROPIC_API_KEY environment variable.");return C}createChatAdapter(T){let C=this.getApiKey(T),H=T?.model??"claude-sonnet-4-5";return q(H,C)}createRunAdapter(T){return this.createChatAdapter(T)}}X=J([D.ai()],X);import{generateImage as k,generateSpeech as K}from"@tanstack/ai";import{createGeminiChat as I,createGeminiImage as G,createGeminiSpeech as b}from"@tanstack/ai-gemini";class Z extends z{getApiKey(T){let C=T?.apiKey||Bun.env.GEMINI_API_KEY;if(!C)throw new L("Gemini API key is required. Provide an API key through config options or set the GEMINI_API_KEY environment variable.");return C}createChatAdapter(T){let C=this.getApiKey(T),H=T?.model??"gemini-2.0-flash";return I(H,C)}createRunAdapter(T){let C=this.getApiKey(T),H=T?.model??"gemini-2.5-pro";return I(H,C)}async textToSpeech(T,C){let H=this.getApiKey(C),v=C?.model??"gemini-2.5-flash-preview-tts",N=b(v,H),_={};if(C?.voice)_.voiceConfig={prebuiltVoiceConfig:{voiceName:C.voice}};if(C?.instructions)_.systemInstruction=C.instructions;if(C?.language)_.languageCode=C.language;let R={adapter:N,text:T};if(C?.format)R.format=C.format;if(C?.speed)R.speed=C.speed;if(Object.keys(_).length>0)R.modelOptions=_;return K(R)}async generateImage(T,C){let H=this.getApiKey(C),v=C?.model??"imagen-4.0-generate-001",_={adapter:G(v,H),prompt:T};if(C?.numberOfImages)_.numberOfImages=C.numberOfImages;if(C?.size)_.size=C.size;let R={};if(C?.aspectRatio)R.aspectRatio=C.aspectRatio;if(C?.personGeneration)R.personGeneration=C.personGeneration;if(C?.negativePrompt)R.negativePrompt=C.negativePrompt;if(C?.addWatermark!==void 0)R.addWatermark=C.addWatermark;if(C?.outputMimeType)R.outputMimeType=C.outputMimeType;if(Object.keys(R).length>0)_.modelOptions=R;return k(_)}}Z=J([D.ai()],Z);import{createGroqText as y}from"@tanstack/ai-groq";class $ extends z{getApiKey(T){let C=T?.apiKey||Bun.env.GROQ_API_KEY;if(!C)throw new L("Groq API key is required. Provide an API key through config options or set the GROQ_API_KEY environment variable.");return C}createChatAdapter(T){let C=this.getApiKey(T),H=T?.model??"llama-3.3-70b-versatile";return y(H,C)}createRunAdapter(T){return this.createChatAdapter(T)}async textToSpeech(T,C){let H=this.getApiKey(C),v=C?.model??"canopylabs/orpheus-v1-english",N=C?.voice??"autumn",_=C?.format??"wav",R={model:v,input:T,voice:N,response_format:_};if(C?.sampleRate)R.sample_rate=C.sampleRate;let Y=await fetch("https://api.groq.com/openai/v1/audio/speech",{method:"POST",headers:{Authorization:`Bearer ${H}`,"Content-Type":"application/json"},body:JSON.stringify(R)});if(!Y.ok){let U=await Y.text();throw new L(`Groq TTS request failed (${Y.status}): ${U}`)}let S=await Y.arrayBuffer(),Q=Buffer.from(S).toString("base64");return{id:Y.headers.get("x-request-id")??crypto.randomUUID(),model:v,audio:Q,format:_}}}$=J([D.ai()],$);import{createOllamaChat as l}from"@tanstack/ai-ollama";class A extends z{getHost(T){return T?.host||Bun.env.OLLAMA_HOST||"http://localhost:11434"}createChatAdapter(T){let C=this.getHost(T),H=T?.model??"llama3";return l(H,C)}createRunAdapter(T){return this.createChatAdapter(T)}}A=J([D.ai()],A);import{generateImage as d,generateSpeech as O,generateTranscription as r}from"@tanstack/ai";import{createOpenaiChat as B,createOpenaiImage as u,createOpenaiSpeech as m,createOpenaiTranscription as a}from"@tanstack/ai-openai";class F extends z{getApiKey(T){let C=T?.apiKey||Bun.env.OPENAI_API_KEY;if(!C)throw new L("OpenAI API key is required. Provide an API key through config options or set the OPENAI_API_KEY environment variable.");return C}createChatAdapter(T){let C=this.getApiKey(T),H=T?.model??"gpt-4o-mini";return B(H,C)}createRunAdapter(T){let C=this.getApiKey(T),H=T?.model??"gpt-4o";return B(H,C)}async textToSpeech(T,C){let H=this.getApiKey(C),v=C?.model??"tts-1",_={adapter:m(v,H),text:T};if(C?.voice)_.voice=C.voice;if(C?.format)_.format=C.format;if(C?.speed)_.speed=C.speed;let R=[];if(C?.language)R.push(`Speak in ${C.language}.`);if(C?.instructions)R.push(C.instructions);if(R.length>0)_.modelOptions={instructions:R.join(" ")};return O(_)}async speechToText(T,C){let H=this.getApiKey(C),v=C?.model??"gpt-4o-transcribe",_={adapter:a(v,H),audio:T};if(C?.language)_.language=C.language;if(C?.prompt)_.prompt=C.prompt;if(C?.responseFormat)_.responseFormat=C.responseFormat;if(C?.modelOptions)_.modelOptions=C.modelOptions;return r(_)}async generateImage(T,C){let H=this.getApiKey(C),v=C?.model??"dall-e-3",_={adapter:u(v,H),prompt:T};if(C?.numberOfImages)_.numberOfImages=C.numberOfImages;if(C?.size)_.size=C.size;let R={};if(C?.quality)R.quality=C.quality;if(C?.background)R.background=C.background;if(C?.outputFormat)R.output_format=C.outputFormat;if(C?.moderation)R.moderation=C.moderation;if(C?.style)R.style=C.style;if(Object.keys(R).length>0)_.modelOptions=R;return d(_)}}F=J([D.ai()],F);export{D as decorator,F as OpenAi,A as OllamaAi,$ as GroqAi,Z as GeminiAi,z as BaseAi,X as AnthropicAi,L as AiException};
17
19
 
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
20
+ //# debugId=C00944452078E5B764756E2164756E21
package/dist/index.js.map CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["src/AiException.ts", "src/AnthropicAi.ts", "src/decorators.ts", "src/GeminiAi.ts", "src/OllamaAi.ts", "src/OpenAi.ts"],
3
+ "sources": ["src/AiException.ts", "src/AnthropicAi.ts", "src/BaseAi.ts", "src/decorators.ts", "src/GeminiAi.ts", "src/GroqAi.ts", "src/OllamaAi.ts", "src/OpenAi.ts"],
4
4
  "sourcesContent": [
5
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",
6
+ "import { createAnthropicChat } from \"@tanstack/ai-anthropic\";\nimport { AiException } from \"./AiException\";\nimport { BaseAi } from \"./BaseAi\";\nimport { decorator } from \"./decorators\";\nimport type { AnthropicConfigType, AnthropicModelType } from \"./types\";\n\n@decorator.ai()\nexport class AnthropicAi extends BaseAi<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 protected createChatAdapter(config?: AnthropicConfigType) {\n const apiKey = this.getApiKey(config);\n const model = (config?.model ?? \"claude-sonnet-4-5\") as AnthropicModelType;\n return createAnthropicChat(model, apiKey);\n }\n\n protected createRunAdapter(config?: AnthropicConfigType) {\n return this.createChatAdapter(config);\n }\n}\n",
7
+ "import { jsonSchemaToTypeString } from \"@ooneex/validation\";\nimport { chat, type ModelMessage } from \"@tanstack/ai\";\nimport { type } from \"arktype\";\nimport { AiException } from \"./AiException\";\nimport type {\n AiConfigType,\n AiImageSourceType,\n AiMessageType,\n AiToneType,\n GenerateCaseQuestionOptionsType,\n GenerateCaseQuestionResultType,\n GenerateFlashcardOptionsType,\n GenerateFlashcardResultType,\n GenerateQuestionOptionsType,\n GenerateQuestionResultType,\n IAiChat,\n} from \"./types\";\n\nexport abstract class BaseAi<TConfig extends AiConfigType> implements IAiChat<TConfig> {\n // biome-ignore lint/suspicious/noExplicitAny: adapter type varies by provider\n protected abstract createChatAdapter(config?: TConfig): any;\n // biome-ignore lint/suspicious/noExplicitAny: adapter type varies by provider\n protected abstract createRunAdapter(config?: TConfig): any;\n\n protected buildPrompt(instruction: string, config?: TConfig): 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 protected toMessages(messages: AiMessageType[]): ModelMessage[] {\n return messages.map((msg) => ({ role: msg.role as \"user\" | \"assistant\" | \"tool\", content: msg.content }));\n }\n\n protected async executeChat(content: string, systemPrompt: string, config?: TConfig): Promise<string> {\n const adapter = this.createChatAdapter(config);\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<TConfig, \"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 as TConfig,\n );\n return this.executeChat(content, prompt, config as TConfig);\n }\n\n public async makeLonger(content: string, config?: Omit<TConfig, \"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 as TConfig,\n );\n return this.executeChat(content, prompt, config as TConfig);\n }\n\n public async summarize(content: string, config?: Omit<TConfig, \"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 as TConfig,\n );\n return this.executeChat(content, prompt, config as TConfig);\n }\n\n public async concise(content: string, config?: Omit<TConfig, \"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 as TConfig,\n );\n return this.executeChat(content, prompt, config as TConfig);\n }\n\n public async paragraph(content: string, config?: Omit<TConfig, \"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 as TConfig,\n );\n return this.executeChat(content, prompt, config as TConfig);\n }\n\n public async bulletPoints(content: string, config?: Omit<TConfig, \"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 as TConfig,\n );\n return this.executeChat(content, prompt, config as TConfig);\n }\n\n public async rephrase(content: string, config?: Omit<TConfig, \"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 as TConfig,\n );\n return this.executeChat(content, prompt, config as TConfig);\n }\n\n public async simplify(content: string, config?: Omit<TConfig, \"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 as TConfig,\n );\n return this.executeChat(content, prompt, config as TConfig);\n }\n\n public async changeTone(\n content: string,\n tone: AiToneType,\n config?: Omit<TConfig, \"tone\" | \"output\">,\n ): Promise<string> {\n const prompt = this.buildPrompt(\n `Rewrite the following text in a ${tone} tone while maintaining clarity.`,\n config as TConfig,\n );\n return this.executeChat(content, prompt, config as TConfig);\n }\n\n public async proofread(content: string, config?: Omit<TConfig, \"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 as TConfig,\n );\n return this.executeChat(content, prompt, config as TConfig);\n }\n\n public async translate(content: string, config?: Omit<TConfig, \"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 as TConfig,\n );\n return this.executeChat(content, prompt, config as TConfig);\n }\n\n public async explain(content: string, config?: Omit<TConfig, \"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 as TConfig,\n );\n return this.executeChat(content, prompt, config as TConfig);\n }\n\n public async expandIdeas(content: string, config?: Omit<TConfig, \"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 as TConfig,\n );\n return this.executeChat(content, prompt, config as TConfig);\n }\n\n public async fixGrammar(content: string, config?: Omit<TConfig, \"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 as TConfig,\n );\n return this.executeChat(content, prompt, config as TConfig);\n }\n\n public async generateTitle(content: string, config?: Omit<TConfig, \"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 as TConfig,\n );\n return this.executeChat(content, prompt, config as TConfig);\n }\n\n public async extractKeywords(content: string, config?: Omit<TConfig, \"output\">): Promise<string[]> {\n const count = config?.count;\n const countInstruction = count ? ` Return exactly ${count} keywords.` : \"\";\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.${countInstruction}`,\n config as TConfig,\n );\n\n const result = await this.executeChat(content, prompt, config as TConfig);\n\n const items = result\n .split(\",\")\n .map((keyword) => keyword.trim())\n .filter((keyword) => keyword.length > 0);\n\n return count ? items.slice(0, count) : items;\n }\n\n public async extractCategories(content: string, config?: Omit<TConfig, \"output\">): Promise<string[]> {\n const count = config?.count;\n const countInstruction = count ? ` Return exactly ${count} categories.` : \"\";\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.${countInstruction}`,\n config as TConfig,\n );\n\n const result = await this.executeChat(content, prompt, config as TConfig);\n\n const items = result\n .split(\",\")\n .map((category) => category.trim())\n .filter((category) => category.length > 0);\n\n return count ? items.slice(0, count) : items;\n }\n\n public async extractTopics(content: string, config?: Omit<TConfig, \"output\">): Promise<string[]> {\n const count = config?.count;\n const countInstruction = count ? ` Return at most ${count} topics.` : \"\";\n const prompt = this.buildPrompt(\n `Extract the main topics discussed in the following text. Return only the topics as a comma-separated list without numbering, brackets, or additional formatting.${countInstruction}`,\n config as TConfig,\n );\n\n const result = await this.executeChat(content, prompt, config as TConfig);\n\n const items = result\n .split(\",\")\n .map((topic) => topic.trim())\n .filter((topic) => topic.length > 0);\n\n return count ? items.slice(0, count) : items;\n }\n\n public async generateCaseQuestion(\n subject: string,\n options?: GenerateCaseQuestionOptionsType,\n config?: TConfig,\n ): Promise<GenerateCaseQuestionResultType> {\n const questionCount = options?.questionCount ?? 3;\n const choiceCount = options?.choiceCount;\n const difficulty = Math.min(100, Math.max(1, options?.difficulty ?? 50));\n\n const choiceInstructions = choiceCount\n ? [\n `Each question must have exactly ${choiceCount} choices.`,\n \"Exactly 1 of the choices must be correct.\",\n \"For each choice (both correct and wrong), provide an explanation in approximately 50 words.\",\n ]\n : [];\n\n const jsonFormat = choiceCount\n ? `{\"title\":\"...\",\"presentation\":\"...\",\"questions\":[{\"text\":\"...\",\"answer\":\"...\",\"explanation\":\"...\",\"choices\":[{\"text\":\"...\",\"isCorrect\":true/false,\"explanation\":\"...\"},...]},...]}`\n : `{\"title\":\"...\",\"presentation\":\"...\",\"questions\":[{\"text\":\"...\",\"answer\":\"...\",\"explanation\":\"...\"},...]}`;\n\n const prompt = this.buildPrompt(\n [\n \"Generate a clinical case study with questions about the following subject.\",\n `Difficulty level: ${difficulty}/100. At easy difficulty (1-25), present straightforward cases with classic presentations. At medium difficulty (26-50), include cases requiring differential diagnosis and standard management. At hard difficulty (51-75), present atypical presentations or cases with complicating factors. At expert difficulty (76-100), present rare conditions, complex multi-system cases, or cases requiring nuanced clinical reasoning.`,\n ...(options?.similarCase\n ? [\n `Generate a case similar in style and topic to: \"${options.similarCase}\". The new case must be different but cover a closely related clinical scenario.`,\n ]\n : []),\n \"Create a detailed clinical presentation with patient demographics, symptoms, history, and relevant findings.\",\n `Generate exactly ${questionCount} questions about the case, numbered sequentially.`,\n \"Each question must have a direct answer and a detailed explanation.\",\n ...choiceInstructions,\n \"Respond ONLY with valid JSON in this exact format:\",\n jsonFormat,\n ].join(\"\\n\"),\n config,\n );\n\n const result = await this.executeChat(subject, prompt, config);\n\n const cleaned = result.replace(/```json\\n?|\\n?```/g, \"\").trim();\n const parsed = JSON.parse(cleaned) as GenerateCaseQuestionResultType;\n\n return parsed;\n }\n\n public async generateFlashcard(\n subject: string,\n options?: GenerateFlashcardOptionsType,\n config?: TConfig,\n ): Promise<GenerateFlashcardResultType> {\n const difficulty = Math.min(100, Math.max(1, options?.difficulty ?? 50));\n\n const prompt = this.buildPrompt(\n [\n \"Generate a flashcard about the following subject.\",\n `Difficulty level: ${difficulty}/100. At easy difficulty (1-25), cover basic definitions and simple facts. At medium difficulty (26-50), cover concepts requiring understanding and application. At hard difficulty (51-75), cover analysis and connections between concepts. At expert difficulty (76-100), cover nuanced details, edge cases, and advanced reasoning.`,\n ...(options?.similarFlashcard\n ? [\n `Generate a flashcard similar in style and topic to: \"${options.similarFlashcard}\". The new flashcard must be different but cover a closely related concept.`,\n ]\n : []),\n \"The front should be a clear, concise question or prompt.\",\n \"The back should be a direct answer.\",\n \"The explanation should provide additional context in approximately 50 words.\",\n \"Respond ONLY with valid JSON in this exact format:\",\n `{\"front\":\"...\",\"back\":\"...\",\"explanation\":\"...\"}`,\n ].join(\"\\n\"),\n config,\n );\n\n const result = await this.executeChat(subject, prompt, config);\n\n const cleaned = result.replace(/```json\\n?|\\n?```/g, \"\").trim();\n const parsed = JSON.parse(cleaned) as GenerateFlashcardResultType;\n\n return parsed;\n }\n\n public async generateQuestion(\n subject: string,\n options?: GenerateQuestionOptionsType,\n config?: TConfig,\n ): Promise<GenerateQuestionResultType> {\n const choiceCount = options?.choiceCount ?? 5;\n const correctChoiceCount = options?.correctChoiceCount ?? 1;\n const difficulty = Math.min(100, Math.max(1, options?.difficulty ?? 50));\n\n const prompt = this.buildPrompt(\n [\n \"Generate a multiple-choice question (MCQ) about the following subject.\",\n `Difficulty level: ${difficulty}/100. At easy difficulty (1-25), ask basic recall questions with obviously wrong distractors. At medium difficulty (26-50), require understanding and application with plausible distractors. At hard difficulty (51-75), test analysis and synthesis with closely related distractors that require careful reasoning. At expert difficulty (76-100), test deep analysis, edge cases, and subtle distinctions where wrong choices are very close to being correct.`,\n `The question must have exactly ${choiceCount} choices.`,\n `Exactly ${correctChoiceCount} of the choices must be correct.`,\n ...(options?.similarQuestion\n ? [\n `Generate a question similar in style and topic to: \"${options.similarQuestion}\". The new question must be different but cover a closely related concept.`,\n ]\n : []),\n \"For each choice (both correct and wrong), provide an explanation in approximately 50 words.\",\n \"Respond ONLY with valid JSON in this exact format:\",\n `{\"question\":\"...\",\"choices\":[{\"text\":\"...\",\"isCorrect\":true/false,\"explanation\":\"...\"},...]}`,\n ].join(\"\\n\"),\n config,\n );\n\n const result = await this.executeChat(subject, prompt, config);\n\n const cleaned = result.replace(/```json\\n?|\\n?```/g, \"\").trim();\n const parsed = JSON.parse(cleaned) as GenerateQuestionResultType;\n\n return parsed;\n }\n\n public async imageToMarkdown(source: AiImageSourceType, config?: Omit<TConfig, \"output\">): Promise<string> {\n const adapter = this.createChatAdapter(config as TConfig);\n\n const systemPrompt = this.buildPrompt(\n \"Convert the content of the provided image into well-structured Markdown. Preserve the document structure including headings, lists, tables, code blocks, and formatting. Transcribe all visible text accurately.\",\n config as TConfig,\n );\n\n const baseMessages: ModelMessage[] = config?.messages ? this.toMessages(config.messages) : [];\n const userMessage: ModelMessage = {\n role: \"user\",\n content: [\n { type: \"text\", content: systemPrompt },\n { type: \"image\", source: { type: source.type, value: source.value } },\n ],\n };\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 run<T>(prompt: string, config?: Omit<TConfig, \"prompt\">): Promise<T> {\n const adapter = this.createRunAdapter(config as TConfig);\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 as TConfig);\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 public async *runStream(\n prompt: string,\n config?: Omit<TConfig, \"prompt\" | \"output\">,\n ): AsyncGenerator<string, void, unknown> {\n const adapter = this.createRunAdapter(config as TConfig);\n\n const defaultPrompt = \"Process the following request and respond appropriately.\";\n const systemPrompt = this.buildPrompt(defaultPrompt, config as TConfig);\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
8
  "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"
9
+ "import type { ImageGenerationResult, TTSResult } from \"@tanstack/ai\";\nimport { generateImage, generateSpeech } from \"@tanstack/ai\";\nimport { createGeminiChat, createGeminiImage, createGeminiSpeech } from \"@tanstack/ai-gemini\";\nimport { AiException } from \"./AiException\";\nimport { BaseAi } from \"./BaseAi\";\nimport { decorator } from \"./decorators\";\nimport type {\n GeminiConfigType,\n GeminiGenerateImageOptionsType,\n GeminiModelType,\n GeminiTextToSpeechOptionsType,\n} from \"./types\";\n\n@decorator.ai()\nexport class GeminiAi extends BaseAi<GeminiConfigType> {\n private getApiKey(config?: { apiKey?: string }): 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 protected createChatAdapter(config?: GeminiConfigType) {\n const apiKey = this.getApiKey(config);\n const model: GeminiModelType = config?.model ?? \"gemini-2.0-flash\";\n return createGeminiChat(model, apiKey);\n }\n\n protected createRunAdapter(config?: GeminiConfigType) {\n const apiKey = this.getApiKey(config);\n const model: GeminiModelType = config?.model ?? \"gemini-2.5-pro\";\n return createGeminiChat(model, apiKey);\n }\n\n public async textToSpeech(text: string, options?: GeminiTextToSpeechOptionsType): Promise<TTSResult> {\n const apiKey = this.getApiKey(options);\n const model = options?.model ?? \"gemini-2.5-flash-preview-tts\";\n const adapter = createGeminiSpeech(model, apiKey);\n\n const modelOptions: Record<string, unknown> = {};\n\n if (options?.voice) {\n modelOptions.voiceConfig = {\n prebuiltVoiceConfig: {\n voiceName: options.voice,\n },\n };\n }\n\n if (options?.instructions) {\n modelOptions.systemInstruction = options.instructions;\n }\n\n if (options?.language) {\n modelOptions.languageCode = options.language;\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: exactOptionalPropertyTypes requires careful handling\n const speechOptions: Record<string, any> = { adapter, text };\n\n if (options?.format) {\n speechOptions.format = options.format;\n }\n\n if (options?.speed) {\n speechOptions.speed = options.speed;\n }\n\n if (Object.keys(modelOptions).length > 0) {\n speechOptions.modelOptions = modelOptions;\n }\n\n return generateSpeech(speechOptions as Parameters<typeof generateSpeech>[0]);\n }\n\n public async generateImage(prompt: string, options?: GeminiGenerateImageOptionsType): Promise<ImageGenerationResult> {\n const apiKey = this.getApiKey(options);\n const model = options?.model ?? \"imagen-4.0-generate-001\";\n const adapter = createGeminiImage(model, apiKey);\n\n // biome-ignore lint/suspicious/noExplicitAny: exactOptionalPropertyTypes requires careful handling\n const imageOptions: Record<string, any> = { adapter, prompt };\n\n if (options?.numberOfImages) {\n imageOptions.numberOfImages = options.numberOfImages;\n }\n if (options?.size) {\n imageOptions.size = options.size;\n }\n\n const modelOptions: Record<string, unknown> = {};\n if (options?.aspectRatio) {\n modelOptions.aspectRatio = options.aspectRatio;\n }\n if (options?.personGeneration) {\n modelOptions.personGeneration = options.personGeneration;\n }\n if (options?.negativePrompt) {\n modelOptions.negativePrompt = options.negativePrompt;\n }\n if (options?.addWatermark !== undefined) {\n modelOptions.addWatermark = options.addWatermark;\n }\n if (options?.outputMimeType) {\n modelOptions.outputMimeType = options.outputMimeType;\n }\n if (Object.keys(modelOptions).length > 0) {\n imageOptions.modelOptions = modelOptions;\n }\n\n return generateImage(imageOptions as Parameters<typeof generateImage>[0]);\n }\n}\n",
10
+ "import type { TTSResult } from \"@tanstack/ai\";\nimport { createGroqText } from \"@tanstack/ai-groq\";\nimport { AiException } from \"./AiException\";\nimport { BaseAi } from \"./BaseAi\";\nimport { decorator } from \"./decorators\";\nimport type { GroqConfigType, GroqModelType, GroqTextToSpeechOptionsType } from \"./types\";\n\n@decorator.ai()\nexport class GroqAi extends BaseAi<GroqConfigType> {\n private getApiKey(config?: { apiKey?: string }): string {\n const apiKey = config?.apiKey || Bun.env.GROQ_API_KEY;\n\n if (!apiKey) {\n throw new AiException(\n \"Groq API key is required. Provide an API key through config options or set the GROQ_API_KEY environment variable.\",\n );\n }\n\n return apiKey;\n }\n\n protected createChatAdapter(config?: GroqConfigType) {\n const apiKey = this.getApiKey(config);\n const model = (config?.model ?? \"llama-3.3-70b-versatile\") as GroqModelType;\n return createGroqText(model, apiKey);\n }\n\n protected createRunAdapter(config?: GroqConfigType) {\n return this.createChatAdapter(config);\n }\n\n public async textToSpeech(text: string, options?: GroqTextToSpeechOptionsType): Promise<TTSResult> {\n const apiKey = this.getApiKey(options);\n const model = options?.model ?? \"canopylabs/orpheus-v1-english\";\n const voice = options?.voice ?? \"autumn\";\n const format = options?.format ?? \"wav\";\n\n // biome-ignore lint/suspicious/noExplicitAny: exactOptionalPropertyTypes requires careful handling\n const body: Record<string, any> = {\n model,\n input: text,\n voice,\n response_format: format,\n };\n\n if (options?.sampleRate) {\n body.sample_rate = options.sampleRate;\n }\n\n const response = await fetch(\"https://api.groq.com/openai/v1/audio/speech\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new AiException(`Groq TTS request failed (${response.status}): ${error}`);\n }\n\n const arrayBuffer = await response.arrayBuffer();\n const audio = Buffer.from(arrayBuffer).toString(\"base64\");\n\n return {\n id: response.headers.get(\"x-request-id\") ?? crypto.randomUUID(),\n model,\n audio,\n format,\n };\n }\n}\n",
11
+ "import { createOllamaChat } from \"@tanstack/ai-ollama\";\nimport { BaseAi } from \"./BaseAi\";\nimport { decorator } from \"./decorators\";\nimport type { OllamaConfigType, OllamaModelType } from \"./types\";\n\n@decorator.ai()\nexport class OllamaAi extends BaseAi<OllamaConfigType> {\n private getHost(config?: OllamaConfigType): string {\n return config?.host || Bun.env.OLLAMA_HOST || \"http://localhost:11434\";\n }\n\n protected createChatAdapter(config?: OllamaConfigType) {\n const host = this.getHost(config);\n const model: OllamaModelType = config?.model ?? \"llama3\";\n return createOllamaChat(model, host);\n }\n\n protected createRunAdapter(config?: OllamaConfigType) {\n return this.createChatAdapter(config);\n }\n}\n",
12
+ "import type { ImageGenerationResult, TranscriptionResult, TTSResult } from \"@tanstack/ai\";\nimport { generateImage, generateSpeech, generateTranscription } from \"@tanstack/ai\";\nimport {\n createOpenaiChat,\n createOpenaiImage,\n createOpenaiSpeech,\n createOpenaiTranscription,\n} from \"@tanstack/ai-openai\";\nimport { AiException } from \"./AiException\";\nimport { BaseAi } from \"./BaseAi\";\nimport { decorator } from \"./decorators\";\nimport type {\n OpenAiConfigType,\n OpenAiGenerateImageOptionsType,\n OpenAiModelType,\n OpenAiSpeechToTextOptionsType,\n OpenAiTextToSpeechOptionsType,\n} from \"./types\";\n\n@decorator.ai()\nexport class OpenAi extends BaseAi<OpenAiConfigType> {\n private getApiKey(config?: { apiKey?: string }): 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 protected createChatAdapter(config?: OpenAiConfigType) {\n const apiKey = this.getApiKey(config);\n const model: OpenAiModelType = config?.model ?? \"gpt-4o-mini\";\n return createOpenaiChat(model, apiKey);\n }\n\n protected createRunAdapter(config?: OpenAiConfigType) {\n const apiKey = this.getApiKey(config);\n const model: OpenAiModelType = config?.model ?? \"gpt-4o\";\n return createOpenaiChat(model, apiKey);\n }\n\n public async textToSpeech(text: string, options?: OpenAiTextToSpeechOptionsType): Promise<TTSResult> {\n const apiKey = this.getApiKey(options);\n const model = options?.model ?? \"tts-1\";\n const adapter = createOpenaiSpeech(model, apiKey);\n\n // biome-ignore lint/suspicious/noExplicitAny: exactOptionalPropertyTypes requires careful handling\n const speechOptions: Record<string, any> = { adapter, text };\n\n if (options?.voice) {\n speechOptions.voice = options.voice;\n }\n if (options?.format) {\n speechOptions.format = options.format;\n }\n if (options?.speed) {\n speechOptions.speed = options.speed;\n }\n const instructionParts: string[] = [];\n if (options?.language) {\n instructionParts.push(`Speak in ${options.language}.`);\n }\n if (options?.instructions) {\n instructionParts.push(options.instructions);\n }\n if (instructionParts.length > 0) {\n speechOptions.modelOptions = { instructions: instructionParts.join(\" \") };\n }\n\n return generateSpeech(speechOptions as Parameters<typeof generateSpeech>[0]);\n }\n\n public async speechToText(\n audio: string | File | Blob | ArrayBuffer,\n options?: OpenAiSpeechToTextOptionsType,\n ): Promise<TranscriptionResult> {\n const apiKey = this.getApiKey(options);\n const model = options?.model ?? \"gpt-4o-transcribe\";\n const adapter = createOpenaiTranscription(model, apiKey);\n\n // biome-ignore lint/suspicious/noExplicitAny: exactOptionalPropertyTypes requires careful handling\n const transcriptionOptions: Record<string, any> = { adapter, audio };\n\n if (options?.language) {\n transcriptionOptions.language = options.language;\n }\n if (options?.prompt) {\n transcriptionOptions.prompt = options.prompt;\n }\n if (options?.responseFormat) {\n transcriptionOptions.responseFormat = options.responseFormat;\n }\n if (options?.modelOptions) {\n transcriptionOptions.modelOptions = options.modelOptions;\n }\n\n return generateTranscription(transcriptionOptions as Parameters<typeof generateTranscription>[0]);\n }\n\n public async generateImage(prompt: string, options?: OpenAiGenerateImageOptionsType): Promise<ImageGenerationResult> {\n const apiKey = this.getApiKey(options);\n const model = options?.model ?? \"dall-e-3\";\n const adapter = createOpenaiImage(model, apiKey);\n\n // biome-ignore lint/suspicious/noExplicitAny: exactOptionalPropertyTypes requires careful handling\n const imageOptions: Record<string, any> = { adapter, prompt };\n\n if (options?.numberOfImages) {\n imageOptions.numberOfImages = options.numberOfImages;\n }\n if (options?.size) {\n imageOptions.size = options.size;\n }\n\n const modelOptions: Record<string, unknown> = {};\n if (options?.quality) {\n modelOptions.quality = options.quality;\n }\n if (options?.background) {\n modelOptions.background = options.background;\n }\n if (options?.outputFormat) {\n modelOptions.output_format = options.outputFormat;\n }\n if (options?.moderation) {\n modelOptions.moderation = options.moderation;\n }\n if (options?.style) {\n modelOptions.style = options.style;\n }\n if (Object.keys(modelOptions).length > 0) {\n imageOptions.modelOptions = modelOptions;\n }\n\n return generateImage(imageOptions as Parameters<typeof generateImage>[0]);\n }\n}\n"
11
13
  ],
12
- "mappings": "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",
13
- "debugId": "66CB2B945DCDCB8864756E2164756E21",
14
+ "mappings": "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",
15
+ "debugId": "C00944452078E5B764756E2164756E21",
14
16
  "names": []
15
17
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ooneex/ai",
3
- "description": "Unified AI client library with support for OpenAI, Anthropic, Google Gemini, and Ollama providers",
4
- "version": "0.0.18",
3
+ "description": "Multi-provider AI toolkit for TypeScript seamlessly integrate OpenAI, Anthropic Claude, Google Gemini, Groq, and Ollama with a unified API for text generation, streaming, and content transformation",
4
+ "version": "1.0.0",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist",
@@ -28,18 +28,19 @@
28
28
  "test": "bun test tests"
29
29
  },
30
30
  "dependencies": {
31
- "@ooneex/container": "0.0.18",
32
- "@ooneex/exception": "0.0.17",
33
- "@ooneex/http-status": "0.0.17",
34
- "@ooneex/validation": "0.0.17",
31
+ "@ooneex/container": "0.0.19",
32
+ "@ooneex/exception": "0.0.18",
33
+ "@ooneex/http-status": "0.0.18",
34
+ "@ooneex/validation": "0.0.19",
35
35
  "@tanstack/ai": "^0.2.0",
36
36
  "@tanstack/ai-anthropic": "^0.2.0",
37
37
  "@tanstack/ai-gemini": "^0.2.0",
38
+ "@tanstack/ai-groq": "^0.1.2",
38
39
  "@tanstack/ai-ollama": "^0.2.0",
39
40
  "@tanstack/ai-openai": "^0.2.0"
40
41
  },
41
42
  "devDependencies": {
42
- "@ooneex/translation": "0.0.17"
43
+ "@ooneex/translation": "0.0.18"
43
44
  },
44
45
  "keywords": [
45
46
  "ai",
@@ -47,6 +48,7 @@
47
48
  "artificial-intelligence",
48
49
  "bun",
49
50
  "gemini",
51
+ "groq",
50
52
  "llm",
51
53
  "machine-learning",
52
54
  "ollama",