@happyvertical/ai 0.80.0 → 0.80.2
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/dist/chunks/anthropic-DA8sdt12.js +438 -0
- package/dist/chunks/anthropic-DA8sdt12.js.map +1 -0
- package/dist/chunks/bedrock-DDiYFUw0.js +699 -0
- package/dist/chunks/bedrock-DDiYFUw0.js.map +1 -0
- package/dist/chunks/bifrost-fM9FpW_w.js +198 -0
- package/dist/chunks/bifrost-fM9FpW_w.js.map +1 -0
- package/dist/chunks/claude-cli-CnJh5KQT.js +498 -0
- package/dist/chunks/claude-cli-CnJh5KQT.js.map +1 -0
- package/dist/chunks/gateway-admin-CiKvHst7.js +283 -0
- package/dist/chunks/gateway-admin-CiKvHst7.js.map +1 -0
- package/dist/chunks/gemini-Bu7Fke7c.js +593 -0
- package/dist/chunks/gemini-Bu7Fke7c.js.map +1 -0
- package/dist/chunks/huggingface-B07_6wHW.js +295 -0
- package/dist/chunks/huggingface-B07_6wHW.js.map +1 -0
- package/dist/chunks/litellm-D_Oo9OQ_.js +185 -0
- package/dist/chunks/litellm-D_Oo9OQ_.js.map +1 -0
- package/dist/chunks/ollama-D4ksOTO8.js +626 -0
- package/dist/chunks/ollama-D4ksOTO8.js.map +1 -0
- package/dist/chunks/openai--F38QHiJ.js +691 -0
- package/dist/chunks/openai--F38QHiJ.js.map +1 -0
- package/dist/chunks/qwen-tts-DRRbOrhA.js +333 -0
- package/dist/chunks/qwen-tts-DRRbOrhA.js.map +1 -0
- package/dist/chunks/rate-limit-BwyPGXFW.js +199 -0
- package/dist/chunks/rate-limit-BwyPGXFW.js.map +1 -0
- package/dist/chunks/safety-CEnoJS6X.js +260 -0
- package/dist/chunks/safety-CEnoJS6X.js.map +1 -0
- package/dist/chunks/types-FHs-KbGL.js +117 -0
- package/dist/chunks/types-FHs-KbGL.js.map +1 -0
- package/dist/chunks/usage-C1Y1Nlg4.js +35 -0
- package/dist/chunks/usage-C1Y1Nlg4.js.map +1 -0
- package/dist/cli/claude-context.js +17 -17
- package/dist/cli/claude-context.js.map +1 -1
- package/dist/index.js +717 -23
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/dist/chunks/anthropic-2z-82zgr.js +0 -530
- package/dist/chunks/anthropic-2z-82zgr.js.map +0 -1
- package/dist/chunks/bedrock-Dc2eVPUD.js +0 -920
- package/dist/chunks/bedrock-Dc2eVPUD.js.map +0 -1
- package/dist/chunks/bifrost-CEnCsciy.js +0 -258
- package/dist/chunks/bifrost-CEnCsciy.js.map +0 -1
- package/dist/chunks/claude-cli-X1ONjE8K.js +0 -603
- package/dist/chunks/claude-cli-X1ONjE8K.js.map +0 -1
- package/dist/chunks/gateway-admin-BUhBzXZb.js +0 -359
- package/dist/chunks/gateway-admin-BUhBzXZb.js.map +0 -1
- package/dist/chunks/gemini-CS56gY0D.js +0 -768
- package/dist/chunks/gemini-CS56gY0D.js.map +0 -1
- package/dist/chunks/huggingface-wQSfO5xA.js +0 -411
- package/dist/chunks/huggingface-wQSfO5xA.js.map +0 -1
- package/dist/chunks/index-DCXO0nZA.js +0 -1293
- package/dist/chunks/index-DCXO0nZA.js.map +0 -1
- package/dist/chunks/litellm-BMFTYbWc.js +0 -245
- package/dist/chunks/litellm-BMFTYbWc.js.map +0 -1
- package/dist/chunks/ollama-DsGDrA-c.js +0 -962
- package/dist/chunks/ollama-DsGDrA-c.js.map +0 -1
- package/dist/chunks/openai-CJEo69jb.js +0 -882
- package/dist/chunks/openai-CJEo69jb.js.map +0 -1
- package/dist/chunks/qwen-tts-BLYZ6d9s.js +0 -365
- package/dist/chunks/qwen-tts-BLYZ6d9s.js.map +0 -1
- package/dist/chunks/usage-DMWiJ2oB.js +0 -21
- package/dist/chunks/usage-DMWiJ2oB.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,24 +1,718 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
P as PACKAGE_VERSION_INITIALIZED,
|
|
17
|
-
R as RateLimitError,
|
|
18
|
-
f as extractTextContent,
|
|
19
|
-
m as getAI,
|
|
20
|
-
o as getAIAuto,
|
|
21
|
-
q as getAIClient,
|
|
22
|
-
r as getOpenAI
|
|
1
|
+
import { a as ContextLengthError, c as extractTextContent, i as ContentFilterError, n as AI_PROVIDER_TYPES, o as ModelNotFoundError, r as AuthenticationError, s as RateLimitError, t as AIError } from "./chunks/types-FHs-KbGL.js";
|
|
2
|
+
import { t as createRateLimitedAI } from "./chunks/rate-limit-BwyPGXFW.js";
|
|
3
|
+
import { a as normalizeBaseAIOptions, i as createObservedAI, n as DEFAULT_AI_MAX_RETRIES, r as DEFAULT_AI_TIMEOUT_MS, t as DEFAULT_AI_GENERATION_LIMITS } from "./chunks/safety-CEnoJS6X.js";
|
|
4
|
+
import { ApiError, ValidationError, loadEnvConfig } from "@happyvertical/utils";
|
|
5
|
+
import OpenAI from "openai";
|
|
6
|
+
//#region \0rolldown/runtime.js
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __exportAll = (all, no_symbols) => {
|
|
9
|
+
let target = {};
|
|
10
|
+
for (var name in all) __defProp(target, name, {
|
|
11
|
+
get: all[name],
|
|
12
|
+
enumerable: true
|
|
13
|
+
});
|
|
14
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
15
|
+
return target;
|
|
23
16
|
};
|
|
24
|
-
//#
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/shared/client.ts
|
|
19
|
+
/**
|
|
20
|
+
* Type guard to check if options are for OpenAI client
|
|
21
|
+
*
|
|
22
|
+
* @param options - Options to check
|
|
23
|
+
* @returns True if options are valid for OpenAI client
|
|
24
|
+
*/
|
|
25
|
+
function isOpenAIClientOptions(options) {
|
|
26
|
+
return options.type === "openai" && "apiKey" in options && !!options.apiKey;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Type guard to check if value is an AI client instance
|
|
30
|
+
*
|
|
31
|
+
* @param value - Value to check
|
|
32
|
+
* @returns True if value is an AI client instance
|
|
33
|
+
*/
|
|
34
|
+
function isAIClientInstance(value) {
|
|
35
|
+
return value instanceof AIClient;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Base class for AI clients
|
|
39
|
+
* Provides a common interface for different AI service providers
|
|
40
|
+
*/
|
|
41
|
+
var AIClient = class {
|
|
42
|
+
/**
|
|
43
|
+
* Configuration options for this client
|
|
44
|
+
*/
|
|
45
|
+
options;
|
|
46
|
+
/**
|
|
47
|
+
* Creates a new AIClient
|
|
48
|
+
*
|
|
49
|
+
* @param options - Client configuration options
|
|
50
|
+
*/
|
|
51
|
+
constructor(options) {
|
|
52
|
+
this.options = options;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Sends a message to the AI
|
|
56
|
+
* Base implementation returns a placeholder response
|
|
57
|
+
*
|
|
58
|
+
* @param text - Message text
|
|
59
|
+
* @param options - Message options
|
|
60
|
+
* @returns Promise resolving to a placeholder response
|
|
61
|
+
*/
|
|
62
|
+
async message(_text, _options = { role: "user" }) {
|
|
63
|
+
return "not a real ai message, this is the base class!";
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Factory method to create appropriate AI client based on options
|
|
67
|
+
*
|
|
68
|
+
* @param options - Client configuration options
|
|
69
|
+
* @returns Promise resolving to an initialized AI client
|
|
70
|
+
* @throws Error if client type is invalid
|
|
71
|
+
*/
|
|
72
|
+
static async create(options) {
|
|
73
|
+
if (isAIClientInstance(options)) return options;
|
|
74
|
+
const clientOptions = options;
|
|
75
|
+
if (isOpenAIClientOptions(clientOptions)) return OpenAIClient.create(clientOptions);
|
|
76
|
+
const providedType = clientOptions.type;
|
|
77
|
+
if (providedType && providedType !== "openai") {
|
|
78
|
+
const { getAI } = await Promise.resolve().then(() => factory_exports);
|
|
79
|
+
return await getAI(clientOptions);
|
|
80
|
+
}
|
|
81
|
+
if (providedType === "openai") throw new ValidationError("OpenAI API key is required but missing or empty", {
|
|
82
|
+
supportedTypes: [...AI_PROVIDER_TYPES],
|
|
83
|
+
providedType,
|
|
84
|
+
hint: "Set OPENAI_API_KEY environment variable or pass apiKey in options"
|
|
85
|
+
});
|
|
86
|
+
throw new ValidationError("Invalid client type specified", {
|
|
87
|
+
supportedTypes: [...AI_PROVIDER_TYPES],
|
|
88
|
+
providedType
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Gets a text completion from the AI
|
|
93
|
+
* In base class, delegates to message method
|
|
94
|
+
*
|
|
95
|
+
* @param text - Input text for completion
|
|
96
|
+
* @param options - Completion options
|
|
97
|
+
* @returns Promise resolving to the completion result
|
|
98
|
+
*/
|
|
99
|
+
textCompletion(text, options = { role: "user" }) {
|
|
100
|
+
return this.message(text, options);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Creates an OpenAI client instance
|
|
105
|
+
*
|
|
106
|
+
* @param options - OpenAI configuration options
|
|
107
|
+
* @returns Promise resolving to an OpenAI client
|
|
108
|
+
*/
|
|
109
|
+
async function getOpenAI(options) {
|
|
110
|
+
return new OpenAI({
|
|
111
|
+
apiKey: options.apiKey,
|
|
112
|
+
baseURL: options.baseUrl
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Client implementation for the OpenAI API
|
|
117
|
+
*/
|
|
118
|
+
var OpenAIClient = class OpenAIClient extends AIClient {
|
|
119
|
+
/**
|
|
120
|
+
* OpenAI client instance
|
|
121
|
+
*/
|
|
122
|
+
openai;
|
|
123
|
+
/**
|
|
124
|
+
* Configuration options for this client
|
|
125
|
+
*/
|
|
126
|
+
options;
|
|
127
|
+
/**
|
|
128
|
+
* Creates a new OpenAIClient
|
|
129
|
+
*
|
|
130
|
+
* @param options - OpenAI client configuration options
|
|
131
|
+
*/
|
|
132
|
+
constructor(options) {
|
|
133
|
+
super(options);
|
|
134
|
+
this.options = options;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Sends a message to OpenAI
|
|
138
|
+
*
|
|
139
|
+
* @param text - Message text
|
|
140
|
+
* @param options - Message options
|
|
141
|
+
* @returns Promise resolving to the OpenAI response
|
|
142
|
+
*/
|
|
143
|
+
async message(text, options = { role: "user" }) {
|
|
144
|
+
return await this.textCompletion(text, options);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Factory method to create and initialize an OpenAIClient
|
|
148
|
+
*
|
|
149
|
+
* @param options - OpenAI client configuration options
|
|
150
|
+
* @returns Promise resolving to an initialized OpenAIClient
|
|
151
|
+
*/
|
|
152
|
+
static async create(options) {
|
|
153
|
+
const client = new OpenAIClient(options);
|
|
154
|
+
await client.initialize();
|
|
155
|
+
return client;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Initializes the OpenAI client
|
|
159
|
+
*/
|
|
160
|
+
async initialize() {
|
|
161
|
+
this.openai = new OpenAI({
|
|
162
|
+
apiKey: this.options.apiKey,
|
|
163
|
+
baseURL: this.options.baseUrl
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Sends a text completion request to the OpenAI API
|
|
168
|
+
*
|
|
169
|
+
* @param message - The message to send
|
|
170
|
+
* @param options - Configuration options for the completion request
|
|
171
|
+
* @returns Promise resolving to the completion text
|
|
172
|
+
* @throws Error if the OpenAI API response is invalid
|
|
173
|
+
*/
|
|
174
|
+
async textCompletion(message, options = {}) {
|
|
175
|
+
const { model = "gpt-4o", role = "user", history = [], name: _name, frequencyPenalty = 0, logitBias, logprobs = false, topLogprobs, maxTokens, n = 1, presencePenalty = 0, responseFormat, seed, stop, stream: _stream = false, temperature = 1, topProbability: topP = 1, tools, toolChoice, user, onProgress } = options;
|
|
176
|
+
const messages = [...history, {
|
|
177
|
+
role,
|
|
178
|
+
content: message
|
|
179
|
+
}];
|
|
180
|
+
if (onProgress) {
|
|
181
|
+
const stream = await this.openai.chat.completions.create({
|
|
182
|
+
model,
|
|
183
|
+
messages,
|
|
184
|
+
stream: true,
|
|
185
|
+
frequency_penalty: frequencyPenalty,
|
|
186
|
+
logit_bias: logitBias,
|
|
187
|
+
logprobs,
|
|
188
|
+
top_logprobs: topLogprobs,
|
|
189
|
+
max_tokens: maxTokens,
|
|
190
|
+
n,
|
|
191
|
+
presence_penalty: presencePenalty,
|
|
192
|
+
response_format: responseFormat,
|
|
193
|
+
seed,
|
|
194
|
+
stop,
|
|
195
|
+
temperature,
|
|
196
|
+
top_p: topP,
|
|
197
|
+
tools,
|
|
198
|
+
tool_choice: toolChoice,
|
|
199
|
+
user
|
|
200
|
+
});
|
|
201
|
+
let fullContent = "";
|
|
202
|
+
for await (const chunk of stream) {
|
|
203
|
+
const content = chunk.choices[0]?.delta?.content || "";
|
|
204
|
+
fullContent += content;
|
|
205
|
+
onProgress(content);
|
|
206
|
+
}
|
|
207
|
+
return fullContent;
|
|
208
|
+
}
|
|
209
|
+
const response = await this.openai.chat.completions.create({
|
|
210
|
+
model,
|
|
211
|
+
messages,
|
|
212
|
+
frequency_penalty: frequencyPenalty,
|
|
213
|
+
logit_bias: logitBias,
|
|
214
|
+
logprobs,
|
|
215
|
+
top_logprobs: topLogprobs,
|
|
216
|
+
max_tokens: maxTokens,
|
|
217
|
+
n,
|
|
218
|
+
presence_penalty: presencePenalty,
|
|
219
|
+
response_format: responseFormat,
|
|
220
|
+
seed,
|
|
221
|
+
stop,
|
|
222
|
+
stream: false,
|
|
223
|
+
temperature,
|
|
224
|
+
top_p: topP,
|
|
225
|
+
tools,
|
|
226
|
+
tool_choice: toolChoice,
|
|
227
|
+
user
|
|
228
|
+
});
|
|
229
|
+
const choice = response.choices[0];
|
|
230
|
+
if (!choice || !choice.message || !choice.message.content) throw new ApiError("Invalid response from OpenAI API: Missing content", {
|
|
231
|
+
model,
|
|
232
|
+
responseId: response.id,
|
|
233
|
+
choices: response.choices?.length || 0,
|
|
234
|
+
hasChoice: !!choice,
|
|
235
|
+
hasMessage: !!choice?.message,
|
|
236
|
+
hasContent: !!choice?.message?.content
|
|
237
|
+
});
|
|
238
|
+
return choice.message.content;
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
242
|
+
* Factory function to create and initialize an appropriate AI client
|
|
243
|
+
* Delegates to the modern getAI() factory for all provider types
|
|
244
|
+
*
|
|
245
|
+
* @param options - Client configuration options
|
|
246
|
+
* @returns Promise resolving to an initialized AI client
|
|
247
|
+
* @throws Error if client type is invalid
|
|
248
|
+
*/
|
|
249
|
+
async function getAIClient(options) {
|
|
250
|
+
const { getAI } = await Promise.resolve().then(() => factory_exports);
|
|
251
|
+
return await getAI(options);
|
|
252
|
+
}
|
|
253
|
+
//#endregion
|
|
254
|
+
//#region src/shared/factory.ts
|
|
255
|
+
/**
|
|
256
|
+
* Universal factory functions for creating AI provider instances
|
|
257
|
+
* Works in both browser and Node.js environments
|
|
258
|
+
*/
|
|
259
|
+
var factory_exports = /* @__PURE__ */ __exportAll({
|
|
260
|
+
getAI: () => getAI,
|
|
261
|
+
getAIAuto: () => getAIAuto
|
|
262
|
+
});
|
|
263
|
+
/**
|
|
264
|
+
* Type guards for provider options
|
|
265
|
+
*/
|
|
266
|
+
/**
|
|
267
|
+
* Checks if the options are for OpenAI provider
|
|
268
|
+
* @param options - The AI provider options to check
|
|
269
|
+
* @returns True if options are for OpenAI provider (including default case)
|
|
270
|
+
*/
|
|
271
|
+
function isOpenAIOptions(options) {
|
|
272
|
+
return !options.type || options.type === "openai";
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Checks if the options are for LiteLLM provider
|
|
276
|
+
* @param options - The AI provider options to check
|
|
277
|
+
* @returns True if options are for LiteLLM provider
|
|
278
|
+
*/
|
|
279
|
+
function isLiteLLMOptions(options) {
|
|
280
|
+
return options.type === "litellm";
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Checks if the options are for Bifrost provider
|
|
284
|
+
* @param options - The AI provider options to check
|
|
285
|
+
* @returns True if options are for Bifrost provider
|
|
286
|
+
*/
|
|
287
|
+
function isBifrostOptions(options) {
|
|
288
|
+
return options.type === "bifrost";
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Checks if the options are for Ollama provider
|
|
292
|
+
* @param options - The AI provider options to check
|
|
293
|
+
* @returns True if options are for Ollama provider
|
|
294
|
+
*/
|
|
295
|
+
function isOllamaOptions(options) {
|
|
296
|
+
return options.type === "ollama";
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Checks if the options are for Google Gemini provider
|
|
300
|
+
* @param options - The AI provider options to check
|
|
301
|
+
* @returns True if options are for Gemini provider
|
|
302
|
+
*/
|
|
303
|
+
function isGeminiOptions(options) {
|
|
304
|
+
return options.type === "gemini";
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Checks if the options are for Anthropic Claude provider
|
|
308
|
+
* @param options - The AI provider options to check
|
|
309
|
+
* @returns True if options are for Anthropic provider
|
|
310
|
+
*/
|
|
311
|
+
function isAnthropicOptions(options) {
|
|
312
|
+
return options.type === "anthropic";
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Checks if the options are for Hugging Face provider
|
|
316
|
+
* @param options - The AI provider options to check
|
|
317
|
+
* @returns True if options are for Hugging Face provider
|
|
318
|
+
*/
|
|
319
|
+
function isHuggingFaceOptions(options) {
|
|
320
|
+
return options.type === "huggingface";
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Checks if the options are for AWS Bedrock provider
|
|
324
|
+
* @param options - The AI provider options to check
|
|
325
|
+
* @returns True if options are for Bedrock provider
|
|
326
|
+
*/
|
|
327
|
+
function isBedrockOptions(options) {
|
|
328
|
+
return options.type === "bedrock";
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Checks if the options are for Claude CLI provider
|
|
332
|
+
* @param options - The AI provider options to check
|
|
333
|
+
* @returns True if options are for Claude CLI provider
|
|
334
|
+
*/
|
|
335
|
+
function isClaudeCliOptions(options) {
|
|
336
|
+
return options.type === "claude-cli";
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Checks if the options are for Qwen3-TTS provider
|
|
340
|
+
* @param options - The AI provider options to check
|
|
341
|
+
* @returns True if options are for Qwen3-TTS provider
|
|
342
|
+
*/
|
|
343
|
+
function isQwen3TTSOptions(options) {
|
|
344
|
+
return options.type === "qwen3-tts";
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Creates an AI provider instance based on the provided options.
|
|
348
|
+
* Universal version that works in both browser and Node.js environments.
|
|
349
|
+
*
|
|
350
|
+
* Supports environment variable configuration using the pattern:
|
|
351
|
+
* - HAVE_AI_PROVIDER → provider type (string)
|
|
352
|
+
* - HAVE_AI_MODEL → defaultModel (string)
|
|
353
|
+
* - HAVE_AI_TIMEOUT → timeout (number)
|
|
354
|
+
* - HAVE_AI_MAX_RETRIES → maxRetries (number)
|
|
355
|
+
* - HAVE_AI_API_KEY → apiKey (string) - fallback if provider-specific key not set
|
|
356
|
+
* - HAVE_AI_BASE_URL → baseUrl (string)
|
|
357
|
+
*
|
|
358
|
+
* User-provided options always take precedence over environment variables.
|
|
359
|
+
*
|
|
360
|
+
* Accepts both GetAIOptions (provider-specific options with literal types)
|
|
361
|
+
* and AIClientOptions (legacy interface with generic string type) for
|
|
362
|
+
* backward compatibility with existing code.
|
|
363
|
+
*
|
|
364
|
+
* @param options - Configuration options for the AI provider. Can be GetAIOptions or AIClientOptions.
|
|
365
|
+
* @returns Promise resolving to an AI provider instance that implements the AIInterface
|
|
366
|
+
* @throws {ValidationError} When the provider type is unsupported or invalid
|
|
367
|
+
*
|
|
368
|
+
* @example
|
|
369
|
+
* ```typescript
|
|
370
|
+
* // Create OpenAI client with explicit options
|
|
371
|
+
* const openai = await getAI({
|
|
372
|
+
* type: 'openai',
|
|
373
|
+
* apiKey: process.env.OPENAI_API_KEY!,
|
|
374
|
+
* defaultModel: 'gpt-4o'
|
|
375
|
+
* });
|
|
376
|
+
*
|
|
377
|
+
* // Or use environment variables (HAVE_AI_PROVIDER=openai, HAVE_AI_API_KEY=sk-...)
|
|
378
|
+
* const client = await getAI({});
|
|
379
|
+
*
|
|
380
|
+
* // Create Anthropic client
|
|
381
|
+
* const anthropic = await getAI({
|
|
382
|
+
* type: 'anthropic',
|
|
383
|
+
* apiKey: process.env.ANTHROPIC_API_KEY!,
|
|
384
|
+
* defaultModel: 'claude-3-5-sonnet-20241022'
|
|
385
|
+
* });
|
|
386
|
+
*
|
|
387
|
+
* // Works with AIClientOptions (legacy interface)
|
|
388
|
+
* const clientOptions: AIClientOptions = { type: 'openai', apiKey: '...' };
|
|
389
|
+
* const legacy = await getAI(clientOptions);
|
|
390
|
+
* ```
|
|
391
|
+
*/
|
|
392
|
+
async function getAI(options = {}) {
|
|
393
|
+
options = loadEnvConfig(options, {
|
|
394
|
+
packageName: "ai",
|
|
395
|
+
schema: {
|
|
396
|
+
provider: "string",
|
|
397
|
+
type: "string",
|
|
398
|
+
model: "string",
|
|
399
|
+
defaultModel: "string",
|
|
400
|
+
timeout: "number",
|
|
401
|
+
maxRetries: "number",
|
|
402
|
+
apiKey: "string",
|
|
403
|
+
baseUrl: "string",
|
|
404
|
+
adminApiKey: "string",
|
|
405
|
+
adminBaseUrl: "string",
|
|
406
|
+
adminUrl: "string",
|
|
407
|
+
adminUser: "string",
|
|
408
|
+
adminUsername: "string",
|
|
409
|
+
adminPassword: "string"
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
if ("provider" in options && !options.type) options.type = options.provider;
|
|
413
|
+
if ("model" in options && !options.defaultModel) options.defaultModel = options.model;
|
|
414
|
+
options = normalizeBaseAIOptions(options);
|
|
415
|
+
let client;
|
|
416
|
+
if (isOpenAIOptions(options)) {
|
|
417
|
+
const { OpenAIProvider } = await import("./chunks/openai--F38QHiJ.js");
|
|
418
|
+
client = new OpenAIProvider(options);
|
|
419
|
+
} else if (isLiteLLMOptions(options)) {
|
|
420
|
+
const { LiteLLMProvider } = await import("./chunks/litellm-D_Oo9OQ_.js");
|
|
421
|
+
client = new LiteLLMProvider(options);
|
|
422
|
+
} else if (isBifrostOptions(options)) {
|
|
423
|
+
const { BifrostProvider } = await import("./chunks/bifrost-fM9FpW_w.js");
|
|
424
|
+
client = new BifrostProvider(options);
|
|
425
|
+
} else if (isOllamaOptions(options)) {
|
|
426
|
+
const { OllamaProvider } = await import("./chunks/ollama-D4ksOTO8.js");
|
|
427
|
+
client = new OllamaProvider(options);
|
|
428
|
+
} else if (isGeminiOptions(options)) {
|
|
429
|
+
const { GeminiProvider } = await import("./chunks/gemini-Bu7Fke7c.js");
|
|
430
|
+
client = new GeminiProvider(options);
|
|
431
|
+
} else if (isAnthropicOptions(options)) {
|
|
432
|
+
const { AnthropicProvider } = await import("./chunks/anthropic-DA8sdt12.js");
|
|
433
|
+
client = new AnthropicProvider(options);
|
|
434
|
+
} else if (isHuggingFaceOptions(options)) {
|
|
435
|
+
const { HuggingFaceProvider } = await import("./chunks/huggingface-B07_6wHW.js");
|
|
436
|
+
client = new HuggingFaceProvider(options);
|
|
437
|
+
} else if (isBedrockOptions(options)) {
|
|
438
|
+
const { BedrockProvider } = await import("./chunks/bedrock-DDiYFUw0.js");
|
|
439
|
+
client = new BedrockProvider(options);
|
|
440
|
+
} else if (isClaudeCliOptions(options)) {
|
|
441
|
+
const { ClaudeCliProvider } = await import("./chunks/claude-cli-CnJh5KQT.js");
|
|
442
|
+
client = new ClaudeCliProvider(options);
|
|
443
|
+
} else if (isQwen3TTSOptions(options)) {
|
|
444
|
+
const { Qwen3TTSProvider } = await import("./chunks/qwen-tts-DRRbOrhA.js");
|
|
445
|
+
client = new Qwen3TTSProvider(options);
|
|
446
|
+
} else throw new ValidationError("Unsupported AI provider type", {
|
|
447
|
+
supportedTypes: [...AI_PROVIDER_TYPES],
|
|
448
|
+
providedType: options.type
|
|
449
|
+
});
|
|
450
|
+
return createObservedAI(createRateLimitedAI(client, options), options);
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Browser-compatible auto-detection of AI provider based on available credentials.
|
|
454
|
+
* Does not rely on process.env, making it suitable for browser environments.
|
|
455
|
+
*
|
|
456
|
+
* @param options - Configuration options that may contain provider-specific credentials
|
|
457
|
+
* @returns Promise resolving to an AI provider instance based on detected credentials
|
|
458
|
+
* @throws {ValidationError} When no provider can be detected from the provided options
|
|
459
|
+
*
|
|
460
|
+
* @example
|
|
461
|
+
* ```typescript
|
|
462
|
+
* // Auto-detect OpenAI from apiKey
|
|
463
|
+
* const client1 = await getAIAuto({
|
|
464
|
+
* apiKey: 'sk-...', // Detected as OpenAI
|
|
465
|
+
* defaultModel: 'gpt-4o'
|
|
466
|
+
* });
|
|
467
|
+
*
|
|
468
|
+
* // Auto-detect Hugging Face from apiToken
|
|
469
|
+
* const client2 = await getAIAuto({
|
|
470
|
+
* apiToken: 'hf_...', // Detected as Hugging Face
|
|
471
|
+
* model: 'microsoft/DialoGPT-medium'
|
|
472
|
+
* });
|
|
473
|
+
*
|
|
474
|
+
* // Auto-detect AWS Bedrock from region and credentials
|
|
475
|
+
* const client3 = await getAIAuto({
|
|
476
|
+
* region: 'us-east-1',
|
|
477
|
+
* credentials: {
|
|
478
|
+
* accessKeyId: 'AKIA...',
|
|
479
|
+
* secretAccessKey: 'xxx'
|
|
480
|
+
* }
|
|
481
|
+
* });
|
|
482
|
+
* ```
|
|
483
|
+
*/
|
|
484
|
+
async function getAIAuto(options) {
|
|
485
|
+
const baseUrl = String(options.baseUrl || "");
|
|
486
|
+
const hasKeepAliveOption = "keepAlive" in options && options.keepAlive !== void 0;
|
|
487
|
+
if (/((?:localhost|127\.0\.0\.1)(?::11434)?(?:\/(?:api|v1))?|ollama(?:\.com)?(?:\/(?:api|v1))?)\/?$/i.test(baseUrl) || hasKeepAliveOption) return getAI({
|
|
488
|
+
...options,
|
|
489
|
+
type: "ollama"
|
|
490
|
+
});
|
|
491
|
+
if (options.apiKey && !options.type) return getAI({
|
|
492
|
+
...options,
|
|
493
|
+
type: "openai"
|
|
494
|
+
});
|
|
495
|
+
if (options.apiToken) return getAI({
|
|
496
|
+
...options,
|
|
497
|
+
type: "huggingface"
|
|
498
|
+
});
|
|
499
|
+
if (options.region && options.credentials) return getAI({
|
|
500
|
+
...options,
|
|
501
|
+
type: "bedrock"
|
|
502
|
+
});
|
|
503
|
+
if (options.projectId || options.anthropicVersion) {
|
|
504
|
+
if (options.anthropicVersion) return getAI({
|
|
505
|
+
...options,
|
|
506
|
+
type: "anthropic"
|
|
507
|
+
});
|
|
508
|
+
if (options.projectId) return getAI({
|
|
509
|
+
...options,
|
|
510
|
+
type: "gemini"
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
throw new ValidationError("Could not auto-detect AI provider from options", {
|
|
514
|
+
hint: "Please specify a \"type\" field in options or provide provider-specific credentials",
|
|
515
|
+
supportedTypes: [...AI_PROVIDER_TYPES],
|
|
516
|
+
providedOptions: Object.keys(options)
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
//#endregion
|
|
520
|
+
//#region src/shared/message.ts
|
|
521
|
+
/**
|
|
522
|
+
* Represents a message in an AI conversation
|
|
523
|
+
*/
|
|
524
|
+
var AIMessage = class AIMessage {
|
|
525
|
+
/**
|
|
526
|
+
* Original options used to create this message
|
|
527
|
+
*/
|
|
528
|
+
options;
|
|
529
|
+
/**
|
|
530
|
+
* Name of the message sender
|
|
531
|
+
*/
|
|
532
|
+
name;
|
|
533
|
+
/**
|
|
534
|
+
* Content of the message
|
|
535
|
+
*/
|
|
536
|
+
content;
|
|
537
|
+
/**
|
|
538
|
+
* Role of the message sender in the conversation
|
|
539
|
+
*/
|
|
540
|
+
role;
|
|
541
|
+
/**
|
|
542
|
+
* Creates a new AI message
|
|
543
|
+
*
|
|
544
|
+
* @param options - Message configuration
|
|
545
|
+
* @param options.role - Role of the message sender
|
|
546
|
+
* @param options.content - Content of the message
|
|
547
|
+
* @param options.name - Name of the message sender
|
|
548
|
+
*/
|
|
549
|
+
constructor(options) {
|
|
550
|
+
this.options = options;
|
|
551
|
+
this.role = options.role;
|
|
552
|
+
this.content = options.content;
|
|
553
|
+
this.name = options.name;
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Factory method to create a new AI message
|
|
557
|
+
*
|
|
558
|
+
* @param options - Message configuration
|
|
559
|
+
* @param options.thread - Thread this message belongs to
|
|
560
|
+
* @param options.role - Role of the message sender
|
|
561
|
+
* @param options.content - Content of the message
|
|
562
|
+
* @param options.name - Name of the message sender
|
|
563
|
+
* @returns Promise resolving to a new AIMessage instance
|
|
564
|
+
*/
|
|
565
|
+
static async create(options) {
|
|
566
|
+
return new AIMessage(options);
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
//#endregion
|
|
570
|
+
//#region src/shared/thread.ts
|
|
571
|
+
/**
|
|
572
|
+
* Represents a conversation thread with an AI model
|
|
573
|
+
* Manages messages, references, and conversation state
|
|
574
|
+
*/
|
|
575
|
+
var AIThread = class AIThread {
|
|
576
|
+
/**
|
|
577
|
+
* AI client instance for this thread
|
|
578
|
+
*/
|
|
579
|
+
ai;
|
|
580
|
+
/**
|
|
581
|
+
* Options used to configure this thread
|
|
582
|
+
*/
|
|
583
|
+
options;
|
|
584
|
+
/**
|
|
585
|
+
* Messages in this conversation thread
|
|
586
|
+
*/
|
|
587
|
+
messages = [];
|
|
588
|
+
/**
|
|
589
|
+
* Reference materials to include in the conversation context
|
|
590
|
+
*/
|
|
591
|
+
references = {};
|
|
592
|
+
/**
|
|
593
|
+
* Creates a new AI thread
|
|
594
|
+
*
|
|
595
|
+
* @param options - Thread configuration options
|
|
596
|
+
*/
|
|
597
|
+
constructor(options) {
|
|
598
|
+
this.options = options;
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Factory method to create and initialize a new AI thread
|
|
602
|
+
*
|
|
603
|
+
* @param options - Thread configuration options
|
|
604
|
+
* @returns Promise resolving to an initialized AIThread
|
|
605
|
+
*/
|
|
606
|
+
static async create(options) {
|
|
607
|
+
const thread = new AIThread(options);
|
|
608
|
+
await thread.initialize();
|
|
609
|
+
return thread;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Initializes the AI client for this thread
|
|
613
|
+
*/
|
|
614
|
+
async initialize() {
|
|
615
|
+
this.ai = await AIClient.create(this.options.ai);
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Adds a system message to the conversation
|
|
619
|
+
*
|
|
620
|
+
* @param prompt - System message content
|
|
621
|
+
* @returns Promise resolving to the created AIMessage
|
|
622
|
+
*/
|
|
623
|
+
async addSystem(prompt) {
|
|
624
|
+
const message = await AIMessage.create({
|
|
625
|
+
thread: this,
|
|
626
|
+
role: "system",
|
|
627
|
+
name: "system",
|
|
628
|
+
content: prompt
|
|
629
|
+
});
|
|
630
|
+
this.messages.push(message);
|
|
631
|
+
return message;
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Adds a message to the conversation
|
|
635
|
+
*
|
|
636
|
+
* @param options - Message options
|
|
637
|
+
* @param options.role - Role of the message sender
|
|
638
|
+
* @param options.name - Optional name of the message sender
|
|
639
|
+
* @param options.content - Content of the message
|
|
640
|
+
* @returns Promise resolving to the created AIMessage
|
|
641
|
+
*/
|
|
642
|
+
async add(options) {
|
|
643
|
+
const message = await AIMessage.create({
|
|
644
|
+
thread: this,
|
|
645
|
+
role: options.role,
|
|
646
|
+
name: options.name || options.role,
|
|
647
|
+
content: options.content
|
|
648
|
+
});
|
|
649
|
+
this.messages.push(message);
|
|
650
|
+
return message;
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Gets all messages in this thread
|
|
654
|
+
*
|
|
655
|
+
* @returns Array of AIMessage objects
|
|
656
|
+
*/
|
|
657
|
+
get() {
|
|
658
|
+
return this.messages;
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Adds a reference to be included in the conversation context
|
|
662
|
+
*
|
|
663
|
+
* @param name - Name of the reference
|
|
664
|
+
* @param body - Content of the reference
|
|
665
|
+
*/
|
|
666
|
+
addReference(name, body) {
|
|
667
|
+
this.references[name] = body;
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* Assembles the conversation history for sending to the AI
|
|
671
|
+
* Properly orders system message, references, and conversation messages
|
|
672
|
+
*
|
|
673
|
+
* @returns Array of message parameters formatted for the OpenAI API
|
|
674
|
+
*/
|
|
675
|
+
assembleHistory() {
|
|
676
|
+
const history = [];
|
|
677
|
+
const systemMessage = this.messages.find((m) => m.role === "system");
|
|
678
|
+
if (systemMessage) history.push({
|
|
679
|
+
role: systemMessage.role,
|
|
680
|
+
content: systemMessage.content
|
|
681
|
+
});
|
|
682
|
+
for (const name in this.references) history.push({
|
|
683
|
+
role: "user",
|
|
684
|
+
content: `Reference - ${name}:\n${this.references[name]}`
|
|
685
|
+
});
|
|
686
|
+
this.messages.filter((m) => m.role !== "system").forEach((message) => {
|
|
687
|
+
history.push({
|
|
688
|
+
role: message.role,
|
|
689
|
+
content: message.content
|
|
690
|
+
});
|
|
691
|
+
});
|
|
692
|
+
return history;
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Sends a prompt to the AI and gets a response
|
|
696
|
+
*
|
|
697
|
+
* @param prompt - Prompt message to send
|
|
698
|
+
* @param options - Options for the AI response
|
|
699
|
+
* @param options.responseFormat - Format for the AI to respond with
|
|
700
|
+
* @returns Promise resolving to the AI response
|
|
701
|
+
*/
|
|
702
|
+
async do(prompt, options = { responseFormat: "text" }) {
|
|
703
|
+
const { responseFormat } = options;
|
|
704
|
+
const history = this.assembleHistory();
|
|
705
|
+
return await this.ai.textCompletion(prompt, {
|
|
706
|
+
history,
|
|
707
|
+
responseFormat: { type: responseFormat === "json" ? "json_object" : "text" }
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
//#endregion
|
|
712
|
+
//#region src/index.ts
|
|
713
|
+
/** @internal */
|
|
714
|
+
var PACKAGE_VERSION_INITIALIZED = true;
|
|
715
|
+
//#endregion
|
|
716
|
+
export { AIClient, AIError, AIMessage as AIMessageClass, AIThread, AI_PROVIDER_TYPES, AuthenticationError, ContentFilterError, ContextLengthError, DEFAULT_AI_GENERATION_LIMITS, DEFAULT_AI_MAX_RETRIES, DEFAULT_AI_TIMEOUT_MS, ModelNotFoundError, OpenAIClient, PACKAGE_VERSION_INITIALIZED, RateLimitError, extractTextContent, getAI, getAIAuto, getAIClient, getOpenAI };
|
|
717
|
+
|
|
718
|
+
//# sourceMappingURL=index.js.map
|