ai.libx.js 0.1.1 → 0.2.1

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 (76) hide show
  1. package/README.md +7 -1
  2. package/build/AIClient.js +12 -3
  3. package/build/AIClient.js.map +1 -1
  4. package/build/adapters/ai21.js +2 -1
  5. package/build/adapters/ai21.js.map +1 -1
  6. package/build/adapters/anthropic.js +3 -2
  7. package/build/adapters/anthropic.js.map +1 -1
  8. package/build/adapters/base/BaseAdapter.js +10 -1
  9. package/build/adapters/base/BaseAdapter.js.map +1 -1
  10. package/build/adapters/cloudflare.js +2 -1
  11. package/build/adapters/cloudflare.js.map +1 -1
  12. package/build/adapters/cohere.js +4 -3
  13. package/build/adapters/cohere.js.map +1 -1
  14. package/build/adapters/deepseek.js +2 -1
  15. package/build/adapters/deepseek.js.map +1 -1
  16. package/build/adapters/google.d.ts +10 -0
  17. package/build/adapters/google.js +277 -14
  18. package/build/adapters/google.js.map +1 -1
  19. package/build/adapters/groq.js +2 -1
  20. package/build/adapters/groq.js.map +1 -1
  21. package/build/adapters/mistral.js +2 -1
  22. package/build/adapters/mistral.js.map +1 -1
  23. package/build/adapters/openai.d.ts +1 -0
  24. package/build/adapters/openai.js +136 -16
  25. package/build/adapters/openai.js.map +1 -1
  26. package/build/adapters/openrouter.js +11 -9
  27. package/build/adapters/openrouter.js.map +1 -1
  28. package/build/adapters/xai.js +2 -1
  29. package/build/adapters/xai.js.map +1 -1
  30. package/build/index.d.ts +6 -5
  31. package/build/index.js +14 -2
  32. package/build/index.js.map +1 -1
  33. package/build/models.d.ts +274 -1
  34. package/build/models.js +11 -11
  35. package/build/models.js.map +1 -1
  36. package/build/types/index.d.ts +71 -1
  37. package/build/types/index.js.map +1 -1
  38. package/build/utils/content-helpers.d.ts +2 -0
  39. package/build/utils/content-helpers.js +13 -0
  40. package/build/utils/content-helpers.js.map +1 -0
  41. package/build/utils/errors.d.ts +19 -1
  42. package/build/utils/errors.js +90 -6
  43. package/build/utils/errors.js.map +1 -1
  44. package/build/utils/message-helpers.d.ts +10 -0
  45. package/build/utils/message-helpers.js +57 -0
  46. package/build/utils/message-helpers.js.map +1 -0
  47. package/build/utils/model-normalization.d.ts +1 -2
  48. package/build/utils/model-normalization.js +12 -40
  49. package/build/utils/model-normalization.js.map +1 -1
  50. package/build/utils/validation.js +23 -2
  51. package/build/utils/validation.js.map +1 -1
  52. package/example-google-features.ts +480 -0
  53. package/example-retry.ts +114 -0
  54. package/example.ts +235 -7
  55. package/package.json +16 -2
  56. package/src/AIClient.ts +24 -6
  57. package/src/adapters/ai21.ts +2 -1
  58. package/src/adapters/anthropic.ts +3 -2
  59. package/src/adapters/base/BaseAdapter.ts +14 -1
  60. package/src/adapters/cloudflare.ts +2 -1
  61. package/src/adapters/cohere.ts +4 -3
  62. package/src/adapters/deepseek.ts +2 -1
  63. package/src/adapters/google.ts +409 -18
  64. package/src/adapters/groq.ts +2 -1
  65. package/src/adapters/mistral.ts +2 -1
  66. package/src/adapters/openai.ts +190 -10
  67. package/src/adapters/openrouter.ts +8 -3
  68. package/src/adapters/xai.ts +2 -1
  69. package/src/index.ts +28 -4
  70. package/src/models.ts +16 -13
  71. package/src/types/index.ts +91 -2
  72. package/src/utils/content-helpers.ts +20 -0
  73. package/src/utils/errors.ts +134 -4
  74. package/src/utils/message-helpers.ts +96 -0
  75. package/src/utils/model-normalization.ts +18 -67
  76. package/src/utils/validation.ts +40 -2
package/README.md CHANGED
@@ -279,7 +279,8 @@ import {
279
279
  normalizeModelName,
280
280
  isReasoningModel,
281
281
  supportsSystemMessages,
282
- getReasoningModelAdjustments
282
+ getReasoningModelAdjustments,
283
+ requiresMaxCompletionTokens
283
284
  } from 'ai.libx.js';
284
285
 
285
286
  // Resolve model aliases
@@ -295,6 +296,11 @@ isReasoningModel('deepseek/deepseek-reasoner'); // true
295
296
  supportsSystemMessages('openai/o1-preview'); // false (o1 doesn't support)
296
297
  supportsSystemMessages('openai/gpt-4o'); // true
297
298
 
299
+ // Check if model requires max_completion_tokens
300
+ requiresMaxCompletionTokens('openai/gpt-5-nano'); // true (GPT-5 models)
301
+ requiresMaxCompletionTokens('openai/o1-preview'); // true (o1/o3 models)
302
+ requiresMaxCompletionTokens('openai/gpt-4o'); // false (standard models)
303
+
298
304
  // Get required parameter adjustments
299
305
  const adjustments = getReasoningModelAdjustments('openai/o3-mini');
300
306
  // { temperature: 1, topP: 1, useMaxCompletionTokens: true }
package/build/AIClient.js CHANGED
@@ -13,7 +13,6 @@ exports.AIClient = void 0;
13
13
  const validation_1 = require("./utils/validation");
14
14
  const errors_1 = require("./utils/errors");
15
15
  const models_1 = require("./models");
16
- const model_normalization_1 = require("./utils/model-normalization");
17
16
  const request_logger_1 = require("./utils/request-logger");
18
17
  const openai_1 = require("./adapters/openai");
19
18
  const anthropic_1 = require("./adapters/anthropic");
