@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 +7 -23
- package/dist/index.d.ts +191 -153
- package/dist/index.js +12 -47
- package/dist/index.js.map +9 -7
- package/package.json +9 -7
package/README.md
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
# @ooneex/ai
|
|
2
2
|
|
|
3
|
-
|
|
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
|

|
|
6
|
-

|
|
7
|
-

|
|
8
6
|

|
|
9
7
|

|
|
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 {
|
|
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 =
|
|
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<
|
|
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
|
|
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
|
-
|
|
70
|
-
|
|
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
|
-
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
|
251
|
+
declare class OllamaAi extends BaseAi<OllamaConfigType> {
|
|
150
252
|
private getHost;
|
|
151
|
-
|
|
152
|
-
|
|
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
|
-
|
|
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
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
`)
|
|
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
|
-
${
|
|
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: ${
|
|
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
|
-
${
|
|
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
|
-
${
|
|
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
|
-
|
|
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": "
|
|
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": "
|
|
4
|
-
"version": "0.0
|
|
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.
|
|
32
|
-
"@ooneex/exception": "0.0.
|
|
33
|
-
"@ooneex/http-status": "0.0.
|
|
34
|
-
"@ooneex/validation": "0.0.
|
|
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.
|
|
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",
|