@happyvertical/ai 0.85.3 → 0.85.5

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.
Files changed (84) hide show
  1. package/README.md +87 -1
  2. package/dist/chunks/{anthropic-DA8sdt12.js → anthropic-DuYUnw8j.js} +20 -4
  3. package/dist/chunks/anthropic-DuYUnw8j.js.map +1 -0
  4. package/dist/chunks/{bedrock-DDiYFUw0.js → bedrock-ikQJAwWB.js} +19 -3
  5. package/dist/chunks/bedrock-ikQJAwWB.js.map +1 -0
  6. package/dist/chunks/{bifrost-fM9FpW_w.js → bifrost-CaYhelVL.js} +5 -4
  7. package/dist/chunks/bifrost-CaYhelVL.js.map +1 -0
  8. package/dist/chunks/byteplus-modelark-B8l8sPXu.js +473 -0
  9. package/dist/chunks/byteplus-modelark-B8l8sPXu.js.map +1 -0
  10. package/dist/chunks/{claude-cli-CnJh5KQT.js → claude-cli-DeTKk9nu.js} +19 -3
  11. package/dist/chunks/claude-cli-DeTKk9nu.js.map +1 -0
  12. package/dist/chunks/{gateway-admin-CiKvHst7.js → gateway-admin-DJXEDpUP.js} +2 -2
  13. package/dist/chunks/{gateway-admin-CiKvHst7.js.map → gateway-admin-DJXEDpUP.js.map} +1 -1
  14. package/dist/chunks/{gemini-Bu7Fke7c.js → gemini-BT8fjXWz.js} +294 -11
  15. package/dist/chunks/gemini-BT8fjXWz.js.map +1 -0
  16. package/dist/chunks/{huggingface-B07_6wHW.js → huggingface-CqzyxeLB.js} +19 -3
  17. package/dist/chunks/huggingface-CqzyxeLB.js.map +1 -0
  18. package/dist/chunks/{litellm-D_Oo9OQ_.js → litellm-viqTuSY8.js} +5 -4
  19. package/dist/chunks/litellm-viqTuSY8.js.map +1 -0
  20. package/dist/chunks/{ollama-D4ksOTO8.js → ollama-CdWqwZ05.js} +19 -3
  21. package/dist/chunks/ollama-CdWqwZ05.js.map +1 -0
  22. package/dist/chunks/{openai--F38QHiJ.js → openai-BgrK3OfW.js} +20 -4
  23. package/dist/chunks/openai-BgrK3OfW.js.map +1 -0
  24. package/dist/chunks/openai-compat-video-D_U7jo0d.js +369 -0
  25. package/dist/chunks/openai-compat-video-D_U7jo0d.js.map +1 -0
  26. package/dist/chunks/{qwen-tts-DRRbOrhA.js → qwen-tts-BXjzY7DX.js} +21 -4
  27. package/dist/chunks/qwen-tts-BXjzY7DX.js.map +1 -0
  28. package/dist/chunks/{rate-limit-BwyPGXFW.js → rate-limit-DgEhanDL.js} +4 -3
  29. package/dist/chunks/rate-limit-DgEhanDL.js.map +1 -0
  30. package/dist/chunks/{safety-CEnoJS6X.js → safety-C415clBm.js} +25 -7
  31. package/dist/chunks/safety-C415clBm.js.map +1 -0
  32. package/dist/chunks/src-CU4qWJ2c.js +740 -0
  33. package/dist/chunks/src-CU4qWJ2c.js.map +1 -0
  34. package/dist/chunks/{types-FHs-KbGL.js → types-CINwUPDo.js} +4 -2
  35. package/dist/chunks/types-CINwUPDo.js.map +1 -0
  36. package/dist/index.js +3 -717
  37. package/dist/node/factory.d.ts +9 -0
  38. package/dist/node/factory.d.ts.map +1 -1
  39. package/dist/node.d.ts +29 -0
  40. package/dist/node.d.ts.map +1 -0
  41. package/dist/node.js +198 -0
  42. package/dist/node.js.map +1 -0
  43. package/dist/shared/factory.d.ts.map +1 -1
  44. package/dist/shared/providers/anthropic.d.ts +6 -1
  45. package/dist/shared/providers/anthropic.d.ts.map +1 -1
  46. package/dist/shared/providers/bedrock.d.ts +6 -1
  47. package/dist/shared/providers/bedrock.d.ts.map +1 -1
  48. package/dist/shared/providers/bifrost.d.ts.map +1 -1
  49. package/dist/shared/providers/byteplus-modelark.d.ts +91 -0
  50. package/dist/shared/providers/byteplus-modelark.d.ts.map +1 -0
  51. package/dist/shared/providers/claude-cli.d.ts +6 -1
  52. package/dist/shared/providers/claude-cli.d.ts.map +1 -1
  53. package/dist/shared/providers/gemini.d.ts +115 -2
  54. package/dist/shared/providers/gemini.d.ts.map +1 -1
  55. package/dist/shared/providers/huggingface.d.ts +6 -1
  56. package/dist/shared/providers/huggingface.d.ts.map +1 -1
  57. package/dist/shared/providers/litellm.d.ts.map +1 -1
  58. package/dist/shared/providers/ollama.d.ts +6 -1
  59. package/dist/shared/providers/ollama.d.ts.map +1 -1
  60. package/dist/shared/providers/openai-compat-video.d.ts +98 -0
  61. package/dist/shared/providers/openai-compat-video.d.ts.map +1 -0
  62. package/dist/shared/providers/openai.d.ts +6 -1
  63. package/dist/shared/providers/openai.d.ts.map +1 -1
  64. package/dist/shared/providers/qwen-tts.d.ts +6 -1
  65. package/dist/shared/providers/qwen-tts.d.ts.map +1 -1
  66. package/dist/shared/rate-limit.d.ts.map +1 -1
  67. package/dist/shared/safety.d.ts.map +1 -1
  68. package/dist/shared/types.d.ts +343 -5
  69. package/dist/shared/types.d.ts.map +1 -1
  70. package/package.json +7 -3
  71. package/dist/chunks/anthropic-DA8sdt12.js.map +0 -1
  72. package/dist/chunks/bedrock-DDiYFUw0.js.map +0 -1
  73. package/dist/chunks/bifrost-fM9FpW_w.js.map +0 -1
  74. package/dist/chunks/claude-cli-CnJh5KQT.js.map +0 -1
  75. package/dist/chunks/gemini-Bu7Fke7c.js.map +0 -1
  76. package/dist/chunks/huggingface-B07_6wHW.js.map +0 -1
  77. package/dist/chunks/litellm-D_Oo9OQ_.js.map +0 -1
  78. package/dist/chunks/ollama-D4ksOTO8.js.map +0 -1
  79. package/dist/chunks/openai--F38QHiJ.js.map +0 -1
  80. package/dist/chunks/qwen-tts-DRRbOrhA.js.map +0 -1
  81. package/dist/chunks/rate-limit-BwyPGXFW.js.map +0 -1
  82. package/dist/chunks/safety-CEnoJS6X.js.map +0 -1
  83. package/dist/chunks/types-FHs-KbGL.js.map +0 -1
  84. package/dist/index.js.map +0 -1