@@ -35,8 +34,6 @@ class AIClient {
35
34
  chat(options) {
36
35
  return __awaiter(this, void 0, void 0, function* () {
37
36
  var _a, _b;
38
- const normalizedModel = (0, model_normalization_1.normalizeModelName)(options.model);
39
- options = Object.assign(Object.assign({}, options), { model: normalizedModel });
40
37
  (0, validation_1.validateChatOptions)(options);
41
38
  const provider = (0, models_1.getProviderFromModel)(options.model);
42
39
  if (!provider) {
@@ -45,6 +42,18 @@ class AIClient {
45
42
  if (!(0, models_1.isModelSupported)(options.model)) {
46
43
  throw new errors_1.ModelNotFoundError(options.model);
47
44
  }
45
+ const modelInfo = (0, models_1.getModelInfo)(options.model);
46
+ if (modelInfo) {
47
+ if (modelInfo.enabled === false) {
48
+ throw new errors_1.InvalidRequestError(`Model "${options.model}" is disabled and not available for use`);
49
+ }
50
+ if (modelInfo.noChat) {
51
+ throw new errors_1.InvalidRequestError(`Model "${options.model}" does not support chat completions (e.g., realtime/audio models)`);
52
+ }
53
+ if (modelInfo.knownIssues) {
54
+ console.warn(`⚠️ Warning: Model "${options.model}" has known issues: ${modelInfo.knownIssues}`);
55
+ }
56
+ }
48
57
  const adapter = this.getAdapter(provider);
49
58
  const chatOptions = Object.assign(Object.assign({}, options), { apiKey: options.apiKey || ((_a = this.config.apiKeys) === null || _a === void 0 ? void 0 : _a[provider]) });
50
59
  const tracker = this.logger.startRequest(provider, options.model);
@@ -1 +1 @@
1
- {"version":3,"file":"AIClient.js","sourceRoot":"","sources":["../src/AIClient.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChatOptions, ChatResponse, StreamChunk, ProviderConfig } from './types';\nimport { IProviderAdapter } from './types/provider';\nimport { validateChatOptions } from './utils/validation';\nimport { ModelNotFoundError, InvalidRequestError } from './utils/errors';\nimport { getProviderFromModel, isModelSupported } from './models';\nimport { normalizeModelName } from './utils/model-normalization';\nimport { RequestLogger, getRequestLogger } from './utils/request-logger';\n\n// Lazy import adapters\nimport { OpenAIAdapter } from './adapters/openai';\nimport { AnthropicAdapter } from './adapters/anthropic';\nimport { GoogleAdapter } from './adapters/google';\nimport { GroqAdapter } from './adapters/groq';\nimport { MistralAdapter } from './adapters/mistral';\nimport { CohereAdapter } from './adapters/cohere';\nimport { XAIAdapter } from './adapters/xai';\nimport { DeepSeekAdapter } from './adapters/deepseek';\nimport { AI21Adapter } from './adapters/ai21';\nimport { OpenRouterAdapter } from './adapters/openrouter';\nimport { CloudflareAdapter } from './adapters/cloudflare';\n\nexport interface AIClientConfig {\n\t/**\n\t * API keys for different providers\n\t * Example: { openai: 'sk-...', anthropic: 'sk-ant-...', google: '...' }\n\t */\n\tapiKeys?: Record<string, string>;\n\n\t/**\n\t * Base URLs for providers (optional, for custom endpoints)\n\t */\n\tbaseUrls?: Record<string, string>;\n\n\t/**\n\t * Cloudflare account ID (required for Cloudflare Workers AI)\n\t */\n\tcloudflareAccountId?: string;\n\n\t/**\n\t * Enable request logging for metrics tracking\n\t */\n\tenableLogging?: boolean;\n}\n\n/**\n * Main AI client class providing unified access to multiple AI providers\n */\nexport class AIClient {\n\tprivate config: AIClientConfig;\n\tprivate adapters: Map<string, IProviderAdapter> = new Map();\n\tprivate logger: RequestLogger;\n\n\tconstructor(config: AIClientConfig = {}) {\n\t\tthis.config = config;\n\t\tthis.logger = getRequestLogger(config.enableLogging || false);\n\t}\n\n\t/**\n\t * Execute a chat completion request\n\t * @param options Chat options including model, messages, and parameters\n\t * @returns ChatResponse for non-streaming, AsyncIterable<StreamChunk> for streaming\n\t */\n\tasync chat(options: ChatOptions): Promise<ChatResponse | AsyncIterable<StreamChunk>> {\n\t\t// Normalize model name (resolve aliases)\n\t\tconst normalizedModel = normalizeModelName(options.model);\n\t\toptions = { ...options, model: normalizedModel };\n\n\t\t// Validate options\n\t\tvalidateChatOptions(options);\n\n\t\t// Extract provider from model string\n\t\tconst provider = getProviderFromModel(options.model);\n\t\tif (!provider) {\n\t\t\tthrow new InvalidRequestError(\n\t\t\t\t`Invalid model format: \"${options.model}\". Expected format: \"provider/model-name\"`\n\t\t\t);\n\t\t}\n\n\t\t// Check if model is supported\n\t\tif (!isModelSupported(options.model)) {\n\t\t\tthrow new ModelNotFoundError(options.model);\n\t\t}\n\n\t\t// Get or create adapter\n\t\tconst adapter = this.getAdapter(provider);\n\n\t\t// Merge API keys from config if not provided in options\n\t\tconst chatOptions: ChatOptions = {\n\t\t\t...options,\n\t\t\tapiKey: options.apiKey || this.config.apiKeys?.[provider],\n\t\t};\n\n\t\t// Start request tracking\n\t\tconst tracker = this.logger.startRequest(provider, options.model);\n\n\t\ttry {\n\t\t\t// Execute chat\n\t\t\tconst result = await adapter.chat(chatOptions);\n\n\t\t\t// Log successful request\n\t\t\tif ('content' in result) {\n\t\t\t\tconst tokens = result.usage?.totalTokens;\n\t\t\t\tthis.logger.logRequest(tracker, true, tokens);\n\t\t\t} else {\n\t\t\t\t// Streaming - log without token count\n\t\t\t\tthis.logger.logRequest(tracker, true);\n\t\t\t}\n\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\t// Log failed request\n\t\t\tthis.logger.logRequest(\n\t\t\t\ttracker,\n\t\t\t\tfalse,\n\t\t\t\tundefined,\n\t\t\t\terror instanceof Error ? error.message : 'Unknown error'\n\t\t\t);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Get adapter for a provider (creates if not exists)\n\t */\n\tprivate getAdapter(provider: string): IProviderAdapter {\n\t\t// Return cached adapter if exists\n\t\tif (this.adapters.has(provider)) {\n\t\t\treturn this.adapters.get(provider)!;\n\t\t}\n\n\t\t// Create adapter config\n\t\tconst adapterConfig: ProviderConfig = {\n\t\t\tapiKey: this.config.apiKeys?.[provider],\n\t\t\tbaseUrl: this.config.baseUrls?.[provider],\n\t\t};\n\n\t\t// Add cloudflare-specific config\n\t\tif (provider === 'cloudflare') {\n\t\t\tadapterConfig.cloudflareAccountId = this.config.cloudflareAccountId;\n\t\t}\n\n\t\t// Create new adapter\n\t\tlet adapter: IProviderAdapter;\n\n\t\tswitch (provider) {\n\t\t\tcase 'openai':\n\t\t\t\tadapter = new OpenAIAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'anthropic':\n\t\t\t\tadapter = new AnthropicAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'google':\n\t\t\t\tadapter = new GoogleAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'groq':\n\t\t\t\tadapter = new GroqAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'mistral':\n\t\t\t\tadapter = new MistralAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'cohere':\n\t\t\t\tadapter = new CohereAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'xai':\n\t\t\t\tadapter = new XAIAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'deepseek':\n\t\t\t\tadapter = new DeepSeekAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'ai21':\n\t\t\t\tadapter = new AI21Adapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'openrouter':\n\t\t\t\tadapter = new OpenRouterAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'cloudflare':\n\t\t\t\tadapter = new CloudflareAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow new InvalidRequestError(`Unsupported provider: ${provider}`);\n\t\t}\n\n\t\t// Cache adapter\n\t\tthis.adapters.set(provider, adapter);\n\n\t\treturn adapter;\n\t}\n\n\t/**\n\t * Clear cached adapters (useful for testing or resetting state)\n\t */\n\tclearAdapters(): void {\n\t\tthis.adapters.clear();\n\t}\n\n\t/**\n\t * Get request logger for metrics\n\t */\n\tgetLogger(): RequestLogger {\n\t\treturn this.logger;\n\t}\n\n\t/**\n\t * Get request statistics\n\t */\n\tgetStats() {\n\t\treturn this.logger.getStats();\n\t}\n}\n\n"]}
1
+ {"version":3,"file":"AIClient.js","sourceRoot":"","sources":["../src/AIClient.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChatOptions, ChatResponse, StreamChunk, ProviderConfig } from './types';\nimport { IProviderAdapter } from './types/provider';\nimport { validateChatOptions } from './utils/validation';\nimport { ModelNotFoundError, InvalidRequestError } from './utils/errors';\nimport { getProviderFromModel, isModelSupported, getModelInfo } from './models';\nimport { RequestLogger, getRequestLogger } from './utils/request-logger';\n\n// Lazy import adapters\nimport { OpenAIAdapter } from './adapters/openai';\nimport { AnthropicAdapter } from './adapters/anthropic';\nimport { GoogleAdapter } from './adapters/google';\nimport { GroqAdapter } from './adapters/groq';\nimport { MistralAdapter } from './adapters/mistral';\nimport { CohereAdapter } from './adapters/cohere';\nimport { XAIAdapter } from './adapters/xai';\nimport { DeepSeekAdapter } from './adapters/deepseek';\nimport { AI21Adapter } from './adapters/ai21';\nimport { OpenRouterAdapter } from './adapters/openrouter';\nimport { CloudflareAdapter } from './adapters/cloudflare';\n\nexport interface AIClientConfig {\n\t/**\n\t * API keys for different providers\n\t * Example: { openai: 'sk-...', anthropic: 'sk-ant-...', google: '...' }\n\t */\n\tapiKeys?: Record<string, string>;\n\n\t/**\n\t * Base URLs for providers (optional, for custom endpoints)\n\t */\n\tbaseUrls?: Record<string, string>;\n\n\t/**\n\t * Cloudflare account ID (required for Cloudflare Workers AI)\n\t */\n\tcloudflareAccountId?: string;\n\n\t/**\n\t * Enable request logging for metrics tracking\n\t */\n\tenableLogging?: boolean;\n}\n\n/**\n * Main AI client class providing unified access to multiple AI providers\n */\nexport class AIClient {\n\tprivate config: AIClientConfig;\n\tprivate adapters: Map<string, IProviderAdapter> = new Map();\n\tprivate logger: RequestLogger;\n\n\tconstructor(config: AIClientConfig = {}) {\n\t\tthis.config = config;\n\t\tthis.logger = getRequestLogger(config.enableLogging || false);\n\t}\n\n\t/**\n\t * Execute a chat completion request\n\t * @param options Chat options including model, messages, and parameters\n\t * @returns ChatResponse for non-streaming, AsyncIterable<StreamChunk> for streaming\n\t */\n\tasync chat(options: ChatOptions): Promise<ChatResponse | AsyncIterable<StreamChunk>> {\n\t\t// Validate options\n\t\tvalidateChatOptions(options);\n\n\t\t// Extract provider from model string\n\t\tconst provider = getProviderFromModel(options.model);\n\t\tif (!provider) {\n\t\t\tthrow new InvalidRequestError(\n\t\t\t\t`Invalid model format: \"${options.model}\". Expected format: \"provider/model-name\"`\n\t\t\t);\n\t\t}\n\n\t\t// Check if model is supported\n\t\tif (!isModelSupported(options.model)) {\n\t\t\tthrow new ModelNotFoundError(options.model);\n\t\t}\n\n\t\t// Check model capabilities and issues\n\t\tconst modelInfo = getModelInfo(options.model);\n\t\tif (modelInfo) {\n\t\t\t// Check if model is enabled\n\t\t\tif (modelInfo.enabled === false) {\n\t\t\t\tthrow new InvalidRequestError(\n\t\t\t\t\t`Model \"${options.model}\" is disabled and not available for use`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Check if model supports chat\n\t\t\tif (modelInfo.noChat) {\n\t\t\t\tthrow new InvalidRequestError(\n\t\t\t\t\t`Model \"${options.model}\" does not support chat completions (e.g., realtime/audio models)`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Warn about known issues (but don't block)\n\t\t\tif (modelInfo.knownIssues) {\n\t\t\t\tconsole.warn(`⚠️ Warning: Model \"${options.model}\" has known issues: ${modelInfo.knownIssues}`);\n\t\t\t}\n\t\t}\n\n\t\t// Get or create adapter\n\t\tconst adapter = this.getAdapter(provider);\n\n\t\t// Merge API keys from config if not provided in options\n\t\tconst chatOptions: ChatOptions = {\n\t\t\t...options,\n\t\t\tapiKey: options.apiKey || this.config.apiKeys?.[provider],\n\t\t};\n\n\t\t// Start request tracking\n\t\tconst tracker = this.logger.startRequest(provider, options.model);\n\n\t\ttry {\n\t\t\t// Execute chat\n\t\t\tconst result = await adapter.chat(chatOptions);\n\n\t\t\t// Log successful request\n\t\t\tif ('content' in result) {\n\t\t\t\tconst tokens = result.usage?.totalTokens;\n\t\t\t\tthis.logger.logRequest(tracker, true, tokens);\n\t\t\t} else {\n\t\t\t\t// Streaming - log without token count\n\t\t\t\tthis.logger.logRequest(tracker, true);\n\t\t\t}\n\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\t// Log failed request\n\t\t\tthis.logger.logRequest(\n\t\t\t\ttracker,\n\t\t\t\tfalse,\n\t\t\t\tundefined,\n\t\t\t\terror instanceof Error ? error.message : 'Unknown error'\n\t\t\t);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Get adapter for a provider (creates if not exists)\n\t */\n\tprivate getAdapter(provider: string): IProviderAdapter {\n\t\t// Return cached adapter if exists\n\t\tif (this.adapters.has(provider)) {\n\t\t\treturn this.adapters.get(provider)!;\n\t\t}\n\n\t\t// Create adapter config\n\t\tconst adapterConfig: ProviderConfig = {\n\t\t\tapiKey: this.config.apiKeys?.[provider],\n\t\t\tbaseUrl: this.config.baseUrls?.[provider],\n\t\t};\n\n\t\t// Add cloudflare-specific config\n\t\tif (provider === 'cloudflare') {\n\t\t\tadapterConfig.cloudflareAccountId = this.config.cloudflareAccountId;\n\t\t}\n\n\t\t// Create new adapter\n\t\tlet adapter: IProviderAdapter;\n\n\t\tswitch (provider) {\n\t\t\tcase 'openai':\n\t\t\t\tadapter = new OpenAIAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'anthropic':\n\t\t\t\tadapter = new AnthropicAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'google':\n\t\t\t\tadapter = new GoogleAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'groq':\n\t\t\t\tadapter = new GroqAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'mistral':\n\t\t\t\tadapter = new MistralAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'cohere':\n\t\t\t\tadapter = new CohereAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'xai':\n\t\t\t\tadapter = new XAIAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'deepseek':\n\t\t\t\tadapter = new DeepSeekAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'ai21':\n\t\t\t\tadapter = new AI21Adapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'openrouter':\n\t\t\t\tadapter = new OpenRouterAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tcase 'cloudflare':\n\t\t\t\tadapter = new CloudflareAdapter(adapterConfig);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow new InvalidRequestError(`Unsupported provider: ${provider}`);\n\t\t}\n\n\t\t// Cache adapter\n\t\tthis.adapters.set(provider, adapter);\n\n\t\treturn adapter;\n\t}\n\n\t/**\n\t * Clear cached adapters (useful for testing or resetting state)\n\t */\n\tclearAdapters(): void {\n\t\tthis.adapters.clear();\n\t}\n\n\t/**\n\t * Get request logger for metrics\n\t */\n\tgetLogger(): RequestLogger {\n\t\treturn this.logger;\n\t}\n\n\t/**\n\t * Get request statistics\n\t */\n\tgetStats() {\n\t\treturn this.logger.getStats();\n\t}\n}\n\n"]}
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.AI21Adapter = void 0;
13
13
  const BaseAdapter_1 = require("./base/BaseAdapter");
14
14
  const errors_1 = require("../utils/errors");
15
+ const content_helpers_1 = require("../utils/content-helpers");
15
16
  class AI21Adapter extends BaseAdapter_1.BaseAdapter {
16
17
  get name() {
17
18
  return 'ai21';
@@ -57,7 +58,7 @@ class AI21Adapter extends BaseAdapter_1.BaseAdapter {
57
58
  transformMessages(messages) {
58
59
  return messages.map((msg) => ({
59
60
  role: msg.role,
60
- content: msg.content,
61
+ content: (0, content_helpers_1.contentToString)(msg.content),
61
62
  }));
62
63
  }
63
64
  handleNonStreamResponse(data, model) {
@@ -1 +1 @@
1
- {"version":3,"file":"ai21.js","sourceRoot":"","sources":["../../src/adapters/ai21.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseAdapter } from './base/BaseAdapter';\nimport { ChatOptions, ChatResponse, StreamChunk, Message } from '../types';\nimport { handleProviderError } from '../utils/errors';\n\ninterface AI21Message {\n\trole: string;\n\tcontent: string;\n}\n\ninterface AI21Request {\n\tmodel: string;\n\tmessages: AI21Message[];\n\ttemperature?: number;\n\tmax_tokens?: number;\n\ttop_p?: number;\n\tstop?: string[];\n}\n\n/**\n * AI21 Labs API adapter\n */\nexport class AI21Adapter extends BaseAdapter {\n\tget name(): string {\n\t\treturn 'ai21';\n\t}\n\n\tasync chat(options: ChatOptions): Promise<ChatResponse | AsyncIterable<StreamChunk>> {\n\t\ttry {\n\t\t\tconst apiKey = this.getApiKey(options);\n\t\t\tconst baseUrl = this.getBaseUrl('https://api.ai21.com/studio/v1');\n\n\t\t\t// Strip provider prefix from model if present\n\t\t\tconst model = options.model.replace(/^ai21\\//, '');\n\n\t\t\tconst request: AI21Request = {\n\t\t\t\tmodel,\n\t\t\t\tmessages: this.transformMessages(options.messages),\n\t\t\t};\n\n\t\t\t// Add optional parameters\n\t\t\tif (options.temperature !== undefined) request.temperature = options.temperature;\n\t\t\tif (options.maxTokens !== undefined) request.max_tokens = options.maxTokens;\n\t\t\tif (options.topP !== undefined) request.top_p = options.topP;\n\t\t\tif (options.stop && Array.isArray(options.stop)) {\n\t\t\t\trequest.stop = options.stop;\n\t\t\t}\n\n\t\t\t// Merge provider-specific options\n\t\t\tif (options.providerOptions) {\n\t\t\t\tObject.assign(request, options.providerOptions);\n\t\t\t}\n\n\t\t\tconst response = await this.fetchWithErrorHandling(\n\t\t\t\t`${baseUrl}/chat/completions`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\t'Authorization': `Bearer ${apiKey}`,\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify(request),\n\t\t\t\t},\n\t\t\t\tthis.name\n\t\t\t);\n\n\t\t\tconst data = await response.json();\n\t\t\treturn this.handleNonStreamResponse(data, model);\n\t\t} catch (error) {\n\t\t\thandleProviderError(error, this.name);\n\t\t}\n\t}\n\n\tprivate transformMessages(messages: Message[]): AI21Message[] {\n\t\treturn messages.map((msg) => ({\n\t\t\trole: msg.role,\n\t\t\tcontent: msg.content,\n\t\t}));\n\t}\n\n\tprivate handleNonStreamResponse(data: any, model: string): ChatResponse {\n\t\tconst choice = data.choices?.[0];\n\t\tif (!choice) {\n\t\t\tthrow new Error('No choices in response');\n\t\t}\n\n\t\treturn {\n\t\t\tcontent: choice.message?.content || '',\n\t\t\tfinishReason: choice.finish_reason,\n\t\t\tusage: data.usage ? {\n\t\t\t\tpromptTokens: data.usage.prompt_tokens || 0,\n\t\t\t\tcompletionTokens: data.usage.completion_tokens || 0,\n\t\t\t\ttotalTokens: data.usage.total_tokens || 0,\n\t\t\t} : undefined,\n\t\t\tmodel,\n\t\t\traw: data,\n\t\t};\n\t}\n}\n\n"]}
1
+ {"version":3,"file":"ai21.js","sourceRoot":"","sources":["../../src/adapters/ai21.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseAdapter } from './base/BaseAdapter';\nimport { ChatOptions, ChatResponse, StreamChunk, Message } from '../types';\nimport { handleProviderError } from '../utils/errors';\nimport { contentToString } from '../utils/content-helpers';\n\ninterface AI21Message {\n\trole: string;\n\tcontent: string;\n}\n\ninterface AI21Request {\n\tmodel: string;\n\tmessages: AI21Message[];\n\ttemperature?: number;\n\tmax_tokens?: number;\n\ttop_p?: number;\n\tstop?: string[];\n}\n\n/**\n * AI21 Labs API adapter\n */\nexport class AI21Adapter extends BaseAdapter {\n\tget name(): string {\n\t\treturn 'ai21';\n\t}\n\n\tasync chat(options: ChatOptions): Promise<ChatResponse | AsyncIterable<StreamChunk>> {\n\t\ttry {\n\t\t\tconst apiKey = this.getApiKey(options);\n\t\t\tconst baseUrl = this.getBaseUrl('https://api.ai21.com/studio/v1');\n\n\t\t\t// Strip provider prefix from model if present\n\t\t\tconst model = options.model.replace(/^ai21\\//, '');\n\n\t\t\tconst request: AI21Request = {\n\t\t\t\tmodel,\n\t\t\t\tmessages: this.transformMessages(options.messages),\n\t\t\t};\n\n\t\t\t// Add optional parameters\n\t\t\tif (options.temperature !== undefined) request.temperature = options.temperature;\n\t\t\tif (options.maxTokens !== undefined) request.max_tokens = options.maxTokens;\n\t\t\tif (options.topP !== undefined) request.top_p = options.topP;\n\t\t\tif (options.stop && Array.isArray(options.stop)) {\n\t\t\t\trequest.stop = options.stop;\n\t\t\t}\n\n\t\t\t// Merge provider-specific options\n\t\t\tif (options.providerOptions) {\n\t\t\t\tObject.assign(request, options.providerOptions);\n\t\t\t}\n\n\t\t\tconst response = await this.fetchWithErrorHandling(\n\t\t\t\t`${baseUrl}/chat/completions`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\t'Authorization': `Bearer ${apiKey}`,\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify(request),\n\t\t\t\t},\n\t\t\t\tthis.name\n\t\t\t);\n\n\t\t\tconst data = await response.json();\n\t\t\treturn this.handleNonStreamResponse(data, model);\n\t\t} catch (error) {\n\t\t\thandleProviderError(error, this.name);\n\t\t}\n\t}\n\n\tprivate transformMessages(messages: Message[]): AI21Message[] {\n\t\treturn messages.map((msg) => ({\n\t\t\trole: msg.role,\n\t\t\tcontent: contentToString(msg.content),\n\t\t}));\n\t}\n\n\tprivate handleNonStreamResponse(data: any, model: string): ChatResponse {\n\t\tconst choice = data.choices?.[0];\n\t\tif (!choice) {\n\t\t\tthrow new Error('No choices in response');\n\t\t}\n\n\t\treturn {\n\t\t\tcontent: choice.message?.content || '',\n\t\t\tfinishReason: choice.finish_reason,\n\t\t\tusage: data.usage ? {\n\t\t\t\tpromptTokens: data.usage.prompt_tokens || 0,\n\t\t\t\tcompletionTokens: data.usage.completion_tokens || 0,\n\t\t\t\ttotalTokens: data.usage.total_tokens || 0,\n\t\t\t} : undefined,\n\t\t\tmodel,\n\t\t\traw: data,\n\t\t};\n\t}\n}\n\n"]}
@@ -33,6 +33,7 @@ exports.AnthropicAdapter = void 0;
33
33
  const BaseAdapter_1 = require("./base/BaseAdapter");
34
34
  const stream_1 = require("../utils/stream");
35
35
  const errors_1 = require("../utils/errors");
36
+ const content_helpers_1 = require("../utils/content-helpers");
36
37
  class AnthropicAdapter extends BaseAdapter_1.BaseAdapter {
37
38
  get name() {
38
39
  return 'anthropic';
@@ -52,7 +53,7 @@ class AnthropicAdapter extends BaseAdapter_1.BaseAdapter {
52
53
  stream: options.stream || false,
53
54
  };
54
55
  if (systemMessage) {
55
- request.system = systemMessage.content;
56
+ request.system = (0, content_helpers_1.contentToString)(systemMessage.content);
56
57
  }
57
58
  if (options.temperature !== undefined)
58
59
  request.temperature = options.temperature;
@@ -88,7 +89,7 @@ class AnthropicAdapter extends BaseAdapter_1.BaseAdapter {
88
89
  transformMessages(messages) {
89
90
  return messages.map((msg) => ({
90
91
  role: msg.role === 'user' ? 'user' : 'assistant',
91
- content: msg.content,
92
+ content: (0, content_helpers_1.contentToString)(msg.content),
92
93
  }));
93
94
  }
94
95
  handleNonStreamResponse(data, model) {
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/adapters/anthropic.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseAdapter } from './base/BaseAdapter';\nimport { ChatOptions, ChatResponse, StreamChunk, Message } from '../types';\nimport { streamLines } from '../utils/stream';\nimport { handleProviderError } from '../utils/errors';\n\ninterface AnthropicMessage {\n\trole: 'user' | 'assistant';\n\tcontent: string;\n}\n\ninterface AnthropicRequest {\n\tmodel: string;\n\tmessages: AnthropicMessage[];\n\tmax_tokens: number;\n\ttemperature?: number;\n\ttop_p?: number;\n\ttop_k?: number;\n\tstop_sequences?: string[];\n\tstream?: boolean;\n\tsystem?: string;\n}\n\n/**\n * Anthropic Claude API adapter\n */\nexport class AnthropicAdapter extends BaseAdapter {\n\tget name(): string {\n\t\treturn 'anthropic';\n\t}\n\n\tasync chat(options: ChatOptions): Promise<ChatResponse | AsyncIterable<StreamChunk>> {\n\t\ttry {\n\t\t\tconst apiKey = this.getApiKey(options);\n\t\t\tconst baseUrl = this.getBaseUrl('https://api.anthropic.com/v1');\n\n\t\t\t// Strip provider prefix from model if present\n\t\t\tconst model = options.model.replace(/^anthropic\\//, '');\n\n\t\t\t// Extract system message if present\n\t\t\tconst systemMessage = options.messages.find((m) => m.role === 'system');\n\t\t\tconst nonSystemMessages = options.messages.filter((m) => m.role !== 'system');\n\n\t\t\tconst request: AnthropicRequest = {\n\t\t\t\tmodel,\n\t\t\t\tmessages: this.transformMessages(nonSystemMessages),\n\t\t\t\tmax_tokens: options.maxTokens || 4096,\n\t\t\t\tstream: options.stream || false,\n\t\t\t};\n\n\t\t\t// Add system prompt\n\t\t\tif (systemMessage) {\n\t\t\t\trequest.system = systemMessage.content;\n\t\t\t}\n\n\t\t\t// Add optional parameters\n\t\t\tif (options.temperature !== undefined) request.temperature = options.temperature;\n\t\t\tif (options.topP !== undefined) request.top_p = options.topP;\n\t\t\tif (options.topK !== undefined) request.top_k = options.topK;\n\t\t\tif (options.stop && Array.isArray(options.stop)) {\n\t\t\t\trequest.stop_sequences = options.stop;\n\t\t\t}\n\n\t\t\t// Merge provider-specific options\n\t\t\tif (options.providerOptions) {\n\t\t\t\tObject.assign(request, options.providerOptions);\n\t\t\t}\n\n\t\t\tconst response = await this.fetchWithErrorHandling(\n\t\t\t\t`${baseUrl}/messages`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\t'x-api-key': apiKey,\n\t\t\t\t\t\t'anthropic-version': '2023-06-01',\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify(request),\n\t\t\t\t},\n\t\t\t\tthis.name\n\t\t\t);\n\n\t\t\tif (options.stream) {\n\t\t\t\treturn this.handleStreamResponse(response, model);\n\t\t\t}\n\n\t\t\treturn this.handleNonStreamResponse(await response.json(), model);\n\t\t} catch (error) {\n\t\t\thandleProviderError(error, this.name);\n\t\t}\n\t}\n\n\tprivate transformMessages(messages: Message[]): AnthropicMessage[] {\n\t\treturn messages.map((msg) => ({\n\t\t\trole: msg.role === 'user' ? 'user' : 'assistant',\n\t\t\tcontent: msg.content,\n\t\t}));\n\t}\n\n\tprivate handleNonStreamResponse(data: any, model: string): ChatResponse {\n\t\tconst content = data.content?.[0]?.text || '';\n\n\t\treturn {\n\t\t\tcontent,\n\t\t\tfinishReason: data.stop_reason,\n\t\t\tusage: data.usage ? {\n\t\t\t\tpromptTokens: data.usage.input_tokens,\n\t\t\t\tcompletionTokens: data.usage.output_tokens,\n\t\t\t\ttotalTokens: data.usage.input_tokens + data.usage.output_tokens,\n\t\t\t} : undefined,\n\t\t\tmodel,\n\t\t\traw: data,\n\t\t};\n\t}\n\n\tprivate async *handleStreamResponse(response: Response, model: string): AsyncIterable<StreamChunk> {\n\t\tif (!response.body) {\n\t\t\tthrow new Error('No response body for streaming');\n\t\t}\n\n\t\tfor await (const line of streamLines(response.body)) {\n\t\t\tif (!line.startsWith('data: ')) continue;\n\n\t\t\tconst data = line.slice(6).trim();\n\t\t\tif (data === '[DONE]') break;\n\n\t\t\ttry {\n\t\t\t\tconst chunk = JSON.parse(data);\n\n\t\t\t\tif (chunk.type === 'content_block_delta') {\n\t\t\t\t\tconst content = chunk.delta?.text || '';\n\t\t\t\t\tif (content) {\n\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\tcontent,\n\t\t\t\t\t\t\tindex: chunk.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t} else if (chunk.type === 'message_delta') {\n\t\t\t\t\tif (chunk.delta?.stop_reason) {\n\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\tcontent: '',\n\t\t\t\t\t\t\tfinishReason: chunk.delta.stop_reason,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\t// Skip invalid JSON\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n}\n\n"]}
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/adapters/anthropic.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseAdapter } from './base/BaseAdapter';\nimport { ChatOptions, ChatResponse, StreamChunk, Message } from '../types';\nimport { streamLines } from '../utils/stream';\nimport { handleProviderError } from '../utils/errors';\nimport { contentToString } from '../utils/content-helpers';\n\ninterface AnthropicMessage {\n\trole: 'user' | 'assistant';\n\tcontent: string;\n}\n\ninterface AnthropicRequest {\n\tmodel: string;\n\tmessages: AnthropicMessage[];\n\tmax_tokens: number;\n\ttemperature?: number;\n\ttop_p?: number;\n\ttop_k?: number;\n\tstop_sequences?: string[];\n\tstream?: boolean;\n\tsystem?: string;\n}\n\n/**\n * Anthropic Claude API adapter\n */\nexport class AnthropicAdapter extends BaseAdapter {\n\tget name(): string {\n\t\treturn 'anthropic';\n\t}\n\n\tasync chat(options: ChatOptions): Promise<ChatResponse | AsyncIterable<StreamChunk>> {\n\t\ttry {\n\t\t\tconst apiKey = this.getApiKey(options);\n\t\t\tconst baseUrl = this.getBaseUrl('https://api.anthropic.com/v1');\n\n\t\t\t// Strip provider prefix from model if present\n\t\t\tconst model = options.model.replace(/^anthropic\\//, '');\n\n\t\t\t// Extract system message if present\n\t\t\tconst systemMessage = options.messages.find((m) => m.role === 'system');\n\t\t\tconst nonSystemMessages = options.messages.filter((m) => m.role !== 'system');\n\n\t\t\tconst request: AnthropicRequest = {\n\t\t\t\tmodel,\n\t\t\t\tmessages: this.transformMessages(nonSystemMessages),\n\t\t\t\tmax_tokens: options.maxTokens || 4096,\n\t\t\t\tstream: options.stream || false,\n\t\t\t};\n\n\t\t\t// Add system prompt\n\t\t\tif (systemMessage) {\n\t\t\t\trequest.system = contentToString(systemMessage.content);\n\t\t\t}\n\n\t\t\t// Add optional parameters\n\t\t\tif (options.temperature !== undefined) request.temperature = options.temperature;\n\t\t\tif (options.topP !== undefined) request.top_p = options.topP;\n\t\t\tif (options.topK !== undefined) request.top_k = options.topK;\n\t\t\tif (options.stop && Array.isArray(options.stop)) {\n\t\t\t\trequest.stop_sequences = options.stop;\n\t\t\t}\n\n\t\t\t// Merge provider-specific options\n\t\t\tif (options.providerOptions) {\n\t\t\t\tObject.assign(request, options.providerOptions);\n\t\t\t}\n\n\t\t\tconst response = await this.fetchWithErrorHandling(\n\t\t\t\t`${baseUrl}/messages`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\t'x-api-key': apiKey,\n\t\t\t\t\t\t'anthropic-version': '2023-06-01',\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify(request),\n\t\t\t\t},\n\t\t\t\tthis.name\n\t\t\t);\n\n\t\t\tif (options.stream) {\n\t\t\t\treturn this.handleStreamResponse(response, model);\n\t\t\t}\n\n\t\t\treturn this.handleNonStreamResponse(await response.json(), model);\n\t\t} catch (error) {\n\t\t\thandleProviderError(error, this.name);\n\t\t}\n\t}\n\n\tprivate transformMessages(messages: Message[]): AnthropicMessage[] {\n\t\treturn messages.map((msg) => ({\n\t\t\trole: msg.role === 'user' ? 'user' : 'assistant',\n\t\t\tcontent: contentToString(msg.content),\n\t\t}));\n\t}\n\n\tprivate handleNonStreamResponse(data: any, model: string): ChatResponse {\n\t\tconst content = data.content?.[0]?.text || '';\n\n\t\treturn {\n\t\t\tcontent,\n\t\t\tfinishReason: data.stop_reason,\n\t\t\tusage: data.usage ? {\n\t\t\t\tpromptTokens: data.usage.input_tokens,\n\t\t\t\tcompletionTokens: data.usage.output_tokens,\n\t\t\t\ttotalTokens: data.usage.input_tokens + data.usage.output_tokens,\n\t\t\t} : undefined,\n\t\t\tmodel,\n\t\t\traw: data,\n\t\t};\n\t}\n\n\tprivate async *handleStreamResponse(response: Response, model: string): AsyncIterable<StreamChunk> {\n\t\tif (!response.body) {\n\t\t\tthrow new Error('No response body for streaming');\n\t\t}\n\n\t\tfor await (const line of streamLines(response.body)) {\n\t\t\tif (!line.startsWith('data: ')) continue;\n\n\t\t\tconst data = line.slice(6).trim();\n\t\t\tif (data === '[DONE]') break;\n\n\t\t\ttry {\n\t\t\t\tconst chunk = JSON.parse(data);\n\n\t\t\t\tif (chunk.type === 'content_block_delta') {\n\t\t\t\t\tconst content = chunk.delta?.text || '';\n\t\t\t\t\tif (content) {\n\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\tcontent,\n\t\t\t\t\t\t\tindex: chunk.index,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t} else if (chunk.type === 'message_delta') {\n\t\t\t\t\tif (chunk.delta?.stop_reason) {\n\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\tcontent: '',\n\t\t\t\t\t\t\tfinishReason: chunk.delta.stop_reason,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\t// Skip invalid JSON\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n}\n\n"]}
@@ -28,17 +28,26 @@ class BaseAdapter {
28
28
  handleFetchError(response, provider) {
29
29
  return __awaiter(this, void 0, void 0, function* () {
30
30
  var _a;
31
+ let errorData;
31
32
  let errorMessage;
32
33
  try {
33
- const errorData = yield response.json();
34
+ errorData = yield response.json();
34
35
  errorMessage = ((_a = errorData.error) === null || _a === void 0 ? void 0 : _a.message) || errorData.message || response.statusText;
35
36
  }
36
37
  catch (_b) {
37
38
  errorMessage = response.statusText || 'Unknown error';
39
+ errorData = {};
38
40
  }
39
41
  const error = new Error(errorMessage);
40
42
  error.status = response.status;
41
43
  error.statusCode = response.status;
44
+ error.error = errorData.error || errorData;
45
+ if (response.status === 429) {
46
+ const retryAfter = response.headers.get('retry-after');
47
+ if (retryAfter) {
48
+ error.retryAfter = parseInt(retryAfter, 10);
49
+ }
50
+ }
42
51
  throw error;
43
52
  });
44
53
  }
@@ -1 +1 @@
1
- {"version":3,"file":"BaseAdapter.js","sourceRoot":"","sources":["../../../src/adapters/base/BaseAdapter.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,uDAAwD;AAKxD,MAAsB,WAAW;IAGhC,YAAY,SAAyB,EAAE;QACtC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAQS,SAAS,CAAC,OAAoB;QACvC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;QACpD,OAAO,IAAA,2BAAc,EAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAKS,UAAU,CAAC,UAAkB;QACtC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,UAAU,CAAC;IAC1C,CAAC;IAKS,aAAa,CAAC,MAAc,EAAE,oBAA4C,EAAE;QACrF,uBACC,cAAc,EAAE,kBAAkB,IAC/B,iBAAiB,EACnB;IACH,CAAC;IAKe,gBAAgB,CAAC,QAAkB,EAAE,QAAgB;;;YACpE,IAAI,YAAoB,CAAC;YACzB,IAAI,CAAC;gBACJ,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAS,CAAC;gBAC/C,YAAY,GAAG,CAAA,MAAA,SAAS,CAAC,KAAK,0CAAE,OAAO,KAAI,SAAS,CAAC,OAAO,IAAI,QAAQ,CAAC,UAAU,CAAC;YACrF,CAAC;YAAC,WAAM,CAAC;gBACR,YAAY,GAAG,QAAQ,CAAC,UAAU,IAAI,eAAe,CAAC;YACvD,CAAC;YAED,MAAM,KAAK,GAAQ,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;YAC3C,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;YAC/B,KAAK,CAAC,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC;YACnC,MAAM,KAAK,CAAC;QACb,CAAC;KAAA;IAKe,sBAAsB,CACrC,GAAW,EACX,OAAoB,EACpB,QAAgB;;YAEhB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAE3C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAClB,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACjD,CAAC;YAED,OAAO,QAAQ,CAAC;QACjB,CAAC;KAAA;CACD;AArED,kCAqEC","sourcesContent":["import { IProviderAdapter } from '../../types/provider';\nimport { ChatOptions, ChatResponse, StreamChunk, ProviderConfig } from '../../types';\nimport { validateApiKey } from '../../utils/validation';\n\n/**\n * Base adapter class with shared functionality for all providers\n */\nexport abstract class BaseAdapter implements IProviderAdapter {\n\tprotected config: ProviderConfig;\n\n\tconstructor(config: ProviderConfig = {}) {\n\t\tthis.config = config;\n\t}\n\n\tabstract get name(): string;\n\tabstract chat(options: ChatOptions): Promise<ChatResponse | AsyncIterable<StreamChunk>>;\n\n\t/**\n\t * Get API key from options or config\n\t */\n\tprotected getApiKey(options: ChatOptions): string {\n\t\tconst apiKey = options.apiKey || this.config.apiKey;\n\t\treturn validateApiKey(apiKey, this.name);\n\t}\n\n\t/**\n\t * Get base URL from options or config, with default fallback\n\t */\n\tprotected getBaseUrl(defaultUrl: string): string {\n\t\treturn this.config.baseUrl || defaultUrl;\n\t}\n\n\t/**\n\t * Create headers for API request\n\t */\n\tprotected createHeaders(apiKey: string, additionalHeaders: Record<string, string> = {}): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t\t...additionalHeaders,\n\t\t};\n\t}\n\n\t/**\n\t * Handle fetch errors consistently\n\t */\n\tprotected async handleFetchError(response: Response, provider: string): Promise<never> {\n\t\tlet errorMessage: string;\n\t\ttry {\n\t\t\tconst errorData = await response.json() as any;\n\t\t\terrorMessage = errorData.error?.message || errorData.message || response.statusText;\n\t\t} catch {\n\t\t\terrorMessage = response.statusText || 'Unknown error';\n\t\t}\n\n\t\tconst error: any = new Error(errorMessage);\n\t\terror.status = response.status;\n\t\terror.statusCode = response.status;\n\t\tthrow error;\n\t}\n\n\t/**\n\t * Make a fetch request with error handling\n\t */\n\tprotected async fetchWithErrorHandling(\n\t\turl: string,\n\t\toptions: RequestInit,\n\t\tprovider: string\n\t): Promise<Response> {\n\t\tconst response = await fetch(url, options);\n\n\t\tif (!response.ok) {\n\t\t\tawait this.handleFetchError(response, provider);\n\t\t}\n\n\t\treturn response;\n\t}\n}\n\n"]}
1
+ {"version":3,"file":"BaseAdapter.js","sourceRoot":"","sources":["../../../src/adapters/base/BaseAdapter.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,uDAAwD;AAKxD,MAAsB,WAAW;IAGhC,YAAY,SAAyB,EAAE;QACtC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAQS,SAAS,CAAC,OAAoB;QACvC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;QACpD,OAAO,IAAA,2BAAc,EAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAKS,UAAU,CAAC,UAAkB;QACtC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,UAAU,CAAC;IAC1C,CAAC;IAKS,aAAa,CAAC,MAAc,EAAE,oBAA4C,EAAE;QACrF,uBACC,cAAc,EAAE,kBAAkB,IAC/B,iBAAiB,EACnB;IACH,CAAC;IAKe,gBAAgB,CAAC,QAAkB,EAAE,QAAgB;;;YACpE,IAAI,SAAc,CAAC;YACnB,IAAI,YAAoB,CAAC;YAEzB,IAAI,CAAC;gBACJ,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAClC,YAAY,GAAG,CAAA,MAAA,SAAS,CAAC,KAAK,0CAAE,OAAO,KAAI,SAAS,CAAC,OAAO,IAAI,QAAQ,CAAC,UAAU,CAAC;YACrF,CAAC;YAAC,WAAM,CAAC;gBACR,YAAY,GAAG,QAAQ,CAAC,UAAU,IAAI,eAAe,CAAC;gBACtD,SAAS,GAAG,EAAE,CAAC;YAChB,CAAC;YAED,MAAM,KAAK,GAAQ,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;YAC3C,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;YAC/B,KAAK,CAAC,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC;YACnC,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,IAAI,SAAS,CAAC;YAG3C,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC7B,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;gBACvD,IAAI,UAAU,EAAE,CAAC;oBAChB,KAAK,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;gBAC7C,CAAC;YACF,CAAC;YAED,MAAM,KAAK,CAAC;QACb,CAAC;KAAA;IAKe,sBAAsB,CACrC,GAAW,EACX,OAAoB,EACpB,QAAgB;;YAEhB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAE3C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAClB,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACjD,CAAC;YAED,OAAO,QAAQ,CAAC;QACjB,CAAC;KAAA;CACD;AAlFD,kCAkFC","sourcesContent":["import { IProviderAdapter } from '../../types/provider';\nimport { ChatOptions, ChatResponse, StreamChunk, ProviderConfig } from '../../types';\nimport { validateApiKey } from '../../utils/validation';\n\n/**\n * Base adapter class with shared functionality for all providers\n */\nexport abstract class BaseAdapter implements IProviderAdapter {\n\tprotected config: ProviderConfig;\n\n\tconstructor(config: ProviderConfig = {}) {\n\t\tthis.config = config;\n\t}\n\n\tabstract get name(): string;\n\tabstract chat(options: ChatOptions): Promise<ChatResponse | AsyncIterable<StreamChunk>>;\n\n\t/**\n\t * Get API key from options or config\n\t */\n\tprotected getApiKey(options: ChatOptions): string {\n\t\tconst apiKey = options.apiKey || this.config.apiKey;\n\t\treturn validateApiKey(apiKey, this.name);\n\t}\n\n\t/**\n\t * Get base URL from options or config, with default fallback\n\t */\n\tprotected getBaseUrl(defaultUrl: string): string {\n\t\treturn this.config.baseUrl || defaultUrl;\n\t}\n\n\t/**\n\t * Create headers for API request\n\t */\n\tprotected createHeaders(apiKey: string, additionalHeaders: Record<string, string> = {}): Record<string, string> {\n\t\treturn {\n\t\t\t'Content-Type': 'application/json',\n\t\t\t...additionalHeaders,\n\t\t};\n\t}\n\n\t/**\n\t * Handle fetch errors consistently\n\t */\n\tprotected async handleFetchError(response: Response, provider: string): Promise<never> {\n\t\tlet errorData: any;\n\t\tlet errorMessage: string;\n\n\t\ttry {\n\t\t\terrorData = await response.json();\n\t\t\terrorMessage = errorData.error?.message || errorData.message || response.statusText;\n\t\t} catch {\n\t\t\terrorMessage = response.statusText || 'Unknown error';\n\t\t\terrorData = {};\n\t\t}\n\n\t\tconst error: any = new Error(errorMessage);\n\t\terror.status = response.status;\n\t\terror.statusCode = response.status;\n\t\terror.error = errorData.error || errorData;\n\n\t\t// Extract retry-after header for rate limits\n\t\tif (response.status === 429) {\n\t\t\tconst retryAfter = response.headers.get('retry-after');\n\t\t\tif (retryAfter) {\n\t\t\t\terror.retryAfter = parseInt(retryAfter, 10);\n\t\t\t}\n\t\t}\n\n\t\tthrow error;\n\t}\n\n\t/**\n\t * Make a fetch request with error handling\n\t */\n\tprotected async fetchWithErrorHandling(\n\t\turl: string,\n\t\toptions: RequestInit,\n\t\tprovider: string\n\t): Promise<Response> {\n\t\tconst response = await fetch(url, options);\n\n\t\tif (!response.ok) {\n\t\t\tawait this.handleFetchError(response, provider);\n\t\t}\n\n\t\treturn response;\n\t}\n}\n\n"]}
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.CloudflareAdapter = void 0;
37
37
  const BaseAdapter_1 = require("./base/BaseAdapter");
38
38
  const errors_1 = require("../utils/errors");
39
+ const content_helpers_1 = require("../utils/content-helpers");
39
40
  class CloudflareAdapter extends BaseAdapter_1.BaseAdapter {
40
41
  get name() {
41
42
  return 'cloudflare';
@@ -54,7 +55,7 @@ class CloudflareAdapter extends BaseAdapter_1.BaseAdapter {
54
55
  const request = {
55
56
  messages: options.messages.map((msg) => ({
56
57
  role: msg.role,
57
- content: msg.content,
58
+ content: (0, content_helpers_1.contentToString)(msg.content),
58
59
  })),
59
60
  stream: options.stream || false,
60
61
  };
@@ -1 +1 @@
1
- {"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../../src/adapters/cloudflare.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseAdapter } from './base/BaseAdapter';\nimport { ChatOptions, ChatResponse, StreamChunk } from '../types';\nimport { handleProviderError, InvalidRequestError } from '../utils/errors';\n\n/**\n * Cloudflare Workers AI adapter\n */\nexport class CloudflareAdapter extends BaseAdapter {\n\tget name(): string {\n\t\treturn 'cloudflare';\n\t}\n\n\tasync chat(options: ChatOptions): Promise<ChatResponse | AsyncIterable<StreamChunk>> {\n\t\ttry {\n\t\t\tconst apiKey = this.getApiKey(options);\n\n\t\t\t// Cloudflare requires account ID\n\t\t\tconst accountId = this.config.cloudflareAccountId || options.providerOptions?.cloudflareAccountId;\n\t\t\tif (!accountId) {\n\t\t\t\tthrow new InvalidRequestError(\n\t\t\t\t\t'Cloudflare account ID is required. Pass it in the constructor or providerOptions.'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst baseUrl = this.getBaseUrl(`https://api.cloudflare.com/client/v4/accounts/${accountId}/ai`);\n\n\t\t\t// Strip provider prefix from model if present\n\t\t\tconst model = options.model.replace(/^cloudflare\\//, '');\n\n\t\t\tconst request: any = {\n\t\t\t\tmessages: options.messages.map((msg) => ({\n\t\t\t\t\trole: msg.role,\n\t\t\t\t\tcontent: msg.content,\n\t\t\t\t})),\n\t\t\t\tstream: options.stream || false,\n\t\t\t};\n\n\t\t\t// Add optional parameters\n\t\t\tif (options.temperature !== undefined) request.temperature = options.temperature;\n\t\t\tif (options.maxTokens !== undefined) request.max_tokens = options.maxTokens;\n\t\t\tif (options.topP !== undefined) request.top_p = options.topP;\n\n\t\t\t// Merge provider-specific options\n\t\t\tif (options.providerOptions) {\n\t\t\t\tconst { cloudflareAccountId, ...rest } = options.providerOptions;\n\t\t\t\tObject.assign(request, rest);\n\t\t\t}\n\n\t\t\tconst response = await this.fetchWithErrorHandling(\n\t\t\t\t`${baseUrl}/run/${model}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\t'Authorization': `Bearer ${apiKey}`,\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify(request),\n\t\t\t\t},\n\t\t\t\tthis.name\n\t\t\t);\n\n\t\t\t// Note: Cloudflare streaming support may vary by model\n\t\t\tif (options.stream) {\n\t\t\t\treturn this.handleStreamResponse(response, model);\n\t\t\t}\n\n\t\t\treturn this.handleNonStreamResponse(await response.json(), model);\n\t\t} catch (error) {\n\t\t\thandleProviderError(error, this.name);\n\t\t}\n\t}\n\n\tprivate handleNonStreamResponse(data: any, model: string): ChatResponse {\n\t\t// Cloudflare response format\n\t\tconst result = data.result;\n\t\tif (!result) {\n\t\t\tthrow new Error('No result in response');\n\t\t}\n\n\t\tconst content = result.response || result.text || '';\n\n\t\treturn {\n\t\t\tcontent,\n\t\t\tfinishReason: 'stop',\n\t\t\tmodel,\n\t\t\traw: data,\n\t\t};\n\t}\n\n\tprivate async *handleStreamResponse(response: Response, model: string): AsyncIterable<StreamChunk> {\n\t\tif (!response.body) {\n\t\t\tthrow new Error('No response body for streaming');\n\t\t}\n\n\t\tconst reader = response.body.getReader();\n\t\tconst decoder = new TextDecoder();\n\n\t\ttry {\n\t\t\twhile (true) {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (done) break;\n\n\t\t\t\tconst text = decoder.decode(value, { stream: true });\n\t\t\t\tif (text) {\n\t\t\t\t\tyield {\n\t\t\t\t\t\tcontent: text,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\treader.releaseLock();\n\t\t}\n\t}\n}\n\n"]}
1
+ {"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../../src/adapters/cloudflare.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseAdapter } from './base/BaseAdapter';\nimport { ChatOptions, ChatResponse, StreamChunk } from '../types';\nimport { handleProviderError, InvalidRequestError } from '../utils/errors';\nimport { contentToString } from '../utils/content-helpers';\n\n/**\n * Cloudflare Workers AI adapter\n */\nexport class CloudflareAdapter extends BaseAdapter {\n\tget name(): string {\n\t\treturn 'cloudflare';\n\t}\n\n\tasync chat(options: ChatOptions): Promise<ChatResponse | AsyncIterable<StreamChunk>> {\n\t\ttry {\n\t\t\tconst apiKey = this.getApiKey(options);\n\n\t\t\t// Cloudflare requires account ID\n\t\t\tconst accountId = this.config.cloudflareAccountId || options.providerOptions?.cloudflareAccountId;\n\t\t\tif (!accountId) {\n\t\t\t\tthrow new InvalidRequestError(\n\t\t\t\t\t'Cloudflare account ID is required. Pass it in the constructor or providerOptions.'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst baseUrl = this.getBaseUrl(`https://api.cloudflare.com/client/v4/accounts/${accountId}/ai`);\n\n\t\t\t// Strip provider prefix from model if present\n\t\t\tconst model = options.model.replace(/^cloudflare\\//, '');\n\n\t\t\tconst request: any = {\n\t\t\t\tmessages: options.messages.map((msg) => ({\n\t\t\t\t\trole: msg.role,\n\t\t\t\t\tcontent: contentToString(msg.content),\n\t\t\t\t})),\n\t\t\t\tstream: options.stream || false,\n\t\t\t};\n\n\t\t\t// Add optional parameters\n\t\t\tif (options.temperature !== undefined) request.temperature = options.temperature;\n\t\t\tif (options.maxTokens !== undefined) request.max_tokens = options.maxTokens;\n\t\t\tif (options.topP !== undefined) request.top_p = options.topP;\n\n\t\t\t// Merge provider-specific options\n\t\t\tif (options.providerOptions) {\n\t\t\t\tconst { cloudflareAccountId, ...rest } = options.providerOptions;\n\t\t\t\tObject.assign(request, rest);\n\t\t\t}\n\n\t\t\tconst response = await this.fetchWithErrorHandling(\n\t\t\t\t`${baseUrl}/run/${model}`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\t'Authorization': `Bearer ${apiKey}`,\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify(request),\n\t\t\t\t},\n\t\t\t\tthis.name\n\t\t\t);\n\n\t\t\t// Note: Cloudflare streaming support may vary by model\n\t\t\tif (options.stream) {\n\t\t\t\treturn this.handleStreamResponse(response, model);\n\t\t\t}\n\n\t\t\treturn this.handleNonStreamResponse(await response.json(), model);\n\t\t} catch (error) {\n\t\t\thandleProviderError(error, this.name);\n\t\t}\n\t}\n\n\tprivate handleNonStreamResponse(data: any, model: string): ChatResponse {\n\t\t// Cloudflare response format\n\t\tconst result = data.result;\n\t\tif (!result) {\n\t\t\tthrow new Error('No result in response');\n\t\t}\n\n\t\tconst content = result.response || result.text || '';\n\n\t\treturn {\n\t\t\tcontent,\n\t\t\tfinishReason: 'stop',\n\t\t\tmodel,\n\t\t\traw: data,\n\t\t};\n\t}\n\n\tprivate async *handleStreamResponse(response: Response, model: string): AsyncIterable<StreamChunk> {\n\t\tif (!response.body) {\n\t\t\tthrow new Error('No response body for streaming');\n\t\t}\n\n\t\tconst reader = response.body.getReader();\n\t\tconst decoder = new TextDecoder();\n\n\t\ttry {\n\t\t\twhile (true) {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (done) break;\n\n\t\t\t\tconst text = decoder.decode(value, { stream: true });\n\t\t\t\tif (text) {\n\t\t\t\t\tyield {\n\t\t\t\t\t\tcontent: text,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\treader.releaseLock();\n\t\t}\n\t}\n}\n\n"]}
@@ -33,6 +33,7 @@ exports.CohereAdapter = void 0;
33
33
  const BaseAdapter_1 = require("./base/BaseAdapter");
34
34
  const stream_1 = require("../utils/stream");
35
35
  const errors_1 = require("../utils/errors");
36
+ const content_helpers_1 = require("../utils/content-helpers");
36
37
  class CohereAdapter extends BaseAdapter_1.BaseAdapter {
37
38
  get name() {
38
39
  return 'cohere';
@@ -92,12 +93,12 @@ class CohereAdapter extends BaseAdapter_1.BaseAdapter {
92
93
  const lastMessage = nonSystemMessages[nonSystemMessages.length - 1];
93
94
  const historyMessages = nonSystemMessages.slice(0, -1);
94
95
  return {
95
- message: (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.content) || '',
96
+ message: lastMessage ? (0, content_helpers_1.contentToString)(lastMessage.content) : '',
96
97
  chatHistory: historyMessages.map((msg) => ({
97
98
  role: msg.role === 'user' ? 'USER' : 'CHATBOT',
98
- message: msg.content,
99
+ message: (0, content_helpers_1.contentToString)(msg.content),
99
100
  })),
100
- preamble: systemMessage === null || systemMessage === void 0 ? void 0 : systemMessage.content,
101
+ preamble: systemMessage ? (0, content_helpers_1.contentToString)(systemMessage.content) : undefined,
101
102
  };
102
103
  }
103
104
  handleNonStreamResponse(data, model) {
@@ -1 +1 @@
1
- {"version":3,"file":"cohere.js","sourceRoot":"","sources":["../../src/adapters/cohere.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseAdapter } from './base/BaseAdapter';\nimport { ChatOptions, ChatResponse, StreamChunk, Message } from '../types';\nimport { streamLines } from '../utils/stream';\nimport { handleProviderError } from '../utils/errors';\n\ninterface CohereChatMessage {\n\trole: 'USER' | 'CHATBOT' | 'SYSTEM';\n\tmessage: string;\n}\n\ninterface CohereRequest {\n\tmodel?: string;\n\tmessage: string;\n\tchat_history?: Array<{ role: 'USER' | 'CHATBOT'; message: string; }>;\n\tpreamble?: string;\n\ttemperature?: number;\n\tmax_tokens?: number;\n\tp?: number;\n\tstop_sequences?: string[];\n\tstream?: boolean;\n}\n\n/**\n * Cohere API adapter\n */\nexport class CohereAdapter extends BaseAdapter {\n\tget name(): string {\n\t\treturn 'cohere';\n\t}\n\n\tasync chat(options: ChatOptions): Promise<ChatResponse | AsyncIterable<StreamChunk>> {\n\t\ttry {\n\t\t\tconst apiKey = this.getApiKey(options);\n\t\t\tconst baseUrl = this.getBaseUrl('https://api.cohere.ai/v1');\n\n\t\t\t// Strip provider prefix from model if present\n\t\t\tconst model = options.model.replace(/^cohere\\//, '');\n\n\t\t\t// Transform messages to Cohere format\n\t\t\tconst { message, chatHistory, preamble } = this.transformMessages(options.messages);\n\n\t\t\tconst request: CohereRequest = {\n\t\t\t\tmessage,\n\t\t\t\tstream: options.stream || false,\n\t\t\t};\n\n\t\t\t// Add model if specified\n\t\t\tif (model) request.model = model;\n\n\t\t\t// Add chat history\n\t\t\tif (chatHistory.length > 0) {\n\t\t\t\trequest.chat_history = chatHistory;\n\t\t\t}\n\n\t\t\t// Add preamble (system message)\n\t\t\tif (preamble) {\n\t\t\t\trequest.preamble = preamble;\n\t\t\t}\n\n\t\t\t// Add optional parameters\n\t\t\tif (options.temperature !== undefined) request.temperature = options.temperature;\n\t\t\tif (options.maxTokens !== undefined) request.max_tokens = options.maxTokens;\n\t\t\tif (options.topP !== undefined) request.p = options.topP;\n\t\t\tif (options.stop && Array.isArray(options.stop)) {\n\t\t\t\trequest.stop_sequences = options.stop;\n\t\t\t}\n\n\t\t\t// Merge provider-specific options\n\t\t\tif (options.providerOptions) {\n\t\t\t\tObject.assign(request, options.providerOptions);\n\t\t\t}\n\n\t\t\tconst response = await this.fetchWithErrorHandling(\n\t\t\t\t`${baseUrl}/chat`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\t'Authorization': `Bearer ${apiKey}`,\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify(request),\n\t\t\t\t},\n\t\t\t\tthis.name\n\t\t\t);\n\n\t\t\tif (options.stream) {\n\t\t\t\treturn this.handleStreamResponse(response, model);\n\t\t\t}\n\n\t\t\treturn this.handleNonStreamResponse(await response.json(), model);\n\t\t} catch (error) {\n\t\t\thandleProviderError(error, this.name);\n\t\t}\n\t}\n\n\tprivate transformMessages(messages: Message[]): {\n\t\tmessage: string;\n\t\tchatHistory: Array<{ role: 'USER' | 'CHATBOT'; message: string; }>;\n\t\tpreamble?: string;\n\t} {\n\t\tconst systemMessage = messages.find((m) => m.role === 'system');\n\t\tconst nonSystemMessages = messages.filter((m) => m.role !== 'system');\n\n\t\t// Last message is the current message\n\t\tconst lastMessage = nonSystemMessages[nonSystemMessages.length - 1];\n\t\tconst historyMessages = nonSystemMessages.slice(0, -1);\n\n\t\treturn {\n\t\t\tmessage: lastMessage?.content || '',\n\t\t\tchatHistory: historyMessages.map((msg) => ({\n\t\t\t\trole: msg.role === 'user' ? 'USER' : 'CHATBOT',\n\t\t\t\tmessage: msg.content,\n\t\t\t})),\n\t\t\tpreamble: systemMessage?.content,\n\t\t};\n\t}\n\n\tprivate handleNonStreamResponse(data: any, model: string): ChatResponse {\n\t\treturn {\n\t\t\tcontent: data.text || '',\n\t\t\tfinishReason: data.finish_reason,\n\t\t\tusage: data.meta?.tokens ? {\n\t\t\t\tpromptTokens: data.meta.tokens.input_tokens || 0,\n\t\t\t\tcompletionTokens: data.meta.tokens.output_tokens || 0,\n\t\t\t\ttotalTokens: (data.meta.tokens.input_tokens || 0) + (data.meta.tokens.output_tokens || 0),\n\t\t\t} : undefined,\n\t\t\tmodel,\n\t\t\traw: data,\n\t\t};\n\t}\n\n\tprivate async *handleStreamResponse(response: Response, model: string): AsyncIterable<StreamChunk> {\n\t\tif (!response.body) {\n\t\t\tthrow new Error('No response body for streaming');\n\t\t}\n\n\t\tfor await (const line of streamLines(response.body)) {\n\t\t\ttry {\n\t\t\t\tconst chunk = JSON.parse(line);\n\n\t\t\t\tif (chunk.event_type === 'text-generation') {\n\t\t\t\t\tyield {\n\t\t\t\t\t\tcontent: chunk.text || '',\n\t\t\t\t\t};\n\t\t\t\t} else if (chunk.event_type === 'stream-end') {\n\t\t\t\t\tyield {\n\t\t\t\t\t\tcontent: '',\n\t\t\t\t\t\tfinishReason: chunk.finish_reason,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\t// Skip invalid JSON\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n}\n\n"]}
1
+ {"version":3,"file":"cohere.js","sourceRoot":"","sources":["../../src/adapters/cohere.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseAdapter } from './base/BaseAdapter';\nimport { ChatOptions, ChatResponse, StreamChunk, Message } from '../types';\nimport { streamLines } from '../utils/stream';\nimport { handleProviderError } from '../utils/errors';\nimport { contentToString } from '../utils/content-helpers';\n\ninterface CohereChatMessage {\n\trole: 'USER' | 'CHATBOT' | 'SYSTEM';\n\tmessage: string;\n}\n\ninterface CohereRequest {\n\tmodel?: string;\n\tmessage: string;\n\tchat_history?: Array<{ role: 'USER' | 'CHATBOT'; message: string; }>;\n\tpreamble?: string;\n\ttemperature?: number;\n\tmax_tokens?: number;\n\tp?: number;\n\tstop_sequences?: string[];\n\tstream?: boolean;\n}\n\n/**\n * Cohere API adapter\n */\nexport class CohereAdapter extends BaseAdapter {\n\tget name(): string {\n\t\treturn 'cohere';\n\t}\n\n\tasync chat(options: ChatOptions): Promise<ChatResponse | AsyncIterable<StreamChunk>> {\n\t\ttry {\n\t\t\tconst apiKey = this.getApiKey(options);\n\t\t\tconst baseUrl = this.getBaseUrl('https://api.cohere.ai/v1');\n\n\t\t\t// Strip provider prefix from model if present\n\t\t\tconst model = options.model.replace(/^cohere\\//, '');\n\n\t\t\t// Transform messages to Cohere format\n\t\t\tconst { message, chatHistory, preamble } = this.transformMessages(options.messages);\n\n\t\t\tconst request: CohereRequest = {\n\t\t\t\tmessage,\n\t\t\t\tstream: options.stream || false,\n\t\t\t};\n\n\t\t\t// Add model if specified\n\t\t\tif (model) request.model = model;\n\n\t\t\t// Add chat history\n\t\t\tif (chatHistory.length > 0) {\n\t\t\t\trequest.chat_history = chatHistory;\n\t\t\t}\n\n\t\t\t// Add preamble (system message)\n\t\t\tif (preamble) {\n\t\t\t\trequest.preamble = preamble;\n\t\t\t}\n\n\t\t\t// Add optional parameters\n\t\t\tif (options.temperature !== undefined) request.temperature = options.temperature;\n\t\t\tif (options.maxTokens !== undefined) request.max_tokens = options.maxTokens;\n\t\t\tif (options.topP !== undefined) request.p = options.topP;\n\t\t\tif (options.stop && Array.isArray(options.stop)) {\n\t\t\t\trequest.stop_sequences = options.stop;\n\t\t\t}\n\n\t\t\t// Merge provider-specific options\n\t\t\tif (options.providerOptions) {\n\t\t\t\tObject.assign(request, options.providerOptions);\n\t\t\t}\n\n\t\t\tconst response = await this.fetchWithErrorHandling(\n\t\t\t\t`${baseUrl}/chat`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\t'Authorization': `Bearer ${apiKey}`,\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify(request),\n\t\t\t\t},\n\t\t\t\tthis.name\n\t\t\t);\n\n\t\t\tif (options.stream) {\n\t\t\t\treturn this.handleStreamResponse(response, model);\n\t\t\t}\n\n\t\t\treturn this.handleNonStreamResponse(await response.json(), model);\n\t\t} catch (error) {\n\t\t\thandleProviderError(error, this.name);\n\t\t}\n\t}\n\n\tprivate transformMessages(messages: Message[]): {\n\t\tmessage: string;\n\t\tchatHistory: Array<{ role: 'USER' | 'CHATBOT'; message: string; }>;\n\t\tpreamble?: string;\n\t} {\n\t\tconst systemMessage = messages.find((m) => m.role === 'system');\n\t\tconst nonSystemMessages = messages.filter((m) => m.role !== 'system');\n\n\t\t// Last message is the current message\n\t\tconst lastMessage = nonSystemMessages[nonSystemMessages.length - 1];\n\t\tconst historyMessages = nonSystemMessages.slice(0, -1);\n\n\t\treturn {\n\t\t\tmessage: lastMessage ? contentToString(lastMessage.content) : '',\n\t\t\tchatHistory: historyMessages.map((msg) => ({\n\t\t\t\trole: msg.role === 'user' ? 'USER' : 'CHATBOT',\n\t\t\t\tmessage: contentToString(msg.content),\n\t\t\t})),\n\t\t\tpreamble: systemMessage ? contentToString(systemMessage.content) : undefined,\n\t\t};\n\t}\n\n\tprivate handleNonStreamResponse(data: any, model: string): ChatResponse {\n\t\treturn {\n\t\t\tcontent: data.text || '',\n\t\t\tfinishReason: data.finish_reason,\n\t\t\tusage: data.meta?.tokens ? {\n\t\t\t\tpromptTokens: data.meta.tokens.input_tokens || 0,\n\t\t\t\tcompletionTokens: data.meta.tokens.output_tokens || 0,\n\t\t\t\ttotalTokens: (data.meta.tokens.input_tokens || 0) + (data.meta.tokens.output_tokens || 0),\n\t\t\t} : undefined,\n\t\t\tmodel,\n\t\t\traw: data,\n\t\t};\n\t}\n\n\tprivate async *handleStreamResponse(response: Response, model: string): AsyncIterable<StreamChunk> {\n\t\tif (!response.body) {\n\t\t\tthrow new Error('No response body for streaming');\n\t\t}\n\n\t\tfor await (const line of streamLines(response.body)) {\n\t\t\ttry {\n\t\t\t\tconst chunk = JSON.parse(line);\n\n\t\t\t\tif (chunk.event_type === 'text-generation') {\n\t\t\t\t\tyield {\n\t\t\t\t\t\tcontent: chunk.text || '',\n\t\t\t\t\t};\n\t\t\t\t} else if (chunk.event_type === 'stream-end') {\n\t\t\t\t\tyield {\n\t\t\t\t\t\tcontent: '',\n\t\t\t\t\t\tfinishReason: chunk.finish_reason,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\t// Skip invalid JSON\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n}\n\n"]}
@@ -33,6 +33,7 @@ exports.DeepSeekAdapter = void 0;
33
33
  const BaseAdapter_1 = require("./base/BaseAdapter");
34
34
  const stream_1 = require("../utils/stream");
35
35
  const errors_1 = require("../utils/errors");
36
+ const content_helpers_1 = require("../utils/content-helpers");
36
37
  class DeepSeekAdapter extends BaseAdapter_1.BaseAdapter {
37
38
  get name() {
38
39
  return 'deepseek';
@@ -47,7 +48,7 @@ class DeepSeekAdapter extends BaseAdapter_1.BaseAdapter {
47
48
  model,
48
49
  messages: options.messages.map((msg) => ({
49
50
  role: msg.role,
50
- content: msg.content,
51
+ content: (0, content_helpers_1.contentToString)(msg.content),
51
52
  })),
52
53
  stream: options.stream || false,
53
54
  };
@@ -1 +1 @@
1
- {"version":3,"file":"deepseek.js","sourceRoot":"","sources":["../../src/adapters/deepseek.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseAdapter } from './base/BaseAdapter';\nimport { ChatOptions, ChatResponse, StreamChunk } from '../types';\nimport { parseSSEStream } from '../utils/stream';\nimport { handleProviderError } from '../utils/errors';\n\n/**\n * DeepSeek API adapter (uses OpenAI-compatible API)\n */\nexport class DeepSeekAdapter extends BaseAdapter {\n\tget name(): string {\n\t\treturn 'deepseek';\n\t}\n\n\tasync chat(options: ChatOptions): Promise<ChatResponse | AsyncIterable<StreamChunk>> {\n\t\ttry {\n\t\t\tconst apiKey = this.getApiKey(options);\n\t\t\tconst baseUrl = this.getBaseUrl('https://api.deepseek.com/v1');\n\n\t\t\t// Strip provider prefix from model if present\n\t\t\tconst model = options.model.replace(/^deepseek\\//, '');\n\n\t\t\tconst request: any = {\n\t\t\t\tmodel,\n\t\t\t\tmessages: options.messages.map((msg) => ({\n\t\t\t\t\trole: msg.role,\n\t\t\t\t\tcontent: msg.content,\n\t\t\t\t})),\n\t\t\t\tstream: options.stream || false,\n\t\t\t};\n\n\t\t\t// Add optional parameters\n\t\t\tif (options.temperature !== undefined) request.temperature = options.temperature;\n\t\t\tif (options.maxTokens !== undefined) request.max_tokens = options.maxTokens;\n\t\t\tif (options.topP !== undefined) request.top_p = options.topP;\n\t\t\tif (options.frequencyPenalty !== undefined) request.frequency_penalty = options.frequencyPenalty;\n\t\t\tif (options.presencePenalty !== undefined) request.presence_penalty = options.presencePenalty;\n\t\t\tif (options.stop !== undefined) request.stop = options.stop;\n\n\t\t\t// Merge provider-specific options\n\t\t\tif (options.providerOptions) {\n\t\t\t\tObject.assign(request, options.providerOptions);\n\t\t\t}\n\n\t\t\tconst response = await this.fetchWithErrorHandling(\n\t\t\t\t`${baseUrl}/chat/completions`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\t'Authorization': `Bearer ${apiKey}`,\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify(request),\n\t\t\t\t},\n\t\t\t\tthis.name\n\t\t\t);\n\n\t\t\tif (options.stream) {\n\t\t\t\treturn this.handleStreamResponse(response, model);\n\t\t\t}\n\n\t\t\treturn this.handleNonStreamResponse(await response.json(), model);\n\t\t} catch (error) {\n\t\t\thandleProviderError(error, this.name);\n\t\t}\n\t}\n\n\tprivate handleNonStreamResponse(data: any, model: string): ChatResponse {\n\t\tconst choice = data.choices?.[0];\n\t\tif (!choice) {\n\t\t\tthrow new Error('No choices in response');\n\t\t}\n\n\t\treturn {\n\t\t\tcontent: choice.message?.content || '',\n\t\t\tfinishReason: choice.finish_reason,\n\t\t\tusage: data.usage ? {\n\t\t\t\tpromptTokens: data.usage.prompt_tokens,\n\t\t\t\tcompletionTokens: data.usage.completion_tokens,\n\t\t\t\ttotalTokens: data.usage.total_tokens,\n\t\t\t} : undefined,\n\t\t\tmodel,\n\t\t\traw: data,\n\t\t};\n\t}\n\n\tprivate async *handleStreamResponse(response: Response, model: string): AsyncIterable<StreamChunk> {\n\t\tif (!response.body) {\n\t\t\tthrow new Error('No response body for streaming');\n\t\t}\n\n\t\tfor await (const chunk of parseSSEStream(response.body)) {\n\t\t\tconst choice = chunk.choices?.[0];\n\t\t\tif (!choice) continue;\n\n\t\t\tconst content = choice.delta?.content || '';\n\t\t\tconst finishReason = choice.finish_reason;\n\n\t\t\tif (content || finishReason) {\n\t\t\t\tyield {\n\t\t\t\t\tcontent,\n\t\t\t\t\tfinishReason,\n\t\t\t\t\tindex: choice.index,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n}\n\n"]}
1
+ {"version":3,"file":"deepseek.js","sourceRoot":"","sources":["../../src/adapters/deepseek.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseAdapter } from './base/BaseAdapter';\nimport { ChatOptions, ChatResponse, StreamChunk } from '../types';\nimport { parseSSEStream } from '../utils/stream';\nimport { handleProviderError } from '../utils/errors';\nimport { contentToString } from '../utils/content-helpers';\n\n/**\n * DeepSeek API adapter (uses OpenAI-compatible API)\n */\nexport class DeepSeekAdapter extends BaseAdapter {\n\tget name(): string {\n\t\treturn 'deepseek';\n\t}\n\n\tasync chat(options: ChatOptions): Promise<ChatResponse | AsyncIterable<StreamChunk>> {\n\t\ttry {\n\t\t\tconst apiKey = this.getApiKey(options);\n\t\t\tconst baseUrl = this.getBaseUrl('https://api.deepseek.com/v1');\n\n\t\t\t// Strip provider prefix from model if present\n\t\t\tconst model = options.model.replace(/^deepseek\\//, '');\n\n\t\t\tconst request: any = {\n\t\t\t\tmodel,\n\t\t\t\tmessages: options.messages.map((msg) => ({\n\t\t\t\t\trole: msg.role,\n\t\t\t\t\tcontent: contentToString(msg.content),\n\t\t\t\t})),\n\t\t\t\tstream: options.stream || false,\n\t\t\t};\n\n\t\t\t// Add optional parameters\n\t\t\tif (options.temperature !== undefined) request.temperature = options.temperature;\n\t\t\tif (options.maxTokens !== undefined) request.max_tokens = options.maxTokens;\n\t\t\tif (options.topP !== undefined) request.top_p = options.topP;\n\t\t\tif (options.frequencyPenalty !== undefined) request.frequency_penalty = options.frequencyPenalty;\n\t\t\tif (options.presencePenalty !== undefined) request.presence_penalty = options.presencePenalty;\n\t\t\tif (options.stop !== undefined) request.stop = options.stop;\n\n\t\t\t// Merge provider-specific options\n\t\t\tif (options.providerOptions) {\n\t\t\t\tObject.assign(request, options.providerOptions);\n\t\t\t}\n\n\t\t\tconst response = await this.fetchWithErrorHandling(\n\t\t\t\t`${baseUrl}/chat/completions`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\t'Authorization': `Bearer ${apiKey}`,\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify(request),\n\t\t\t\t},\n\t\t\t\tthis.name\n\t\t\t);\n\n\t\t\tif (options.stream) {\n\t\t\t\treturn this.handleStreamResponse(response, model);\n\t\t\t}\n\n\t\t\treturn this.handleNonStreamResponse(await response.json(), model);\n\t\t} catch (error) {\n\t\t\thandleProviderError(error, this.name);\n\t\t}\n\t}\n\n\tprivate handleNonStreamResponse(data: any, model: string): ChatResponse {\n\t\tconst choice = data.choices?.[0];\n\t\tif (!choice) {\n\t\t\tthrow new Error('No choices in response');\n\t\t}\n\n\t\treturn {\n\t\t\tcontent: choice.message?.content || '',\n\t\t\tfinishReason: choice.finish_reason,\n\t\t\tusage: data.usage ? {\n\t\t\t\tpromptTokens: data.usage.prompt_tokens,\n\t\t\t\tcompletionTokens: data.usage.completion_tokens,\n\t\t\t\ttotalTokens: data.usage.total_tokens,\n\t\t\t} : undefined,\n\t\t\tmodel,\n\t\t\traw: data,\n\t\t};\n\t}\n\n\tprivate async *handleStreamResponse(response: Response, model: string): AsyncIterable<StreamChunk> {\n\t\tif (!response.body) {\n\t\t\tthrow new Error('No response body for streaming');\n\t\t}\n\n\t\tfor await (const chunk of parseSSEStream(response.body)) {\n\t\t\tconst choice = chunk.choices?.[0];\n\t\t\tif (!choice) continue;\n\n\t\t\tconst content = choice.delta?.content || '';\n\t\t\tconst finishReason = choice.finish_reason;\n\n\t\t\tif (content || finishReason) {\n\t\t\t\tyield {\n\t\t\t\t\tcontent,\n\t\t\t\t\tfinishReason,\n\t\t\t\t\tindex: choice.index,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n}\n\n"]}
@@ -4,6 +4,16 @@ export declare class GoogleAdapter extends BaseAdapter {
4
4
  get name(): string;
5
5
  chat(options: ChatOptions): Promise<ChatResponse | AsyncIterable<StreamChunk>>;
6
6
  private transformMessages;
7
+ private transformContentParts;
8
+ private transformRegularContent;
9
+ private transformImagePart;
10
+ private getMimeTypeFromUrl;
11
+ private transformTools;
12
+ private transformToolChoice;
13
+ private transformResponseFormat;
7
14
  private handleNonStreamResponse;
15
+ private extractContentText;
16
+ private extractToolCalls;
8
17
  private handleStreamResponse;
18
+ private getModelCapabilities;
9
19
  }