krisspy-ai 1.1.17

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/providers/base.ts","../src/providers/openai.ts","../src/providers/zai.ts","../src/providers/gemini.ts","../src/providers/bedrock.ts","../src/providers/azure.ts","../src/providers/krisspy.ts","../src/providers/index.ts","../src/services/image/azure-dalle.ts","../src/services/base.ts","../src/services/image/base.ts","../src/services/image/openai-image.ts","../src/services/image/krisspy-image.ts","../src/services/video/azure-sora.ts","../src/services/video/base.ts","../src/services/video/openai-sora.ts","../src/services/video/krisspy-sora.ts","../src/services/audio/azure-transcription.ts","../src/services/audio/base.ts","../src/services/audio/openai-transcription.ts","../src/services/audio/krisspy-transcription.ts","../src/services/audio/azure-tts.ts","../src/services/audio/openai-tts.ts","../src/services/audio/krisspy-tts.ts","../src/services/index.ts"],"sourcesContent":["// krisspy-ai - Drop-in replacement for @anthropic-ai/claude-agent-sdk\n// Same API as claude-agent-sdk but with multi-provider support via integrated proxy\n\nimport { query as claudeQuery } from '@anthropic-ai/claude-agent-sdk';\nimport fetch from 'node-fetch';\nimport FormData from 'form-data';\nimport { createServer, Server, IncomingMessage, ServerResponse } from 'http';\nimport { getProvider, registerProvider } from './providers';\nimport type { Provider, ProviderConfig } from './types';\nimport type { BedrockProvider } from './providers/bedrock';\n\n// Re-export everything from claude-agent-sdk for compatibility\nexport * from '@anthropic-ai/claude-agent-sdk';\n\n// Types\ninterface FilesAPIResponse {\n id: string;\n}\n\ninterface FileAttachment {\n type: 'pdf' | 'xlsx' | 'docx' | 'pptx' | 'csv' | 'unknown';\n media_type: string;\n data: string;\n}\n\ninterface ImageAttachment {\n type: 'url' | 'base64';\n url?: string;\n media_type?: string;\n data?: string;\n}\n\nexport type ProviderType = 'claude_cli' | 'anthropic' | 'openai' | 'gemini' | 'zai' | 'zai_direct' | 'bedrock' | 'azure' | 'codex' | 'codex_cli' | 'krisspy';\n\n// MCP Server configuration - supports both stdio (command) and HTTP transports\nexport interface MCPServerConfigStdio {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n cwd?: string;\n}\n\nexport interface MCPServerConfigHttp {\n type: 'http';\n url: string;\n headers?: Record<string, string>;\n}\n\nexport type MCPServerConfig = MCPServerConfigStdio | MCPServerConfigHttp;\n\n// Hook configuration for lifecycle events\nexport interface HookConfig {\n command: string;\n timeout?: number;\n}\n\nexport interface HooksConfig {\n onStart?: HookConfig;\n onStop?: HookConfig;\n onToolCall?: HookConfig;\n onToolResult?: HookConfig;\n}\n\n// Agent configuration\nexport interface AgentConfig {\n name: string;\n model?: string;\n systemPrompt?: string;\n tools?: string[];\n}\n\nexport interface KrissyQueryOptions {\n [key: string]: unknown;\n\n // Provider configuration - ALL explicit, no env vars by default\n provider?: ProviderType;\n model?: string; // Model to use (default: 'sonnet')\n apiKey?: string; // API key for the provider\n baseUrl?: string; // Base URL override\n\n // Attachments\n attachments?: {\n images?: Array<ImageAttachment>;\n files?: Array<FileAttachment>;\n };\n\n // Extended thinking\n maxThinkingTokens?: number;\n\n // MCP Servers - connect to external tools via MCP protocol\n mcpServers?: Record<string, MCPServerConfig>;\n\n // Skills (beta) - enable Anthropic Skills for Office files, etc.\n betas?: string[];\n\n // Tools configuration\n allowedTools?: string[];\n permissionMode?: 'default' | 'acceptEdits' | 'plan' | 'bypassPermissions';\n\n // System prompt\n systemPrompt?: string | { type: 'preset'; preset: string } | { type: 'custom'; content: string };\n\n // Working directory\n cwd?: string;\n\n // Environment variables to pass to the agent\n env?: Record<string, string>;\n\n // === Additional SDK options ===\n\n // Hooks - lifecycle event handlers\n hooks?: HooksConfig;\n\n // Agents - custom agent definitions\n agents?: Record<string, AgentConfig>;\n\n // Execution limits\n maxTurns?: number; // Max conversation turns\n maxBudgetUsd?: number; // Cost limit in USD\n\n // Output format\n outputFormat?: 'text' | 'json' | 'stream-json';\n\n // Session management\n resume?: string; // Resume session by ID\n\n // Sandbox mode\n sandbox?: boolean;\n\n // Include partial messages in streaming\n includePartialMessages?: boolean;\n\n // === AWS Bedrock specific ===\n accessKeyId?: string; // AWS Access Key ID\n secretAccessKey?: string; // AWS Secret Access Key\n region?: string; // AWS Region (default: us-west-2)\n\n // === Azure AI Foundry specific ===\n deploymentName?: string; // Azure deployment name\n apiVersion?: string; // Azure API version\n}\n\n// Default configurations per provider - no env vars, just sensible defaults\nconst PROVIDER_DEFAULTS: Record<string, { baseUrl: string; model: string }> = {\n anthropic: {\n baseUrl: 'https://api.anthropic.com',\n model: 'sonnet',\n },\n openai: {\n baseUrl: 'https://api.openai.com/v1',\n model: 'gpt-5.2',\n },\n gemini: {\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta/openai',\n model: 'gemini-2.5-flash',\n },\n zai: {\n baseUrl: 'https://api.z.ai/api/coding/paas/v4',\n model: 'glm-4.7',\n },\n zai_direct: {\n baseUrl: 'https://api.z.ai/v1', // Anthropic-compatible endpoint\n model: 'sonnet',\n },\n bedrock: {\n baseUrl: '', // Constructed from region\n model: 'sonnet', // Will be mapped to anthropic.claude-sonnet-4-20250514-v1:0\n },\n azure: {\n baseUrl: '', // Must be provided (e.g., https://your-resource.openai.azure.com)\n model: 'gpt-5.2',\n },\n claude_cli: {\n baseUrl: '', // Not needed - uses CLI subscription\n model: 'sonnet',\n },\n krisspy: {\n baseUrl: 'https://api.krisspy.ai', // Krisspy AI proxy with credit billing\n model: 'sonnet',\n },\n};\n\n// Embedded proxy server state\nlet proxyServer: Server | null = null;\nlet proxyPort = 0;\nlet currentProxyProvider: Provider | null = null;\nlet currentProviderConfig: ProviderConfig | null = null;\n\n// Error tracking for proxy errors\nlet lastProxyError: string | null = null;\n\n// Files API helper\nasync function uploadFileToFilesAPI(\n fileData: FileAttachment,\n apiKey: string,\n baseUrl = 'https://api.anthropic.com'\n): Promise<string> {\n const form = new FormData();\n const buffer = Buffer.from(fileData.data, 'base64');\n\n let filename = 'document';\n if (fileData.media_type?.includes('pdf')) filename = 'document.pdf';\n else if (fileData.media_type?.includes('spreadsheet') || fileData.type === 'xlsx') filename = 'document.xlsx';\n else if (fileData.media_type?.includes('wordprocessing') || fileData.type === 'docx') filename = 'document.docx';\n else if (fileData.media_type?.includes('presentation') || fileData.type === 'pptx') filename = 'document.pptx';\n else if (fileData.type === 'csv') filename = 'document.csv';\n\n form.append('file', buffer, { filename, contentType: fileData.media_type || 'application/octet-stream' });\n\n const response = await fetch(`${baseUrl}/v1/files`, {\n method: 'POST',\n headers: {\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n 'anthropic-beta': 'files-api-2025-04-14',\n ...form.getHeaders(),\n },\n body: form as unknown as NodeJS.ReadableStream,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Files API upload failed: ${response.status} - ${errorText}`);\n }\n\n const result = (await response.json()) as FilesAPIResponse;\n return result.id;\n}\n\n// Start embedded proxy server for OpenAI/Gemini/ZAI\nasync function startProxyServer(providerName: string, config: ProviderConfig): Promise<number> {\n // Check if we can reuse existing server\n if (proxyServer && currentProxyProvider?.getName() === providerName) {\n // Check if config changed\n const sameConfig = currentProviderConfig?.apiKey === config.apiKey &&\n currentProviderConfig?.baseUrl === config.baseUrl;\n if (sameConfig) {\n return proxyPort;\n }\n }\n\n // Stop existing server if different provider or config\n if (proxyServer) {\n await stopProxyServer();\n }\n\n currentProxyProvider = getProvider(providerName, config);\n currentProviderConfig = config;\n\n return new Promise((resolve, reject) => {\n proxyServer = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n if (req.method !== 'POST' || !req.url?.includes('/v1/messages')) {\n res.writeHead(404);\n res.end('Not found');\n return;\n }\n\n let body = '';\n req.on('data', chunk => { body += chunk; });\n req.on('end', async () => {\n try {\n const anthropicRequest = JSON.parse(body);\n const providerRequest = currentProxyProvider!.buildRequest(anthropicRequest);\n const requestBody = JSON.stringify(providerRequest);\n\n // Bedrock needs signed headers with the payload\n const headers = currentProxyProvider!.getName() === 'bedrock'\n ? (currentProxyProvider as unknown as BedrockProvider).getSignedHeaders(requestBody)\n : currentProxyProvider!.getHeaders();\n\n const endpoint = currentProxyProvider!.getEndpoint();\n console.log(`[krisspy-ai] Proxy forwarding to: ${endpoint}`);\n console.log(`[krisspy-ai] Headers:`, JSON.stringify(headers, null, 2));\n console.log(`[krisspy-ai] Body preview:`, requestBody.substring(0, 200));\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: requestBody,\n });\n\n console.log(`[krisspy-ai] Response status: ${response.status}`);\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = errorText;\n try {\n const parsed = JSON.parse(errorText);\n errorMessage = parsed.error?.message || errorText;\n } catch {\n // Keep original error text\n }\n // Only log once per unique error\n if (lastProxyError !== errorMessage) {\n lastProxyError = errorMessage;\n console.error(`[krisspy-ai] Proxy error: ${errorMessage}`);\n }\n // Map to Anthropic error types - authentication_error won't be retried\n const errorType = response.status === 401 ? 'authentication_error'\n : response.status === 403 ? 'permission_error'\n : response.status === 404 ? 'not_found_error'\n : response.status === 429 ? 'rate_limit_error'\n : 'api_error';\n res.writeHead(response.status, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({\n type: 'error',\n error: { type: errorType, message: errorMessage }\n }));\n return;\n }\n\n const messageId = `msg_${Date.now()}`;\n const stream = anthropicRequest.stream !== false;\n\n if (stream && response.body) {\n await currentProxyProvider!.handleStreamingResponse(\n response as unknown as { body: NodeJS.ReadableStream },\n res as unknown as import('./types').StreamResponse,\n messageId,\n anthropicRequest.model\n );\n res.end();\n } else {\n const data = await response.json();\n const anthropicResponse = currentProxyProvider!.convertResponse(data, messageId, anthropicRequest.model);\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(anthropicResponse));\n }\n } catch (error) {\n const errorMessage = (error as Error).message;\n lastProxyError = errorMessage;\n console.error(`[krisspy-ai] Proxy error: ${errorMessage}`);\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({\n type: 'error',\n error: { type: 'api_error', message: errorMessage }\n }));\n }\n });\n });\n\n // Use any available port\n proxyServer.listen(0, '127.0.0.1', () => {\n const addr = proxyServer!.address();\n proxyPort = typeof addr === 'object' && addr ? addr.port : 0;\n console.log(`[krisspy-ai] Proxy started on port ${proxyPort} for ${providerName}`);\n resolve(proxyPort);\n });\n\n proxyServer.on('error', reject);\n });\n}\n\nasync function stopProxyServer(): Promise<void> {\n if (proxyServer) {\n return new Promise((resolve) => {\n proxyServer!.close(() => {\n proxyServer = null;\n currentProxyProvider = null;\n currentProviderConfig = null;\n proxyPort = 0;\n resolve();\n });\n });\n }\n}\n\n/**\n * query() - Drop-in replacement for claude-agent-sdk's query()\n *\n * Same API as @anthropic-ai/claude-agent-sdk but with:\n * - Multi-provider support via options.provider\n * - Integrated proxy for OpenAI/Gemini/ZAI (no separate server needed)\n * - Multimodal support via options.attachments\n * - All configuration via explicit options (no env vars required)\n *\n * @example\n * // Use OpenAI with explicit API key\n * for await (const event of query({\n * prompt: 'Hello',\n * options: {\n * provider: 'openai',\n * apiKey: 'sk-...',\n * model: 'gpt-4o'\n * }\n * })) {\n * console.log(event);\n * }\n *\n * @example\n * // Use Anthropic directly\n * for await (const event of query({\n * prompt: 'Hello',\n * options: {\n * provider: 'anthropic',\n * apiKey: 'sk-ant-...'\n * }\n * })) {\n * console.log(event);\n * }\n */\nexport async function* query(params: {\n prompt: string | AsyncIterable<unknown>;\n options?: KrissyQueryOptions;\n}): AsyncGenerator<unknown, void, unknown> {\n const { prompt, options = {} } = params;\n const {\n attachments,\n provider: explicitProvider,\n apiKey,\n baseUrl,\n model: explicitModel,\n maxThinkingTokens,\n ...claudeOptions\n } = options;\n\n // Provider defaults to claude_cli (uses Claude CLI subscription)\n const provider = (explicitProvider || 'claude_cli').toLowerCase();\n const images = attachments?.images || [];\n const files = attachments?.files || [];\n\n // Get defaults for this provider\n const defaults = PROVIDER_DEFAULTS[provider] || PROVIDER_DEFAULTS.claude_cli;\n\n // Resolve final values: explicit options override defaults\n const finalBaseUrl = baseUrl || defaults.baseUrl;\n const finalModel = explicitModel || defaults.model;\n\n // Bedrock uses native SDK support via env vars (no proxy needed)\n // Krisspy and zai_direct make direct HTTP calls (no embedded proxy needed)\n const needsProxy = ['openai', 'zai', 'gemini', 'azure'].includes(provider);\n\n // Build provider config from explicit options (with defaults)\n const providerConfig: ProviderConfig & {\n accessKeyId?: string;\n secretAccessKey?: string;\n region?: string;\n deploymentName?: string;\n apiVersion?: string;\n } = {\n apiKey: apiKey,\n baseUrl: finalBaseUrl,\n defaultModel: finalModel,\n // AWS Bedrock specific\n accessKeyId: options.accessKeyId as string,\n secretAccessKey: options.secretAccessKey as string,\n region: (options.region as string) || 'us-west-2',\n // Azure specific\n deploymentName: options.deploymentName as string,\n apiVersion: options.apiVersion as string,\n };\n\n // Validate Bedrock credentials\n if (provider === 'bedrock') {\n if (!providerConfig.accessKeyId || !providerConfig.secretAccessKey) {\n throw new Error(`[krisspy-ai] AWS credentials required for Bedrock. Pass accessKeyId and secretAccessKey via options.`);\n }\n }\n\n // Start proxy server if needed (not for Bedrock, Krisspy, or zai_direct)\n let port = 0;\n if (needsProxy) {\n if (provider === 'azure') {\n if (!apiKey) {\n throw new Error(`[krisspy-ai] API key required for Azure. Pass it via options.apiKey`);\n }\n if (!finalBaseUrl) {\n throw new Error(`[krisspy-ai] Base URL required for Azure. Pass it via options.baseUrl (e.g., https://your-resource.openai.azure.com)`);\n }\n } else if (!apiKey) {\n throw new Error(`[krisspy-ai] API key required for provider '${provider}'. Pass it via options.apiKey`);\n }\n port = await startProxyServer(provider, providerConfig);\n }\n\n // Build clean system env (only PATH, HOME, etc. - no API keys that could interfere)\n const systemEnvKeys = ['PATH', 'HOME', 'USER', 'SHELL', 'TERM', 'LANG', 'LC_ALL', 'TMPDIR', 'TMP', 'TEMP'];\n const cleanSystemEnv: Record<string, string> = {};\n for (const key of systemEnvKeys) {\n if (process.env[key]) {\n cleanSystemEnv[key] = process.env[key]!;\n }\n }\n\n // Build provider-specific env vars for claude-agent-sdk\n const providerEnv: Record<string, string> = {};\n\n if (provider === 'anthropic') {\n if (apiKey) providerEnv.ANTHROPIC_API_KEY = apiKey;\n providerEnv.ANTHROPIC_BASE_URL = finalBaseUrl; // Always set with default\n } else if (provider === 'zai_direct') {\n if (apiKey) providerEnv.ANTHROPIC_API_KEY = apiKey;\n providerEnv.ANTHROPIC_BASE_URL = finalBaseUrl; // Always set with default\n } else if (provider === 'krisspy') {\n // Krisspy works like zai_direct - direct HTTP calls to backend\n if (!apiKey) {\n throw new Error(`[krisspy-ai] Krisspy API key required. Pass it via options.apiKey`);\n }\n providerEnv.ANTHROPIC_API_KEY = apiKey;\n // Claude Agent SDK adds /v1/messages, so base URL should be /api/v1/ai\n // Result: /api/v1/ai/v1/messages matches backend route\n const baseUrlWithoutTrailingSlash = finalBaseUrl.replace(/\\/$/, '');\n providerEnv.ANTHROPIC_BASE_URL = `${baseUrlWithoutTrailingSlash}/api/v1/ai`;\n console.log(`[krisspy-ai] Using Krisspy provider with base URL ${providerEnv.ANTHROPIC_BASE_URL}`);\n } else if (provider === 'bedrock') {\n // Bedrock uses native SDK support via env vars\n providerEnv.AWS_ACCESS_KEY_ID = providerConfig.accessKeyId!;\n providerEnv.AWS_SECRET_ACCESS_KEY = providerConfig.secretAccessKey!;\n providerEnv.AWS_DEFAULT_REGION = providerConfig.region || 'us-west-2';\n // Map friendly model names to Bedrock model IDs (Claude 4 / 4.5 with global endpoints)\n const bedrockModelMap: Record<string, string> = {\n // Haiku aliases -> Haiku 4.5 (global endpoint)\n 'haiku': 'global.anthropic.claude-haiku-4-5-20251001-v1:0',\n 'haiku-4.5': 'global.anthropic.claude-haiku-4-5-20251001-v1:0',\n // Sonnet aliases -> Sonnet 4 (global endpoint)\n 'sonnet': 'global.anthropic.claude-sonnet-4-20250514-v1:0',\n 'sonnet-4': 'global.anthropic.claude-sonnet-4-20250514-v1:0',\n 'sonnet-4.5': 'us.anthropic.claude-sonnet-4-5-20250929-v1:0',\n // Opus aliases -> Opus 4 / 4.5 (global endpoint)\n 'opus': 'global.anthropic.claude-opus-4-5-20251101-v1:0',\n 'opus-4': 'global.anthropic.claude-opus-4-20250514-v1:0',\n 'opus-4.5': 'global.anthropic.claude-opus-4-5-20251101-v1:0',\n // Also support full model IDs passed directly\n };\n const mappedModel = bedrockModelMap[finalModel] || finalModel;\n providerEnv.ANTHROPIC_MODEL = mappedModel;\n console.log(`[krisspy-ai] Bedrock native mode: model=${mappedModel}, region=${providerConfig.region}`);\n } else if (needsProxy) {\n // For proxy providers, claude-agent-sdk connects to our local proxy\n providerEnv.ANTHROPIC_API_KEY = apiKey || 'proxy-key';\n providerEnv.ANTHROPIC_BASE_URL = `http://127.0.0.1:${port}`;\n }\n\n // Detect Office files that need Skills\n const hasOfficeFiles = files.some((f) => ['xlsx', 'docx', 'pptx'].includes(f.type));\n const useSkills = hasOfficeFiles && !needsProxy;\n\n // Build query options - use explicit values, fallback to sensible defaults\n const queryOptions: Record<string, unknown> = {\n allowedTools: ['Read', 'Edit', 'Bash', 'Glob', 'Grep', 'WebFetch', 'WebSearch'],\n permissionMode: 'acceptEdits',\n includePartialMessages: true,\n systemPrompt: { type: 'preset', preset: 'claude_code' },\n model: finalModel, // Use resolved model with default\n ...claudeOptions,\n env: {\n ...cleanSystemEnv, // Only system vars (PATH, HOME, etc.)\n ...providerEnv, // Our explicit provider config\n ...(claudeOptions.env as Record<string, string> || {}),\n },\n };\n\n // Merge betas - add Skills betas for Office files if needed\n if (useSkills) {\n console.log('[krisspy-ai] Enabling Skills betas for Office files...');\n const existingBetas = (queryOptions.betas as string[]) || [];\n const skillsBetas = ['code-execution-2025-08-25', 'skills-2025-10-02'];\n queryOptions.betas = [...new Set([...existingBetas, ...skillsBetas])];\n }\n\n if (maxThinkingTokens !== undefined && maxThinkingTokens > 0) {\n queryOptions.maxThinkingTokens = maxThinkingTokens;\n }\n\n // Build prompt with multimodal content if needed\n let finalPrompt: string | AsyncIterable<unknown>;\n\n if (typeof prompt === 'string' && (images.length > 0 || files.length > 0)) {\n const content: unknown[] = [];\n\n // Add images\n for (const img of images) {\n if (img.type === 'url') {\n content.push({ type: 'image', source: { type: 'url', url: img.url } });\n } else if (img.type === 'base64') {\n content.push({\n type: 'image',\n source: { type: 'base64', media_type: img.media_type || 'image/jpeg', data: img.data },\n });\n }\n }\n\n // Add files\n const officeFiles: FileAttachment[] = [];\n for (const file of files) {\n if (file.type === 'pdf') {\n content.push({\n type: 'document',\n source: { type: 'base64', media_type: 'application/pdf', data: file.data },\n });\n } else if (['xlsx', 'docx', 'pptx', 'csv'].includes(file.type)) {\n officeFiles.push(file);\n } else {\n content.push({\n type: 'text',\n text: `[Note: A ${file.type?.toUpperCase() || 'unknown'} file was attached but this format is not supported.]`,\n });\n }\n }\n\n // Upload Office files via Files API if any\n if (officeFiles.length > 0 && !needsProxy) {\n const filesApiKey = apiKey || '';\n const filesBaseUrl = baseUrl || 'https://api.anthropic.com';\n\n if (filesApiKey && !filesBaseUrl.includes('127.0.0.1') && !filesBaseUrl.includes('localhost')) {\n for (const file of officeFiles) {\n try {\n console.log(`[krisspy-ai] Uploading ${file.type.toUpperCase()} via Files API...`);\n const fileId = await uploadFileToFilesAPI(file, filesApiKey, filesBaseUrl);\n console.log(`[krisspy-ai] File uploaded: ${fileId}`);\n content.push({ type: 'document', source: { type: 'file', file_id: fileId } });\n } catch (err) {\n console.error(`[krisspy-ai] Failed to upload ${file.type}:`, (err as Error).message);\n content.push({\n type: 'text',\n text: `[Note: Failed to upload ${file.type.toUpperCase()} file: ${(err as Error).message}]`,\n });\n }\n }\n }\n } else if (officeFiles.length > 0) {\n // Proxy mode - pass through\n for (const file of officeFiles) {\n content.push({\n type: 'document',\n source: { type: 'base64', media_type: file.media_type, data: file.data },\n });\n }\n }\n\n content.push({ type: 'text', text: prompt });\n\n finalPrompt = (async function* () {\n yield { type: 'user', message: { role: 'user', content } };\n })();\n } else {\n finalPrompt = prompt;\n }\n\n // Call claude-agent-sdk's query\n console.log(`[krisspy-ai] Using provider: ${provider}${needsProxy ? ` (proxy on port ${port})` : ''}`);\n\n // Reset proxy error before request\n lastProxyError = null;\n\n try {\n for await (const event of claudeQuery({ prompt: finalPrompt, options: queryOptions } as Parameters<typeof claudeQuery>[0])) {\n // Check for proxy errors during iteration\n if (lastProxyError) {\n yield {\n type: 'result',\n subtype: 'error',\n is_error: true,\n errors: [lastProxyError],\n };\n lastProxyError = null;\n return;\n }\n yield event;\n }\n } catch (error) {\n // If there was a proxy error, include it in the error message\n const errorMessage = lastProxyError || (error as Error).message;\n lastProxyError = null;\n yield {\n type: 'result',\n subtype: 'error',\n is_error: true,\n errors: [errorMessage],\n };\n }\n}\n\n// Cleanup function\nexport async function cleanup(): Promise<void> {\n await stopProxyServer();\n}\n\n// Export providers for advanced usage\nexport { getProvider, registerProvider, getAvailableProviders } from './providers';\nexport { OpenAIProvider } from './providers/openai';\nexport { GeminiProvider } from './providers/gemini';\nexport { ZAIProvider } from './providers/zai';\nexport { BedrockProvider } from './providers/bedrock';\nexport { AzureProvider } from './providers/azure';\nexport { KrisspyProvider } from './providers/krisspy';\nexport { BaseProvider } from './providers/base';\n\nexport type {\n Provider,\n ProviderConfig,\n AnthropicMessage,\n AnthropicRequest,\n AnthropicResponse,\n OpenAIMessage,\n OpenAIRequest,\n} from './types';\n\n// ============================================================================\n// GENERATIVE AI SERVICES (Image, Video, Audio)\n// ============================================================================\n\n// Import services\nimport {\n getImageService,\n getVideoService,\n getTranscriptionService,\n getTTSService,\n registerImageService,\n registerVideoService,\n registerTranscriptionService,\n registerTTSService,\n getAvailableImageServices,\n getAvailableVideoServices,\n getAvailableTranscriptionServices,\n getAvailableTTSServices,\n} from './services';\nimport type {\n GenerateImageOptions,\n GenerateVideoOptions,\n TranscribeOptions,\n SynthesizeOptions,\n ImageGenerationResult,\n VideoGenerationEvent,\n TranscriptionResult,\n TTSResult,\n} from './services/types';\n\n// Re-export services\nexport {\n // Factory functions\n getImageService,\n getVideoService,\n getTranscriptionService,\n getTTSService,\n registerImageService,\n registerVideoService,\n registerTranscriptionService,\n registerTTSService,\n getAvailableImageServices,\n getAvailableVideoServices,\n getAvailableTranscriptionServices,\n getAvailableTTSServices,\n // Base classes\n BaseGenerativeService,\n BaseImageService,\n BaseVideoService,\n BaseTranscriptionService,\n BaseTTSService,\n // Service implementations\n AzureDalleService,\n OpenAIImageService,\n AzureSoraService,\n OpenAISoraService,\n AzureTranscriptionService,\n OpenAITranscriptionService,\n AzureTTSService,\n OpenAITTSService,\n} from './services';\n\n// Re-export service types\nexport type {\n GenerativeServiceConfig,\n // Image types\n ImageGenerationOptions,\n ImageGenerationResult,\n GeneratedImage,\n GenerateImageOptions,\n // Video types\n VideoGenerationOptions,\n VideoJobSubmission,\n VideoJobStatus,\n VideoGenerationResult,\n GeneratedVideo,\n VideoGenerationEvent,\n GenerateVideoOptions,\n // Audio transcription types\n TranscriptionOptions,\n TranscriptionResult,\n TranscriptionWord,\n TranscriptionSegment,\n DiarizedUtterance,\n TranscribeOptions,\n // TTS types\n TTSOptions,\n TTSResult,\n TTSVoice,\n TTSFormat,\n SynthesizeOptions,\n} from './services/types';\n\n// ============================================================================\n// CONVENIENCE FUNCTIONS FOR GENERATIVE AI\n// ============================================================================\n\n/**\n * Generate an image using the specified service\n *\n * @param options - Image generation options\n * @returns Promise resolving to image generation result\n *\n * @example\n * const result = await generateImage({\n * prompt: 'A cute baby polar bear',\n * apiKey: 'your-azure-key',\n * baseUrl: 'https://your-resource.openai.azure.com',\n * deploymentName: 'gpt-image-1.5',\n * size: '1024x1024',\n * });\n * console.log(result.data[0].url);\n *\n * // Save to file\n * const imageUrl = result.data[0].url;\n * // or if using b64_json:\n * const imageBuffer = Buffer.from(result.data[0].b64_json!, 'base64');\n */\nexport async function generateImage(options: GenerateImageOptions): Promise<ImageGenerationResult> {\n const service = getImageService(options.service || 'azure', {\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n deploymentName: options.deploymentName,\n apiVersion: options.apiVersion,\n });\n\n return service.generate({\n prompt: options.prompt,\n n: options.n,\n size: options.size,\n quality: options.quality,\n style: options.style,\n responseFormat: options.responseFormat,\n user: options.user,\n });\n}\n\n/**\n * Generate a video using the specified service (async with polling)\n *\n * This is an async generator that yields status updates and finally the result.\n *\n * @param options - Video generation options\n * @yields Status updates as { type: 'status', status: VideoJobStatus }\n * @yields Final result as { type: 'result', data: VideoGenerationResult }\n *\n * @example\n * for await (const event of generateVideo({\n * prompt: 'Wooly mammoths slowly walking in the ice',\n * apiKey: 'your-azure-key',\n * baseUrl: 'https://your-resource.openai.azure.com',\n * deploymentName: 'sora-2',\n * duration: 5,\n * })) {\n * if (event.type === 'status') {\n * console.log(`Status: ${event.status.status}`);\n * } else if (event.type === 'result') {\n * console.log(`Video ready! Generation ID: ${event.data.generations[0].id}`);\n * // Download the video\n * const videoService = getVideoService('azure', { apiKey, baseUrl });\n * const videoBuffer = await videoService.downloadVideo(event.data.generations[0].id);\n * fs.writeFileSync('output.mp4', videoBuffer);\n * }\n * }\n */\nexport async function* generateVideo(\n options: GenerateVideoOptions\n): AsyncGenerator<VideoGenerationEvent> {\n const service = getVideoService(options.service || 'azure', {\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n deploymentName: options.deploymentName,\n apiVersion: options.apiVersion,\n });\n\n const generator = service.generateAndWait(\n {\n prompt: options.prompt,\n duration: options.duration,\n width: options.width,\n height: options.height,\n nVariants: options.nVariants,\n user: options.user,\n referenceImage: options.referenceImage,\n referenceImageFormat: options.referenceImageFormat,\n },\n options.pollInterval,\n options.timeout\n );\n\n let result: IteratorResult<import('./services/types').VideoJobStatus, import('./services/types').VideoGenerationResult>;\n while (!(result = await generator.next()).done) {\n yield { type: 'status', status: result.value };\n }\n\n yield { type: 'result', data: result.value };\n}\n\n/**\n * Transcribe audio to text using the specified service\n *\n * @param options - Transcription options\n * @returns Promise resolving to transcription result\n *\n * @example\n * // Using OpenAI Whisper\n * const result = await transcribe({\n * audio: fs.readFileSync('audio.mp3'),\n * apiKey: 'sk-...',\n * deploymentName: 'whisper',\n * });\n * console.log(result.text);\n *\n * @example\n * // Using GPT-4o with diarization (speaker identification)\n * const result = await transcribe({\n * audio: fs.readFileSync('meeting.mp3'),\n * apiKey: 'sk-...',\n * deploymentName: 'gpt-4o-transcribe-diarize',\n * responseFormat: 'verbose_json',\n * });\n * for (const utterance of result.utterances || []) {\n * console.log(`${utterance.speaker}: ${utterance.text}`);\n * }\n */\nexport async function transcribe(options: TranscribeOptions): Promise<TranscriptionResult> {\n const service = getTranscriptionService(options.service || 'openai', {\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n deploymentName: options.deploymentName,\n apiVersion: options.apiVersion,\n });\n\n return service.transcribe({\n audio: options.audio,\n language: options.language,\n prompt: options.prompt,\n responseFormat: options.responseFormat,\n temperature: options.temperature,\n timestampGranularities: options.timestampGranularities,\n });\n}\n\n/**\n * Synthesize speech from text using the specified service\n *\n * @param options - TTS options\n * @returns Promise resolving to audio buffer\n *\n * @example\n * // Using OpenAI TTS\n * const result = await synthesize({\n * input: 'Hello, how are you today?',\n * apiKey: 'sk-...',\n * voice: 'nova',\n * responseFormat: 'mp3',\n * });\n * fs.writeFileSync('output.mp3', result.audio);\n *\n * @example\n * // Using gpt-4o-mini-tts with voice style instructions\n * const result = await synthesize({\n * input: 'Welcome to our podcast!',\n * apiKey: 'sk-...',\n * deploymentName: 'gpt-4o-mini-tts',\n * voice: 'coral',\n * instructions: 'Speak in an enthusiastic, energetic podcast host style',\n * });\n * fs.writeFileSync('intro.mp3', result.audio);\n */\nexport async function synthesize(options: SynthesizeOptions): Promise<TTSResult> {\n const service = getTTSService(options.service || 'openai', {\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n deploymentName: options.deploymentName,\n apiVersion: options.apiVersion,\n });\n\n return service.synthesize({\n input: options.input,\n voice: options.voice,\n responseFormat: options.responseFormat,\n speed: options.speed,\n instructions: options.instructions,\n });\n}\n","import type {\n Provider,\n ProviderConfig,\n AnthropicMessage,\n AnthropicTool,\n AnthropicRequest,\n AnthropicResponse,\n OpenAIMessage,\n OpenAITool,\n ProviderRequest,\n StreamResponse,\n} from '../types';\n\n/**\n * Base provider interface\n * All providers must implement these methods\n */\nexport abstract class BaseProvider implements Provider {\n protected config: ProviderConfig;\n\n constructor(config: ProviderConfig = {}) {\n this.config = config;\n }\n\n /**\n * Get provider name\n */\n abstract getName(): string;\n\n /**\n * Convert Anthropic messages to provider format\n */\n abstract convertMessages(anthropicMessages: AnthropicMessage[]): OpenAIMessage[] | AnthropicMessage[];\n\n /**\n * Convert Anthropic tools to provider format\n */\n abstract convertTools(anthropicTools?: AnthropicTool[]): OpenAITool[] | AnthropicTool[] | undefined;\n\n /**\n * Map Anthropic model to provider model\n */\n abstract mapModel(anthropicModel: string): string;\n\n /**\n * Build request body for provider API\n */\n abstract buildRequest(anthropicRequest: AnthropicRequest): ProviderRequest;\n\n /**\n * Get API endpoint URL\n */\n abstract getEndpoint(): string;\n\n /**\n * Get request headers\n */\n abstract getHeaders(): Record<string, string>;\n\n /**\n * Handle streaming response - convert provider SSE to Anthropic SSE format\n */\n abstract handleStreamingResponse(\n providerResponse: { body: NodeJS.ReadableStream },\n res: StreamResponse,\n messageId: string,\n requestedModel: string\n ): Promise<void>;\n\n /**\n * Convert non-streaming response to Anthropic format\n */\n abstract convertResponse(\n providerData: unknown,\n messageId: string,\n requestedModel: string\n ): AnthropicResponse;\n}\n\nexport default BaseProvider;\n","import { BaseProvider } from './base';\nimport type {\n ProviderConfig,\n AnthropicMessage,\n AnthropicTool,\n AnthropicRequest,\n AnthropicResponse,\n AnthropicContentBlock,\n OpenAIMessage,\n OpenAITool,\n OpenAIRequest,\n OpenAIContentPart,\n OpenAIToolCall,\n StreamResponse,\n} from '../types';\n\ninterface ToolCallBuffer {\n id: string;\n name: string;\n arguments: string;\n}\n\ninterface OpenAIStreamChunk {\n choices?: Array<{\n delta?: {\n content?: string;\n tool_calls?: Array<{\n index: number;\n id?: string;\n function?: {\n name?: string;\n arguments?: string;\n };\n }>;\n };\n }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n };\n}\n\ninterface OpenAIResponse {\n choices: Array<{\n message: {\n content?: string;\n tool_calls?: Array<{\n id: string;\n function: {\n name: string;\n arguments: string;\n };\n }>;\n };\n }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n };\n}\n\nexport class OpenAIProvider extends BaseProvider {\n protected baseUrl: string;\n protected apiKey: string;\n protected defaultModel: string;\n protected modelMap: Record<string, string>;\n\n constructor(config: ProviderConfig = {}) {\n super(config);\n // All config must be explicit - no env var fallbacks\n this.baseUrl = config.baseUrl || 'https://api.openai.com/v1';\n this.apiKey = config.apiKey || '';\n this.defaultModel = config.defaultModel || 'gpt-4o';\n\n this.modelMap = {\n 'claude-3-5-haiku-20241022': 'gpt-4o-mini',\n 'claude-3-5-haiku-latest': 'gpt-4o-mini',\n 'claude-haiku-4-5-20251001': 'gpt-4o-mini',\n 'claude-3-5-sonnet-20241022': 'gpt-5',\n 'claude-sonnet-4-20250514': 'gpt-5',\n 'claude-opus-4-20250514': 'gpt-5.2',\n 'claude-opus-4-5-20250514': 'gpt-5.2',\n 'claude-opus-4-5-20251101': 'gpt-5.2',\n };\n }\n\n getName(): string {\n return 'openai';\n }\n\n mapModel(anthropicModel: string): string {\n return this.modelMap[anthropicModel] || this.defaultModel;\n }\n\n convertMessages(anthropicMessages: AnthropicMessage[]): OpenAIMessage[] {\n const openaiMessages: OpenAIMessage[] = [];\n\n for (const msg of anthropicMessages) {\n if (typeof msg.content === 'string') {\n openaiMessages.push({\n role: msg.role === 'assistant' ? 'assistant' : 'user',\n content: msg.content,\n });\n } else if (Array.isArray(msg.content)) {\n const contentParts: OpenAIContentPart[] = [];\n const toolCalls: OpenAIToolCall[] = [];\n let hasImages = false;\n\n for (const block of msg.content as AnthropicContentBlock[]) {\n if (block.type === 'text') {\n contentParts.push({ type: 'text', text: block.text });\n } else if (block.type === 'image') {\n hasImages = true;\n // Convert Anthropic image format to OpenAI format\n if (block.source?.type === 'url') {\n contentParts.push({\n type: 'image_url',\n image_url: { url: block.source.url! },\n });\n } else if (block.source?.type === 'base64') {\n contentParts.push({\n type: 'image_url',\n image_url: {\n url: `data:${block.source.media_type};base64,${block.source.data}`,\n },\n });\n }\n } else if (block.type === 'document') {\n hasImages = true; // Use same multimodal flag\n // Convert document format to OpenAI file format\n const source = block.source;\n const data = source?.data;\n\n // Always use PDF mime type - OpenAI only accepts PDF inline\n contentParts.push({\n type: 'file',\n file: {\n filename: 'document.pdf',\n file_data: `data:application/pdf;base64,${data}`,\n },\n });\n } else if (block.type === 'tool_result') {\n openaiMessages.push({\n role: 'tool',\n tool_call_id: block.tool_use_id,\n content:\n typeof block.content === 'string' ? block.content : JSON.stringify(block.content),\n });\n } else if (block.type === 'tool_use') {\n toolCalls.push({\n id: block.id,\n type: 'function',\n function: {\n name: block.name,\n arguments: JSON.stringify(block.input),\n },\n });\n }\n }\n\n if (msg.role === 'assistant' && toolCalls.length > 0) {\n const textContent = contentParts\n .filter((p) => p.type === 'text')\n .map((p) => p.text)\n .join('');\n openaiMessages.push({\n role: 'assistant',\n content: textContent || null,\n tool_calls: toolCalls,\n });\n } else if (contentParts.length > 0) {\n if (hasImages) {\n // Use array format for multimodal content\n openaiMessages.push({\n role: msg.role === 'assistant' ? 'assistant' : 'user',\n content: contentParts,\n });\n } else {\n const textContent = contentParts.map((p) => p.text).join('');\n if (textContent) {\n openaiMessages.push({\n role: msg.role === 'assistant' ? 'assistant' : 'user',\n content: textContent,\n });\n }\n }\n }\n }\n }\n\n return openaiMessages;\n }\n\n convertTools(anthropicTools?: AnthropicTool[]): OpenAITool[] | undefined {\n if (!anthropicTools || anthropicTools.length === 0) return undefined;\n\n return anthropicTools.map((tool) => {\n const params = tool.input_schema || { type: 'object', properties: {} };\n return {\n type: 'function' as const,\n function: {\n name: tool.name,\n description: tool.description || '',\n parameters: params,\n },\n };\n });\n }\n\n buildRequest(anthropicRequest: AnthropicRequest): OpenAIRequest {\n const { model, messages, max_tokens, system, tools, tool_choice } = anthropicRequest;\n\n const mappedModel = this.mapModel(model);\n const openaiMessages: OpenAIMessage[] = [];\n\n // Add system message\n if (system) {\n let systemContent: string;\n if (typeof system === 'string') {\n systemContent = system;\n } else if (Array.isArray(system)) {\n systemContent = system.map((s) => s.text || s).join('\\n');\n } else {\n systemContent = '';\n }\n openaiMessages.push({ role: 'system', content: systemContent });\n }\n\n // Convert messages\n openaiMessages.push(...this.convertMessages(messages));\n\n const openaiRequest: OpenAIRequest & { stream_options?: { include_usage: boolean } } = {\n model: mappedModel,\n messages: openaiMessages,\n stream: true,\n stream_options: { include_usage: true },\n };\n\n // Handle max_tokens based on model\n if (max_tokens) {\n if (\n mappedModel.startsWith('o1') ||\n mappedModel.startsWith('o3') ||\n mappedModel.startsWith('gpt-5')\n ) {\n openaiRequest.max_completion_tokens = max_tokens;\n } else {\n openaiRequest.max_tokens = max_tokens;\n }\n }\n\n // Add tools\n const openaiTools = this.convertTools(tools);\n if (openaiTools && openaiTools.length > 0) {\n openaiRequest.tools = openaiTools;\n\n if (tool_choice) {\n if (tool_choice.type === 'auto') {\n openaiRequest.tool_choice = 'auto';\n } else if (tool_choice.type === 'any') {\n openaiRequest.tool_choice = 'required';\n } else if (tool_choice.type === 'tool' && tool_choice.name) {\n openaiRequest.tool_choice = {\n type: 'function',\n function: { name: tool_choice.name },\n };\n }\n }\n }\n\n return openaiRequest;\n }\n\n getEndpoint(): string {\n return `${this.baseUrl}/chat/completions`;\n }\n\n getHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n };\n }\n\n async handleStreamingResponse(\n providerResponse: { body: NodeJS.ReadableStream },\n res: StreamResponse,\n messageId: string,\n requestedModel: string\n ): Promise<void> {\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.setHeader('X-Accel-Buffering', 'no');\n res.flushHeaders();\n\n let contentBlockIndex = 0;\n let outputTokens = 0;\n const toolCallsBuffer: Record<number, ToolCallBuffer> = {};\n\n const writeAndFlush = (data: string) => {\n res.write(data);\n if (res.flush) res.flush();\n };\n\n // Send message_start event\n const messageStart = {\n type: 'message_start',\n message: {\n id: messageId,\n type: 'message',\n role: 'assistant',\n content: [],\n model: requestedModel,\n stop_reason: null,\n stop_sequence: null,\n usage: { input_tokens: 0, output_tokens: 0 },\n },\n };\n writeAndFlush(`event: message_start\\ndata: ${JSON.stringify(messageStart)}\\n\\n`);\n\n // Send initial content_block_start for text\n writeAndFlush(\n `event: content_block_start\\ndata: ${JSON.stringify({\n type: 'content_block_start',\n index: contentBlockIndex,\n content_block: { type: 'text', text: '' },\n })}\\n\\n`\n );\n\n const reader = providerResponse.body;\n let buffer = '';\n\n return new Promise((resolve, reject) => {\n reader.on('data', (chunk: Buffer) => {\n buffer += chunk.toString();\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6).trim();\n if (data === '[DONE]') {\n // Close text block\n writeAndFlush(\n `event: content_block_stop\\ndata: ${JSON.stringify({\n type: 'content_block_stop',\n index: contentBlockIndex,\n })}\\n\\n`\n );\n\n // Handle tool calls\n const toolCalls = Object.values(toolCallsBuffer);\n if (toolCalls.length > 0) {\n for (const tc of toolCalls) {\n contentBlockIndex++;\n\n writeAndFlush(\n `event: content_block_start\\ndata: ${JSON.stringify({\n type: 'content_block_start',\n index: contentBlockIndex,\n content_block: {\n type: 'tool_use',\n id: tc.id,\n name: tc.name,\n input: {},\n },\n })}\\n\\n`\n );\n\n if (tc.arguments) {\n writeAndFlush(\n `event: content_block_delta\\ndata: ${JSON.stringify({\n type: 'content_block_delta',\n index: contentBlockIndex,\n delta: { type: 'input_json_delta', partial_json: tc.arguments },\n })}\\n\\n`\n );\n }\n\n writeAndFlush(\n `event: content_block_stop\\ndata: ${JSON.stringify({\n type: 'content_block_stop',\n index: contentBlockIndex,\n })}\\n\\n`\n );\n }\n }\n\n const stopReason = toolCalls.length > 0 ? 'tool_use' : 'end_turn';\n\n writeAndFlush(\n `event: message_delta\\ndata: ${JSON.stringify({\n type: 'message_delta',\n delta: { stop_reason: stopReason, stop_sequence: null },\n usage: { output_tokens: outputTokens },\n })}\\n\\n`\n );\n\n writeAndFlush(\n `event: message_stop\\ndata: ${JSON.stringify({ type: 'message_stop' })}\\n\\n`\n );\n resolve();\n return;\n }\n\n try {\n const parsed = JSON.parse(data) as OpenAIStreamChunk;\n const choice = parsed.choices?.[0];\n\n const textContent = choice?.delta?.content;\n if (textContent) {\n outputTokens++;\n writeAndFlush(\n `event: content_block_delta\\ndata: ${JSON.stringify({\n type: 'content_block_delta',\n index: contentBlockIndex,\n delta: { type: 'text_delta', text: textContent },\n })}\\n\\n`\n );\n }\n\n if (choice?.delta?.tool_calls) {\n for (const toolCall of choice.delta.tool_calls) {\n const idx = toolCall.index;\n\n if (!toolCallsBuffer[idx]) {\n toolCallsBuffer[idx] = {\n id: toolCall.id || `toolu_${Date.now()}_${idx}`,\n name: '',\n arguments: '',\n };\n }\n\n if (toolCall.id) {\n toolCallsBuffer[idx].id = toolCall.id;\n }\n if (toolCall.function?.name) {\n toolCallsBuffer[idx].name = toolCall.function.name;\n }\n if (toolCall.function?.arguments) {\n toolCallsBuffer[idx].arguments += toolCall.function.arguments;\n }\n }\n }\n\n if (parsed.usage) {\n outputTokens = parsed.usage.completion_tokens || 0;\n }\n } catch {\n // Ignore parse errors\n }\n }\n }\n });\n\n reader.on('end', () => resolve());\n reader.on('error', reject);\n });\n }\n\n convertResponse(\n providerData: unknown,\n messageId: string,\n requestedModel: string\n ): AnthropicResponse {\n const data = providerData as OpenAIResponse;\n const content: AnthropicContentBlock[] = [];\n\n if (data.choices[0].message.content) {\n content.push({ type: 'text', text: data.choices[0].message.content });\n }\n\n if (data.choices[0].message.tool_calls) {\n for (const tc of data.choices[0].message.tool_calls) {\n let parsedInput: Record<string, unknown> = {};\n try {\n parsedInput = JSON.parse(tc.function.arguments);\n } catch {\n parsedInput = {};\n }\n content.push({\n type: 'tool_use',\n id: tc.id,\n name: tc.function.name,\n input: parsedInput,\n });\n }\n }\n\n const stopReason = data.choices[0].message.tool_calls ? 'tool_use' : 'end_turn';\n\n return {\n id: messageId,\n type: 'message',\n role: 'assistant',\n content: content,\n model: requestedModel,\n stop_reason: stopReason,\n stop_sequence: null,\n usage: {\n input_tokens: data.usage?.prompt_tokens || 0,\n output_tokens: data.usage?.completion_tokens || 0,\n },\n };\n }\n}\n\nexport default OpenAIProvider;\n","import { BaseProvider } from './base';\nimport type {\n ProviderConfig,\n AnthropicMessage,\n AnthropicTool,\n AnthropicRequest,\n AnthropicResponse,\n AnthropicContentBlock,\n OpenAIMessage,\n OpenAITool,\n OpenAIRequest,\n OpenAIContentPart,\n OpenAIToolCall,\n StreamResponse,\n} from '../types';\n\ninterface ToolCallBuffer {\n id: string;\n name: string;\n arguments: string;\n}\n\ninterface ZAIStreamChunk {\n choices?: Array<{\n delta?: {\n content?: string;\n reasoning_content?: string;\n tool_calls?: Array<{\n index: number;\n id?: string;\n function?: {\n name?: string;\n arguments?: string;\n };\n }>;\n };\n }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n };\n}\n\ninterface ZAIResponse {\n choices: Array<{\n message: {\n content?: string;\n };\n }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n };\n}\n\nexport class ZAIProvider extends BaseProvider {\n protected baseUrl: string;\n protected apiKey: string;\n protected defaultModel: string;\n protected modelMap: Record<string, string>;\n\n constructor(config: ProviderConfig = {}) {\n super(config);\n // All config must be explicit - no env var fallbacks\n this.baseUrl = config.baseUrl || 'https://api.z.ai/api/coding/paas/v4';\n this.apiKey = config.apiKey || '';\n this.defaultModel = config.defaultModel || 'glm-4.7';\n\n this.modelMap = {\n 'claude-3-5-haiku-20241022': 'glm-4.7',\n 'claude-3-5-haiku-latest': 'glm-4.7',\n 'claude-haiku-4-5-20251001': 'glm-4.7',\n 'claude-3-5-sonnet-20241022': 'glm-4.7',\n 'claude-sonnet-4-20250514': 'glm-4.7',\n 'claude-opus-4-20250514': 'glm-4.7',\n 'claude-opus-4-5-20250514': 'glm-4.7',\n 'claude-opus-4-5-20251101': 'glm-4.7',\n };\n }\n\n getName(): string {\n return 'zai';\n }\n\n mapModel(anthropicModel: string): string {\n return this.modelMap[anthropicModel] || this.defaultModel;\n }\n\n convertMessages(anthropicMessages: AnthropicMessage[]): OpenAIMessage[] {\n const openaiMessages: OpenAIMessage[] = [];\n\n for (const msg of anthropicMessages) {\n if (typeof msg.content === 'string') {\n openaiMessages.push({\n role: msg.role === 'assistant' ? 'assistant' : 'user',\n content: msg.content,\n });\n } else if (Array.isArray(msg.content)) {\n const contentParts: OpenAIContentPart[] = [];\n const toolCalls: OpenAIToolCall[] = [];\n let hasMultimodal = false;\n\n for (const block of msg.content as AnthropicContentBlock[]) {\n if (block.type === 'text') {\n contentParts.push({ type: 'text', text: block.text });\n } else if (block.type === 'image') {\n hasMultimodal = true;\n // Convert Anthropic image format to OpenAI format\n if (block.source?.type === 'url') {\n contentParts.push({\n type: 'image_url',\n image_url: { url: block.source.url! },\n });\n } else if (block.source?.type === 'base64') {\n contentParts.push({\n type: 'image_url',\n image_url: {\n url: `data:${block.source.media_type};base64,${block.source.data}`,\n },\n });\n }\n } else if (block.type === 'document') {\n hasMultimodal = true;\n // Convert document format to OpenAI file format\n const source = block.source;\n const data = source?.data;\n\n // Always use PDF mime type - OpenAI-style APIs only accept PDF inline\n contentParts.push({\n type: 'file',\n file: {\n filename: 'document.pdf',\n file_data: `data:application/pdf;base64,${data}`,\n },\n });\n } else if (block.type === 'tool_result') {\n openaiMessages.push({\n role: 'tool',\n tool_call_id: block.tool_use_id,\n content:\n typeof block.content === 'string' ? block.content : JSON.stringify(block.content),\n });\n } else if (block.type === 'tool_use') {\n toolCalls.push({\n id: block.id,\n type: 'function',\n function: {\n name: block.name,\n arguments: JSON.stringify(block.input),\n },\n });\n }\n }\n\n if (msg.role === 'assistant' && toolCalls.length > 0) {\n const textContent = contentParts\n .filter((p) => p.type === 'text')\n .map((p) => p.text)\n .join('');\n openaiMessages.push({\n role: 'assistant',\n content: textContent || null,\n tool_calls: toolCalls,\n });\n } else if (contentParts.length > 0) {\n if (hasMultimodal) {\n // Use array format for multimodal content\n openaiMessages.push({\n role: msg.role === 'assistant' ? 'assistant' : 'user',\n content: contentParts,\n });\n } else {\n const textContent = contentParts.map((p) => p.text).join('');\n if (textContent) {\n openaiMessages.push({\n role: msg.role === 'assistant' ? 'assistant' : 'user',\n content: textContent,\n });\n }\n }\n }\n }\n }\n\n return openaiMessages;\n }\n\n convertTools(anthropicTools?: AnthropicTool[]): OpenAITool[] | undefined {\n if (!anthropicTools) return undefined;\n\n return anthropicTools.map((tool) => ({\n type: 'function' as const,\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.input_schema,\n },\n }));\n }\n\n buildRequest(anthropicRequest: AnthropicRequest): OpenAIRequest {\n const { model, messages, max_tokens, system, tools } = anthropicRequest;\n\n const mappedModel = this.mapModel(model);\n const openaiMessages: OpenAIMessage[] = [];\n\n // Add system message\n if (system) {\n const systemContent =\n typeof system === 'string' ? system : system.map((s) => s.text).join('\\n');\n openaiMessages.push({ role: 'system', content: systemContent });\n }\n\n // Convert messages\n openaiMessages.push(...this.convertMessages(messages));\n\n const openaiRequest: OpenAIRequest = {\n model: mappedModel,\n messages: openaiMessages,\n max_tokens: max_tokens || 4096,\n stream: true,\n temperature: 0.7,\n };\n\n // Add tools if present\n const openaiTools = this.convertTools(tools);\n if (openaiTools) {\n openaiRequest.tools = openaiTools;\n }\n\n return openaiRequest;\n }\n\n getEndpoint(): string {\n return `${this.baseUrl}/chat/completions`;\n }\n\n getHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n 'Accept-Language': 'en-US,en',\n };\n }\n\n async handleStreamingResponse(\n providerResponse: { body: NodeJS.ReadableStream },\n res: StreamResponse,\n messageId: string,\n requestedModel: string\n ): Promise<void> {\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.setHeader('X-Accel-Buffering', 'no');\n res.flushHeaders();\n\n let contentBlockIndex = 0;\n let outputTokens = 0;\n const toolCallsBuffer: Record<number, ToolCallBuffer> = {};\n\n const writeAndFlush = (data: string) => {\n res.write(data);\n if (res.flush) res.flush();\n };\n\n // Send message_start event\n const messageStart = {\n type: 'message_start',\n message: {\n id: messageId,\n type: 'message',\n role: 'assistant',\n content: [],\n model: requestedModel,\n stop_reason: null,\n stop_sequence: null,\n usage: { input_tokens: 0, output_tokens: 0 },\n },\n };\n writeAndFlush(`event: message_start\\ndata: ${JSON.stringify(messageStart)}\\n\\n`);\n\n // Send initial content_block_start for text\n writeAndFlush(\n `event: content_block_start\\ndata: ${JSON.stringify({\n type: 'content_block_start',\n index: contentBlockIndex,\n content_block: { type: 'text', text: '' },\n })}\\n\\n`\n );\n\n const reader = providerResponse.body;\n let buffer = '';\n\n return new Promise((resolve, reject) => {\n reader.on('data', (chunk: Buffer) => {\n buffer += chunk.toString();\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6);\n if (data === '[DONE]') {\n // Send content_block_stop\n writeAndFlush(\n `event: content_block_stop\\ndata: ${JSON.stringify({\n type: 'content_block_stop',\n index: contentBlockIndex,\n })}\\n\\n`\n );\n\n // Send message_delta\n writeAndFlush(\n `event: message_delta\\ndata: ${JSON.stringify({\n type: 'message_delta',\n delta: { stop_reason: 'end_turn', stop_sequence: null },\n usage: { output_tokens: outputTokens },\n })}\\n\\n`\n );\n\n // Send message_stop\n writeAndFlush(\n `event: message_stop\\ndata: ${JSON.stringify({ type: 'message_stop' })}\\n\\n`\n );\n resolve();\n return;\n }\n\n try {\n const parsed = JSON.parse(data) as ZAIStreamChunk;\n const choice = parsed.choices?.[0];\n\n // Z.AI uses reasoning_content for the main content\n const textContent = choice?.delta?.content || choice?.delta?.reasoning_content;\n if (textContent) {\n outputTokens++;\n writeAndFlush(\n `event: content_block_delta\\ndata: ${JSON.stringify({\n type: 'content_block_delta',\n index: contentBlockIndex,\n delta: { type: 'text_delta', text: textContent },\n })}\\n\\n`\n );\n }\n\n // Handle tool calls\n if (choice?.delta?.tool_calls) {\n for (const toolCall of choice.delta.tool_calls) {\n const idx = toolCall.index;\n\n if (!toolCallsBuffer[idx]) {\n toolCallsBuffer[idx] = {\n id: toolCall.id || `tool_${idx}`,\n name: '',\n arguments: '',\n };\n }\n\n if (toolCall.function?.name) {\n toolCallsBuffer[idx].name = toolCall.function.name;\n }\n if (toolCall.function?.arguments) {\n toolCallsBuffer[idx].arguments += toolCall.function.arguments;\n }\n }\n }\n\n if (parsed.usage) {\n outputTokens = parsed.usage.completion_tokens || 0;\n }\n } catch {\n // Ignore parse errors\n }\n }\n }\n });\n\n reader.on('end', () => {\n // Handle any remaining tool calls\n const toolCalls = Object.values(toolCallsBuffer);\n if (toolCalls.length > 0) {\n for (const tc of toolCalls) {\n contentBlockIndex++;\n writeAndFlush(\n `event: content_block_start\\ndata: ${JSON.stringify({\n type: 'content_block_start',\n index: contentBlockIndex,\n content_block: {\n type: 'tool_use',\n id: tc.id,\n name: tc.name,\n input: {},\n },\n })}\\n\\n`\n );\n\n if (tc.arguments) {\n writeAndFlush(\n `event: content_block_delta\\ndata: ${JSON.stringify({\n type: 'content_block_delta',\n index: contentBlockIndex,\n delta: { type: 'input_json_delta', partial_json: tc.arguments },\n })}\\n\\n`\n );\n }\n\n writeAndFlush(\n `event: content_block_stop\\ndata: ${JSON.stringify({\n type: 'content_block_stop',\n index: contentBlockIndex,\n })}\\n\\n`\n );\n }\n }\n\n resolve();\n });\n\n reader.on('error', reject);\n });\n }\n\n convertResponse(\n providerData: unknown,\n messageId: string,\n requestedModel: string\n ): AnthropicResponse {\n const data = providerData as ZAIResponse;\n return {\n id: messageId,\n type: 'message',\n role: 'assistant',\n content: [{ type: 'text', text: data.choices[0].message.content || '' }],\n model: requestedModel,\n stop_reason: 'end_turn',\n stop_sequence: null,\n usage: {\n input_tokens: data.usage?.prompt_tokens || 0,\n output_tokens: data.usage?.completion_tokens || 0,\n },\n };\n }\n}\n\nexport default ZAIProvider;\n","import { OpenAIProvider } from './openai';\nimport type { ProviderConfig, AnthropicRequest, OpenAIRequest } from '../types';\n\nexport class GeminiProvider extends OpenAIProvider {\n constructor(config: ProviderConfig = {}) {\n super(config);\n // All config must be explicit - no env var fallbacks\n this.baseUrl = config.baseUrl || 'https://generativelanguage.googleapis.com/v1beta/openai';\n this.apiKey = config.apiKey || '';\n this.defaultModel = config.defaultModel || 'gemini-2.5-flash';\n\n // Claude -> Gemini model mapping\n this.modelMap = {\n 'claude-3-5-haiku-20241022': 'gemini-2.5-flash',\n 'claude-3-5-haiku-latest': 'gemini-2.5-flash',\n 'claude-haiku-4-5-20251001': 'gemini-2.5-flash',\n 'claude-3-5-sonnet-20241022': 'gemini-2.5-pro',\n 'claude-sonnet-4-20250514': 'gemini-2.5-pro',\n 'claude-opus-4-20250514': 'gemini-2.5-pro',\n 'claude-opus-4-5-20250514': 'gemini-2.5-pro',\n 'claude-opus-4-5-20251101': 'gemini-2.5-pro',\n };\n }\n\n getName(): string {\n return 'gemini';\n }\n\n buildRequest(anthropicRequest: AnthropicRequest): OpenAIRequest {\n const request = super.buildRequest(anthropicRequest);\n // Gemini uses max_tokens, not max_completion_tokens\n if (request.max_completion_tokens) {\n request.max_tokens = request.max_completion_tokens;\n delete request.max_completion_tokens;\n }\n return request;\n }\n\n getHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n };\n }\n}\n\nexport default GeminiProvider;\n","import { BaseProvider } from './base';\nimport type {\n ProviderConfig,\n AnthropicMessage,\n AnthropicTool,\n AnthropicRequest,\n AnthropicResponse,\n AnthropicContentBlock,\n StreamResponse,\n} from '../types';\n\n// AWS Signature V4 implementation for Bedrock\nimport * as crypto from 'crypto';\n\ninterface BedrockConfig extends ProviderConfig {\n accessKeyId?: string;\n secretAccessKey?: string;\n region?: string;\n}\n\ninterface BedrockStreamChunk {\n type?: string;\n delta?: {\n type?: string;\n text?: string;\n };\n content_block?: {\n type: string;\n text?: string;\n };\n message?: {\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n };\n };\n usage?: {\n output_tokens?: number;\n };\n}\n\ninterface BedrockResponse {\n id: string;\n type: string;\n role: string;\n content: Array<{\n type: string;\n text?: string;\n }>;\n model: string;\n stop_reason: string;\n usage: {\n input_tokens: number;\n output_tokens: number;\n };\n}\n\nexport class BedrockProvider extends BaseProvider {\n protected region: string;\n protected accessKeyId: string;\n protected secretAccessKey: string;\n protected defaultModel: string;\n protected modelMap: Record<string, string>;\n protected currentModel: string; // Track model for current request\n\n constructor(config: BedrockConfig = {}) {\n super(config);\n // All config must be explicit - no env var fallbacks\n this.region = config.region || 'us-west-2';\n this.accessKeyId = config.accessKeyId || config.apiKey || '';\n this.secretAccessKey = config.secretAccessKey || '';\n this.defaultModel = config.defaultModel || 'anthropic.claude-3-5-sonnet-20241022-v2:0';\n\n // Claude model names to Bedrock model IDs\n // Note: Claude 4 models require inference profiles on Bedrock\n // Use Claude 3.5 models for on-demand access\n this.modelMap = {\n 'claude-3-5-haiku-20241022': 'anthropic.claude-3-5-haiku-20241022-v1:0',\n 'claude-3-5-haiku-latest': 'anthropic.claude-3-5-haiku-20241022-v1:0',\n 'claude-haiku-4-5-20251001': 'anthropic.claude-3-5-haiku-20241022-v1:0',\n 'claude-3-5-sonnet-20241022': 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n 'claude-3-5-sonnet-latest': 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n // Claude 4 models - these require inference profiles, fallback to 3.5 for on-demand\n 'claude-sonnet-4-20250514': 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n 'claude-sonnet-4-5-20250514': 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n 'claude-sonnet-4-5': 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n 'claude-opus-4-20250514': 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n 'claude-opus-4-5-20250514': 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n 'claude-opus-4-5-20251101': 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n // Short aliases\n 'sonnet': 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n 'haiku': 'anthropic.claude-3-5-haiku-20241022-v1:0',\n 'opus': 'anthropic.claude-3-5-sonnet-20241022-v2:0',\n };\n this.currentModel = this.defaultModel;\n }\n\n getName(): string {\n return 'bedrock';\n }\n\n mapModel(anthropicModel: string): string {\n return this.modelMap[anthropicModel] || this.defaultModel;\n }\n\n // Bedrock uses native Anthropic format - pass through\n convertMessages(anthropicMessages: AnthropicMessage[]): AnthropicMessage[] {\n return anthropicMessages;\n }\n\n // Bedrock uses native Anthropic format - pass through\n convertTools(anthropicTools?: AnthropicTool[]): AnthropicTool[] | undefined {\n return anthropicTools;\n }\n\n // AWS Signature V4 signing\n private sign(key: Buffer, msg: string): Buffer {\n return crypto.createHmac('sha256', key).update(msg, 'utf8').digest();\n }\n\n private getSignatureKey(key: string, dateStamp: string, region: string, service: string): Buffer {\n const kDate = this.sign(Buffer.from('AWS4' + key, 'utf8'), dateStamp);\n const kRegion = this.sign(kDate, region);\n const kService = this.sign(kRegion, service);\n const kSigning = this.sign(kService, 'aws4_request');\n return kSigning;\n }\n\n private createAuthHeaders(\n method: string,\n host: string,\n uri: string,\n queryString: string,\n payload: string,\n amzDate: string,\n dateStamp: string\n ): Record<string, string> {\n const service = 'bedrock';\n const algorithm = 'AWS4-HMAC-SHA256';\n const contentType = 'application/json';\n\n // Create canonical request\n const payloadHash = crypto.createHash('sha256').update(payload, 'utf8').digest('hex');\n const canonicalHeaders =\n `content-type:${contentType}\\n` +\n `host:${host}\\n` +\n `x-amz-date:${amzDate}\\n`;\n const signedHeaders = 'content-type;host;x-amz-date';\n\n const canonicalRequest = [\n method,\n uri,\n queryString,\n canonicalHeaders,\n signedHeaders,\n payloadHash,\n ].join('\\n');\n\n // Create string to sign\n const credentialScope = `${dateStamp}/${this.region}/${service}/aws4_request`;\n const stringToSign = [\n algorithm,\n amzDate,\n credentialScope,\n crypto.createHash('sha256').update(canonicalRequest, 'utf8').digest('hex'),\n ].join('\\n');\n\n // Calculate signature\n const signingKey = this.getSignatureKey(this.secretAccessKey, dateStamp, this.region, service);\n const signature = crypto.createHmac('sha256', signingKey).update(stringToSign, 'utf8').digest('hex');\n\n // Create authorization header\n const authorizationHeader =\n `${algorithm} Credential=${this.accessKeyId}/${credentialScope}, ` +\n `SignedHeaders=${signedHeaders}, Signature=${signature}`;\n\n return {\n 'Content-Type': contentType,\n 'X-Amz-Date': amzDate,\n 'Authorization': authorizationHeader,\n };\n }\n\n buildRequest(anthropicRequest: AnthropicRequest): AnthropicRequest {\n // Bedrock uses Anthropic's native format, but model is in URL, not body\n const { model, messages, max_tokens, system, tools, tool_choice } = anthropicRequest;\n\n // Track current model for endpoint/headers methods\n this.currentModel = this.mapModel(model);\n\n // Bedrock request format - NO model field (it's in the URL)\n const bedrockRequest: AnthropicRequest = {\n anthropic_version: 'bedrock-2023-05-31',\n model: '', // Will be removed below\n messages,\n max_tokens: max_tokens || 4096,\n };\n\n if (system) {\n bedrockRequest.system = system;\n }\n\n if (tools && tools.length > 0) {\n bedrockRequest.tools = tools;\n if (tool_choice) {\n bedrockRequest.tool_choice = tool_choice;\n }\n }\n\n // Remove model field - Bedrock doesn't want it in the body\n delete (bedrockRequest as unknown as Record<string, unknown>).model;\n\n return bedrockRequest;\n }\n\n getEndpoint(): string {\n const modelId = this.currentModel || this.defaultModel;\n // Don't encode the model ID - AWS expects the colon literally in the URL\n return `https://bedrock-runtime.${this.region}.amazonaws.com/model/${modelId}/invoke-with-response-stream`;\n }\n\n getHeaders(): Record<string, string> {\n const now = new Date();\n const amzDate = now.toISOString().replace(/[:-]|\\.\\d{3}/g, '');\n\n const host = `bedrock-runtime.${this.region}.amazonaws.com`;\n\n // We'll set payload later, for now return basic headers\n // The actual signing happens in the proxy handler\n return {\n 'Content-Type': 'application/json',\n 'X-Amz-Date': amzDate,\n 'Host': host,\n };\n }\n\n // Custom method to get signed headers with payload\n getSignedHeaders(payload: string): Record<string, string> {\n const now = new Date();\n const amzDate = now.toISOString().replace(/[:-]|\\.\\d{3}/g, '');\n const dateStamp = amzDate.slice(0, 8);\n\n const host = `bedrock-runtime.${this.region}.amazonaws.com`;\n const modelId = this.currentModel || this.defaultModel;\n // Encode the colon in model ID as %3A for canonical URI (fetch will do this too)\n const encodedModelId = modelId.replace(/:/g, '%3A');\n const uri = `/model/${encodedModelId}/invoke-with-response-stream`;\n\n return this.createAuthHeaders('POST', host, uri, '', payload, amzDate, dateStamp);\n }\n\n async handleStreamingResponse(\n providerResponse: { body: NodeJS.ReadableStream },\n res: StreamResponse,\n messageId: string,\n requestedModel: string\n ): Promise<void> {\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.setHeader('X-Accel-Buffering', 'no');\n res.flushHeaders();\n\n let contentBlockIndex = 0;\n let outputTokens = 0;\n\n const writeAndFlush = (data: string) => {\n res.write(data);\n if (res.flush) res.flush();\n };\n\n // Send message_start event\n const messageStart = {\n type: 'message_start',\n message: {\n id: messageId,\n type: 'message',\n role: 'assistant',\n content: [],\n model: requestedModel,\n stop_reason: null,\n stop_sequence: null,\n usage: { input_tokens: 0, output_tokens: 0 },\n },\n };\n writeAndFlush(`event: message_start\\ndata: ${JSON.stringify(messageStart)}\\n\\n`);\n\n // Send initial content_block_start for text\n writeAndFlush(\n `event: content_block_start\\ndata: ${JSON.stringify({\n type: 'content_block_start',\n index: contentBlockIndex,\n content_block: { type: 'text', text: '' },\n })}\\n\\n`\n );\n\n const reader = providerResponse.body;\n let buffer = Buffer.alloc(0);\n let hasStartedContent = false;\n\n // Parse AWS Event Stream message\n // Format: prelude (8 bytes) + prelude CRC (4 bytes) + headers + payload + message CRC (4 bytes)\n const parseEventStreamMessage = (data: Buffer): { eventType: string; payload: string } | null => {\n if (data.length < 16) return null;\n\n const totalLength = data.readUInt32BE(0);\n const headersLength = data.readUInt32BE(4);\n\n if (data.length < totalLength) return null;\n\n const headersStart = 12; // After prelude (8) + prelude CRC (4)\n const headersEnd = headersStart + headersLength;\n const payloadStart = headersEnd;\n const payloadEnd = totalLength - 4; // Before message CRC\n\n // Parse headers\n let eventType = '';\n let pos = headersStart;\n while (pos < headersEnd && pos < data.length) {\n const nameLen = data.readUInt8(pos);\n pos++;\n if (pos + nameLen > data.length) break;\n const name = data.slice(pos, pos + nameLen).toString('utf8');\n pos += nameLen;\n if (pos >= data.length) break;\n const headerType = data.readUInt8(pos);\n pos++;\n if (headerType === 7) { // String\n if (pos + 2 > data.length) break;\n const valueLen = data.readUInt16BE(pos);\n pos += 2;\n if (pos + valueLen > data.length) break;\n const value = data.slice(pos, pos + valueLen).toString('utf8');\n pos += valueLen;\n if (name === ':event-type') eventType = value;\n }\n }\n\n const payload = data.slice(payloadStart, payloadEnd).toString('utf8');\n return { eventType, payload };\n };\n\n return new Promise((resolve, reject) => {\n let chunkCount = 0;\n\n reader.on('data', (chunk: Buffer) => {\n buffer = Buffer.concat([buffer, chunk]);\n chunkCount++;\n\n // Process complete messages\n while (buffer.length >= 16) {\n const totalLength = buffer.readUInt32BE(0);\n if (buffer.length < totalLength) break;\n\n const message = buffer.slice(0, totalLength);\n buffer = buffer.slice(totalLength);\n\n const event = parseEventStreamMessage(message);\n if (!event || !event.payload) continue;\n\n // Find JSON in payload\n const jsonStart = event.payload.indexOf('{');\n if (jsonStart === -1) continue;\n\n try {\n const jsonStr = event.payload.slice(jsonStart);\n const wrapper = JSON.parse(jsonStr) as { bytes?: string };\n\n // Bedrock wraps payloads in {bytes: \"base64...\"} - decode it\n let parsed: BedrockStreamChunk;\n if (wrapper.bytes) {\n const decodedPayload = Buffer.from(wrapper.bytes, 'base64').toString('utf8');\n parsed = JSON.parse(decodedPayload) as BedrockStreamChunk;\n if (process.env.DEBUG_BEDROCK) {\n console.log(`[Bedrock] Decoded: ${decodedPayload.substring(0, 100)}`);\n }\n } else {\n parsed = wrapper as unknown as BedrockStreamChunk;\n }\n\n if (parsed.type === 'content_block_delta' && parsed.delta?.text) {\n hasStartedContent = true;\n outputTokens++;\n writeAndFlush(\n `event: content_block_delta\\ndata: ${JSON.stringify({\n type: 'content_block_delta',\n index: contentBlockIndex,\n delta: { type: 'text_delta', text: parsed.delta.text },\n })}\\n\\n`\n );\n }\n\n if (parsed.type === 'message_delta' && parsed.usage) {\n outputTokens = parsed.usage.output_tokens || outputTokens;\n }\n\n if (parsed.type === 'message_stop') {\n writeAndFlush(\n `event: content_block_stop\\ndata: ${JSON.stringify({\n type: 'content_block_stop',\n index: contentBlockIndex,\n })}\\n\\n`\n );\n writeAndFlush(\n `event: message_delta\\ndata: ${JSON.stringify({\n type: 'message_delta',\n delta: { stop_reason: 'end_turn', stop_sequence: null },\n usage: { output_tokens: outputTokens },\n })}\\n\\n`\n );\n writeAndFlush(\n `event: message_stop\\ndata: ${JSON.stringify({ type: 'message_stop' })}\\n\\n`\n );\n }\n } catch {\n // Ignore parse errors\n }\n }\n });\n\n reader.on('end', () => {\n if (process.env.DEBUG_BEDROCK) {\n console.log(`[Bedrock] Stream ended. Chunks: ${chunkCount}, hasContent: ${hasStartedContent}`);\n }\n if (hasStartedContent) {\n writeAndFlush(\n `event: content_block_stop\\ndata: ${JSON.stringify({\n type: 'content_block_stop',\n index: contentBlockIndex,\n })}\\n\\n`\n );\n }\n writeAndFlush(\n `event: message_delta\\ndata: ${JSON.stringify({\n type: 'message_delta',\n delta: { stop_reason: 'end_turn', stop_sequence: null },\n usage: { output_tokens: outputTokens },\n })}\\n\\n`\n );\n\n writeAndFlush(\n `event: message_stop\\ndata: ${JSON.stringify({ type: 'message_stop' })}\\n\\n`\n );\n\n resolve();\n });\n\n reader.on('error', reject);\n });\n }\n\n convertResponse(\n providerData: unknown,\n messageId: string,\n requestedModel: string\n ): AnthropicResponse {\n const data = providerData as BedrockResponse;\n return {\n id: messageId,\n type: 'message',\n role: 'assistant',\n content: data.content as AnthropicContentBlock[],\n model: requestedModel,\n stop_reason: data.stop_reason || 'end_turn',\n stop_sequence: null,\n usage: {\n input_tokens: data.usage?.input_tokens || 0,\n output_tokens: data.usage?.output_tokens || 0,\n },\n };\n }\n}\n\nexport default BedrockProvider;\n","import { OpenAIProvider } from './openai';\nimport type { ProviderConfig, AnthropicRequest, OpenAIRequest } from '../types';\n\ninterface AzureConfig extends ProviderConfig {\n deploymentName?: string;\n apiVersion?: string;\n}\n\n/**\n * Azure AI Foundry Provider (formerly Azure OpenAI)\n *\n * Uses the OpenAI-compatible API format with Azure-specific authentication and endpoints.\n *\n * Required config:\n * - apiKey: Azure API key\n * - baseUrl: Azure endpoint (e.g., https://your-resource.openai.azure.com)\n * - deploymentName: Your model deployment name\n */\nexport class AzureProvider extends OpenAIProvider {\n protected deploymentName: string;\n protected apiVersion: string;\n\n constructor(config: AzureConfig = {}) {\n super(config);\n // All config must be explicit - no env var fallbacks\n this.baseUrl = config.baseUrl || '';\n this.apiKey = config.apiKey || '';\n this.deploymentName = config.deploymentName || config.defaultModel || 'gpt-4o';\n this.apiVersion = config.apiVersion || '2024-10-21';\n this.defaultModel = this.deploymentName;\n\n // Azure uses deployment names, not model IDs\n // Map Claude model names to common Azure deployment patterns\n this.modelMap = {\n 'claude-3-5-haiku-20241022': 'gpt-4o-mini',\n 'claude-3-5-haiku-latest': 'gpt-4o-mini',\n 'claude-haiku-4-5-20251001': 'gpt-4o-mini',\n 'claude-3-5-sonnet-20241022': 'gpt-4o',\n 'claude-sonnet-4-20250514': 'gpt-4o',\n 'claude-opus-4-20250514': 'gpt-4o',\n 'claude-opus-4-5-20250514': 'gpt-4o',\n 'claude-opus-4-5-20251101': 'gpt-4o',\n 'sonnet': 'gpt-4o',\n 'haiku': 'gpt-4o-mini',\n 'opus': 'gpt-4o',\n };\n }\n\n getName(): string {\n return 'azure';\n }\n\n mapModel(anthropicModel: string): string {\n // If deployment name is explicitly set, use it\n if (this.deploymentName && this.deploymentName !== 'gpt-4o') {\n return this.deploymentName;\n }\n return this.modelMap[anthropicModel] || this.defaultModel;\n }\n\n buildRequest(anthropicRequest: AnthropicRequest): OpenAIRequest {\n const request = super.buildRequest(anthropicRequest);\n // Azure doesn't use model in the body - it's in the URL\n // But we still need it for our proxy to know what was requested\n return request;\n }\n\n getEndpoint(): string {\n const deployment = this.mapModel(this.defaultModel);\n // Azure AI Foundry endpoint format\n return `${this.baseUrl}/openai/deployments/${deployment}/chat/completions?api-version=${this.apiVersion}`;\n }\n\n getHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n 'api-key': this.apiKey,\n };\n }\n}\n\nexport default AzureProvider;\n","/**\n * Krisspy Provider\n * Routes requests through Krisspy backend for credit-based billing\n *\n * The Krisspy backend acts as a proxy that:\n * 1. Validates the user's API key\n * 2. Checks their credit balance\n * 3. Forwards to AWS Bedrock (using Krisspy's AWS credentials)\n * 4. Deducts credits based on token usage\n */\n\nimport { BaseProvider } from './base';\nimport type {\n ProviderConfig,\n AnthropicMessage,\n AnthropicTool,\n AnthropicRequest,\n AnthropicResponse,\n OpenAIMessage,\n OpenAITool,\n StreamResponse,\n} from '../types';\n\nexport interface KrisspyProviderConfig extends ProviderConfig {\n /** Krisspy API key (required at runtime) */\n apiKey?: string;\n /** Krisspy backend URL (default: https://api.krisspy.ai) */\n baseUrl?: string;\n /** App ID for billing context */\n appId?: string;\n /** User ID for billing context */\n userId?: string;\n}\n\nexport class KrisspyProvider extends BaseProvider {\n private krisspyConfig: KrisspyProviderConfig;\n\n constructor(config: KrisspyProviderConfig) {\n super(config);\n this.krisspyConfig = config;\n }\n\n getName(): string {\n return 'krisspy';\n }\n\n /**\n * Pass through model names as-is\n * Krisspy backend will handle model name mapping\n */\n mapModel(model: string): string {\n // Don't transform - let the backend handle it\n return model;\n }\n\n /**\n * Pass through Anthropic messages as-is\n * Krisspy backend expects Anthropic format\n */\n convertMessages(messages: AnthropicMessage[]): AnthropicMessage[] {\n return messages;\n }\n\n /**\n * Pass through Anthropic tools as-is\n */\n convertTools(tools?: AnthropicTool[]): AnthropicTool[] | undefined {\n return tools;\n }\n\n /**\n * Build request - pass through as Anthropic format\n * Add Krisspy-specific headers/metadata\n */\n buildRequest(request: AnthropicRequest): AnthropicRequest {\n return {\n ...request,\n model: this.mapModel(request.model),\n };\n }\n\n /**\n * Get Krisspy AI proxy endpoint\n * Uses /messages endpoint for transparent LLM proxying (agent runs client-side)\n */\n getEndpoint(): string {\n const baseUrl = this.krisspyConfig.baseUrl || 'https://api.krisspy.ai';\n return `${baseUrl}/api/v1/ai/messages`;\n }\n\n /**\n * Get headers with Krisspy API key\n */\n getHeaders(): Record<string, string> {\n if (!this.krisspyConfig.apiKey) {\n throw new Error('Krisspy API key is required');\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.krisspyConfig.apiKey}`,\n 'X-Krisspy-Provider': 'krisspy-ai-sdk',\n };\n\n // Add billing context if provided\n if (this.krisspyConfig.appId) {\n headers['X-Krisspy-App-Id'] = this.krisspyConfig.appId;\n }\n if (this.krisspyConfig.userId) {\n headers['X-Krisspy-User-Id'] = this.krisspyConfig.userId;\n }\n\n return headers;\n }\n\n /**\n * Handle streaming response from Krisspy backend\n * The backend streams krisspy-ai events as SSE, so we parse and pass through\n */\n async handleStreamingResponse(\n providerResponse: { body: NodeJS.ReadableStream },\n res: StreamResponse,\n messageId: string,\n requestedModel: string\n ): Promise<void> {\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.flushHeaders();\n\n const stream = providerResponse.body;\n let buffer = '';\n\n return new Promise((resolve, reject) => {\n stream.on('data', (chunk: Buffer) => {\n buffer += chunk.toString();\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n if (line.startsWith('data: ')) {\n const data = line.slice(6).trim();\n\n // Forward the event data as-is from backend\n res.write(`data: ${data}\\n\\n`);\n\n if (res.flush) {\n res.flush();\n }\n }\n }\n });\n\n stream.on('end', () => {\n resolve();\n });\n\n stream.on('error', (err) => {\n console.error('[krisspy provider] Stream error:', err);\n reject(err);\n });\n });\n }\n\n /**\n * Convert non-streaming response\n * Krisspy backend returns Anthropic format, so minimal conversion needed\n */\n convertResponse(\n data: unknown,\n messageId: string,\n requestedModel: string\n ): AnthropicResponse {\n const response = data as AnthropicResponse;\n\n // Ensure we have a proper response structure\n return {\n id: response.id || messageId,\n type: 'message',\n role: 'assistant',\n content: response.content || [],\n model: response.model || requestedModel,\n stop_reason: response.stop_reason || null,\n stop_sequence: response.stop_sequence || null,\n usage: response.usage || { input_tokens: 0, output_tokens: 0 },\n };\n }\n}\n\nexport default KrisspyProvider;\n","import { OpenAIProvider } from './openai';\nimport { ZAIProvider } from './zai';\nimport { GeminiProvider } from './gemini';\nimport { BedrockProvider } from './bedrock';\nimport { AzureProvider } from './azure';\nimport { KrisspyProvider } from './krisspy';\nimport type { Provider, ProviderConfig } from '../types';\n\ntype ProviderConstructor = new (config: ProviderConfig) => Provider;\n\n// Provider registry\nconst providers: Record<string, ProviderConstructor> = {\n openai: OpenAIProvider,\n zai: ZAIProvider,\n gemini: GeminiProvider,\n bedrock: BedrockProvider,\n azure: AzureProvider,\n krisspy: KrisspyProvider,\n};\n\n/**\n * Get provider instance by name\n * @param name - Provider name (openai, zai, etc.)\n * @param config - Optional configuration\n * @returns Provider instance\n */\nexport function getProvider(name: string, config: ProviderConfig = {}): Provider {\n const ProviderClass = providers[name.toLowerCase()];\n if (!ProviderClass) {\n throw new Error(`Unknown provider: ${name}. Available: ${Object.keys(providers).join(', ')}`);\n }\n return new ProviderClass(config);\n}\n\n/**\n * Register a new provider\n * @param name - Provider name\n * @param ProviderClass - Provider class extending BaseProvider\n */\nexport function registerProvider(name: string, ProviderClass: ProviderConstructor): void {\n providers[name.toLowerCase()] = ProviderClass;\n}\n\n/**\n * Get list of available providers\n * @returns Provider names\n */\nexport function getAvailableProviders(): string[] {\n return Object.keys(providers);\n}\n\nexport { OpenAIProvider, ZAIProvider, GeminiProvider, BedrockProvider, AzureProvider, KrisspyProvider };\nexport { BaseProvider } from './base';\n","// Azure OpenAI DALL-E / GPT-Image service implementation\n\nimport fetch from 'node-fetch';\nimport { BaseImageService } from './base';\nimport type { ImageGenerationOptions, ImageGenerationResult, GenerativeServiceConfig } from '../types';\n\ninterface AzureImageResponse {\n created: number;\n data: Array<{\n url?: string;\n b64_json?: string;\n revised_prompt?: string;\n }>;\n}\n\nexport class AzureDalleService extends BaseImageService {\n private baseUrl: string;\n private apiKey: string;\n private deploymentName: string;\n private apiVersion: string;\n\n constructor(config: GenerativeServiceConfig = {}) {\n super(config);\n this.baseUrl = config.baseUrl || '';\n this.apiKey = config.apiKey || '';\n this.deploymentName = config.deploymentName || 'dall-e-3';\n this.apiVersion = config.apiVersion || '2024-10-21';\n }\n\n getName(): string {\n return 'azure-dalle';\n }\n\n async generate(options: ImageGenerationOptions): Promise<ImageGenerationResult> {\n if (!this.baseUrl) {\n throw new Error('[krisspy-ai] Azure baseUrl is required for image generation');\n }\n if (!this.apiKey) {\n throw new Error('[krisspy-ai] Azure apiKey is required for image generation');\n }\n\n const endpoint = `${this.baseUrl}/openai/deployments/${this.deploymentName}/images/generations?api-version=${this.apiVersion}`;\n\n // Build request body - only include supported parameters\n // GPT-Image has different parameters than DALL-E 3\n // GPT-Image: prompt, n, size\n // DALL-E 3: prompt, n, size, quality, style, response_format, user\n const isGptImage = this.deploymentName.toLowerCase().includes('gpt-image');\n\n const body: Record<string, unknown> = {\n prompt: options.prompt,\n n: options.n || 1,\n size: options.size || '1024x1024',\n };\n\n // DALL-E 3 specific parameters\n if (!isGptImage) {\n if (options.quality) body.quality = options.quality;\n if (options.style) body.style = options.style;\n if (options.responseFormat) body.response_format = options.responseFormat;\n if (options.user) body.user = options.user;\n }\n\n console.log(`[krisspy-ai] Generating image with Azure DALL-E (deployment: ${this.deploymentName})...`);\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'api-key': this.apiKey,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = errorText;\n try {\n const parsed = JSON.parse(errorText);\n errorMessage = parsed.error?.message || errorText;\n } catch {\n // Keep original error text\n }\n throw new Error(`[krisspy-ai] Azure DALL-E generation failed: ${response.status} - ${errorMessage}`);\n }\n\n const data = (await response.json()) as AzureImageResponse;\n\n console.log(`[krisspy-ai] Image generation complete. Generated ${data.data.length} image(s).`);\n\n return {\n created: data.created,\n data: data.data.map((img) => ({\n url: img.url,\n b64_json: img.b64_json,\n revisedPrompt: img.revised_prompt,\n })),\n };\n }\n}\n","// Base class for all generative services\n\nimport type { GenerativeServiceConfig } from './types';\n\nexport abstract class BaseGenerativeService {\n protected config: GenerativeServiceConfig;\n\n constructor(config: GenerativeServiceConfig = {}) {\n this.config = config;\n }\n\n abstract getName(): string;\n abstract getServiceType(): 'image' | 'video' | 'transcription' | 'tts';\n}\n","// Base class for image generation services\n\nimport { BaseGenerativeService } from '../base';\nimport type { ImageGenerationOptions, ImageGenerationResult, GenerativeServiceConfig } from '../types';\n\nexport abstract class BaseImageService extends BaseGenerativeService {\n constructor(config: GenerativeServiceConfig = {}) {\n super(config);\n }\n\n getServiceType(): 'image' {\n return 'image';\n }\n\n abstract generate(options: ImageGenerationOptions): Promise<ImageGenerationResult>;\n}\n","// OpenAI direct API image generation service (gpt-image-1)\n\nimport fetch from 'node-fetch';\nimport { BaseImageService } from './base';\nimport type { ImageGenerationOptions, ImageGenerationResult, GenerativeServiceConfig } from '../types';\n\ninterface OpenAIImageResponse {\n created: number;\n data: Array<{\n url?: string;\n b64_json?: string;\n revised_prompt?: string;\n }>;\n}\n\nexport class OpenAIImageService extends BaseImageService {\n private apiKey: string;\n private baseUrl: string;\n private model: string;\n\n constructor(config: GenerativeServiceConfig = {}) {\n super(config);\n this.apiKey = config.apiKey || '';\n this.baseUrl = config.baseUrl || 'https://api.openai.com/v1';\n // Default to gpt-image-1, can be overridden with deploymentName\n this.model = config.deploymentName || 'gpt-image-1';\n }\n\n getName(): string {\n return 'openai-image';\n }\n\n async generate(options: ImageGenerationOptions): Promise<ImageGenerationResult> {\n if (!this.apiKey) {\n throw new Error('[krisspy-ai] OpenAI apiKey is required for image generation');\n }\n\n const endpoint = `${this.baseUrl}/images/generations`;\n\n // Build request body\n // gpt-image-1 supports: model, prompt, n, size, quality, response_format, user\n const body: Record<string, unknown> = {\n model: this.model,\n prompt: options.prompt,\n n: options.n || 1,\n size: options.size || '1024x1024',\n };\n\n // Optional parameters\n if (options.quality) body.quality = options.quality;\n // Note: gpt-image-1.5 does not support response_format, only older models like dall-e-3\n if (options.responseFormat && !this.model.includes('gpt-image')) {\n body.response_format = options.responseFormat;\n }\n if (options.user) body.user = options.user;\n\n console.log(`[krisspy-ai] Generating image with OpenAI (model: ${this.model})...`);\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = errorText;\n try {\n const parsed = JSON.parse(errorText);\n errorMessage = parsed.error?.message || errorText;\n } catch {\n // Keep original error text\n }\n throw new Error(`[krisspy-ai] OpenAI image generation failed: ${response.status} - ${errorMessage}`);\n }\n\n const data = (await response.json()) as OpenAIImageResponse;\n\n console.log(`[krisspy-ai] Image generation complete. Generated ${data.data.length} image(s).`);\n\n return {\n created: data.created,\n data: data.data.map((img) => ({\n url: img.url,\n b64_json: img.b64_json,\n revisedPrompt: img.revised_prompt,\n })),\n };\n }\n}\n","import { BaseImageService } from './base';\nimport type { ImageGenerationOptions, ImageGenerationResult } from '../types';\nimport fetch from 'node-fetch';\n\n/**\n * Krisspy AI Image Generation Service\n * Routes requests to Krisspy backend for credit billing\n */\nexport class KrisspyImageService extends BaseImageService {\n getName(): string {\n return 'krisspy';\n }\n\n async generate(options: ImageGenerationOptions): Promise<ImageGenerationResult> {\n const { prompt, size = '1024x1024' } = options;\n const baseUrl = this.config.baseUrl || 'https://api.krisspy.ai';\n const apiKey = this.config.apiKey;\n\n if (!apiKey) {\n throw new Error('API key is required for Krisspy image service');\n }\n\n const response = await fetch(`${baseUrl}/api/v1/ai/image`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ prompt, size }),\n });\n\n if (!response.ok) {\n const error = await response.json() as any;\n throw new Error(error.message || `Image generation failed: ${response.statusText}`);\n }\n\n const data = await response.json() as any;\n\n return {\n created: Math.floor(Date.now() / 1000),\n data: [{\n b64_json: data.image,\n url: undefined,\n revisedPrompt: data.revisedPrompt,\n }],\n };\n }\n}\n","// Azure Sora video generation service implementation\n\nimport fetch from 'node-fetch';\nimport FormData from 'form-data';\nimport { BaseVideoService } from './base';\nimport type {\n VideoGenerationOptions,\n VideoJobSubmission,\n VideoJobStatus,\n VideoGenerationResult,\n VideoJobStatusType,\n GenerativeServiceConfig,\n} from '../types';\n\n// Azure Sora API response types\ninterface SoraJobResponse {\n id: string;\n object: string;\n status: 'pending' | 'in_progress' | 'completed' | 'failed' | 'canceled';\n created_at: number;\n completed_at?: number | null;\n expires_at?: number | null;\n model: string;\n progress?: number;\n prompt: string;\n seconds: string;\n size: string;\n error?: {\n code: string;\n message: string;\n } | null;\n output_video?: string;\n generations?: Array<{\n id: string;\n }>;\n}\n\nexport class AzureSoraService extends BaseVideoService {\n private baseUrl: string;\n private apiKey: string;\n private deploymentName: string;\n private apiVersion: string;\n\n constructor(config: GenerativeServiceConfig = {}) {\n super(config);\n this.baseUrl = config.baseUrl || '';\n this.apiKey = config.apiKey || '';\n this.deploymentName = config.deploymentName || 'sora-2';\n this.apiVersion = config.apiVersion || 'preview';\n }\n\n getName(): string {\n return 'azure-sora';\n }\n\n private mapStatus(azureStatus: string): VideoJobStatusType {\n switch (azureStatus) {\n // Azure Sora uses lowercase snake_case status values\n case 'pending':\n case 'queued':\n return 'pending';\n case 'in_progress':\n return 'running';\n case 'completed':\n return 'succeeded';\n case 'failed':\n return 'failed';\n case 'canceled':\n return 'canceled';\n default:\n console.log(`[krisspy-ai] Unknown status: ${azureStatus}`);\n return 'pending';\n }\n }\n\n async submitJob(options: VideoGenerationOptions): Promise<VideoJobSubmission> {\n if (!this.baseUrl) {\n throw new Error('[krisspy-ai] Azure baseUrl is required for video generation');\n }\n if (!this.apiKey) {\n throw new Error('[krisspy-ai] Azure apiKey is required for video generation');\n }\n\n const endpoint = `${this.baseUrl}/openai/v1/videos`;\n\n // Azure Sora supported sizes: 720x1280, 1280x720, 1024x1792, 1792x1024\n const validSizes = ['720x1280', '1280x720', '1024x1792', '1792x1024'];\n const requestedSize = options.width && options.height\n ? `${options.width}x${options.height}`\n : '1280x720'; // Default landscape HD\n const size = validSizes.includes(requestedSize) ? requestedSize : '1280x720';\n\n // Azure Sora only supports 4, 8, or 12 seconds\n const requestedDuration = options.duration || 4;\n const validDurations = [4, 8, 12];\n const seconds = validDurations.includes(requestedDuration)\n ? requestedDuration\n : validDurations.reduce((prev, curr) =>\n Math.abs(curr - requestedDuration) < Math.abs(prev - requestedDuration) ? curr : prev\n );\n\n console.log(`[krisspy-ai] Submitting video job to Azure Sora (deployment: ${this.deploymentName})...`);\n\n let response: import('node-fetch').Response;\n\n // Use multipart form-data for image-to-video, JSON for text-to-video\n if (options.referenceImage) {\n // Image-to-video: use multipart form-data with input_reference\n const formData = new FormData();\n formData.append('model', this.deploymentName);\n formData.append('prompt', options.prompt);\n formData.append('size', size);\n formData.append('seconds', String(seconds));\n if (options.nVariants && options.nVariants > 1) {\n formData.append('n_variants', String(options.nVariants));\n }\n\n // Convert base64 to buffer for form-data\n const isUrl = options.referenceImage.startsWith('http://') || options.referenceImage.startsWith('https://');\n\n if (isUrl) {\n // For URL, we need to fetch the image first\n const imageResponse = await fetch(options.referenceImage);\n const imageBuffer = await imageResponse.buffer();\n formData.append('input_reference', imageBuffer, { filename: 'reference.png', contentType: 'image/png' });\n } else {\n // Base64 encoded image\n const base64Data = options.referenceImage.startsWith('data:')\n ? options.referenceImage.split(',')[1]\n : options.referenceImage;\n const imageBuffer = Buffer.from(base64Data, 'base64');\n formData.append('input_reference', imageBuffer, { filename: 'reference.png', contentType: 'image/png' });\n }\n\n console.log(`[krisspy-ai] Using reference image for video generation (multipart form-data)`);\n\n response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n ...formData.getHeaders(),\n },\n body: formData,\n });\n } else {\n // Text-to-video: use JSON\n const body: Record<string, unknown> = {\n prompt: options.prompt,\n seconds: String(seconds),\n size,\n model: this.deploymentName,\n };\n\n // Add n_variants if specified (generates multiple video variants)\n if (options.nVariants && options.nVariants > 1) {\n body.n_variants = String(options.nVariants);\n }\n\n response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify(body),\n });\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = errorText;\n try {\n const parsed = JSON.parse(errorText);\n errorMessage = parsed.error?.message || errorText;\n } catch {\n // Keep original error text\n }\n throw new Error(`[krisspy-ai] Azure Sora job submission failed: ${response.status} - ${errorMessage}`);\n }\n\n const data = (await response.json()) as SoraJobResponse;\n\n return {\n jobId: data.id,\n status: this.mapStatus(data.status),\n createdAt: new Date(data.created_at * 1000).toISOString(),\n };\n }\n\n async getJobStatus(jobId: string): Promise<VideoJobStatus> {\n const endpoint = `${this.baseUrl}/openai/v1/videos/${jobId}`;\n\n const response = await fetch(endpoint, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`[krisspy-ai] Failed to get job status: ${response.status} - ${errorText}`);\n }\n\n const data = (await response.json()) as SoraJobResponse;\n\n // Log error details for failed jobs\n if (data.status === 'failed' && data.error) {\n console.log(`[krisspy-ai] Job failed: ${data.error.code} - ${data.error.message}`);\n }\n\n return {\n jobId: data.id,\n status: this.mapStatus(data.status),\n progress: data.progress,\n error: data.error?.message,\n createdAt: new Date(data.created_at * 1000).toISOString(),\n expiresAt: data.expires_at ? new Date(data.expires_at * 1000).toISOString() : undefined,\n };\n }\n\n async getResult(jobId: string): Promise<VideoGenerationResult> {\n const endpoint = `${this.baseUrl}/openai/v1/videos/${jobId}`;\n\n const response = await fetch(endpoint, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`[krisspy-ai] Failed to get job result: ${response.status} - ${errorText}`);\n }\n\n const data = (await response.json()) as SoraJobResponse;\n\n if (data.status !== 'completed') {\n throw new Error(`[krisspy-ai] Job ${jobId} not complete. Status: ${data.status}`);\n }\n\n // Azure Sora uses the job ID itself as the generation ID for download\n // The video is downloaded via GET /openai/v1/videos/{jobId}/content\n const generations = [{ id: data.id }];\n\n console.log(`[krisspy-ai] Video generation complete. ${generations.length} video(s) generated.`);\n\n return {\n jobId: data.id,\n status: 'succeeded',\n generations,\n createdAt: new Date(data.created_at * 1000).toISOString(),\n };\n }\n\n async downloadVideo(generationId: string): Promise<Buffer> {\n const endpoint = `${this.baseUrl}/openai/v1/videos/${generationId}/content`;\n\n console.log(`[krisspy-ai] Downloading video ${generationId}...`);\n\n const response = await fetch(endpoint, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`[krisspy-ai] Failed to download video: ${response.status} - ${errorText}`);\n }\n\n const buffer = await response.buffer();\n console.log(`[krisspy-ai] Video downloaded: ${buffer.length} bytes`);\n\n return buffer;\n }\n}\n","// Base class for video generation services\n\nimport { BaseGenerativeService } from '../base';\nimport type {\n VideoGenerationOptions,\n VideoJobSubmission,\n VideoJobStatus,\n VideoGenerationResult,\n GenerativeServiceConfig,\n} from '../types';\n\nexport abstract class BaseVideoService extends BaseGenerativeService {\n constructor(config: GenerativeServiceConfig = {}) {\n super(config);\n }\n\n getServiceType(): 'video' {\n return 'video';\n }\n\n abstract submitJob(options: VideoGenerationOptions): Promise<VideoJobSubmission>;\n abstract getJobStatus(jobId: string): Promise<VideoJobStatus>;\n abstract getResult(jobId: string): Promise<VideoGenerationResult>;\n abstract downloadVideo(generationId: string): Promise<Buffer>;\n\n /**\n * Convenience generator that submits a job and polls until completion.\n * Yields status updates and returns the final result.\n *\n * @param options - Video generation options\n * @param pollInterval - Time between status checks in ms (default: 5000)\n * @param timeout - Max wait time in ms (default: 600000 = 10 minutes)\n */\n async *generateAndWait(\n options: VideoGenerationOptions,\n pollInterval = 5000,\n timeout = 600000\n ): AsyncGenerator<VideoJobStatus, VideoGenerationResult> {\n const submission = await this.submitJob(options);\n const startTime = Date.now();\n let status: VideoJobStatus;\n\n console.log(`[krisspy-ai] Video job submitted: ${submission.jobId}`);\n\n do {\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n status = await this.getJobStatus(submission.jobId);\n\n console.log(`[krisspy-ai] Job ${submission.jobId} status: ${status.status}`);\n yield status;\n\n if (Date.now() - startTime > timeout) {\n throw new Error(`[krisspy-ai] Video generation timed out after ${timeout}ms`);\n }\n } while (status.status === 'pending' || status.status === 'running');\n\n if (status.status === 'failed') {\n throw new Error(`[krisspy-ai] Video generation failed: ${status.error || 'Unknown error'}`);\n }\n\n if (status.status === 'canceled') {\n throw new Error(`[krisspy-ai] Video generation was canceled`);\n }\n\n return await this.getResult(submission.jobId);\n }\n}\n","// OpenAI direct API Sora video generation service\n\nimport fetch from 'node-fetch';\nimport FormData from 'form-data';\nimport { BaseVideoService } from './base';\nimport type {\n VideoGenerationOptions,\n VideoJobSubmission,\n VideoJobStatus,\n VideoGenerationResult,\n VideoJobStatusType,\n GenerativeServiceConfig,\n} from '../types';\n\n// OpenAI Sora API response types\ninterface SoraJobResponse {\n id: string;\n object: string;\n status: 'pending' | 'in_progress' | 'completed' | 'failed' | 'canceled';\n created_at: number;\n completed_at?: number | null;\n expires_at?: number | null;\n model: string;\n progress?: number;\n prompt: string;\n seconds: string;\n size: string;\n error?: {\n code: string;\n message: string;\n } | null;\n output_video?: string;\n generations?: Array<{\n id: string;\n }>;\n}\n\nexport class OpenAISoraService extends BaseVideoService {\n private baseUrl: string;\n private apiKey: string;\n private model: string;\n\n constructor(config: GenerativeServiceConfig = {}) {\n super(config);\n this.baseUrl = config.baseUrl || 'https://api.openai.com/v1';\n this.apiKey = config.apiKey || '';\n // Default to sora-2, can be overridden with deploymentName\n this.model = config.deploymentName || 'sora-2';\n }\n\n getName(): string {\n return 'openai-sora';\n }\n\n private mapStatus(openaiStatus: string): VideoJobStatusType {\n switch (openaiStatus) {\n case 'pending':\n case 'queued':\n return 'pending';\n case 'in_progress':\n return 'running';\n case 'completed':\n return 'succeeded';\n case 'failed':\n return 'failed';\n case 'canceled':\n return 'canceled';\n default:\n console.log(`[krisspy-ai] Unknown status: ${openaiStatus}`);\n return 'pending';\n }\n }\n\n async submitJob(options: VideoGenerationOptions): Promise<VideoJobSubmission> {\n if (!this.apiKey) {\n throw new Error('[krisspy-ai] OpenAI apiKey is required for video generation');\n }\n\n const endpoint = `${this.baseUrl}/videos/generations`;\n\n // OpenAI Sora supported sizes: 720x1280, 1280x720, 1024x1792, 1792x1024\n const validSizes = ['720x1280', '1280x720', '1024x1792', '1792x1024'];\n const requestedSize = options.width && options.height\n ? `${options.width}x${options.height}`\n : '1280x720'; // Default landscape HD\n const size = validSizes.includes(requestedSize) ? requestedSize : '1280x720';\n\n // OpenAI Sora only supports 5, 10, 15, or 20 seconds\n const requestedDuration = options.duration || 5;\n const validDurations = [5, 10, 15, 20];\n const seconds = validDurations.includes(requestedDuration)\n ? requestedDuration\n : validDurations.reduce((prev, curr) =>\n Math.abs(curr - requestedDuration) < Math.abs(prev - requestedDuration) ? curr : prev\n );\n\n console.log(`[krisspy-ai] Submitting video job to OpenAI Sora (model: ${this.model})...`);\n\n let response: import('node-fetch').Response;\n\n // Use multipart form-data for image-to-video, JSON for text-to-video\n if (options.referenceImage) {\n // Image-to-video: use multipart form-data with input_image\n const formData = new FormData();\n formData.append('model', this.model);\n formData.append('prompt', options.prompt);\n formData.append('size', size);\n formData.append('duration', String(seconds));\n if (options.nVariants && options.nVariants > 1) {\n formData.append('n', String(options.nVariants));\n }\n\n // Convert base64 to buffer for form-data\n const isUrl = options.referenceImage.startsWith('http://') || options.referenceImage.startsWith('https://');\n\n if (isUrl) {\n // For URL, we need to fetch the image first\n const imageResponse = await fetch(options.referenceImage);\n const imageBuffer = await imageResponse.buffer();\n formData.append('image', imageBuffer, { filename: 'reference.png', contentType: 'image/png' });\n } else {\n // Base64 encoded image\n const base64Data = options.referenceImage.startsWith('data:')\n ? options.referenceImage.split(',')[1]\n : options.referenceImage;\n const imageBuffer = Buffer.from(base64Data, 'base64');\n formData.append('image', imageBuffer, { filename: 'reference.png', contentType: 'image/png' });\n }\n\n console.log(`[krisspy-ai] Using reference image for video generation (multipart form-data)`);\n\n response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n ...formData.getHeaders(),\n },\n body: formData,\n });\n } else {\n // Text-to-video: use JSON\n const body: Record<string, unknown> = {\n model: this.model,\n prompt: options.prompt,\n duration: seconds,\n size,\n };\n\n // Add n if specified (generates multiple video variants)\n if (options.nVariants && options.nVariants > 1) {\n body.n = options.nVariants;\n }\n\n response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify(body),\n });\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = errorText;\n try {\n const parsed = JSON.parse(errorText);\n errorMessage = parsed.error?.message || errorText;\n } catch {\n // Keep original error text\n }\n throw new Error(`[krisspy-ai] OpenAI Sora job submission failed: ${response.status} - ${errorMessage}`);\n }\n\n const data = (await response.json()) as SoraJobResponse;\n\n return {\n jobId: data.id,\n status: this.mapStatus(data.status),\n createdAt: new Date(data.created_at * 1000).toISOString(),\n };\n }\n\n async getJobStatus(jobId: string): Promise<VideoJobStatus> {\n const endpoint = `${this.baseUrl}/videos/generations/${jobId}`;\n\n const response = await fetch(endpoint, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`[krisspy-ai] Failed to get job status: ${response.status} - ${errorText}`);\n }\n\n const data = (await response.json()) as SoraJobResponse;\n\n // Log error details for failed jobs\n if (data.status === 'failed' && data.error) {\n console.log(`[krisspy-ai] Job failed: ${data.error.code} - ${data.error.message}`);\n }\n\n return {\n jobId: data.id,\n status: this.mapStatus(data.status),\n progress: data.progress,\n error: data.error?.message,\n createdAt: new Date(data.created_at * 1000).toISOString(),\n expiresAt: data.expires_at ? new Date(data.expires_at * 1000).toISOString() : undefined,\n };\n }\n\n async getResult(jobId: string): Promise<VideoGenerationResult> {\n const endpoint = `${this.baseUrl}/videos/generations/${jobId}`;\n\n const response = await fetch(endpoint, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`[krisspy-ai] Failed to get job result: ${response.status} - ${errorText}`);\n }\n\n const data = (await response.json()) as SoraJobResponse;\n\n if (data.status !== 'completed') {\n throw new Error(`[krisspy-ai] Job ${jobId} not complete. Status: ${data.status}`);\n }\n\n // Use the job ID as the generation ID for download\n const generations = [{ id: data.id }];\n\n console.log(`[krisspy-ai] Video generation complete. ${generations.length} video(s) generated.`);\n\n return {\n jobId: data.id,\n status: 'succeeded',\n generations,\n createdAt: new Date(data.created_at * 1000).toISOString(),\n };\n }\n\n async downloadVideo(generationId: string): Promise<Buffer> {\n const endpoint = `${this.baseUrl}/videos/generations/${generationId}/content`;\n\n console.log(`[krisspy-ai] Downloading video ${generationId}...`);\n\n const response = await fetch(endpoint, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`[krisspy-ai] Failed to download video: ${response.status} - ${errorText}`);\n }\n\n const buffer = await response.buffer();\n console.log(`[krisspy-ai] Video downloaded: ${buffer.length} bytes`);\n\n return buffer;\n }\n}\n","import { BaseVideoService } from './base';\nimport type {\n VideoGenerationOptions,\n VideoJobSubmission,\n VideoJobStatus,\n VideoGenerationResult,\n} from '../types';\nimport fetch from 'node-fetch';\n\n/**\n * Krisspy AI Video Generation Service\n * Routes requests to Krisspy backend for credit billing\n */\nexport class KrisspySoraService extends BaseVideoService {\n getName(): string {\n return 'krisspy';\n }\n\n async submitJob(options: VideoGenerationOptions): Promise<VideoJobSubmission> {\n const { prompt, duration = 5 } = options;\n const baseUrl = this.config.baseUrl || 'https://api.krisspy.ai';\n const apiKey = this.config.apiKey;\n\n if (!apiKey) {\n throw new Error('API key is required for Krisspy video service');\n }\n\n const response = await fetch(`${baseUrl}/api/v1/ai/video`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ prompt, duration }),\n });\n\n if (!response.ok) {\n const error = await response.json() as any;\n throw new Error(error.message || `Video generation failed: ${response.statusText}`);\n }\n\n const data = await response.json() as any;\n\n // Backend returns video immediately, store it for later download\n this.cachedVideo = data.video;\n\n return {\n jobId: data.jobId,\n status: 'succeeded',\n createdAt: new Date().toISOString(),\n };\n }\n\n private cachedVideo: string | null = null;\n\n async getJobStatus(jobId: string): Promise<VideoJobStatus> {\n const baseUrl = this.config.baseUrl || 'https://api.krisspy.ai';\n const apiKey = this.config.apiKey;\n\n if (!apiKey) {\n throw new Error('API key is required for Krisspy video service');\n }\n\n const response = await fetch(`${baseUrl}/ai/video/status/${jobId}`, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n },\n });\n\n if (!response.ok) {\n const error = await response.json() as any;\n throw new Error(error.message || `Failed to get video status: ${response.statusText}`);\n }\n\n const data = await response.json() as any;\n return data;\n }\n\n async getResult(jobId: string): Promise<VideoGenerationResult> {\n const baseUrl = this.config.baseUrl || 'https://api.krisspy.ai';\n const apiKey = this.config.apiKey;\n\n if (!apiKey) {\n throw new Error('API key is required for Krisspy video service');\n }\n\n const response = await fetch(`${baseUrl}/ai/video/result/${jobId}`, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n },\n });\n\n if (!response.ok) {\n const error = await response.json() as any;\n throw new Error(error.message || `Failed to get video result: ${response.statusText}`);\n }\n\n const data = await response.json() as any;\n return data;\n }\n\n async downloadVideo(jobId: string): Promise<Buffer> {\n // Return cached video from submitJob\n if (this.cachedVideo) {\n const buffer = Buffer.from(this.cachedVideo, 'base64');\n this.cachedVideo = null; // Clear cache\n return buffer;\n }\n\n throw new Error('No video available. Call submitJob first.');\n }\n}\n","// Azure OpenAI transcription service (Whisper, GPT-4o-transcribe)\n\nimport fetch from 'node-fetch';\nimport FormData from 'form-data';\nimport { BaseTranscriptionService } from './base';\nimport type {\n TranscriptionOptions,\n TranscriptionResult,\n GenerativeServiceConfig,\n} from '../types';\n\ninterface AzureTranscriptionResponse {\n text: string;\n language?: string;\n duration?: number;\n words?: Array<{\n word: string;\n start: number;\n end: number;\n }>;\n segments?: Array<{\n id: number;\n seek: number;\n start: number;\n end: number;\n text: string;\n tokens: number[];\n temperature: number;\n avg_logprob: number;\n compression_ratio: number;\n no_speech_prob: number;\n }>;\n}\n\nexport class AzureTranscriptionService extends BaseTranscriptionService {\n private baseUrl: string;\n private apiKey: string;\n private deploymentName: string;\n private apiVersion: string;\n\n constructor(config: GenerativeServiceConfig = {}) {\n super(config);\n this.baseUrl = config.baseUrl || '';\n this.apiKey = config.apiKey || '';\n this.deploymentName = config.deploymentName || 'whisper';\n this.apiVersion = config.apiVersion || '2024-10-21';\n }\n\n getName(): string {\n return 'azure-transcription';\n }\n\n async transcribe(options: TranscriptionOptions): Promise<TranscriptionResult> {\n if (!this.baseUrl) {\n throw new Error('[krisspy-ai] Azure baseUrl is required for transcription');\n }\n if (!this.apiKey) {\n throw new Error('[krisspy-ai] Azure apiKey is required for transcription');\n }\n\n const endpoint = `${this.baseUrl}/openai/deployments/${this.deploymentName}/audio/transcriptions?api-version=${this.apiVersion}`;\n\n const formData = new FormData();\n\n // Handle audio input (Buffer or file path)\n if (Buffer.isBuffer(options.audio)) {\n formData.append('file', options.audio, { filename: 'audio.mp3', contentType: 'audio/mpeg' });\n } else if (typeof options.audio === 'string') {\n // File path - read the file\n const fs = await import('fs');\n const buffer = fs.readFileSync(options.audio);\n const filename = options.audio.split('/').pop() || 'audio.mp3';\n formData.append('file', buffer, { filename });\n }\n\n // Optional parameters\n if (options.language) {\n formData.append('language', options.language);\n }\n if (options.prompt) {\n formData.append('prompt', options.prompt);\n }\n if (options.responseFormat) {\n formData.append('response_format', options.responseFormat);\n }\n if (options.temperature !== undefined) {\n formData.append('temperature', String(options.temperature));\n }\n if (options.timestampGranularities && options.timestampGranularities.length > 0) {\n for (const granularity of options.timestampGranularities) {\n formData.append('timestamp_granularities[]', granularity);\n }\n }\n\n console.log(`[krisspy-ai] Transcribing audio with Azure (deployment: ${this.deploymentName})...`);\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'api-key': this.apiKey,\n ...formData.getHeaders(),\n },\n body: formData,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = errorText;\n try {\n const parsed = JSON.parse(errorText);\n errorMessage = parsed.error?.message || errorText;\n } catch {\n // Keep original error text\n }\n throw new Error(`[krisspy-ai] Azure transcription failed: ${response.status} - ${errorMessage}`);\n }\n\n // Handle different response formats\n if (options.responseFormat === 'text') {\n const text = await response.text();\n return { text };\n }\n\n if (options.responseFormat === 'srt' || options.responseFormat === 'vtt') {\n const text = await response.text();\n return { text };\n }\n\n const data = (await response.json()) as AzureTranscriptionResponse;\n\n console.log(`[krisspy-ai] Transcription complete. Duration: ${data.duration || 'unknown'}s`);\n\n return {\n text: data.text,\n language: data.language,\n duration: data.duration,\n words: data.words,\n segments: data.segments,\n };\n }\n}\n","// Base classes for audio services (transcription and TTS)\n\nimport { BaseGenerativeService } from '../base';\nimport type {\n TranscriptionOptions,\n TranscriptionResult,\n TTSOptions,\n TTSResult,\n GenerativeServiceConfig,\n} from '../types';\n\n/**\n * Base class for speech-to-text transcription services\n */\nexport abstract class BaseTranscriptionService extends BaseGenerativeService {\n constructor(config: GenerativeServiceConfig = {}) {\n super(config);\n }\n\n getServiceType(): 'transcription' {\n return 'transcription';\n }\n\n abstract transcribe(options: TranscriptionOptions): Promise<TranscriptionResult>;\n}\n\n/**\n * Base class for text-to-speech synthesis services\n */\nexport abstract class BaseTTSService extends BaseGenerativeService {\n constructor(config: GenerativeServiceConfig = {}) {\n super(config);\n }\n\n getServiceType(): 'tts' {\n return 'tts';\n }\n\n abstract synthesize(options: TTSOptions): Promise<TTSResult>;\n}\n","// OpenAI direct API transcription service (whisper, gpt-4o-transcribe, gpt-4o-transcribe-diarize)\n\nimport fetch from 'node-fetch';\nimport FormData from 'form-data';\nimport { BaseTranscriptionService } from './base';\nimport type {\n TranscriptionOptions,\n TranscriptionResult,\n DiarizedUtterance,\n GenerativeServiceConfig,\n} from '../types';\n\ninterface OpenAITranscriptionResponse {\n text: string;\n language?: string;\n duration?: number;\n words?: Array<{\n word: string;\n start: number;\n end: number;\n }>;\n segments?: Array<{\n id: number;\n seek: number;\n start: number;\n end: number;\n text: string;\n tokens: number[];\n temperature: number;\n avg_logprob: number;\n compression_ratio: number;\n no_speech_prob: number;\n }>;\n // For diarization models\n utterances?: Array<{\n speaker: string;\n start: number;\n end: number;\n text: string;\n }>;\n}\n\nexport class OpenAITranscriptionService extends BaseTranscriptionService {\n private baseUrl: string;\n private apiKey: string;\n private model: string;\n\n constructor(config: GenerativeServiceConfig = {}) {\n super(config);\n this.baseUrl = config.baseUrl || 'https://api.openai.com/v1';\n this.apiKey = config.apiKey || '';\n // Default to whisper-1, can use gpt-4o-transcribe or gpt-4o-transcribe-diarize\n // Map Azure-style name to OpenAI name for compatibility\n let modelName = config.deploymentName || 'whisper-1';\n if (modelName === 'whisper') modelName = 'whisper-1';\n this.model = modelName;\n }\n\n getName(): string {\n return 'openai-transcription';\n }\n\n async transcribe(options: TranscriptionOptions): Promise<TranscriptionResult> {\n if (!this.apiKey) {\n throw new Error('[krisspy-ai] OpenAI apiKey is required for transcription');\n }\n\n const endpoint = `${this.baseUrl}/audio/transcriptions`;\n\n const formData = new FormData();\n formData.append('model', this.model);\n\n // Handle audio input (Buffer or file path)\n if (Buffer.isBuffer(options.audio)) {\n formData.append('file', options.audio, { filename: 'audio.mp3', contentType: 'audio/mpeg' });\n } else if (typeof options.audio === 'string') {\n // File path - read the file\n const fs = await import('fs');\n const buffer = fs.readFileSync(options.audio);\n const filename = options.audio.split('/').pop() || 'audio.mp3';\n formData.append('file', buffer, { filename });\n }\n\n // Optional parameters\n if (options.language) {\n formData.append('language', options.language);\n }\n if (options.prompt) {\n formData.append('prompt', options.prompt);\n }\n if (options.responseFormat) {\n formData.append('response_format', options.responseFormat);\n }\n if (options.temperature !== undefined) {\n formData.append('temperature', String(options.temperature));\n }\n if (options.timestampGranularities && options.timestampGranularities.length > 0) {\n for (const granularity of options.timestampGranularities) {\n formData.append('timestamp_granularities[]', granularity);\n }\n }\n\n console.log(`[krisspy-ai] Transcribing audio with OpenAI (model: ${this.model})...`);\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n ...formData.getHeaders(),\n },\n body: formData,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = errorText;\n try {\n const parsed = JSON.parse(errorText);\n errorMessage = parsed.error?.message || errorText;\n } catch {\n // Keep original error text\n }\n throw new Error(`[krisspy-ai] OpenAI transcription failed: ${response.status} - ${errorMessage}`);\n }\n\n // Handle different response formats\n if (options.responseFormat === 'text') {\n const text = await response.text();\n return { text };\n }\n\n if (options.responseFormat === 'srt' || options.responseFormat === 'vtt') {\n const text = await response.text();\n return { text };\n }\n\n const data = (await response.json()) as OpenAITranscriptionResponse;\n\n console.log(`[krisspy-ai] Transcription complete. Duration: ${data.duration || 'unknown'}s`);\n\n const result: TranscriptionResult = {\n text: data.text,\n language: data.language,\n duration: data.duration,\n words: data.words,\n segments: data.segments,\n };\n\n // Include diarization data if present\n if (data.utterances) {\n result.utterances = data.utterances as DiarizedUtterance[];\n console.log(`[krisspy-ai] Diarization: ${data.utterances.length} utterances from ${new Set(data.utterances.map(u => u.speaker)).size} speakers`);\n }\n\n return result;\n }\n}\n","import { BaseTranscriptionService } from './base';\nimport type { TranscriptionOptions, TranscriptionResult } from '../types';\nimport fetch from 'node-fetch';\nimport FormData from 'form-data';\n\n/**\n * Krisspy AI Transcription Service\n * Routes requests to Krisspy backend for credit billing\n */\nexport class KrisspyTranscriptionService extends BaseTranscriptionService {\n getName(): string {\n return 'krisspy';\n }\n\n async transcribe(options: TranscriptionOptions): Promise<TranscriptionResult> {\n const { audio, language, responseFormat = 'verbose_json', timestampGranularities } = options;\n const baseUrl = this.config.baseUrl || 'https://api.krisspy.ai';\n const apiKey = this.config.apiKey;\n\n if (!apiKey) {\n throw new Error('API key is required for Krisspy transcription service');\n }\n\n // Create form data\n const form = new FormData();\n form.append('audio', audio, { filename: 'audio.mp3' });\n if (language) form.append('language', language);\n if (responseFormat) form.append('response_format', responseFormat);\n if (timestampGranularities) {\n form.append('timestamp_granularities', JSON.stringify(timestampGranularities));\n }\n\n const response = await fetch(`${baseUrl}/api/v1/ai/transcribe`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n ...form.getHeaders(),\n },\n body: form as any,\n });\n\n if (!response.ok) {\n const error = await response.json() as any;\n throw new Error(error.message || `Transcription failed: ${response.statusText}`);\n }\n\n const data = await response.json() as any;\n return data;\n }\n}\n","// Azure OpenAI Text-to-Speech service\n\nimport fetch from 'node-fetch';\nimport { BaseTTSService } from './base';\nimport type {\n TTSOptions,\n TTSResult,\n TTSFormat,\n GenerativeServiceConfig,\n} from '../types';\n\nexport class AzureTTSService extends BaseTTSService {\n private baseUrl: string;\n private apiKey: string;\n private deploymentName: string;\n private apiVersion: string;\n\n constructor(config: GenerativeServiceConfig = {}) {\n super(config);\n this.baseUrl = config.baseUrl || '';\n this.apiKey = config.apiKey || '';\n this.deploymentName = config.deploymentName || 'tts';\n this.apiVersion = config.apiVersion || '2025-03-01-preview';\n }\n\n getName(): string {\n return 'azure-tts';\n }\n\n async synthesize(options: TTSOptions): Promise<TTSResult> {\n if (!this.baseUrl) {\n throw new Error('[krisspy-ai] Azure baseUrl is required for TTS');\n }\n if (!this.apiKey) {\n throw new Error('[krisspy-ai] Azure apiKey is required for TTS');\n }\n\n const endpoint = `${this.baseUrl}/openai/deployments/${this.deploymentName}/audio/speech?api-version=${this.apiVersion}`;\n\n const body: Record<string, unknown> = {\n model: this.deploymentName,\n input: options.input,\n voice: options.voice || 'alloy',\n };\n\n if (options.responseFormat) {\n body.response_format = options.responseFormat;\n }\n if (options.speed !== undefined) {\n body.speed = options.speed;\n }\n\n console.log(`[krisspy-ai] Synthesizing speech with Azure TTS (deployment: ${this.deploymentName})...`);\n console.log(`[krisspy-ai] Azure TTS endpoint: ${endpoint}`);\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'api-key': this.apiKey,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = errorText;\n try {\n const parsed = JSON.parse(errorText);\n errorMessage = parsed.error?.message || errorText;\n } catch {\n // Keep original error text\n }\n throw new Error(`[krisspy-ai] Azure TTS failed: ${response.status} - ${errorMessage}`);\n }\n\n const buffer = await response.buffer();\n const format: TTSFormat = options.responseFormat || 'mp3';\n\n console.log(`[krisspy-ai] Speech synthesis complete: ${buffer.length} bytes (${format})`);\n\n return {\n audio: buffer,\n format,\n };\n }\n}\n","// OpenAI direct API Text-to-Speech service (tts, tts-hd, gpt-4o-mini-tts)\n\nimport fetch from 'node-fetch';\nimport { BaseTTSService } from './base';\nimport type {\n TTSOptions,\n TTSResult,\n TTSFormat,\n GenerativeServiceConfig,\n} from '../types';\n\nexport class OpenAITTSService extends BaseTTSService {\n private baseUrl: string;\n private apiKey: string;\n private model: string;\n\n constructor(config: GenerativeServiceConfig = {}) {\n super(config);\n this.baseUrl = config.baseUrl || 'https://api.openai.com/v1';\n this.apiKey = config.apiKey || '';\n // Default to tts-1, can use tts-1-hd or gpt-4o-mini-tts\n // Map Azure-style names to OpenAI names for compatibility\n let modelName = config.deploymentName || 'tts-1';\n if (modelName === 'tts') modelName = 'tts-1';\n if (modelName === 'tts-hd') modelName = 'tts-1-hd';\n this.model = modelName;\n }\n\n getName(): string {\n return 'openai-tts';\n }\n\n async synthesize(options: TTSOptions): Promise<TTSResult> {\n if (!this.apiKey) {\n throw new Error('[krisspy-ai] OpenAI apiKey is required for TTS');\n }\n\n const endpoint = `${this.baseUrl}/audio/speech`;\n\n const body: Record<string, unknown> = {\n model: this.model,\n input: options.input,\n voice: options.voice || 'alloy',\n };\n\n if (options.responseFormat) {\n body.response_format = options.responseFormat;\n }\n if (options.speed !== undefined) {\n body.speed = options.speed;\n }\n // gpt-4o-mini-tts supports instructions for voice style\n if (options.instructions && this.model.includes('gpt-4o')) {\n body.instructions = options.instructions;\n }\n\n console.log(`[krisspy-ai] Synthesizing speech with OpenAI TTS (model: ${this.model})...`);\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n let errorMessage = errorText;\n try {\n const parsed = JSON.parse(errorText);\n errorMessage = parsed.error?.message || errorText;\n } catch {\n // Keep original error text\n }\n throw new Error(`[krisspy-ai] OpenAI TTS failed: ${response.status} - ${errorMessage}`);\n }\n\n const buffer = await response.buffer();\n const format: TTSFormat = options.responseFormat || 'mp3';\n\n console.log(`[krisspy-ai] Speech synthesis complete: ${buffer.length} bytes (${format})`);\n\n return {\n audio: buffer,\n format,\n };\n }\n}\n","import { BaseTTSService } from './base';\nimport type { TTSOptions, TTSResult } from '../types';\nimport fetch from 'node-fetch';\n\n/**\n * Krisspy AI TTS Service\n * Routes requests to Krisspy backend for credit billing\n */\nexport class KrisspyTTSService extends BaseTTSService {\n getName(): string {\n return 'krisspy';\n }\n\n async synthesize(options: TTSOptions): Promise<TTSResult> {\n const { input, voice = 'nova', speed = 1.0, instructions, responseFormat = 'mp3' } = options;\n const baseUrl = this.config.baseUrl || 'https://api.krisspy.ai';\n const apiKey = this.config.apiKey;\n\n if (!apiKey) {\n throw new Error('API key is required for Krisspy TTS service');\n }\n\n const response = await fetch(`${baseUrl}/api/v1/ai/tts`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n text: input,\n voice,\n speed,\n instructions,\n response_format: responseFormat,\n }),\n });\n\n if (!response.ok) {\n const error = await response.json() as any;\n throw new Error(error.message || `TTS failed: ${response.statusText}`);\n }\n\n const data = await response.json() as any;\n\n // Convert base64 to Buffer\n const audioBuffer = Buffer.from(data.audio, 'base64');\n\n return {\n audio: audioBuffer,\n format: data.format || responseFormat,\n };\n }\n}\n","// krisspy-ai Generative Services\n// Services for image, video, audio, and other media generation\n\nimport { AzureDalleService } from './image/azure-dalle';\nimport { OpenAIImageService } from './image/openai-image';\nimport { KrisspyImageService } from './image/krisspy-image';\nimport { AzureSoraService } from './video/azure-sora';\nimport { OpenAISoraService } from './video/openai-sora';\nimport { KrisspySoraService } from './video/krisspy-sora';\nimport { AzureTranscriptionService } from './audio/azure-transcription';\nimport { OpenAITranscriptionService } from './audio/openai-transcription';\nimport { KrisspyTranscriptionService } from './audio/krisspy-transcription';\nimport { AzureTTSService } from './audio/azure-tts';\nimport { OpenAITTSService } from './audio/openai-tts';\nimport { KrisspyTTSService } from './audio/krisspy-tts';\nimport type { BaseImageService } from './image/base';\nimport type { BaseVideoService } from './video/base';\nimport type { BaseTranscriptionService, BaseTTSService } from './audio/base';\nimport type { GenerativeServiceConfig } from './types';\n\n// Service constructor types\ntype ImageServiceConstructor = new (config: GenerativeServiceConfig) => BaseImageService;\ntype VideoServiceConstructor = new (config: GenerativeServiceConfig) => BaseVideoService;\ntype TranscriptionServiceConstructor = new (config: GenerativeServiceConfig) => BaseTranscriptionService;\ntype TTSServiceConstructor = new (config: GenerativeServiceConfig) => BaseTTSService;\n\n// === IMAGE SERVICES REGISTRY ===\n\nconst imageServices: Record<string, ImageServiceConstructor> = {\n // Krisspy AI (proxy to backend)\n 'krisspy': KrisspyImageService,\n // Azure OpenAI\n 'azure-dalle': AzureDalleService,\n 'azure': AzureDalleService,\n 'azure-gpt-image': AzureDalleService,\n // OpenAI direct\n 'openai': OpenAIImageService,\n 'openai-image': OpenAIImageService,\n 'gpt-image': OpenAIImageService,\n};\n\n// === VIDEO SERVICES REGISTRY ===\n\nconst videoServices: Record<string, VideoServiceConstructor> = {\n // Krisspy AI (proxy to backend)\n 'krisspy': KrisspySoraService,\n // Azure OpenAI\n 'azure-sora': AzureSoraService,\n 'azure': AzureSoraService,\n // OpenAI direct\n 'openai': OpenAISoraService,\n 'openai-sora': OpenAISoraService,\n 'sora': OpenAISoraService,\n};\n\n// === TRANSCRIPTION SERVICES REGISTRY ===\n\nconst transcriptionServices: Record<string, TranscriptionServiceConstructor> = {\n // Krisspy AI (proxy to backend)\n 'krisspy': KrisspyTranscriptionService,\n // Azure OpenAI\n 'azure': AzureTranscriptionService,\n 'azure-whisper': AzureTranscriptionService,\n 'azure-transcription': AzureTranscriptionService,\n // OpenAI direct\n 'openai': OpenAITranscriptionService,\n 'openai-whisper': OpenAITranscriptionService,\n 'whisper': OpenAITranscriptionService,\n 'gpt-4o-transcribe': OpenAITranscriptionService,\n 'gpt-4o-transcribe-diarize': OpenAITranscriptionService,\n};\n\n// === TTS SERVICES REGISTRY ===\n\nconst ttsServices: Record<string, TTSServiceConstructor> = {\n // Krisspy AI (proxy to backend)\n 'krisspy': KrisspyTTSService,\n // Azure OpenAI\n 'azure': AzureTTSService,\n 'azure-tts': AzureTTSService,\n // OpenAI direct\n 'openai': OpenAITTSService,\n 'openai-tts': OpenAITTSService,\n 'tts': OpenAITTSService,\n 'tts-hd': OpenAITTSService,\n 'gpt-4o-mini-tts': OpenAITTSService,\n};\n\n// === FACTORY FUNCTIONS ===\n\n/**\n * Get an image generation service by name\n *\n * @param name - Service name: 'azure', 'openai', 'gpt-image'\n * @param config - Service configuration\n * @returns Image service instance\n */\nexport function getImageService(name: string, config: GenerativeServiceConfig = {}): BaseImageService {\n const ServiceClass = imageServices[name.toLowerCase()];\n if (!ServiceClass) {\n throw new Error(\n `[krisspy-ai] Unknown image service: ${name}. Available: ${Object.keys(imageServices).join(', ')}`\n );\n }\n return new ServiceClass(config);\n}\n\n/**\n * Get a video generation service by name\n *\n * @param name - Service name: 'azure', 'openai', 'sora'\n * @param config - Service configuration\n * @returns Video service instance\n */\nexport function getVideoService(name: string, config: GenerativeServiceConfig = {}): BaseVideoService {\n const ServiceClass = videoServices[name.toLowerCase()];\n if (!ServiceClass) {\n throw new Error(\n `[krisspy-ai] Unknown video service: ${name}. Available: ${Object.keys(videoServices).join(', ')}`\n );\n }\n return new ServiceClass(config);\n}\n\n/**\n * Get a transcription (speech-to-text) service by name\n *\n * @param name - Service name: 'azure', 'openai', 'whisper', 'gpt-4o-transcribe', 'gpt-4o-transcribe-diarize'\n * @param config - Service configuration\n * @returns Transcription service instance\n *\n * @example\n * const service = getTranscriptionService('openai', {\n * apiKey: 'sk-...',\n * deploymentName: 'whisper' // or 'gpt-4o-transcribe-diarize'\n * });\n * const result = await service.transcribe({ audio: audioBuffer });\n */\nexport function getTranscriptionService(name: string, config: GenerativeServiceConfig = {}): BaseTranscriptionService {\n const ServiceClass = transcriptionServices[name.toLowerCase()];\n if (!ServiceClass) {\n throw new Error(\n `[krisspy-ai] Unknown transcription service: ${name}. Available: ${Object.keys(transcriptionServices).join(', ')}`\n );\n }\n return new ServiceClass(config);\n}\n\n/**\n * Get a TTS (text-to-speech) service by name\n *\n * @param name - Service name: 'azure', 'openai', 'tts', 'tts', 'gpt-4o-mini-tts'\n * @param config - Service configuration\n * @returns TTS service instance\n *\n * @example\n * const service = getTTSService('openai', {\n * apiKey: 'sk-...',\n * deploymentName: 'gpt-4o-mini-tts'\n * });\n * const result = await service.synthesize({ input: 'Hello world', voice: 'nova' });\n */\nexport function getTTSService(name: string, config: GenerativeServiceConfig = {}): BaseTTSService {\n const ServiceClass = ttsServices[name.toLowerCase()];\n if (!ServiceClass) {\n throw new Error(\n `[krisspy-ai] Unknown TTS service: ${name}. Available: ${Object.keys(ttsServices).join(', ')}`\n );\n }\n return new ServiceClass(config);\n}\n\n// === REGISTRATION FUNCTIONS ===\n\n/**\n * Register a custom image generation service\n */\nexport function registerImageService(name: string, ServiceClass: ImageServiceConstructor): void {\n imageServices[name.toLowerCase()] = ServiceClass;\n}\n\n/**\n * Register a custom video generation service\n */\nexport function registerVideoService(name: string, ServiceClass: VideoServiceConstructor): void {\n videoServices[name.toLowerCase()] = ServiceClass;\n}\n\n/**\n * Register a custom transcription service\n */\nexport function registerTranscriptionService(name: string, ServiceClass: TranscriptionServiceConstructor): void {\n transcriptionServices[name.toLowerCase()] = ServiceClass;\n}\n\n/**\n * Register a custom TTS service\n */\nexport function registerTTSService(name: string, ServiceClass: TTSServiceConstructor): void {\n ttsServices[name.toLowerCase()] = ServiceClass;\n}\n\n// === LIST FUNCTIONS ===\n\nexport function getAvailableImageServices(): string[] {\n return Object.keys(imageServices);\n}\n\nexport function getAvailableVideoServices(): string[] {\n return Object.keys(videoServices);\n}\n\nexport function getAvailableTranscriptionServices(): string[] {\n return Object.keys(transcriptionServices);\n}\n\nexport function getAvailableTTSServices(): string[] {\n return Object.keys(ttsServices);\n}\n\n// === EXPORTS ===\n\n// Base classes\nexport { BaseGenerativeService } from './base';\nexport { BaseImageService } from './image/base';\nexport { BaseVideoService } from './video/base';\nexport { BaseTranscriptionService, BaseTTSService } from './audio/base';\n\n// Service implementations\nexport { AzureDalleService } from './image/azure-dalle';\nexport { OpenAIImageService } from './image/openai-image';\nexport { KrisspyImageService } from './image/krisspy-image';\nexport { AzureSoraService } from './video/azure-sora';\nexport { OpenAISoraService } from './video/openai-sora';\nexport { KrisspySoraService } from './video/krisspy-sora';\nexport { AzureTranscriptionService } from './audio/azure-transcription';\nexport { OpenAITranscriptionService } from './audio/openai-transcription';\nexport { KrisspyTranscriptionService } from './audio/krisspy-transcription';\nexport { AzureTTSService } from './audio/azure-tts';\nexport { OpenAITTSService } from './audio/openai-tts';\nexport { KrisspyTTSService } from './audio/krisspy-tts';\n\n// Types\nexport * from './types';\n"],"mappings":"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","names":["fetch","FormData","fetch","fetch","fetch","fetch","fetch","fetch","FormData","FormData","fetch","fetch","fetch","FormData","FormData","fetch","fetch","FormData","FormData","fetch","fetch","FormData","fetch","fetch","fetch","fetch","fetch","FormData","fetch"]}