@@ -0,0 +1,740 @@
1
+ import { n as AI_PROVIDER_TYPES } from "./types-CINwUPDo.js";
2
+ import { t as createRateLimitedAI } from "./rate-limit-DgEhanDL.js";
3
+ import { a as normalizeBaseAIOptions, i as createObservedAI } from "./safety-C415clBm.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;
16
+ };
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
+ * Checks if the options are for the OpenAI-compatible video-generation provider
348
+ * @param options - The AI provider options to check
349
+ * @returns True if options are for the openai-compat-video provider
350
+ */
351
+ function isOpenAICompatVideoOptions(options) {
352
+ return options.type === "openai-compat-video";
353
+ }
354
+ /**
355
+ * Checks if the options are for the BytePlus ModelArk (Seedance) provider
356
+ * @param options - The AI provider options to check
357
+ * @returns True if options are for the byteplus-modelark provider
358
+ */
359
+ function isByteplusModelArkOptions(options) {
360
+ return options.type === "byteplus-modelark";
361
+ }
362
+ /**
363
+ * Creates an AI provider instance based on the provided options.
364
+ * Universal version that works in both browser and Node.js environments.
365
+ *
366
+ * Supports environment variable configuration using the pattern:
367
+ * - HAVE_AI_PROVIDER → provider type (string)
368
+ * - HAVE_AI_MODEL → defaultModel (string)
369
+ * - HAVE_AI_TIMEOUT → timeout (number)
370
+ * - HAVE_AI_MAX_RETRIES → maxRetries (number)
371
+ * - HAVE_AI_API_KEY → apiKey (string) - fallback if provider-specific key not set
372
+ * - HAVE_AI_BASE_URL → baseUrl (string)
373
+ *
374
+ * User-provided options always take precedence over environment variables.
375
+ *
376
+ * Accepts both GetAIOptions (provider-specific options with literal types)
377
+ * and AIClientOptions (legacy interface with generic string type) for
378
+ * backward compatibility with existing code.
379
+ *
380
+ * @param options - Configuration options for the AI provider. Can be GetAIOptions or AIClientOptions.
381
+ * @returns Promise resolving to an AI provider instance that implements the AIInterface
382
+ * @throws {ValidationError} When the provider type is unsupported or invalid
383
+ *
384
+ * @example
385
+ * ```typescript
386
+ * // Create OpenAI client with explicit options
387
+ * const openai = await getAI({
388
+ * type: 'openai',
389
+ * apiKey: process.env.OPENAI_API_KEY!,
390
+ * defaultModel: 'gpt-4o'
391
+ * });
392
+ *
393
+ * // Or use environment variables (HAVE_AI_PROVIDER=openai, HAVE_AI_API_KEY=sk-...)
394
+ * const client = await getAI({});
395
+ *
396
+ * // Create Anthropic client
397
+ * const anthropic = await getAI({
398
+ * type: 'anthropic',
399
+ * apiKey: process.env.ANTHROPIC_API_KEY!,
400
+ * defaultModel: 'claude-3-5-sonnet-20241022'
401
+ * });
402
+ *
403
+ * // Works with AIClientOptions (legacy interface)
404
+ * const clientOptions: AIClientOptions = { type: 'openai', apiKey: '...' };
405
+ * const legacy = await getAI(clientOptions);
406
+ * ```
407
+ */
408
+ async function getAI(options = {}) {
409
+ options = loadEnvConfig(options, {
410
+ packageName: "ai",
411
+ schema: {
412
+ provider: "string",
413
+ type: "string",
414
+ model: "string",
415
+ defaultModel: "string",
416
+ timeout: "number",
417
+ maxRetries: "number",
418
+ apiKey: "string",
419
+ baseUrl: "string",
420
+ adminApiKey: "string",
421
+ adminBaseUrl: "string",
422
+ adminUrl: "string",
423
+ adminUser: "string",
424
+ adminUsername: "string",
425
+ adminPassword: "string"
426
+ }
427
+ });
428
+ if ("provider" in options && !options.type) options.type = options.provider;
429
+ if ("model" in options && !options.defaultModel) options.defaultModel = options.model;
430
+ options = normalizeBaseAIOptions(options);
431
+ let client;
432
+ if (isOpenAIOptions(options)) {
433
+ const { OpenAIProvider } = await import("./openai-BgrK3OfW.js");
434
+ client = new OpenAIProvider(options);
435
+ } else if (isLiteLLMOptions(options)) {
436
+ const { LiteLLMProvider } = await import("./litellm-viqTuSY8.js");
437
+ client = new LiteLLMProvider(options);
438
+ } else if (isBifrostOptions(options)) {
439
+ const { BifrostProvider } = await import("./bifrost-CaYhelVL.js");
440
+ client = new BifrostProvider(options);
441
+ } else if (isOllamaOptions(options)) {
442
+ const { OllamaProvider } = await import("./ollama-CdWqwZ05.js");
443
+ client = new OllamaProvider(options);
444
+ } else if (isGeminiOptions(options)) {
445
+ const { GeminiProvider } = await import("./gemini-BT8fjXWz.js");
446
+ client = new GeminiProvider(options);
447
+ } else if (isAnthropicOptions(options)) {
448
+ const { AnthropicProvider } = await import("./anthropic-DuYUnw8j.js");
449
+ client = new AnthropicProvider(options);
450
+ } else if (isHuggingFaceOptions(options)) {
451
+ const { HuggingFaceProvider } = await import("./huggingface-CqzyxeLB.js");
452
+ client = new HuggingFaceProvider(options);
453
+ } else if (isBedrockOptions(options)) {
454
+ const { BedrockProvider } = await import("./bedrock-ikQJAwWB.js");
455
+ client = new BedrockProvider(options);
456
+ } else if (isClaudeCliOptions(options)) {
457
+ const { ClaudeCliProvider } = await import("./claude-cli-DeTKk9nu.js");
458
+ client = new ClaudeCliProvider(options);
459
+ } else if (isQwen3TTSOptions(options)) {
460
+ const { Qwen3TTSProvider } = await import("./qwen-tts-BXjzY7DX.js");
461
+ client = new Qwen3TTSProvider(options);
462
+ } else if (isOpenAICompatVideoOptions(options)) {
463
+ const { OpenAICompatVideoProvider } = await import("./openai-compat-video-D_U7jo0d.js");
464
+ client = new OpenAICompatVideoProvider(options);
465
+ } else if (isByteplusModelArkOptions(options)) {
466
+ const { ByteplusModelArkProvider } = await import("./byteplus-modelark-B8l8sPXu.js");
467
+ client = new ByteplusModelArkProvider(options);
468
+ } else throw new ValidationError("Unsupported AI provider type", {
469
+ supportedTypes: [...AI_PROVIDER_TYPES],
470
+ providedType: options.type
471
+ });
472
+ return createObservedAI(createRateLimitedAI(client, options), options);
473
+ }
474
+ /**
475
+ * Browser-compatible auto-detection of AI provider based on available credentials.
476
+ * Does not rely on process.env, making it suitable for browser environments.
477
+ *
478
+ * @param options - Configuration options that may contain provider-specific credentials
479
+ * @returns Promise resolving to an AI provider instance based on detected credentials
480
+ * @throws {ValidationError} When no provider can be detected from the provided options
481
+ *
482
+ * @example
483
+ * ```typescript
484
+ * // Auto-detect OpenAI from apiKey
485
+ * const client1 = await getAIAuto({
486
+ * apiKey: 'sk-...', // Detected as OpenAI
487
+ * defaultModel: 'gpt-4o'
488
+ * });
489
+ *
490
+ * // Auto-detect Hugging Face from apiToken
491
+ * const client2 = await getAIAuto({
492
+ * apiToken: 'hf_...', // Detected as Hugging Face
493
+ * model: 'microsoft/DialoGPT-medium'
494
+ * });
495
+ *
496
+ * // Auto-detect AWS Bedrock from region and credentials
497
+ * const client3 = await getAIAuto({
498
+ * region: 'us-east-1',
499
+ * credentials: {
500
+ * accessKeyId: 'AKIA...',
501
+ * secretAccessKey: 'xxx'
502
+ * }
503
+ * });
504
+ * ```
505
+ */
506
+ async function getAIAuto(options) {
507
+ const baseUrl = String(options.baseUrl || "");
508
+ const hasKeepAliveOption = "keepAlive" in options && options.keepAlive !== void 0;
509
+ if (/((?:localhost|127\.0\.0\.1)(?::11434)?(?:\/(?:api|v1))?|ollama(?:\.com)?(?:\/(?:api|v1))?)\/?$/i.test(baseUrl) || hasKeepAliveOption) return getAI({
510
+ ...options,
511
+ type: "ollama"
512
+ });
513
+ if (options.apiKey && !options.type) return getAI({
514
+ ...options,
515
+ type: "openai"
516
+ });
517
+ if (options.apiToken) return getAI({
518
+ ...options,
519
+ type: "huggingface"
520
+ });
521
+ if (options.region && options.credentials) return getAI({
522
+ ...options,
523
+ type: "bedrock"
524
+ });
525
+ if (options.projectId || options.anthropicVersion) {
526
+ if (options.anthropicVersion) return getAI({
527
+ ...options,
528
+ type: "anthropic"
529
+ });
530
+ if (options.projectId) return getAI({
531
+ ...options,
532
+ type: "gemini"
533
+ });
534
+ }
535
+ throw new ValidationError("Could not auto-detect AI provider from options", {
536
+ hint: "Please specify a \"type\" field in options or provide provider-specific credentials",
537
+ supportedTypes: [...AI_PROVIDER_TYPES],
538
+ providedOptions: Object.keys(options)
539
+ });
540
+ }
541
+ //#endregion
542
+ //#region src/shared/message.ts
543
+ /**
544
+ * Represents a message in an AI conversation
545
+ */
546
+ var AIMessage = class AIMessage {
547
+ /**
548
+ * Original options used to create this message
549
+ */
550
+ options;
551
+ /**
552
+ * Name of the message sender
553
+ */
554
+ name;
555
+ /**
556
+ * Content of the message
557
+ */
558
+ content;
559
+ /**
560
+ * Role of the message sender in the conversation
561
+ */
562
+ role;
563
+ /**
564
+ * Creates a new AI message
565
+ *
566
+ * @param options - Message configuration
567
+ * @param options.role - Role of the message sender
568
+ * @param options.content - Content of the message
569
+ * @param options.name - Name of the message sender
570
+ */
571
+ constructor(options) {
572
+ this.options = options;
573
+ this.role = options.role;
574
+ this.content = options.content;
575
+ this.name = options.name;
576
+ }
577
+ /**
578
+ * Factory method to create a new AI message
579
+ *
580
+ * @param options - Message configuration
581
+ * @param options.thread - Thread this message belongs to
582
+ * @param options.role - Role of the message sender
583
+ * @param options.content - Content of the message
584
+ * @param options.name - Name of the message sender
585
+ * @returns Promise resolving to a new AIMessage instance
586
+ */
587
+ static async create(options) {
588
+ return new AIMessage(options);
589
+ }
590
+ };
591
+ //#endregion
592
+ //#region src/shared/thread.ts
593
+ /**
594
+ * Represents a conversation thread with an AI model
595
+ * Manages messages, references, and conversation state
596
+ */
597
+ var AIThread = class AIThread {
598
+ /**
599
+ * AI client instance for this thread
600
+ */
601
+ ai;
602
+ /**
603
+ * Options used to configure this thread
604
+ */
605
+ options;
606
+ /**
607
+ * Messages in this conversation thread
608
+ */
609
+ messages = [];
610
+ /**
611
+ * Reference materials to include in the conversation context
612
+ */
613
+ references = {};
614
+ /**
615
+ * Creates a new AI thread
616
+ *
617
+ * @param options - Thread configuration options
618
+ */
619
+ constructor(options) {
620
+ this.options = options;
621
+ }
622
+ /**
623
+ * Factory method to create and initialize a new AI thread
624
+ *
625
+ * @param options - Thread configuration options
626
+ * @returns Promise resolving to an initialized AIThread
627
+ */
628
+ static async create(options) {
629
+ const thread = new AIThread(options);
630
+ await thread.initialize();
631
+ return thread;
632
+ }
633
+ /**
634
+ * Initializes the AI client for this thread
635
+ */
636
+ async initialize() {
637
+ this.ai = await AIClient.create(this.options.ai);
638
+ }
639
+ /**
640
+ * Adds a system message to the conversation
641
+ *
642
+ * @param prompt - System message content
643
+ * @returns Promise resolving to the created AIMessage
644
+ */
645
+ async addSystem(prompt) {
646
+ const message = await AIMessage.create({
647
+ thread: this,
648
+ role: "system",
649
+ name: "system",
650
+ content: prompt
651
+ });
652
+ this.messages.push(message);
653
+ return message;
654
+ }
655
+ /**
656
+ * Adds a message to the conversation
657
+ *
658
+ * @param options - Message options
659
+ * @param options.role - Role of the message sender
660
+ * @param options.name - Optional name of the message sender
661
+ * @param options.content - Content of the message
662
+ * @returns Promise resolving to the created AIMessage
663
+ */
664
+ async add(options) {
665
+ const message = await AIMessage.create({
666
+ thread: this,
667
+ role: options.role,
668
+ name: options.name || options.role,
669
+ content: options.content
670
+ });
671
+ this.messages.push(message);
672
+ return message;
673
+ }
674
+ /**
675
+ * Gets all messages in this thread
676
+ *
677
+ * @returns Array of AIMessage objects
678
+ */
679
+ get() {
680
+ return this.messages;
681
+ }
682
+ /**
683
+ * Adds a reference to be included in the conversation context
684
+ *
685
+ * @param name - Name of the reference
686
+ * @param body - Content of the reference
687
+ */
688
+ addReference(name, body) {
689
+ this.references[name] = body;
690
+ }
691
+ /**
692
+ * Assembles the conversation history for sending to the AI
693
+ * Properly orders system message, references, and conversation messages
694
+ *
695
+ * @returns Array of message parameters formatted for the OpenAI API
696
+ */
697
+ assembleHistory() {
698
+ const history = [];
699
+ const systemMessage = this.messages.find((m) => m.role === "system");
700
+ if (systemMessage) history.push({
701
+ role: systemMessage.role,
702
+ content: systemMessage.content
703
+ });
704
+ for (const name in this.references) history.push({
705
+ role: "user",
706
+ content: `Reference - ${name}:\n${this.references[name]}`
707
+ });
708
+ this.messages.filter((m) => m.role !== "system").forEach((message) => {
709
+ history.push({
710
+ role: message.role,
711
+ content: message.content
712
+ });
713
+ });
714
+ return history;
715
+ }
716
+ /**
717
+ * Sends a prompt to the AI and gets a response
718
+ *
719
+ * @param prompt - Prompt message to send
720
+ * @param options - Options for the AI response
721
+ * @param options.responseFormat - Format for the AI to respond with
722
+ * @returns Promise resolving to the AI response
723
+ */
724
+ async do(prompt, options = { responseFormat: "text" }) {
725
+ const { responseFormat } = options;
726
+ const history = this.assembleHistory();
727
+ return await this.ai.textCompletion(prompt, {
728
+ history,
729
+ responseFormat: { type: responseFormat === "json" ? "json_object" : "text" }
730
+ });
731
+ }
732
+ };
733
+ //#endregion
734
+ //#region src/index.ts
735
+ /** @internal */
736
+ var PACKAGE_VERSION_INITIALIZED = true;
737
+ //#endregion
738
+ export { getAI as a, OpenAIClient as c, factory_exports as i, getAIClient as l, AIThread as n, getAIAuto as o, AIMessage as r, AIClient as s, PACKAGE_VERSION_INITIALIZED as t, getOpenAI as u };
739
+
740
+ //# sourceMappingURL=src-CU4qWJ2c.js.map