@happyvertical/ai 0.103.3 → 0.103.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +81 -0
  2. package/dist/chunks/{anthropic-CdbK9Jl-.js → anthropic-DhNGsQpl.js} +3 -3
  3. package/dist/chunks/{anthropic-CdbK9Jl-.js.map → anthropic-DhNGsQpl.js.map} +1 -1
  4. package/dist/chunks/{bedrock-DNkxz3ow.js → bedrock-CrtUO8yx.js} +3 -3
  5. package/dist/chunks/{bedrock-DNkxz3ow.js.map → bedrock-CrtUO8yx.js.map} +1 -1
  6. package/dist/chunks/{bifrost-DmbaXObX.js → bifrost-BPQ0aL1i.js} +4 -4
  7. package/dist/chunks/{bifrost-DmbaXObX.js.map → bifrost-BPQ0aL1i.js.map} +1 -1
  8. package/dist/chunks/{byteplus-modelark-BAi0y9SK.js → byteplus-modelark-gG941oea.js} +3 -3
  9. package/dist/chunks/{byteplus-modelark-BAi0y9SK.js.map → byteplus-modelark-gG941oea.js.map} +1 -1
  10. package/dist/chunks/{claude-cli-C40pIzrp.js → claude-cli-CW_gIocm.js} +3 -3
  11. package/dist/chunks/{claude-cli-C40pIzrp.js.map → claude-cli-CW_gIocm.js.map} +1 -1
  12. package/dist/chunks/{continuation-L5KnnE9R.js → continuation-BMGvMlzq.js} +3 -3
  13. package/dist/chunks/continuation-BMGvMlzq.js.map +1 -0
  14. package/dist/chunks/{gateway-audio-models-B1tGNv1H.js → gateway-audio-models-DuXbi_2q.js} +2 -2
  15. package/dist/chunks/{gateway-audio-models-B1tGNv1H.js.map → gateway-audio-models-DuXbi_2q.js.map} +1 -1
  16. package/dist/chunks/{gemini-C-r6c4N9.js → gemini-DCo6d-n1.js} +3 -3
  17. package/dist/chunks/{gemini-C-r6c4N9.js.map → gemini-DCo6d-n1.js.map} +1 -1
  18. package/dist/chunks/{huggingface-DtuYF1vb.js → huggingface-jqjeFPdr.js} +3 -3
  19. package/dist/chunks/{huggingface-DtuYF1vb.js.map → huggingface-jqjeFPdr.js.map} +1 -1
  20. package/dist/chunks/{laya-D-P82D0h.js → laya-D8o5TEO7.js} +3 -3
  21. package/dist/chunks/{laya-D-P82D0h.js.map → laya-D8o5TEO7.js.map} +1 -1
  22. package/dist/chunks/{litellm-BaGgWzHR.js → litellm-C5Ek8B0K.js} +4 -4
  23. package/dist/chunks/{litellm-BaGgWzHR.js.map → litellm-C5Ek8B0K.js.map} +1 -1
  24. package/dist/chunks/{ollama-C3T3mn68.js → ollama-CuDjAyTy.js} +4 -4
  25. package/dist/chunks/{ollama-C3T3mn68.js.map → ollama-CuDjAyTy.js.map} +1 -1
  26. package/dist/chunks/{openai-compat-video-CwFsKAxR.js → openai-compat-video-ByTC2nzb.js} +3 -3
  27. package/dist/chunks/{openai-compat-video-CwFsKAxR.js.map → openai-compat-video-ByTC2nzb.js.map} +1 -1
  28. package/dist/chunks/{qwen-tts-DqMxfA54.js → qwen-tts-CWdO07D_.js} +2 -2
  29. package/dist/chunks/{qwen-tts-DqMxfA54.js.map → qwen-tts-CWdO07D_.js.map} +1 -1
  30. package/dist/chunks/{rate-limit-BkK4-hXY.js → rate-limit-Dwyde1BY.js} +2 -2
  31. package/dist/chunks/{rate-limit-BkK4-hXY.js.map → rate-limit-Dwyde1BY.js.map} +1 -1
  32. package/dist/chunks/{seevio-EzC6eKz-.js → seevio-B9V2nZtr.js} +3 -3
  33. package/dist/chunks/{seevio-EzC6eKz-.js.map → seevio-B9V2nZtr.js.map} +1 -1
  34. package/dist/chunks/{src-Cc5yFnnQ.js → src-DBah9G3i.js} +462 -20
  35. package/dist/chunks/src-DBah9G3i.js.map +1 -0
  36. package/dist/chunks/{typesafe-D7ZmI9-n.js → typesafe-B1_jGusy.js} +3 -3
  37. package/dist/chunks/{typesafe-D7ZmI9-n.js.map → typesafe-B1_jGusy.js.map} +1 -1
  38. package/dist/chunks/{usage-B9gPCWSa.js → usage-DS7uDhi1.js} +2 -1
  39. package/dist/chunks/usage-DS7uDhi1.js.map +1 -0
  40. package/dist/chunks/{webllm-DT31sqUY.js → webllm-DVDsgVT7.js} +2 -2
  41. package/dist/chunks/{webllm-DT31sqUY.js.map → webllm-DVDsgVT7.js.map} +1 -1
  42. package/dist/index.d.ts +1 -0
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +3 -3
  45. package/dist/local.js +2 -2
  46. package/dist/node.js +4 -4
  47. package/dist/shared/client.d.ts +3 -7
  48. package/dist/shared/client.d.ts.map +1 -1
  49. package/dist/shared/continuation.d.ts.map +1 -1
  50. package/dist/shared/factory.d.ts.map +1 -1
  51. package/dist/shared/message.d.ts +2 -3
  52. package/dist/shared/message.d.ts.map +1 -1
  53. package/dist/shared/providers/chatgpt-plan.d.ts +60 -0
  54. package/dist/shared/providers/chatgpt-plan.d.ts.map +1 -0
  55. package/dist/shared/types.d.ts +42 -8
  56. package/dist/shared/types.d.ts.map +1 -1
  57. package/package.json +2 -2
  58. package/dist/chunks/continuation-L5KnnE9R.js.map +0 -1
  59. package/dist/chunks/src-Cc5yFnnQ.js.map +0 -1
  60. package/dist/chunks/usage-B9gPCWSa.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"huggingface-DtuYF1vb.js","names":[],"sources":["../../src/shared/providers/huggingface.ts"],"sourcesContent":["/**\n * Hugging Face provider implementation\n */\n\nimport { rateLimitErrorFrom } from '../rate-limit';\nimport {\n normalizeBaseAIOptions,\n normalizeChatOptions,\n type PreparedRequestControls,\n prepareRequestControls,\n} from '../safety';\nimport type {\n AICapabilities,\n AIInterface,\n AIMessage,\n AIModel,\n AIResponse,\n ChatOptions,\n CompletionOptions,\n EmbeddingOptions,\n EmbeddingResponse,\n HuggingFaceOptions,\n ImageDescriptionOptions,\n ImageEmbeddingOptions,\n ImageGenerationOptions,\n ImageGenerationResponse,\n MessageOptions,\n TokenUsage,\n TTSOptions,\n TTSResponse,\n VideoGenerationJob,\n VideoGenerationOptions,\n VideoGenerationResult,\n VideoGenerationStatusResult,\n Voice,\n VoiceCloneOptions,\n VoiceDesignOptions,\n VoiceListOptions,\n} from '../types';\nimport {\n AIError,\n AuthenticationError,\n ContextLengthError,\n extractTextContent,\n ModelNotFoundError,\n} from '../types';\nimport { emitUsage } from './usage';\n\nexport class HuggingFaceProvider implements AIInterface {\n private options: HuggingFaceOptions;\n private baseUrl: string;\n\n constructor(options: HuggingFaceOptions) {\n this.options = normalizeBaseAIOptions({\n defaultModel: 'microsoft/DialoGPT-medium',\n useCache: true,\n waitForModel: true,\n ...options,\n });\n\n this.baseUrl =\n this.options.endpoint || 'https://api-inference.huggingface.co';\n }\n\n async chat(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): Promise<AIResponse> {\n const startTime = Date.now();\n let controls: PreparedRequestControls | undefined;\n try {\n // Convert messages to a single prompt for text generation models\n const prompt = this.messagesToPrompt(messages);\n const model =\n options.model || this.options.model || this.options.defaultModel;\n options = normalizeChatOptions(\n this.options,\n options,\n 'huggingface',\n model,\n );\n controls = prepareRequestControls(this.options, options);\n\n const response = await this.makeRequest(\n `/models/${model}`,\n {\n inputs: prompt,\n parameters: {\n max_new_tokens: options.maxTokens,\n temperature: options.temperature ?? 1.0,\n top_p: options.topP ?? 1.0,\n do_sample:\n (options.temperature && options.temperature > 0) || false,\n stop_sequences: Array.isArray(options.stop)\n ? options.stop\n : options.stop\n ? [options.stop]\n : undefined,\n },\n options: {\n use_cache: this.options.useCache,\n wait_for_model: this.options.waitForModel,\n },\n },\n controls.signal,\n );\n\n if (Array.isArray(response) && response[0]?.generated_text) {\n const generatedText = response[0].generated_text;\n // Remove the input prompt from the response\n const content = generatedText.replace(prompt, '').trim();\n\n emitUsage(\n this.options,\n 'huggingface',\n 'chat',\n model!,\n undefined,\n startTime,\n options.usageTags,\n );\n\n return {\n content,\n model,\n finishReason: 'stop',\n };\n }\n\n throw new AIError(\n 'Invalid response format from Hugging Face',\n 'INVALID_RESPONSE',\n 'huggingface',\n );\n } catch (error) {\n if (controls?.didTimeout()) {\n throw new AIError(\n `AI request timed out after ${controls.timeout}ms`,\n 'AI_TIMEOUT',\n 'huggingface',\n options.model,\n );\n }\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'huggingface',\n options.model,\n );\n }\n throw this.mapError(error);\n } finally {\n controls?.cleanup();\n }\n }\n\n async complete(\n prompt: string,\n options: CompletionOptions = {},\n ): Promise<AIResponse> {\n return this.chat([{ role: 'user', content: prompt }], {\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n n: options.n,\n stop: options.stop,\n stream: options.stream,\n onProgress: options.onProgress,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n continueOnLength: options.continueOnLength,\n });\n }\n\n /**\n * Simple message interface for single-turn interactions with optional history\n *\n * @param text - The message text to send\n * @param options - Configuration options including history, model, etc.\n * @returns Promise resolving to the response content string\n */\n async message(text: string, options: MessageOptions = {}): Promise<string> {\n // Build messages array from history + current message\n const messages: AIMessage[] = [\n ...(options.history || []),\n { role: options.role || 'user', content: text },\n ];\n\n const response = await this.chat(messages, {\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n stop: options.stop,\n stream: options.stream,\n frequencyPenalty: options.frequencyPenalty,\n presencePenalty: options.presencePenalty,\n responseFormat: options.responseFormat,\n seed: options.seed,\n tools: options.tools,\n toolChoice: options.toolChoice,\n onProgress: options.onProgress,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n continueOnLength: options.continueOnLength,\n });\n\n return response.content;\n }\n\n async embed(\n text: string | string[],\n options: EmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n const startTime = Date.now();\n try {\n const input = Array.isArray(text) ? text : [text];\n const model = options.model || 'sentence-transformers/all-MiniLM-L6-v2';\n\n const response = await this.makeRequest(`/models/${model}`, {\n inputs: input,\n options: {\n use_cache: this.options.useCache,\n wait_for_model: this.options.waitForModel,\n },\n });\n\n // Handle different response formats from different embedding models\n let embeddings: number[][];\n if (Array.isArray(response) && Array.isArray(response[0])) {\n // Direct array of embeddings\n embeddings = Array.isArray(text) ? response : [response[0]];\n } else if (\n response &&\n typeof response === 'object' &&\n response.embeddings\n ) {\n // Response with embeddings property\n embeddings = response.embeddings;\n } else {\n throw new AIError(\n 'Invalid embedding response format',\n 'INVALID_RESPONSE',\n 'huggingface',\n );\n }\n\n emitUsage(\n this.options,\n 'huggingface',\n 'embed',\n model,\n undefined,\n startTime,\n options.usageTags,\n );\n\n return {\n embeddings,\n model,\n };\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async embedImage(\n _image: string | Buffer,\n _options: ImageEmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n throw new AIError(\n 'Hugging Face image embeddings not implemented. Use OpenAI or Gemini.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async describeImage(\n _image: string | Buffer,\n _prompt?: string,\n _options: ImageDescriptionOptions = {},\n ): Promise<string> {\n throw new AIError(\n 'Image description is not implemented for Hugging Face. Use OpenAI or Gemini.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async generateImage(\n _prompt: string,\n _options: ImageGenerationOptions = {},\n ): Promise<ImageGenerationResponse> {\n // Note: Hugging Face has image generation models (Stable Diffusion), but we're keeping this as a stub\n throw new AIError(\n 'Image generation is not implemented for Hugging Face. Use OpenAI or Gemini.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async *stream(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): AsyncIterable<string> {\n // Hugging Face Inference API doesn't support streaming for most models\n // Fall back to regular completion and yield the result\n const startTime = Date.now();\n const response = await this.chat(messages, {\n ...options,\n _skipUsage: true,\n } as any);\n\n // Simulate streaming by yielding chunks\n const content = response.content;\n const chunkSize = 10;\n\n for (let i = 0; i < content.length; i += chunkSize) {\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'huggingface',\n options.model,\n );\n }\n const chunk = content.slice(i, i + chunkSize);\n if (options.onProgress) {\n options.onProgress(chunk);\n }\n yield chunk;\n\n // Add small delay to simulate streaming\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n\n const model = options.model || this.options.defaultModel || 'gpt2';\n emitUsage(\n this.options,\n 'huggingface',\n 'stream',\n model,\n undefined,\n startTime,\n options.usageTags,\n );\n }\n\n async countTokens(text: string): Promise<number> {\n // Approximation - Hugging Face models use different tokenizers\n return Math.ceil(text.length / 4);\n }\n\n async getModels(): Promise<AIModel[]> {\n // Return some popular text generation models available on Hugging Face\n return [\n {\n id: 'microsoft/DialoGPT-medium',\n name: 'DialoGPT Medium',\n description: 'Conversational AI model by Microsoft',\n contextLength: 1024,\n capabilities: ['text', 'chat'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: 'microsoft/DialoGPT-large',\n name: 'DialoGPT Large',\n description: 'Large conversational AI model by Microsoft',\n contextLength: 1024,\n capabilities: ['text', 'chat'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: 'facebook/blenderbot-400M-distill',\n name: 'BlenderBot 400M',\n description: 'Conversational AI model by Meta',\n contextLength: 512,\n capabilities: ['text', 'chat'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: 'gpt2',\n name: 'GPT-2',\n description: 'OpenAI GPT-2 model',\n contextLength: 1024,\n capabilities: ['text', 'completion'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: 'sentence-transformers/all-MiniLM-L6-v2',\n name: 'All-MiniLM-L6-v2',\n description: 'Sentence embedding model',\n contextLength: 512,\n capabilities: ['embeddings'],\n supportsFunctions: false,\n supportsVision: false,\n },\n ];\n }\n\n async getCapabilities(): Promise<AICapabilities> {\n return {\n chat: true,\n completion: true,\n embeddings: true,\n streaming: true,\n functions: false, // Most HF models don't support function calling\n vision: false, // Limited vision model support\n fineTuning: true, // Via Hugging Face training API\n imageEmbeddings: false,\n imageGeneration: false, // Stable Diffusion exists but not implemented\n videoGeneration: false,\n tts: false,\n voiceCloning: false,\n voiceDesign: false,\n maxContextLength: 2048,\n supportedOperations: ['chat', 'completion', 'embedding', 'streaming'],\n };\n }\n\n // ============================================================================\n // Video Generation Methods (Not supported - use gemini, byteplus-modelark,\n // or openai-compat-video provider)\n // ============================================================================\n\n async submitVideoGenerationJob(\n _options: VideoGenerationOptions,\n ): Promise<VideoGenerationJob> {\n throw new AIError(\n 'Video generation is not supported by HuggingFace provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async getVideoGenerationJob(\n _handle: VideoGenerationJob,\n ): Promise<VideoGenerationStatusResult> {\n throw new AIError(\n 'Video generation is not supported by HuggingFace provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async fetchVideoGenerationResult(\n _handle: VideoGenerationJob,\n ): Promise<VideoGenerationResult> {\n throw new AIError(\n 'Video generation is not supported by HuggingFace provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async cancelVideoGenerationJob(_handle: VideoGenerationJob): Promise<void> {\n throw new AIError(\n 'Video generation is not supported by HuggingFace provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async validateVideoGenerationAccess(): Promise<boolean> {\n throw new AIError(\n 'Video generation is not supported by HuggingFace provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n // ============================================================================\n // TTS Methods (Not supported - use Qwen3-TTS provider)\n // ============================================================================\n\n async synthesizeSpeech(\n _text: string,\n _options?: TTSOptions,\n ): Promise<TTSResponse> {\n throw new AIError(\n 'TTS is not supported by HuggingFace provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n streamSpeech(_text: string, _options?: TTSOptions): AsyncIterable<Buffer> {\n const error = new AIError(\n 'TTS streaming is not supported by HuggingFace provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n return {\n [Symbol.asyncIterator]: () => ({\n next: () => Promise.reject(error),\n }),\n };\n }\n\n async cloneVoice(_options: VoiceCloneOptions): Promise<Voice> {\n throw new AIError(\n 'Voice cloning is not supported by HuggingFace provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async designVoice(_options: VoiceDesignOptions): Promise<Voice> {\n throw new AIError(\n 'Voice design is not supported by HuggingFace provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async getVoices(_options?: VoiceListOptions): Promise<Voice[]> {\n throw new AIError(\n 'Voice listing is not supported by HuggingFace provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n private messagesToPrompt(messages: AIMessage[]): string {\n // Convert chat messages to a single prompt format\n return `${messages\n .map((message) => {\n const textContent = extractTextContent(message.content);\n switch (message.role) {\n case 'system':\n return `System: ${textContent}`;\n case 'user':\n return `Human: ${textContent}`;\n case 'assistant':\n return `Assistant: ${textContent}`;\n default:\n return textContent;\n }\n })\n .join('\\n')}\\nAssistant:`;\n }\n\n private async makeRequest(\n endpoint: string,\n data: any,\n signal?: AbortSignal,\n ): Promise<any> {\n const url = `${this.baseUrl}${endpoint}`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.options.apiToken}`,\n 'Content-Type': 'application/json',\n ...this.options.headers,\n },\n body: JSON.stringify(data),\n signal,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n return response.json();\n }\n\n private mapError(error: unknown): AIError {\n if (error instanceof AIError) {\n return error;\n }\n\n const message = error instanceof Error ? error.message : 'Unknown error';\n\n // Map common HTTP status codes\n if (message.includes('401') || message.includes('Unauthorized')) {\n return new AuthenticationError('huggingface');\n }\n\n if (message.includes('429') || message.includes('rate limit')) {\n return rateLimitErrorFrom('huggingface', error);\n }\n\n if (message.includes('404') || message.includes('not found')) {\n return new ModelNotFoundError(message, 'huggingface');\n }\n\n if (message.includes('413') || message.includes('too large')) {\n return new ContextLengthError('huggingface');\n }\n\n return new AIError(message, 'UNKNOWN_ERROR', 'huggingface');\n }\n}\n"],"mappings":";;;;;;AAgDA,IAAa,sBAAb,MAAwD;CACtD;CACA;CAEA,YAAY,SAA6B;EACvC,KAAK,UAAU,uBAAuB;GACpC,cAAc;GACd,UAAU;GACV,cAAc;GACd,GAAG;EACL,CAAC;EAED,KAAK,UACH,KAAK,QAAQ,YAAY;CAC7B;CAEA,MAAM,KACJ,UACA,UAAuB,CAAC,GACH;EACrB,MAAM,YAAY,KAAK,IAAI;EAC3B,IAAI;EACJ,IAAI;GAEF,MAAM,SAAS,KAAK,iBAAiB,QAAQ;GAC7C,MAAM,QACJ,QAAQ,SAAS,KAAK,QAAQ,SAAS,KAAK,QAAQ;GACtD,UAAU,qBACR,KAAK,SACL,SACA,eACA,KACF;GACA,WAAW,uBAAuB,KAAK,SAAS,OAAO;GAEvD,MAAM,WAAW,MAAM,KAAK,YAC1B,WAAW,SACX;IACE,QAAQ;IACR,YAAY;KACV,gBAAgB,QAAQ;KACxB,aAAa,QAAQ,eAAe;KACpC,OAAO,QAAQ,QAAQ;KACvB,WACG,QAAQ,eAAe,QAAQ,cAAc,KAAM;KACtD,gBAAgB,MAAM,QAAQ,QAAQ,IAAI,IACtC,QAAQ,OACR,QAAQ,OACN,CAAC,QAAQ,IAAI,IACb,KAAA;IACR;IACA,SAAS;KACP,WAAW,KAAK,QAAQ;KACxB,gBAAgB,KAAK,QAAQ;IAC/B;GACF,GACA,SAAS,MACX;GAEA,IAAI,MAAM,QAAQ,QAAQ,KAAK,SAAS,EAAE,EAAE,gBAAgB;IAG1D,MAAM,UAFgB,SAAS,EAAE,CAAC,eAEJ,QAAQ,QAAQ,EAAE,CAAC,CAAC,KAAK;IAEvD,UACE,KAAK,SACL,eACA,QACA,OACA,KAAA,GACA,WACA,QAAQ,SACV;IAEA,OAAO;KACL;KACA;KACA,cAAc;IAChB;GACF;GAEA,MAAM,IAAI,QACR,6CACA,oBACA,aACF;EACF,SAAS,OAAO;GACd,IAAI,UAAU,WAAW,GACvB,MAAM,IAAI,QACR,8BAA8B,SAAS,QAAQ,KAC/C,cACA,eACA,QAAQ,KACV;GAEF,IAAI,QAAQ,QAAQ,SAClB,MAAM,IAAI,QACR,gCACA,cACA,eACA,QAAQ,KACV;GAEF,MAAM,KAAK,SAAS,KAAK;EAC3B,UAAU;GACR,UAAU,QAAQ;EACpB;CACF;CAEA,MAAM,SACJ,QACA,UAA6B,CAAC,GACT;EACrB,OAAO,KAAK,KAAK,CAAC;GAAE,MAAM;GAAQ,SAAS;EAAO,CAAC,GAAG;GACpD,OAAO,QAAQ;GACf,WAAW,QAAQ;GACnB,aAAa,QAAQ;GACrB,MAAM,QAAQ;GACd,GAAG,QAAQ;GACX,MAAM,QAAQ;GACd,QAAQ,QAAQ;GAChB,YAAY,QAAQ;GACpB,QAAQ,QAAQ;GAChB,SAAS,QAAQ;GACjB,WAAW,QAAQ;GACnB,WAAW,QAAQ;GACnB,kBAAkB,QAAQ;EAC5B,CAAC;CACH;;;;;;;;CASA,MAAM,QAAQ,MAAc,UAA0B,CAAC,GAAoB;EAEzE,MAAM,WAAwB,CAC5B,GAAI,QAAQ,WAAW,CAAC,GACxB;GAAE,MAAM,QAAQ,QAAQ;GAAQ,SAAS;EAAK,CAChD;EAuBA,QAAO,MArBgB,KAAK,KAAK,UAAU;GACzC,OAAO,QAAQ;GACf,WAAW,QAAQ;GACnB,aAAa,QAAQ;GACrB,MAAM,QAAQ;GACd,MAAM,QAAQ;GACd,QAAQ,QAAQ;GAChB,kBAAkB,QAAQ;GAC1B,iBAAiB,QAAQ;GACzB,gBAAgB,QAAQ;GACxB,MAAM,QAAQ;GACd,OAAO,QAAQ;GACf,YAAY,QAAQ;GACpB,YAAY,QAAQ;GACpB,QAAQ,QAAQ;GAChB,SAAS,QAAQ;GACjB,WAAW,QAAQ;GACnB,WAAW,QAAQ;GACnB,kBAAkB,QAAQ;EAC5B,CAAC,EAAA,CAEe;CAClB;CAEA,MAAM,MACJ,MACA,UAA4B,CAAC,GACD;EAC5B,MAAM,YAAY,KAAK,IAAI;EAC3B,IAAI;GACF,MAAM,QAAQ,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,IAAI;GAChD,MAAM,QAAQ,QAAQ,SAAS;GAE/B,MAAM,WAAW,MAAM,KAAK,YAAY,WAAW,SAAS;IAC1D,QAAQ;IACR,SAAS;KACP,WAAW,KAAK,QAAQ;KACxB,gBAAgB,KAAK,QAAQ;IAC/B;GACF,CAAC;GAGD,IAAI;GACJ,IAAI,MAAM,QAAQ,QAAQ,KAAK,MAAM,QAAQ,SAAS,EAAE,GAEtD,aAAa,MAAM,QAAQ,IAAI,IAAI,WAAW,CAAC,SAAS,EAAE;QACrD,IACL,YACA,OAAO,aAAa,YACpB,SAAS,YAGT,aAAa,SAAS;QAEtB,MAAM,IAAI,QACR,qCACA,oBACA,aACF;GAGF,UACE,KAAK,SACL,eACA,SACA,OACA,KAAA,GACA,WACA,QAAQ,SACV;GAEA,OAAO;IACL;IACA;GACF;EACF,SAAS,OAAO;GACd,MAAM,KAAK,SAAS,KAAK;EAC3B;CACF;CAEA,MAAM,WACJ,QACA,WAAkC,CAAC,GACP;EAC5B,MAAM,IAAI,QACR,wEACA,mBACA,aACF;CACF;CAEA,MAAM,cACJ,QACA,SACA,WAAoC,CAAC,GACpB;EACjB,MAAM,IAAI,QACR,gFACA,mBACA,aACF;CACF;CAEA,MAAM,cACJ,SACA,WAAmC,CAAC,GACF;EAElC,MAAM,IAAI,QACR,+EACA,mBACA,aACF;CACF;CAEA,OAAO,OACL,UACA,UAAuB,CAAC,GACD;EAGvB,MAAM,YAAY,KAAK,IAAI;EAO3B,MAAM,WAAU,MANO,KAAK,KAAK,UAAU;GACzC,GAAG;GACH,YAAY;EACd,CAAQ,EAAA,CAGiB;EACzB,MAAM,YAAY;EAElB,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK,WAAW;GAClD,IAAI,QAAQ,QAAQ,SAClB,MAAM,IAAI,QACR,gCACA,cACA,eACA,QAAQ,KACV;GAEF,MAAM,QAAQ,QAAQ,MAAM,GAAG,IAAI,SAAS;GAC5C,IAAI,QAAQ,YACV,QAAQ,WAAW,KAAK;GAE1B,MAAM;GAGN,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,EAAE,CAAC;EACxD;EAEA,MAAM,QAAQ,QAAQ,SAAS,KAAK,QAAQ,gBAAgB;EAC5D,UACE,KAAK,SACL,eACA,UACA,OACA,KAAA,GACA,WACA,QAAQ,SACV;CACF;CAEA,MAAM,YAAY,MAA+B;EAE/C,OAAO,KAAK,KAAK,KAAK,SAAS,CAAC;CAClC;CAEA,MAAM,YAAgC;EAEpC,OAAO;GACL;IACE,IAAI;IACJ,MAAM;IACN,aAAa;IACb,eAAe;IACf,cAAc,CAAC,QAAQ,MAAM;IAC7B,mBAAmB;IACnB,gBAAgB;GAClB;GACA;IACE,IAAI;IACJ,MAAM;IACN,aAAa;IACb,eAAe;IACf,cAAc,CAAC,QAAQ,MAAM;IAC7B,mBAAmB;IACnB,gBAAgB;GAClB;GACA;IACE,IAAI;IACJ,MAAM;IACN,aAAa;IACb,eAAe;IACf,cAAc,CAAC,QAAQ,MAAM;IAC7B,mBAAmB;IACnB,gBAAgB;GAClB;GACA;IACE,IAAI;IACJ,MAAM;IACN,aAAa;IACb,eAAe;IACf,cAAc,CAAC,QAAQ,YAAY;IACnC,mBAAmB;IACnB,gBAAgB;GAClB;GACA;IACE,IAAI;IACJ,MAAM;IACN,aAAa;IACb,eAAe;IACf,cAAc,CAAC,YAAY;IAC3B,mBAAmB;IACnB,gBAAgB;GAClB;EACF;CACF;CAEA,MAAM,kBAA2C;EAC/C,OAAO;GACL,MAAM;GACN,YAAY;GACZ,YAAY;GACZ,WAAW;GACX,WAAW;GACX,QAAQ;GACR,YAAY;GACZ,iBAAiB;GACjB,iBAAiB;GACjB,iBAAiB;GACjB,KAAK;GACL,cAAc;GACd,aAAa;GACb,kBAAkB;GAClB,qBAAqB;IAAC;IAAQ;IAAc;IAAa;GAAW;EACtE;CACF;CAOA,MAAM,yBACJ,UAC6B;EAC7B,MAAM,IAAI,QACR,8HACA,mBACA,aACF;CACF;CAEA,MAAM,sBACJ,SACsC;EACtC,MAAM,IAAI,QACR,8HACA,mBACA,aACF;CACF;CAEA,MAAM,2BACJ,SACgC;EAChC,MAAM,IAAI,QACR,8HACA,mBACA,aACF;CACF;CAEA,MAAM,yBAAyB,SAA4C;EACzE,MAAM,IAAI,QACR,8HACA,mBACA,aACF;CACF;CAEA,MAAM,gCAAkD;EACtD,MAAM,IAAI,QACR,8HACA,mBACA,aACF;CACF;CAMA,MAAM,iBACJ,OACA,UACsB;EACtB,MAAM,IAAI,QACR,yEACA,mBACA,aACF;CACF;CAEA,aAAa,OAAe,UAA8C;EACxE,MAAM,QAAQ,IAAI,QAChB,mFACA,mBACA,aACF;EACA,OAAO,GACJ,OAAO,uBAAuB,EAC7B,YAAY,QAAQ,OAAO,KAAK,EAClC,GACF;CACF;CAEA,MAAM,WAAW,UAA6C;EAC5D,MAAM,IAAI,QACR,mFACA,mBACA,aACF;CACF;CAEA,MAAM,YAAY,UAA8C;EAC9D,MAAM,IAAI,QACR,kFACA,mBACA,aACF;CACF;CAEA,MAAM,UAAU,UAA+C;EAC7D,MAAM,IAAI,QACR,mFACA,mBACA,aACF;CACF;CAEA,iBAAyB,UAA+B;EAEtD,OAAO,GAAG,SACP,KAAK,YAAY;GAChB,MAAM,cAAc,mBAAmB,QAAQ,OAAO;GACtD,QAAQ,QAAQ,MAAhB;IACE,KAAK,UACH,OAAO,WAAW;IACpB,KAAK,QACH,OAAO,UAAU;IACnB,KAAK,aACH,OAAO,cAAc;IACvB,SACE,OAAO;GACX;EACF,CAAC,CAAC,CACD,KAAK,IAAI,EAAE;CAChB;CAEA,MAAc,YACZ,UACA,MACA,QACc;EACd,MAAM,MAAM,GAAG,KAAK,UAAU;EAE9B,MAAM,WAAW,MAAM,MAAM,KAAK;GAChC,QAAQ;GACR,SAAS;IACP,eAAe,UAAU,KAAK,QAAQ;IACtC,gBAAgB;IAChB,GAAG,KAAK,QAAQ;GAClB;GACA,MAAM,KAAK,UAAU,IAAI;GACzB;EACF,CAAC;EAED,IAAI,CAAC,SAAS,IAAI;GAChB,MAAM,YAAY,MAAM,SAAS,KAAK;GACtC,MAAM,IAAI,MAAM,QAAQ,SAAS,OAAO,IAAI,WAAW;EACzD;EAEA,OAAO,SAAS,KAAK;CACvB;CAEA,SAAiB,OAAyB;EACxC,IAAI,iBAAiB,SACnB,OAAO;EAGT,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;EAGzD,IAAI,QAAQ,SAAS,KAAK,KAAK,QAAQ,SAAS,cAAc,GAC5D,OAAO,IAAI,oBAAoB,aAAa;EAG9C,IAAI,QAAQ,SAAS,KAAK,KAAK,QAAQ,SAAS,YAAY,GAC1D,OAAO,mBAAmB,eAAe,KAAK;EAGhD,IAAI,QAAQ,SAAS,KAAK,KAAK,QAAQ,SAAS,WAAW,GACzD,OAAO,IAAI,mBAAmB,SAAS,aAAa;EAGtD,IAAI,QAAQ,SAAS,KAAK,KAAK,QAAQ,SAAS,WAAW,GACzD,OAAO,IAAI,mBAAmB,aAAa;EAG7C,OAAO,IAAI,QAAQ,SAAS,iBAAiB,aAAa;CAC5D;AACF"}
1
+ {"version":3,"file":"huggingface-jqjeFPdr.js","names":[],"sources":["../../src/shared/providers/huggingface.ts"],"sourcesContent":["/**\n * Hugging Face provider implementation\n */\n\nimport { rateLimitErrorFrom } from '../rate-limit';\nimport {\n normalizeBaseAIOptions,\n normalizeChatOptions,\n type PreparedRequestControls,\n prepareRequestControls,\n} from '../safety';\nimport type {\n AICapabilities,\n AIInterface,\n AIMessage,\n AIModel,\n AIResponse,\n ChatOptions,\n CompletionOptions,\n EmbeddingOptions,\n EmbeddingResponse,\n HuggingFaceOptions,\n ImageDescriptionOptions,\n ImageEmbeddingOptions,\n ImageGenerationOptions,\n ImageGenerationResponse,\n MessageOptions,\n TokenUsage,\n TTSOptions,\n TTSResponse,\n VideoGenerationJob,\n VideoGenerationOptions,\n VideoGenerationResult,\n VideoGenerationStatusResult,\n Voice,\n VoiceCloneOptions,\n VoiceDesignOptions,\n VoiceListOptions,\n} from '../types';\nimport {\n AIError,\n AuthenticationError,\n ContextLengthError,\n extractTextContent,\n ModelNotFoundError,\n} from '../types';\nimport { emitUsage } from './usage';\n\nexport class HuggingFaceProvider implements AIInterface {\n private options: HuggingFaceOptions;\n private baseUrl: string;\n\n constructor(options: HuggingFaceOptions) {\n this.options = normalizeBaseAIOptions({\n defaultModel: 'microsoft/DialoGPT-medium',\n useCache: true,\n waitForModel: true,\n ...options,\n });\n\n this.baseUrl =\n this.options.endpoint || 'https://api-inference.huggingface.co';\n }\n\n async chat(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): Promise<AIResponse> {\n const startTime = Date.now();\n let controls: PreparedRequestControls | undefined;\n try {\n // Convert messages to a single prompt for text generation models\n const prompt = this.messagesToPrompt(messages);\n const model =\n options.model || this.options.model || this.options.defaultModel;\n options = normalizeChatOptions(\n this.options,\n options,\n 'huggingface',\n model,\n );\n controls = prepareRequestControls(this.options, options);\n\n const response = await this.makeRequest(\n `/models/${model}`,\n {\n inputs: prompt,\n parameters: {\n max_new_tokens: options.maxTokens,\n temperature: options.temperature ?? 1.0,\n top_p: options.topP ?? 1.0,\n do_sample:\n (options.temperature && options.temperature > 0) || false,\n stop_sequences: Array.isArray(options.stop)\n ? options.stop\n : options.stop\n ? [options.stop]\n : undefined,\n },\n options: {\n use_cache: this.options.useCache,\n wait_for_model: this.options.waitForModel,\n },\n },\n controls.signal,\n );\n\n if (Array.isArray(response) && response[0]?.generated_text) {\n const generatedText = response[0].generated_text;\n // Remove the input prompt from the response\n const content = generatedText.replace(prompt, '').trim();\n\n emitUsage(\n this.options,\n 'huggingface',\n 'chat',\n model!,\n undefined,\n startTime,\n options.usageTags,\n );\n\n return {\n content,\n model,\n finishReason: 'stop',\n };\n }\n\n throw new AIError(\n 'Invalid response format from Hugging Face',\n 'INVALID_RESPONSE',\n 'huggingface',\n );\n } catch (error) {\n if (controls?.didTimeout()) {\n throw new AIError(\n `AI request timed out after ${controls.timeout}ms`,\n 'AI_TIMEOUT',\n 'huggingface',\n options.model,\n );\n }\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'huggingface',\n options.model,\n );\n }\n throw this.mapError(error);\n } finally {\n controls?.cleanup();\n }\n }\n\n async complete(\n prompt: string,\n options: CompletionOptions = {},\n ): Promise<AIResponse> {\n return this.chat([{ role: 'user', content: prompt }], {\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n n: options.n,\n stop: options.stop,\n stream: options.stream,\n onProgress: options.onProgress,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n continueOnLength: options.continueOnLength,\n });\n }\n\n /**\n * Simple message interface for single-turn interactions with optional history\n *\n * @param text - The message text to send\n * @param options - Configuration options including history, model, etc.\n * @returns Promise resolving to the response content string\n */\n async message(text: string, options: MessageOptions = {}): Promise<string> {\n // Build messages array from history + current message\n const messages: AIMessage[] = [\n ...(options.history || []),\n { role: options.role || 'user', content: text },\n ];\n\n const response = await this.chat(messages, {\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n stop: options.stop,\n stream: options.stream,\n frequencyPenalty: options.frequencyPenalty,\n presencePenalty: options.presencePenalty,\n responseFormat: options.responseFormat,\n seed: options.seed,\n tools: options.tools,\n toolChoice: options.toolChoice,\n onProgress: options.onProgress,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n continueOnLength: options.continueOnLength,\n });\n\n return response.content;\n }\n\n async embed(\n text: string | string[],\n options: EmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n const startTime = Date.now();\n try {\n const input = Array.isArray(text) ? text : [text];\n const model = options.model || 'sentence-transformers/all-MiniLM-L6-v2';\n\n const response = await this.makeRequest(`/models/${model}`, {\n inputs: input,\n options: {\n use_cache: this.options.useCache,\n wait_for_model: this.options.waitForModel,\n },\n });\n\n // Handle different response formats from different embedding models\n let embeddings: number[][];\n if (Array.isArray(response) && Array.isArray(response[0])) {\n // Direct array of embeddings\n embeddings = Array.isArray(text) ? response : [response[0]];\n } else if (\n response &&\n typeof response === 'object' &&\n response.embeddings\n ) {\n // Response with embeddings property\n embeddings = response.embeddings;\n } else {\n throw new AIError(\n 'Invalid embedding response format',\n 'INVALID_RESPONSE',\n 'huggingface',\n );\n }\n\n emitUsage(\n this.options,\n 'huggingface',\n 'embed',\n model,\n undefined,\n startTime,\n options.usageTags,\n );\n\n return {\n embeddings,\n model,\n };\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async embedImage(\n _image: string | Buffer,\n _options: ImageEmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n throw new AIError(\n 'Hugging Face image embeddings not implemented. Use OpenAI or Gemini.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async describeImage(\n _image: string | Buffer,\n _prompt?: string,\n _options: ImageDescriptionOptions = {},\n ): Promise<string> {\n throw new AIError(\n 'Image description is not implemented for Hugging Face. Use OpenAI or Gemini.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async generateImage(\n _prompt: string,\n _options: ImageGenerationOptions = {},\n ): Promise<ImageGenerationResponse> {\n // Note: Hugging Face has image generation models (Stable Diffusion), but we're keeping this as a stub\n throw new AIError(\n 'Image generation is not implemented for Hugging Face. Use OpenAI or Gemini.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async *stream(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): AsyncIterable<string> {\n // Hugging Face Inference API doesn't support streaming for most models\n // Fall back to regular completion and yield the result\n const startTime = Date.now();\n const response = await this.chat(messages, {\n ...options,\n _skipUsage: true,\n } as any);\n\n // Simulate streaming by yielding chunks\n const content = response.content;\n const chunkSize = 10;\n\n for (let i = 0; i < content.length; i += chunkSize) {\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'huggingface',\n options.model,\n );\n }\n const chunk = content.slice(i, i + chunkSize);\n if (options.onProgress) {\n options.onProgress(chunk);\n }\n yield chunk;\n\n // Add small delay to simulate streaming\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n\n const model = options.model || this.options.defaultModel || 'gpt2';\n emitUsage(\n this.options,\n 'huggingface',\n 'stream',\n model,\n undefined,\n startTime,\n options.usageTags,\n );\n }\n\n async countTokens(text: string): Promise<number> {\n // Approximation - Hugging Face models use different tokenizers\n return Math.ceil(text.length / 4);\n }\n\n async getModels(): Promise<AIModel[]> {\n // Return some popular text generation models available on Hugging Face\n return [\n {\n id: 'microsoft/DialoGPT-medium',\n name: 'DialoGPT Medium',\n description: 'Conversational AI model by Microsoft',\n contextLength: 1024,\n capabilities: ['text', 'chat'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: 'microsoft/DialoGPT-large',\n name: 'DialoGPT Large',\n description: 'Large conversational AI model by Microsoft',\n contextLength: 1024,\n capabilities: ['text', 'chat'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: 'facebook/blenderbot-400M-distill',\n name: 'BlenderBot 400M',\n description: 'Conversational AI model by Meta',\n contextLength: 512,\n capabilities: ['text', 'chat'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: 'gpt2',\n name: 'GPT-2',\n description: 'OpenAI GPT-2 model',\n contextLength: 1024,\n capabilities: ['text', 'completion'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: 'sentence-transformers/all-MiniLM-L6-v2',\n name: 'All-MiniLM-L6-v2',\n description: 'Sentence embedding model',\n contextLength: 512,\n capabilities: ['embeddings'],\n supportsFunctions: false,\n supportsVision: false,\n },\n ];\n }\n\n async getCapabilities(): Promise<AICapabilities> {\n return {\n chat: true,\n completion: true,\n embeddings: true,\n streaming: true,\n functions: false, // Most HF models don't support function calling\n vision: false, // Limited vision model support\n fineTuning: true, // Via Hugging Face training API\n imageEmbeddings: false,\n imageGeneration: false, // Stable Diffusion exists but not implemented\n videoGeneration: false,\n tts: false,\n voiceCloning: false,\n voiceDesign: false,\n maxContextLength: 2048,\n supportedOperations: ['chat', 'completion', 'embedding', 'streaming'],\n };\n }\n\n // ============================================================================\n // Video Generation Methods (Not supported - use gemini, byteplus-modelark,\n // or openai-compat-video provider)\n // ============================================================================\n\n async submitVideoGenerationJob(\n _options: VideoGenerationOptions,\n ): Promise<VideoGenerationJob> {\n throw new AIError(\n 'Video generation is not supported by HuggingFace provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async getVideoGenerationJob(\n _handle: VideoGenerationJob,\n ): Promise<VideoGenerationStatusResult> {\n throw new AIError(\n 'Video generation is not supported by HuggingFace provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async fetchVideoGenerationResult(\n _handle: VideoGenerationJob,\n ): Promise<VideoGenerationResult> {\n throw new AIError(\n 'Video generation is not supported by HuggingFace provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async cancelVideoGenerationJob(_handle: VideoGenerationJob): Promise<void> {\n throw new AIError(\n 'Video generation is not supported by HuggingFace provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async validateVideoGenerationAccess(): Promise<boolean> {\n throw new AIError(\n 'Video generation is not supported by HuggingFace provider. Use gemini, byteplus-modelark, or openai-compat-video provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n // ============================================================================\n // TTS Methods (Not supported - use Qwen3-TTS provider)\n // ============================================================================\n\n async synthesizeSpeech(\n _text: string,\n _options?: TTSOptions,\n ): Promise<TTSResponse> {\n throw new AIError(\n 'TTS is not supported by HuggingFace provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n streamSpeech(_text: string, _options?: TTSOptions): AsyncIterable<Buffer> {\n const error = new AIError(\n 'TTS streaming is not supported by HuggingFace provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n return {\n [Symbol.asyncIterator]: () => ({\n next: () => Promise.reject(error),\n }),\n };\n }\n\n async cloneVoice(_options: VoiceCloneOptions): Promise<Voice> {\n throw new AIError(\n 'Voice cloning is not supported by HuggingFace provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async designVoice(_options: VoiceDesignOptions): Promise<Voice> {\n throw new AIError(\n 'Voice design is not supported by HuggingFace provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async getVoices(_options?: VoiceListOptions): Promise<Voice[]> {\n throw new AIError(\n 'Voice listing is not supported by HuggingFace provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n private messagesToPrompt(messages: AIMessage[]): string {\n // Convert chat messages to a single prompt format\n return `${messages\n .map((message) => {\n const textContent = extractTextContent(message.content);\n switch (message.role) {\n case 'system':\n return `System: ${textContent}`;\n case 'user':\n return `Human: ${textContent}`;\n case 'assistant':\n return `Assistant: ${textContent}`;\n default:\n return textContent;\n }\n })\n .join('\\n')}\\nAssistant:`;\n }\n\n private async makeRequest(\n endpoint: string,\n data: any,\n signal?: AbortSignal,\n ): Promise<any> {\n const url = `${this.baseUrl}${endpoint}`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.options.apiToken}`,\n 'Content-Type': 'application/json',\n ...this.options.headers,\n },\n body: JSON.stringify(data),\n signal,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n return response.json();\n }\n\n private mapError(error: unknown): AIError {\n if (error instanceof AIError) {\n return error;\n }\n\n const message = error instanceof Error ? error.message : 'Unknown error';\n\n // Map common HTTP status codes\n if (message.includes('401') || message.includes('Unauthorized')) {\n return new AuthenticationError('huggingface');\n }\n\n if (message.includes('429') || message.includes('rate limit')) {\n return rateLimitErrorFrom('huggingface', error);\n }\n\n if (message.includes('404') || message.includes('not found')) {\n return new ModelNotFoundError(message, 'huggingface');\n }\n\n if (message.includes('413') || message.includes('too large')) {\n return new ContextLengthError('huggingface');\n }\n\n return new AIError(message, 'UNKNOWN_ERROR', 'huggingface');\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { f as AuthenticationError, l as prepareRequestControls, o as normalizeBaseAIOptions, t as emitUsage, u as AIError } from "./usage-B9gPCWSa.js";
2
- import { n as rateLimitErrorFrom } from "./rate-limit-BkK4-hXY.js";
1
+ import { f as AuthenticationError, l as prepareRequestControls, o as normalizeBaseAIOptions, t as emitUsage, u as AIError } from "./usage-DS7uDhi1.js";
2
+ import { n as rateLimitErrorFrom } from "./rate-limit-Dwyde1BY.js";
3
3
  import { ValidationError } from "@happyvertical/utils";
4
4
  //#region src/shared/providers/laya.ts
5
5
  /**
@@ -468,4 +468,4 @@ var LayaProvider = class {
468
468
  //#endregion
469
469
  export { LayaProvider };
470
470
 
471
- //# sourceMappingURL=laya-D-P82D0h.js.map
471
+ //# sourceMappingURL=laya-D8o5TEO7.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"laya-D-P82D0h.js","names":[],"sources":["../../src/shared/providers/laya.ts"],"sourcesContent":["/**\n * Laya typed-decision provider.\n *\n * Laya (https://github.com/NandhaKishorM/laya) is a self-hosted,\n * non-autoregressive decision engine. Its `laya-serve` HTTP server answers the\n * Jev `POST /v1/systemone` wire shape, with differences this adapter handles\n * itself rather than inheriting from the TypeSafe adapter: optional auth, a\n * checkpoint chosen by the server's router, a `max_len` token window,\n * probabilities rounded to four decimals one at a time, and truncation facts.\n *\n * The public SDK contract calls Laya's `noul` primitive a `predicate`; the\n * server's vocabulary stays confined to this wire translation.\n */\n\nimport { ValidationError } from '@happyvertical/utils';\n\nimport { rateLimitErrorFrom } from '../rate-limit';\nimport { normalizeBaseAIOptions, prepareRequestControls } from '../safety';\nimport type {\n AICapabilities,\n AIInterface,\n AIMessage,\n AIModel,\n AIResponse,\n ChatOptions,\n CompletionOptions,\n DecisionAnswer,\n DecisionQuestion,\n DecisionRequest,\n DecisionResult,\n DecisionValue,\n EmbeddingOptions,\n EmbeddingResponse,\n ImageDescriptionOptions,\n ImageEmbeddingOptions,\n ImageGenerationOptions,\n ImageGenerationResponse,\n LayaDecisionOptions,\n LayaOptions,\n MessageOptions,\n ScoreDecisionQuestion,\n TTSOptions,\n TTSResponse,\n VideoGenerationJob,\n VideoGenerationOptions,\n VideoGenerationResult,\n VideoGenerationStatusResult,\n Voice,\n VoiceCloneOptions,\n VoiceDesignOptions,\n VoiceListOptions,\n} from '../types';\nimport { AIError, AuthenticationError } from '../types';\nimport { emitUsage } from './usage';\n\nconst PROVIDER = 'laya';\n\n/** Distributions this close to unit mass are used exactly as received. */\nconst STRICT_DISTRIBUTION_EPSILON = 1e-6;\n/**\n * `laya-serve` rounds every probability to four decimals on its own, so each\n * value is off by at most half of the last place and a distribution of `n`\n * values can be off by `n * 0.00005`.\n */\nconst ROUNDING_ERROR_PER_VALUE = 5e-5;\n/** No rounding story justifies renormalizing a distribution further out. */\nconst MAX_NORMALIZED_ERROR = 0.01;\n\ntype WireQuestion =\n | {\n type: 'noul';\n instructions: DecisionValue;\n criteria?: Record<string, DecisionValue>;\n }\n | {\n type: 'choice';\n instructions: DecisionValue;\n criteria: Record<string, DecisionValue | null>;\n }\n | { type: 'score'; instructions: DecisionValue; criteria: DecisionValue[] };\n\ninterface WireRequest {\n state: DecisionValue;\n questions: Record<string, WireQuestion>;\n model?: string;\n max_len?: number;\n}\n\ninterface WireResponse {\n model?: unknown;\n answers?: unknown;\n usage?: unknown;\n routing?: unknown;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction invalid(message: string): AIError {\n return new AIError(`Laya response ${message}`, 'INVALID_RESPONSE', PROVIDER);\n}\n\nfunction finite(value: unknown, field: string): number {\n if (typeof value !== 'number' || !Number.isFinite(value))\n throw invalid(`${field} must be finite`);\n return value;\n}\n\nfunction probability(value: unknown, field: string): number {\n const result = finite(value, field);\n if (result < 0 || result > 1)\n throw invalid(`${field} must be between 0 and 1`);\n return result;\n}\n\nfunction tokenCount(value: unknown, field: string): number {\n const result = finite(value, field);\n if (!Number.isSafeInteger(result) || result < 0)\n throw invalid(`${field} must be a non-negative integer`);\n return result;\n}\n\nfunction optionalString(\n source: Record<string, unknown>,\n key: string,\n field: string,\n): string | undefined {\n const value = source[key];\n if (value === undefined) return undefined;\n if (typeof value !== 'string' || !value)\n throw invalid(`${field} must be a non-empty string`);\n return value;\n}\n\nfunction sameDecisionValue(left: DecisionValue, right: unknown): boolean {\n if (left === right) return true;\n if (Array.isArray(left)) {\n return (\n Array.isArray(right) &&\n left.length === right.length &&\n left.every((value, index) => sameDecisionValue(value, right[index]))\n );\n }\n if (isRecord(left)) {\n return (\n isRecord(right) &&\n Object.keys(left).length === Object.keys(right).length &&\n Object.entries(left).every(\n ([key, value]) => key in right && sameDecisionValue(value, right[key]),\n )\n );\n }\n return false;\n}\n\n/**\n * `laya-serve` returns a rubric level in `legend` as sent when it is a string\n * and as Python's `json.dumps` text when it is anything else.\n */\nfunction legendMatches(level: DecisionValue, legend: unknown): boolean {\n if (sameDecisionValue(level, legend)) return true;\n if (typeof level === 'string' || typeof legend !== 'string') return false;\n try {\n return sameDecisionValue(level, JSON.parse(legend));\n } catch {\n return false;\n }\n}\n\nfunction validateValue(\n value: unknown,\n field: string,\n): asserts value is DecisionValue {\n if (value === null || typeof value === 'string' || typeof value === 'boolean')\n return;\n if (typeof value === 'number') {\n if (!Number.isFinite(value))\n throw new ValidationError(`${field} must contain finite numbers`, {\n provider: PROVIDER,\n });\n return;\n }\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n validateValue(item, `${field}[${index}]`);\n });\n return;\n }\n if (isRecord(value)) {\n Object.entries(value).forEach(([key, item]) => {\n validateValue(item, `${field}.${key}`);\n });\n return;\n }\n throw new ValidationError(`${field} must be JSON-compatible`, {\n provider: PROVIDER,\n });\n}\n\nfunction validateMaxLen(value: unknown, field: string): number | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== 'number' || !Number.isSafeInteger(value) || value <= 0)\n throw new ValidationError(`${field} must be a positive integer`, {\n provider: PROVIDER,\n });\n return value;\n}\n\n/**\n * Checks the provider-neutral request shape. Laya's own size limits (questions\n * per request, options per question, state length) are left to the server,\n * which reports them as explicit 413 errors.\n */\nfunction validateRequest(request: DecisionRequest): void {\n if (request.state === null || request.state === undefined)\n throw new ValidationError('state is required', { provider: PROVIDER });\n validateValue(request.state, 'state');\n const entries = Object.entries(request.questions || {});\n if (entries.length === 0)\n throw new ValidationError('questions must not be empty', {\n provider: PROVIDER,\n });\n for (const [id, question] of entries) {\n if (!id.trim())\n throw new ValidationError('question IDs must not be empty', {\n provider: PROVIDER,\n });\n validateValue(question.instructions, `questions.${id}.instructions`);\n if (question.type === 'predicate') {\n if (question.criteria) {\n for (const [key, value] of Object.entries(question.criteria))\n validateValue(value, `questions.${id}.criteria.${key}`);\n }\n } else if (question.type === 'choice') {\n const options = Object.keys(question.criteria || {});\n if (options.length === 0)\n throw new ValidationError(\n `questions.${id}.criteria must contain at least one option`,\n { provider: PROVIDER },\n );\n for (const [key, value] of Object.entries(question.criteria))\n if (value !== null)\n validateValue(value, `questions.${id}.criteria.${key}`);\n } else if (question.type === 'score') {\n if (!Array.isArray(question.criteria) || question.criteria.length < 2)\n throw new ValidationError(\n `questions.${id}.criteria must contain at least 2 ordered levels`,\n { provider: PROVIDER },\n );\n question.criteria.forEach((value, index) => {\n // Laya rejects a null level because its legend entry would be null.\n if (value === null)\n throw new ValidationError(\n `questions.${id}.criteria[${index}] must describe the level`,\n { provider: PROVIDER },\n );\n validateValue(value, `questions.${id}.criteria[${index}]`);\n });\n } else {\n throw new ValidationError(`questions.${id}.type is unsupported`, {\n provider: PROVIDER,\n });\n }\n }\n}\n\n/**\n * Builds each wire question field by field so unknown properties on a caller's\n * object (for example a generation control) are never forwarded.\n */\nfunction wireQuestion(question: DecisionQuestion): WireQuestion {\n if (question.type === 'predicate')\n return {\n type: 'noul',\n instructions: question.instructions,\n ...(question.criteria ? { criteria: question.criteria } : {}),\n };\n if (question.type === 'choice')\n return {\n type: 'choice',\n instructions: question.instructions,\n criteria: question.criteria,\n };\n return {\n type: 'score',\n instructions: question.instructions,\n criteria: question.criteria,\n };\n}\n\n/** Resolves the server root from a base URL that may carry the API path. */\nfunction serverRoot(value: string | undefined): string {\n const text = (value || '').trim();\n if (!text)\n throw new ValidationError(\n 'Laya requires baseUrl, for example http://localhost:8000',\n { provider: PROVIDER },\n );\n let url: URL;\n try {\n url = new URL(text);\n } catch {\n throw new ValidationError('Laya baseUrl must be an absolute http(s) URL', {\n provider: PROVIDER,\n });\n }\n if (url.protocol !== 'http:' && url.protocol !== 'https:')\n throw new ValidationError('Laya baseUrl must be an absolute http(s) URL', {\n provider: PROVIDER,\n });\n if (url.search || url.hash || url.username || url.password)\n throw new ValidationError(\n 'Laya baseUrl must not contain credentials, a query, or a fragment',\n { provider: PROVIDER },\n );\n const path = url.pathname\n .replace(/\\/+$/, '')\n .replace(/\\/v1(\\/systemone)?$/, '');\n return `${url.origin}${path}`;\n}\n\ninterface Distribution {\n values: Record<string, number>;\n /** The values as received, set only when they were renormalized. */\n raw?: Record<string, number>;\n}\n\n/**\n * Validates a choice or score distribution. Mass within the four-decimal\n * rounding bound is normalized by its actual sum; anything else is rejected.\n */\nfunction distribution(\n value: unknown,\n expected: string[],\n field: string,\n): Distribution {\n if (\n !isRecord(value) ||\n Object.keys(value).length !== expected.length ||\n expected.some((key) => !(key in value))\n )\n throw invalid(`${field} must cover exactly the requested values`);\n const values = Object.fromEntries(\n expected.map((key) => [key, probability(value[key], `${field}.${key}`)]),\n );\n const sum = Object.values(values).reduce((total, item) => total + item, 0);\n const drift = Math.abs(sum - 1);\n if (drift <= STRICT_DISTRIBUTION_EPSILON) return { values };\n const allowed =\n Math.min(expected.length * ROUNDING_ERROR_PER_VALUE, MAX_NORMALIZED_ERROR) +\n STRICT_DISTRIBUTION_EPSILON;\n if (sum <= 0 || drift > allowed) throw invalid(`${field} must sum to 1`);\n return {\n values: Object.fromEntries(\n Object.entries(values).map(([key, item]) => [key, item / sum]),\n ),\n raw: values,\n };\n}\n\nfunction answer(\n question: DecisionQuestion,\n raw: unknown,\n id: string,\n renormalized: Record<string, Record<string, number>>,\n): DecisionAnswer {\n if (!isRecord(raw)) throw invalid(`answers.${id} must be an object`);\n if (question.type === 'predicate') {\n if (raw.type !== 'noul')\n throw invalid(`answers.${id} type does not match predicate`);\n return {\n type: 'predicate',\n probability: probability(raw.noul, `answers.${id}.noul`),\n };\n }\n if (raw.type !== question.type)\n throw invalid(`answers.${id} type does not match request`);\n if (question.type === 'choice') {\n const choices = Object.keys(question.criteria);\n if (typeof raw.choice !== 'string' || !choices.includes(raw.choice))\n throw invalid(`answers.${id}.choice is not a requested option`);\n const probabilities = distribution(\n raw.probabilities,\n choices,\n `answers.${id}.probabilities`,\n );\n if (probabilities.raw) renormalized[id] = probabilities.raw;\n return {\n type: 'choice',\n choice: raw.choice,\n probabilities: probabilities.values,\n confidence: probability(raw.confidence, `answers.${id}.confidence`),\n };\n }\n const levels = (question as ScoreDecisionQuestion).criteria;\n const levelKeys = levels.map((_, index) => String(index));\n const score = finite(raw.score, `answers.${id}.score`);\n if (score < 0 || score > levels.length - 1)\n throw invalid(`answers.${id}.score is outside the requested rubric`);\n const legend = raw.legend;\n if (\n !isRecord(legend) ||\n levelKeys.some((key, index) => !legendMatches(levels[index], legend[key]))\n )\n throw invalid(`answers.${id}.legend does not match the requested rubric`);\n const probabilities = distribution(\n raw.probabilities,\n levelKeys,\n `answers.${id}.probabilities`,\n );\n if (probabilities.raw) renormalized[id] = probabilities.raw;\n return {\n type: 'score',\n score,\n probabilities: probabilities.values,\n confidence: probability(raw.confidence, `answers.${id}.confidence`),\n levels,\n };\n}\n\n/** A decision-only adapter for a `laya-serve` `/v1/systemone` endpoint. */\nexport class LayaProvider implements AIInterface {\n private readonly options: LayaOptions;\n private readonly root: string;\n private readonly maxLen?: number;\n\n constructor(options: LayaOptions) {\n this.root = serverRoot(options.baseUrl);\n this.maxLen = validateMaxLen(options.maxLen, 'maxLen');\n this.options = normalizeBaseAIOptions({ ...options, baseUrl: this.root });\n }\n\n async decide(\n request: DecisionRequest,\n options: LayaDecisionOptions = {},\n ): Promise<DecisionResult> {\n validateRequest(request);\n const maxLen = validateMaxLen(options.maxLen, 'maxLen') ?? this.maxLen;\n const controls = prepareRequestControls(this.options, options);\n const startedAt = Date.now();\n const requestedModel =\n options.model || this.options.defaultModel || undefined;\n const wire: WireRequest = {\n state: request.state,\n questions: Object.fromEntries(\n Object.entries(request.questions).map(([id, question]) => [\n id,\n wireQuestion(question),\n ]),\n ),\n ...(requestedModel ? { model: requestedModel } : {}),\n ...(maxLen !== undefined ? { max_len: maxLen } : {}),\n };\n try {\n const response = await fetch(`${this.root}/v1/systemone`, {\n method: 'POST',\n redirect: 'error',\n headers: {\n ...(this.options.apiKey\n ? { Authorization: `Bearer ${this.options.apiKey}` }\n : {}),\n 'Content-Type': 'application/json',\n ...this.options.headers,\n },\n body: JSON.stringify(wire),\n signal: controls.signal,\n });\n if (!response.ok) {\n if (response.status === 401) throw new AuthenticationError(PROVIDER);\n const text = await response.text();\n // 503 is laya-serve's admission limit (LAYA_MAX_CONCURRENT), which\n // sends Retry-After; 429 covers a rate-limiting proxy in front of it.\n if (response.status === 429 || response.status === 503)\n throw rateLimitErrorFrom(\n PROVIDER,\n { headers: response.headers, message: text },\n { model: requestedModel },\n );\n throw new AIError(\n `Laya request failed (${response.status}): ${text.slice(0, 500)}`,\n 'API_ERROR',\n PROVIDER,\n requestedModel,\n response.status >= 500,\n );\n }\n let body: WireResponse;\n try {\n body = (await response.json()) as WireResponse;\n } catch (error) {\n if (error instanceof SyntaxError)\n throw new AIError(\n 'Laya response contained invalid JSON',\n 'INVALID_RESPONSE',\n PROVIDER,\n requestedModel,\n );\n throw error;\n }\n return this.result(\n request,\n body,\n requestedModel,\n maxLen,\n options,\n startedAt,\n );\n } catch (error) {\n if (controls.didTimeout())\n throw new AIError(\n `Laya request timed out after ${controls.timeout}ms`,\n 'REQUEST_TIMEOUT',\n PROVIDER,\n requestedModel,\n true,\n );\n if (controls.signal.aborted && !(error instanceof AIError))\n throw new AIError(\n 'Laya request was aborted',\n 'REQUEST_ABORTED',\n PROVIDER,\n requestedModel,\n );\n if (!(error instanceof AIError)) {\n throw new AIError(\n `Network error calling Laya: ${\n error instanceof Error ? error.message : String(error)\n }`,\n 'NETWORK_ERROR',\n PROVIDER,\n requestedModel,\n true,\n );\n }\n throw error;\n } finally {\n controls.cleanup();\n }\n }\n\n private result(\n request: DecisionRequest,\n body: WireResponse,\n requestedModel: string | undefined,\n maxLen: number | undefined,\n options: LayaDecisionOptions,\n startedAt: number,\n ): DecisionResult {\n if (!isRecord(body)) throw invalid('must be an object');\n // The root `model` names Laya's decision head, not the checkpoint.\n if (typeof body.model !== 'string' || !body.model)\n throw invalid('model is required');\n if (!isRecord(body.answers)) throw invalid('answers is required');\n const responseAnswers = body.answers;\n const ids = Object.keys(request.questions);\n if (\n Object.keys(responseAnswers).length !== ids.length ||\n ids.some((id) => !(id in responseAnswers))\n )\n throw invalid('answers must match requested question IDs');\n const renormalized: Record<string, Record<string, number>> = {};\n const answers = Object.fromEntries(\n ids.map((id) => [\n id,\n answer(request.questions[id], responseAnswers[id], id, renormalized),\n ]),\n );\n\n let usage:\n | { promptTokens: number; completionTokens: number; totalTokens: number }\n | undefined;\n const facts: Record<string, DecisionValue> = {};\n if (body.usage !== undefined) {\n const wireUsage = body.usage;\n if (\n !isRecord(wireUsage) ||\n !('input_tokens' in wireUsage) ||\n !('output_tokens' in wireUsage)\n )\n throw invalid('usage must include input_tokens and output_tokens');\n const input = tokenCount(wireUsage.input_tokens, 'usage.input_tokens');\n const output = tokenCount(wireUsage.output_tokens, 'usage.output_tokens');\n usage = {\n promptTokens: input,\n completionTokens: output,\n totalTokens: input + output,\n };\n // Truncation is invisible anywhere else in the response.\n for (const [key, name] of [\n ['state_tokens', 'stateTokens'],\n ['state_tokens_dropped', 'stateTokensDropped'],\n ] as const)\n if (wireUsage[key] !== undefined)\n facts[name] = tokenCount(wireUsage[key], `usage.${key}`);\n if (wireUsage.truncated !== undefined) {\n if (typeof wireUsage.truncated !== 'boolean')\n throw invalid('usage.truncated must be a boolean');\n facts.truncated = wireUsage.truncated;\n }\n if (wireUsage.truncated_questions !== undefined) {\n const truncated = wireUsage.truncated_questions;\n if (\n !Array.isArray(truncated) ||\n truncated.some((id) => typeof id !== 'string')\n )\n throw invalid('usage.truncated_questions must list question IDs');\n facts.truncatedQuestions = truncated as string[];\n }\n }\n\n let checkpoint: string | undefined;\n if (body.routing !== undefined) {\n if (!isRecord(body.routing)) throw invalid('routing must be an object');\n checkpoint = optionalString(body.routing, 'model', 'routing.model');\n const repo = optionalString(body.routing, 'repo', 'routing.repo');\n const reason = optionalString(body.routing, 'reason', 'routing.reason');\n if (checkpoint) facts.checkpoint = checkpoint;\n if (repo) facts.checkpointRepo = repo;\n if (reason) facts.routeReason = reason;\n }\n\n // The checkpoint that answered is reported only in `routing`, which a\n // server running LAYA_JEV_STRICT omits. Without it, report the decision\n // head and leave `details.checkpoint` unset rather than guess.\n const model = checkpoint || body.model;\n const renormalizedIds = Object.keys(renormalized);\n const details: Record<string, DecisionValue> = {\n serverModel: body.model,\n ...(requestedModel ? { requestedModel } : {}),\n ...(maxLen !== undefined ? { maxLen } : {}),\n ...facts,\n ...(renormalizedIds.length\n ? { renormalized: renormalizedIds, rawProbabilities: renormalized }\n : {}),\n };\n emitUsage(\n this.options,\n PROVIDER,\n 'decide',\n model,\n usage,\n startedAt,\n options.usageTags,\n );\n return {\n model,\n ...(usage ? { usage } : {}),\n provenance: { provider: PROVIDER, model, details },\n answers,\n };\n }\n\n async getModels(): Promise<AIModel[]> {\n // laya-serve has no model-listing route; these are the checkpoints of the\n // convaiinnovations/laya bundle. A server may register others.\n const checkpoints: Array<[string, string, number]> = [\n ['typed-decisions', 'Laya typed decisions (421M)', 1024],\n ['english', 'Laya English (421M)', 512],\n ['multilingual', 'Laya multilingual (322M)', 1024],\n ];\n const configured = this.options.defaultModel;\n const models = checkpoints.map(([id, name, contextLength]) => ({\n id,\n name,\n description: 'Laya typed decisions',\n contextLength,\n capabilities: ['decisions'],\n supportsFunctions: false,\n supportsVision: false,\n }));\n if (configured && !models.some((model) => model.id === configured))\n models.push({\n id: configured,\n name: configured,\n description: 'Laya typed decisions (configured checkpoint)',\n contextLength: 0,\n capabilities: ['decisions'],\n supportsFunctions: false,\n supportsVision: false,\n });\n return models;\n }\n async getCapabilities(): Promise<AICapabilities> {\n return {\n decisions: true,\n chat: false,\n completion: false,\n embeddings: false,\n streaming: false,\n functions: false,\n vision: false,\n fineTuning: false,\n imageEmbeddings: false,\n imageGeneration: false,\n videoGeneration: false,\n tts: false,\n voiceCloning: false,\n voiceDesign: false,\n maxContextLength: 0,\n supportedOperations: ['decide'],\n };\n }\n private unsupported(): never {\n throw new AIError(\n 'This operation is not supported by the Laya decision-only provider.',\n 'NOT_IMPLEMENTED',\n PROVIDER,\n );\n }\n async chat(_a: AIMessage[], _b?: ChatOptions): Promise<AIResponse> {\n return this.unsupported();\n }\n async complete(_a: string, _b?: CompletionOptions): Promise<AIResponse> {\n return this.unsupported();\n }\n async message(_a: string, _b?: MessageOptions): Promise<string> {\n return this.unsupported();\n }\n async embed(\n _a: string | string[],\n _b?: EmbeddingOptions,\n ): Promise<EmbeddingResponse> {\n return this.unsupported();\n }\n async embedImage(\n _a: string | Buffer,\n _b?: ImageEmbeddingOptions,\n ): Promise<EmbeddingResponse> {\n return this.unsupported();\n }\n async describeImage(\n _a: string | Buffer,\n _b?: string,\n _c?: ImageDescriptionOptions,\n ): Promise<string> {\n return this.unsupported();\n }\n async generateImage(\n _a: string,\n _b?: ImageGenerationOptions,\n ): Promise<ImageGenerationResponse> {\n return this.unsupported();\n }\n stream(_a: AIMessage[], _b?: ChatOptions): AsyncIterable<string> {\n const error = new AIError(\n 'Chat streaming is not supported by the Laya decision-only provider.',\n 'NOT_IMPLEMENTED',\n PROVIDER,\n );\n return {\n [Symbol.asyncIterator]: () => ({ next: () => Promise.reject(error) }),\n };\n }\n async countTokens(_a: string): Promise<number> {\n return this.unsupported();\n }\n async submitVideoGenerationJob(\n _a: VideoGenerationOptions,\n ): Promise<VideoGenerationJob> {\n return this.unsupported();\n }\n async getVideoGenerationJob(\n _a: VideoGenerationJob,\n ): Promise<VideoGenerationStatusResult> {\n return this.unsupported();\n }\n async fetchVideoGenerationResult(\n _a: VideoGenerationJob,\n ): Promise<VideoGenerationResult> {\n return this.unsupported();\n }\n async cancelVideoGenerationJob(_a: VideoGenerationJob): Promise<void> {\n return this.unsupported();\n }\n async validateVideoGenerationAccess(): Promise<boolean> {\n return this.unsupported();\n }\n async synthesizeSpeech(_a: string, _b?: TTSOptions): Promise<TTSResponse> {\n return this.unsupported();\n }\n streamSpeech(_a: string, _b?: TTSOptions): AsyncIterable<Buffer> {\n const error = new AIError(\n 'TTS streaming is not supported by the Laya decision-only provider.',\n 'NOT_IMPLEMENTED',\n PROVIDER,\n );\n return {\n [Symbol.asyncIterator]: () => ({ next: () => Promise.reject(error) }),\n };\n }\n async cloneVoice(_a: VoiceCloneOptions): Promise<Voice> {\n return this.unsupported();\n }\n async designVoice(_a: VoiceDesignOptions): Promise<Voice> {\n return this.unsupported();\n }\n async getVoices(_a?: VoiceListOptions): Promise<Voice[]> {\n return this.unsupported();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"laya-D8o5TEO7.js","names":[],"sources":["../../src/shared/providers/laya.ts"],"sourcesContent":["/**\n * Laya typed-decision provider.\n *\n * Laya (https://github.com/NandhaKishorM/laya) is a self-hosted,\n * non-autoregressive decision engine. Its `laya-serve` HTTP server answers the\n * Jev `POST /v1/systemone` wire shape, with differences this adapter handles\n * itself rather than inheriting from the TypeSafe adapter: optional auth, a\n * checkpoint chosen by the server's router, a `max_len` token window,\n * probabilities rounded to four decimals one at a time, and truncation facts.\n *\n * The public SDK contract calls Laya's `noul` primitive a `predicate`; the\n * server's vocabulary stays confined to this wire translation.\n */\n\nimport { ValidationError } from '@happyvertical/utils';\n\nimport { rateLimitErrorFrom } from '../rate-limit';\nimport { normalizeBaseAIOptions, prepareRequestControls } from '../safety';\nimport type {\n AICapabilities,\n AIInterface,\n AIMessage,\n AIModel,\n AIResponse,\n ChatOptions,\n CompletionOptions,\n DecisionAnswer,\n DecisionQuestion,\n DecisionRequest,\n DecisionResult,\n DecisionValue,\n EmbeddingOptions,\n EmbeddingResponse,\n ImageDescriptionOptions,\n ImageEmbeddingOptions,\n ImageGenerationOptions,\n ImageGenerationResponse,\n LayaDecisionOptions,\n LayaOptions,\n MessageOptions,\n ScoreDecisionQuestion,\n TTSOptions,\n TTSResponse,\n VideoGenerationJob,\n VideoGenerationOptions,\n VideoGenerationResult,\n VideoGenerationStatusResult,\n Voice,\n VoiceCloneOptions,\n VoiceDesignOptions,\n VoiceListOptions,\n} from '../types';\nimport { AIError, AuthenticationError } from '../types';\nimport { emitUsage } from './usage';\n\nconst PROVIDER = 'laya';\n\n/** Distributions this close to unit mass are used exactly as received. */\nconst STRICT_DISTRIBUTION_EPSILON = 1e-6;\n/**\n * `laya-serve` rounds every probability to four decimals on its own, so each\n * value is off by at most half of the last place and a distribution of `n`\n * values can be off by `n * 0.00005`.\n */\nconst ROUNDING_ERROR_PER_VALUE = 5e-5;\n/** No rounding story justifies renormalizing a distribution further out. */\nconst MAX_NORMALIZED_ERROR = 0.01;\n\ntype WireQuestion =\n | {\n type: 'noul';\n instructions: DecisionValue;\n criteria?: Record<string, DecisionValue>;\n }\n | {\n type: 'choice';\n instructions: DecisionValue;\n criteria: Record<string, DecisionValue | null>;\n }\n | { type: 'score'; instructions: DecisionValue; criteria: DecisionValue[] };\n\ninterface WireRequest {\n state: DecisionValue;\n questions: Record<string, WireQuestion>;\n model?: string;\n max_len?: number;\n}\n\ninterface WireResponse {\n model?: unknown;\n answers?: unknown;\n usage?: unknown;\n routing?: unknown;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction invalid(message: string): AIError {\n return new AIError(`Laya response ${message}`, 'INVALID_RESPONSE', PROVIDER);\n}\n\nfunction finite(value: unknown, field: string): number {\n if (typeof value !== 'number' || !Number.isFinite(value))\n throw invalid(`${field} must be finite`);\n return value;\n}\n\nfunction probability(value: unknown, field: string): number {\n const result = finite(value, field);\n if (result < 0 || result > 1)\n throw invalid(`${field} must be between 0 and 1`);\n return result;\n}\n\nfunction tokenCount(value: unknown, field: string): number {\n const result = finite(value, field);\n if (!Number.isSafeInteger(result) || result < 0)\n throw invalid(`${field} must be a non-negative integer`);\n return result;\n}\n\nfunction optionalString(\n source: Record<string, unknown>,\n key: string,\n field: string,\n): string | undefined {\n const value = source[key];\n if (value === undefined) return undefined;\n if (typeof value !== 'string' || !value)\n throw invalid(`${field} must be a non-empty string`);\n return value;\n}\n\nfunction sameDecisionValue(left: DecisionValue, right: unknown): boolean {\n if (left === right) return true;\n if (Array.isArray(left)) {\n return (\n Array.isArray(right) &&\n left.length === right.length &&\n left.every((value, index) => sameDecisionValue(value, right[index]))\n );\n }\n if (isRecord(left)) {\n return (\n isRecord(right) &&\n Object.keys(left).length === Object.keys(right).length &&\n Object.entries(left).every(\n ([key, value]) => key in right && sameDecisionValue(value, right[key]),\n )\n );\n }\n return false;\n}\n\n/**\n * `laya-serve` returns a rubric level in `legend` as sent when it is a string\n * and as Python's `json.dumps` text when it is anything else.\n */\nfunction legendMatches(level: DecisionValue, legend: unknown): boolean {\n if (sameDecisionValue(level, legend)) return true;\n if (typeof level === 'string' || typeof legend !== 'string') return false;\n try {\n return sameDecisionValue(level, JSON.parse(legend));\n } catch {\n return false;\n }\n}\n\nfunction validateValue(\n value: unknown,\n field: string,\n): asserts value is DecisionValue {\n if (value === null || typeof value === 'string' || typeof value === 'boolean')\n return;\n if (typeof value === 'number') {\n if (!Number.isFinite(value))\n throw new ValidationError(`${field} must contain finite numbers`, {\n provider: PROVIDER,\n });\n return;\n }\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n validateValue(item, `${field}[${index}]`);\n });\n return;\n }\n if (isRecord(value)) {\n Object.entries(value).forEach(([key, item]) => {\n validateValue(item, `${field}.${key}`);\n });\n return;\n }\n throw new ValidationError(`${field} must be JSON-compatible`, {\n provider: PROVIDER,\n });\n}\n\nfunction validateMaxLen(value: unknown, field: string): number | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== 'number' || !Number.isSafeInteger(value) || value <= 0)\n throw new ValidationError(`${field} must be a positive integer`, {\n provider: PROVIDER,\n });\n return value;\n}\n\n/**\n * Checks the provider-neutral request shape. Laya's own size limits (questions\n * per request, options per question, state length) are left to the server,\n * which reports them as explicit 413 errors.\n */\nfunction validateRequest(request: DecisionRequest): void {\n if (request.state === null || request.state === undefined)\n throw new ValidationError('state is required', { provider: PROVIDER });\n validateValue(request.state, 'state');\n const entries = Object.entries(request.questions || {});\n if (entries.length === 0)\n throw new ValidationError('questions must not be empty', {\n provider: PROVIDER,\n });\n for (const [id, question] of entries) {\n if (!id.trim())\n throw new ValidationError('question IDs must not be empty', {\n provider: PROVIDER,\n });\n validateValue(question.instructions, `questions.${id}.instructions`);\n if (question.type === 'predicate') {\n if (question.criteria) {\n for (const [key, value] of Object.entries(question.criteria))\n validateValue(value, `questions.${id}.criteria.${key}`);\n }\n } else if (question.type === 'choice') {\n const options = Object.keys(question.criteria || {});\n if (options.length === 0)\n throw new ValidationError(\n `questions.${id}.criteria must contain at least one option`,\n { provider: PROVIDER },\n );\n for (const [key, value] of Object.entries(question.criteria))\n if (value !== null)\n validateValue(value, `questions.${id}.criteria.${key}`);\n } else if (question.type === 'score') {\n if (!Array.isArray(question.criteria) || question.criteria.length < 2)\n throw new ValidationError(\n `questions.${id}.criteria must contain at least 2 ordered levels`,\n { provider: PROVIDER },\n );\n question.criteria.forEach((value, index) => {\n // Laya rejects a null level because its legend entry would be null.\n if (value === null)\n throw new ValidationError(\n `questions.${id}.criteria[${index}] must describe the level`,\n { provider: PROVIDER },\n );\n validateValue(value, `questions.${id}.criteria[${index}]`);\n });\n } else {\n throw new ValidationError(`questions.${id}.type is unsupported`, {\n provider: PROVIDER,\n });\n }\n }\n}\n\n/**\n * Builds each wire question field by field so unknown properties on a caller's\n * object (for example a generation control) are never forwarded.\n */\nfunction wireQuestion(question: DecisionQuestion): WireQuestion {\n if (question.type === 'predicate')\n return {\n type: 'noul',\n instructions: question.instructions,\n ...(question.criteria ? { criteria: question.criteria } : {}),\n };\n if (question.type === 'choice')\n return {\n type: 'choice',\n instructions: question.instructions,\n criteria: question.criteria,\n };\n return {\n type: 'score',\n instructions: question.instructions,\n criteria: question.criteria,\n };\n}\n\n/** Resolves the server root from a base URL that may carry the API path. */\nfunction serverRoot(value: string | undefined): string {\n const text = (value || '').trim();\n if (!text)\n throw new ValidationError(\n 'Laya requires baseUrl, for example http://localhost:8000',\n { provider: PROVIDER },\n );\n let url: URL;\n try {\n url = new URL(text);\n } catch {\n throw new ValidationError('Laya baseUrl must be an absolute http(s) URL', {\n provider: PROVIDER,\n });\n }\n if (url.protocol !== 'http:' && url.protocol !== 'https:')\n throw new ValidationError('Laya baseUrl must be an absolute http(s) URL', {\n provider: PROVIDER,\n });\n if (url.search || url.hash || url.username || url.password)\n throw new ValidationError(\n 'Laya baseUrl must not contain credentials, a query, or a fragment',\n { provider: PROVIDER },\n );\n const path = url.pathname\n .replace(/\\/+$/, '')\n .replace(/\\/v1(\\/systemone)?$/, '');\n return `${url.origin}${path}`;\n}\n\ninterface Distribution {\n values: Record<string, number>;\n /** The values as received, set only when they were renormalized. */\n raw?: Record<string, number>;\n}\n\n/**\n * Validates a choice or score distribution. Mass within the four-decimal\n * rounding bound is normalized by its actual sum; anything else is rejected.\n */\nfunction distribution(\n value: unknown,\n expected: string[],\n field: string,\n): Distribution {\n if (\n !isRecord(value) ||\n Object.keys(value).length !== expected.length ||\n expected.some((key) => !(key in value))\n )\n throw invalid(`${field} must cover exactly the requested values`);\n const values = Object.fromEntries(\n expected.map((key) => [key, probability(value[key], `${field}.${key}`)]),\n );\n const sum = Object.values(values).reduce((total, item) => total + item, 0);\n const drift = Math.abs(sum - 1);\n if (drift <= STRICT_DISTRIBUTION_EPSILON) return { values };\n const allowed =\n Math.min(expected.length * ROUNDING_ERROR_PER_VALUE, MAX_NORMALIZED_ERROR) +\n STRICT_DISTRIBUTION_EPSILON;\n if (sum <= 0 || drift > allowed) throw invalid(`${field} must sum to 1`);\n return {\n values: Object.fromEntries(\n Object.entries(values).map(([key, item]) => [key, item / sum]),\n ),\n raw: values,\n };\n}\n\nfunction answer(\n question: DecisionQuestion,\n raw: unknown,\n id: string,\n renormalized: Record<string, Record<string, number>>,\n): DecisionAnswer {\n if (!isRecord(raw)) throw invalid(`answers.${id} must be an object`);\n if (question.type === 'predicate') {\n if (raw.type !== 'noul')\n throw invalid(`answers.${id} type does not match predicate`);\n return {\n type: 'predicate',\n probability: probability(raw.noul, `answers.${id}.noul`),\n };\n }\n if (raw.type !== question.type)\n throw invalid(`answers.${id} type does not match request`);\n if (question.type === 'choice') {\n const choices = Object.keys(question.criteria);\n if (typeof raw.choice !== 'string' || !choices.includes(raw.choice))\n throw invalid(`answers.${id}.choice is not a requested option`);\n const probabilities = distribution(\n raw.probabilities,\n choices,\n `answers.${id}.probabilities`,\n );\n if (probabilities.raw) renormalized[id] = probabilities.raw;\n return {\n type: 'choice',\n choice: raw.choice,\n probabilities: probabilities.values,\n confidence: probability(raw.confidence, `answers.${id}.confidence`),\n };\n }\n const levels = (question as ScoreDecisionQuestion).criteria;\n const levelKeys = levels.map((_, index) => String(index));\n const score = finite(raw.score, `answers.${id}.score`);\n if (score < 0 || score > levels.length - 1)\n throw invalid(`answers.${id}.score is outside the requested rubric`);\n const legend = raw.legend;\n if (\n !isRecord(legend) ||\n levelKeys.some((key, index) => !legendMatches(levels[index], legend[key]))\n )\n throw invalid(`answers.${id}.legend does not match the requested rubric`);\n const probabilities = distribution(\n raw.probabilities,\n levelKeys,\n `answers.${id}.probabilities`,\n );\n if (probabilities.raw) renormalized[id] = probabilities.raw;\n return {\n type: 'score',\n score,\n probabilities: probabilities.values,\n confidence: probability(raw.confidence, `answers.${id}.confidence`),\n levels,\n };\n}\n\n/** A decision-only adapter for a `laya-serve` `/v1/systemone` endpoint. */\nexport class LayaProvider implements AIInterface {\n private readonly options: LayaOptions;\n private readonly root: string;\n private readonly maxLen?: number;\n\n constructor(options: LayaOptions) {\n this.root = serverRoot(options.baseUrl);\n this.maxLen = validateMaxLen(options.maxLen, 'maxLen');\n this.options = normalizeBaseAIOptions({ ...options, baseUrl: this.root });\n }\n\n async decide(\n request: DecisionRequest,\n options: LayaDecisionOptions = {},\n ): Promise<DecisionResult> {\n validateRequest(request);\n const maxLen = validateMaxLen(options.maxLen, 'maxLen') ?? this.maxLen;\n const controls = prepareRequestControls(this.options, options);\n const startedAt = Date.now();\n const requestedModel =\n options.model || this.options.defaultModel || undefined;\n const wire: WireRequest = {\n state: request.state,\n questions: Object.fromEntries(\n Object.entries(request.questions).map(([id, question]) => [\n id,\n wireQuestion(question),\n ]),\n ),\n ...(requestedModel ? { model: requestedModel } : {}),\n ...(maxLen !== undefined ? { max_len: maxLen } : {}),\n };\n try {\n const response = await fetch(`${this.root}/v1/systemone`, {\n method: 'POST',\n redirect: 'error',\n headers: {\n ...(this.options.apiKey\n ? { Authorization: `Bearer ${this.options.apiKey}` }\n : {}),\n 'Content-Type': 'application/json',\n ...this.options.headers,\n },\n body: JSON.stringify(wire),\n signal: controls.signal,\n });\n if (!response.ok) {\n if (response.status === 401) throw new AuthenticationError(PROVIDER);\n const text = await response.text();\n // 503 is laya-serve's admission limit (LAYA_MAX_CONCURRENT), which\n // sends Retry-After; 429 covers a rate-limiting proxy in front of it.\n if (response.status === 429 || response.status === 503)\n throw rateLimitErrorFrom(\n PROVIDER,\n { headers: response.headers, message: text },\n { model: requestedModel },\n );\n throw new AIError(\n `Laya request failed (${response.status}): ${text.slice(0, 500)}`,\n 'API_ERROR',\n PROVIDER,\n requestedModel,\n response.status >= 500,\n );\n }\n let body: WireResponse;\n try {\n body = (await response.json()) as WireResponse;\n } catch (error) {\n if (error instanceof SyntaxError)\n throw new AIError(\n 'Laya response contained invalid JSON',\n 'INVALID_RESPONSE',\n PROVIDER,\n requestedModel,\n );\n throw error;\n }\n return this.result(\n request,\n body,\n requestedModel,\n maxLen,\n options,\n startedAt,\n );\n } catch (error) {\n if (controls.didTimeout())\n throw new AIError(\n `Laya request timed out after ${controls.timeout}ms`,\n 'REQUEST_TIMEOUT',\n PROVIDER,\n requestedModel,\n true,\n );\n if (controls.signal.aborted && !(error instanceof AIError))\n throw new AIError(\n 'Laya request was aborted',\n 'REQUEST_ABORTED',\n PROVIDER,\n requestedModel,\n );\n if (!(error instanceof AIError)) {\n throw new AIError(\n `Network error calling Laya: ${\n error instanceof Error ? error.message : String(error)\n }`,\n 'NETWORK_ERROR',\n PROVIDER,\n requestedModel,\n true,\n );\n }\n throw error;\n } finally {\n controls.cleanup();\n }\n }\n\n private result(\n request: DecisionRequest,\n body: WireResponse,\n requestedModel: string | undefined,\n maxLen: number | undefined,\n options: LayaDecisionOptions,\n startedAt: number,\n ): DecisionResult {\n if (!isRecord(body)) throw invalid('must be an object');\n // The root `model` names Laya's decision head, not the checkpoint.\n if (typeof body.model !== 'string' || !body.model)\n throw invalid('model is required');\n if (!isRecord(body.answers)) throw invalid('answers is required');\n const responseAnswers = body.answers;\n const ids = Object.keys(request.questions);\n if (\n Object.keys(responseAnswers).length !== ids.length ||\n ids.some((id) => !(id in responseAnswers))\n )\n throw invalid('answers must match requested question IDs');\n const renormalized: Record<string, Record<string, number>> = {};\n const answers = Object.fromEntries(\n ids.map((id) => [\n id,\n answer(request.questions[id], responseAnswers[id], id, renormalized),\n ]),\n );\n\n let usage:\n | { promptTokens: number; completionTokens: number; totalTokens: number }\n | undefined;\n const facts: Record<string, DecisionValue> = {};\n if (body.usage !== undefined) {\n const wireUsage = body.usage;\n if (\n !isRecord(wireUsage) ||\n !('input_tokens' in wireUsage) ||\n !('output_tokens' in wireUsage)\n )\n throw invalid('usage must include input_tokens and output_tokens');\n const input = tokenCount(wireUsage.input_tokens, 'usage.input_tokens');\n const output = tokenCount(wireUsage.output_tokens, 'usage.output_tokens');\n usage = {\n promptTokens: input,\n completionTokens: output,\n totalTokens: input + output,\n };\n // Truncation is invisible anywhere else in the response.\n for (const [key, name] of [\n ['state_tokens', 'stateTokens'],\n ['state_tokens_dropped', 'stateTokensDropped'],\n ] as const)\n if (wireUsage[key] !== undefined)\n facts[name] = tokenCount(wireUsage[key], `usage.${key}`);\n if (wireUsage.truncated !== undefined) {\n if (typeof wireUsage.truncated !== 'boolean')\n throw invalid('usage.truncated must be a boolean');\n facts.truncated = wireUsage.truncated;\n }\n if (wireUsage.truncated_questions !== undefined) {\n const truncated = wireUsage.truncated_questions;\n if (\n !Array.isArray(truncated) ||\n truncated.some((id) => typeof id !== 'string')\n )\n throw invalid('usage.truncated_questions must list question IDs');\n facts.truncatedQuestions = truncated as string[];\n }\n }\n\n let checkpoint: string | undefined;\n if (body.routing !== undefined) {\n if (!isRecord(body.routing)) throw invalid('routing must be an object');\n checkpoint = optionalString(body.routing, 'model', 'routing.model');\n const repo = optionalString(body.routing, 'repo', 'routing.repo');\n const reason = optionalString(body.routing, 'reason', 'routing.reason');\n if (checkpoint) facts.checkpoint = checkpoint;\n if (repo) facts.checkpointRepo = repo;\n if (reason) facts.routeReason = reason;\n }\n\n // The checkpoint that answered is reported only in `routing`, which a\n // server running LAYA_JEV_STRICT omits. Without it, report the decision\n // head and leave `details.checkpoint` unset rather than guess.\n const model = checkpoint || body.model;\n const renormalizedIds = Object.keys(renormalized);\n const details: Record<string, DecisionValue> = {\n serverModel: body.model,\n ...(requestedModel ? { requestedModel } : {}),\n ...(maxLen !== undefined ? { maxLen } : {}),\n ...facts,\n ...(renormalizedIds.length\n ? { renormalized: renormalizedIds, rawProbabilities: renormalized }\n : {}),\n };\n emitUsage(\n this.options,\n PROVIDER,\n 'decide',\n model,\n usage,\n startedAt,\n options.usageTags,\n );\n return {\n model,\n ...(usage ? { usage } : {}),\n provenance: { provider: PROVIDER, model, details },\n answers,\n };\n }\n\n async getModels(): Promise<AIModel[]> {\n // laya-serve has no model-listing route; these are the checkpoints of the\n // convaiinnovations/laya bundle. A server may register others.\n const checkpoints: Array<[string, string, number]> = [\n ['typed-decisions', 'Laya typed decisions (421M)', 1024],\n ['english', 'Laya English (421M)', 512],\n ['multilingual', 'Laya multilingual (322M)', 1024],\n ];\n const configured = this.options.defaultModel;\n const models = checkpoints.map(([id, name, contextLength]) => ({\n id,\n name,\n description: 'Laya typed decisions',\n contextLength,\n capabilities: ['decisions'],\n supportsFunctions: false,\n supportsVision: false,\n }));\n if (configured && !models.some((model) => model.id === configured))\n models.push({\n id: configured,\n name: configured,\n description: 'Laya typed decisions (configured checkpoint)',\n contextLength: 0,\n capabilities: ['decisions'],\n supportsFunctions: false,\n supportsVision: false,\n });\n return models;\n }\n async getCapabilities(): Promise<AICapabilities> {\n return {\n decisions: true,\n chat: false,\n completion: false,\n embeddings: false,\n streaming: false,\n functions: false,\n vision: false,\n fineTuning: false,\n imageEmbeddings: false,\n imageGeneration: false,\n videoGeneration: false,\n tts: false,\n voiceCloning: false,\n voiceDesign: false,\n maxContextLength: 0,\n supportedOperations: ['decide'],\n };\n }\n private unsupported(): never {\n throw new AIError(\n 'This operation is not supported by the Laya decision-only provider.',\n 'NOT_IMPLEMENTED',\n PROVIDER,\n );\n }\n async chat(_a: AIMessage[], _b?: ChatOptions): Promise<AIResponse> {\n return this.unsupported();\n }\n async complete(_a: string, _b?: CompletionOptions): Promise<AIResponse> {\n return this.unsupported();\n }\n async message(_a: string, _b?: MessageOptions): Promise<string> {\n return this.unsupported();\n }\n async embed(\n _a: string | string[],\n _b?: EmbeddingOptions,\n ): Promise<EmbeddingResponse> {\n return this.unsupported();\n }\n async embedImage(\n _a: string | Buffer,\n _b?: ImageEmbeddingOptions,\n ): Promise<EmbeddingResponse> {\n return this.unsupported();\n }\n async describeImage(\n _a: string | Buffer,\n _b?: string,\n _c?: ImageDescriptionOptions,\n ): Promise<string> {\n return this.unsupported();\n }\n async generateImage(\n _a: string,\n _b?: ImageGenerationOptions,\n ): Promise<ImageGenerationResponse> {\n return this.unsupported();\n }\n stream(_a: AIMessage[], _b?: ChatOptions): AsyncIterable<string> {\n const error = new AIError(\n 'Chat streaming is not supported by the Laya decision-only provider.',\n 'NOT_IMPLEMENTED',\n PROVIDER,\n );\n return {\n [Symbol.asyncIterator]: () => ({ next: () => Promise.reject(error) }),\n };\n }\n async countTokens(_a: string): Promise<number> {\n return this.unsupported();\n }\n async submitVideoGenerationJob(\n _a: VideoGenerationOptions,\n ): Promise<VideoGenerationJob> {\n return this.unsupported();\n }\n async getVideoGenerationJob(\n _a: VideoGenerationJob,\n ): Promise<VideoGenerationStatusResult> {\n return this.unsupported();\n }\n async fetchVideoGenerationResult(\n _a: VideoGenerationJob,\n ): Promise<VideoGenerationResult> {\n return this.unsupported();\n }\n async cancelVideoGenerationJob(_a: VideoGenerationJob): Promise<void> {\n return this.unsupported();\n }\n async validateVideoGenerationAccess(): Promise<boolean> {\n return this.unsupported();\n }\n async synthesizeSpeech(_a: string, _b?: TTSOptions): Promise<TTSResponse> {\n return this.unsupported();\n }\n streamSpeech(_a: string, _b?: TTSOptions): AsyncIterable<Buffer> {\n const error = new AIError(\n 'TTS streaming is not supported by the Laya decision-only provider.',\n 'NOT_IMPLEMENTED',\n PROVIDER,\n );\n return {\n [Symbol.asyncIterator]: () => ({ next: () => Promise.reject(error) }),\n };\n }\n async cloneVoice(_a: VoiceCloneOptions): Promise<Voice> {\n return this.unsupported();\n }\n async designVoice(_a: VoiceDesignOptions): Promise<Voice> {\n return this.unsupported();\n }\n async getVoices(_a?: VoiceListOptions): Promise<Voice[]> {\n return this.unsupported();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAuDA,IAAM,WAAW;;AAGjB,IAAM,8BAA8B;;;;;;AAMpC,IAAM,2BAA2B;;AAEjC,IAAM,uBAAuB;AA6B7B,SAAS,SAAS,OAAkD;CAClE,OAAO,QAAQ,KAAK,KAAK,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,QAAQ,SAA0B;CACzC,OAAO,IAAI,QAAQ,iBAAiB,WAAW,oBAAoB,QAAQ;AAC7E;AAEA,SAAS,OAAO,OAAgB,OAAuB;CACrD,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GACrD,MAAM,QAAQ,GAAG,MAAM,gBAAgB;CACzC,OAAO;AACT;AAEA,SAAS,YAAY,OAAgB,OAAuB;CAC1D,MAAM,SAAS,OAAO,OAAO,KAAK;CAClC,IAAI,SAAS,KAAK,SAAS,GACzB,MAAM,QAAQ,GAAG,MAAM,yBAAyB;CAClD,OAAO;AACT;AAEA,SAAS,WAAW,OAAgB,OAAuB;CACzD,MAAM,SAAS,OAAO,OAAO,KAAK;CAClC,IAAI,CAAC,OAAO,cAAc,MAAM,KAAK,SAAS,GAC5C,MAAM,QAAQ,GAAG,MAAM,gCAAgC;CACzD,OAAO;AACT;AAEA,SAAS,eACP,QACA,KACA,OACoB;CACpB,MAAM,QAAQ,OAAO;CACrB,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;CAChC,IAAI,OAAO,UAAU,YAAY,CAAC,OAChC,MAAM,QAAQ,GAAG,MAAM,4BAA4B;CACrD,OAAO;AACT;AAEA,SAAS,kBAAkB,MAAqB,OAAyB;CACvE,IAAI,SAAS,OAAO,OAAO;CAC3B,IAAI,MAAM,QAAQ,IAAI,GACpB,OACE,MAAM,QAAQ,KAAK,KACnB,KAAK,WAAW,MAAM,UACtB,KAAK,OAAO,OAAO,UAAU,kBAAkB,OAAO,MAAM,MAAM,CAAC;CAGvE,IAAI,SAAS,IAAI,GACf,OACE,SAAS,KAAK,KACd,OAAO,KAAK,IAAI,CAAC,CAAC,WAAW,OAAO,KAAK,KAAK,CAAC,CAAC,UAChD,OAAO,QAAQ,IAAI,CAAC,CAAC,OAClB,CAAC,KAAK,WAAW,OAAO,SAAS,kBAAkB,OAAO,MAAM,IAAI,CACvE;CAGJ,OAAO;AACT;;;;;AAMA,SAAS,cAAc,OAAsB,QAA0B;CACrE,IAAI,kBAAkB,OAAO,MAAM,GAAG,OAAO;CAC7C,IAAI,OAAO,UAAU,YAAY,OAAO,WAAW,UAAU,OAAO;CACpE,IAAI;EACF,OAAO,kBAAkB,OAAO,KAAK,MAAM,MAAM,CAAC;CACpD,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,cACP,OACA,OACgC;CAChC,IAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,OAAO,UAAU,WAClE;CACF,IAAI,OAAO,UAAU,UAAU;EAC7B,IAAI,CAAC,OAAO,SAAS,KAAK,GACxB,MAAM,IAAI,gBAAgB,GAAG,MAAM,+BAA+B,EAChE,UAAU,SACZ,CAAC;EACH;CACF;CACA,IAAI,MAAM,QAAQ,KAAK,GAAG;EACxB,MAAM,SAAS,MAAM,UAAU;GAC7B,cAAc,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE;EAC1C,CAAC;EACD;CACF;CACA,IAAI,SAAS,KAAK,GAAG;EACnB,OAAO,QAAQ,KAAK,CAAC,CAAC,SAAS,CAAC,KAAK,UAAU;GAC7C,cAAc,MAAM,GAAG,MAAM,GAAG,KAAK;EACvC,CAAC;EACD;CACF;CACA,MAAM,IAAI,gBAAgB,GAAG,MAAM,2BAA2B,EAC5D,UAAU,SACZ,CAAC;AACH;AAEA,SAAS,eAAe,OAAgB,OAAmC;CACzE,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;CAChC,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,cAAc,KAAK,KAAK,SAAS,GACxE,MAAM,IAAI,gBAAgB,GAAG,MAAM,8BAA8B,EAC/D,UAAU,SACZ,CAAC;CACH,OAAO;AACT;;;;;;AAOA,SAAS,gBAAgB,SAAgC;CACvD,IAAI,QAAQ,UAAU,QAAQ,QAAQ,UAAU,KAAA,GAC9C,MAAM,IAAI,gBAAgB,qBAAqB,EAAE,UAAU,SAAS,CAAC;CACvE,cAAc,QAAQ,OAAO,OAAO;CACpC,MAAM,UAAU,OAAO,QAAQ,QAAQ,aAAa,CAAC,CAAC;CACtD,IAAI,QAAQ,WAAW,GACrB,MAAM,IAAI,gBAAgB,+BAA+B,EACvD,UAAU,SACZ,CAAC;CACH,KAAK,MAAM,CAAC,IAAI,aAAa,SAAS;EACpC,IAAI,CAAC,GAAG,KAAK,GACX,MAAM,IAAI,gBAAgB,kCAAkC,EAC1D,UAAU,SACZ,CAAC;EACH,cAAc,SAAS,cAAc,aAAa,GAAG,cAAc;EACnE,IAAI,SAAS,SAAS;OAChB,SAAS,UACX,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,SAAS,QAAQ,GACzD,cAAc,OAAO,aAAa,GAAG,YAAY,KAAK;EAAA,OAErD,IAAI,SAAS,SAAS,UAAU;GAErC,IADgB,OAAO,KAAK,SAAS,YAAY,CAAC,CAC9C,CAAA,CAAQ,WAAW,GACrB,MAAM,IAAI,gBACR,aAAa,GAAG,6CAChB,EAAE,UAAU,SAAS,CACvB;GACF,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,SAAS,QAAQ,GACzD,IAAI,UAAU,MACZ,cAAc,OAAO,aAAa,GAAG,YAAY,KAAK;EAC5D,OAAO,IAAI,SAAS,SAAS,SAAS;GACpC,IAAI,CAAC,MAAM,QAAQ,SAAS,QAAQ,KAAK,SAAS,SAAS,SAAS,GAClE,MAAM,IAAI,gBACR,aAAa,GAAG,mDAChB,EAAE,UAAU,SAAS,CACvB;GACF,SAAS,SAAS,SAAS,OAAO,UAAU;IAE1C,IAAI,UAAU,MACZ,MAAM,IAAI,gBACR,aAAa,GAAG,YAAY,MAAM,4BAClC,EAAE,UAAU,SAAS,CACvB;IACF,cAAc,OAAO,aAAa,GAAG,YAAY,MAAM,EAAE;GAC3D,CAAC;EACH,OACE,MAAM,IAAI,gBAAgB,aAAa,GAAG,uBAAuB,EAC/D,UAAU,SACZ,CAAC;CAEL;AACF;;;;;AAMA,SAAS,aAAa,UAA0C;CAC9D,IAAI,SAAS,SAAS,aACpB,OAAO;EACL,MAAM;EACN,cAAc,SAAS;EACvB,GAAI,SAAS,WAAW,EAAE,UAAU,SAAS,SAAS,IAAI,CAAC;CAC7D;CACF,IAAI,SAAS,SAAS,UACpB,OAAO;EACL,MAAM;EACN,cAAc,SAAS;EACvB,UAAU,SAAS;CACrB;CACF,OAAO;EACL,MAAM;EACN,cAAc,SAAS;EACvB,UAAU,SAAS;CACrB;AACF;;AAGA,SAAS,WAAW,OAAmC;CACrD,MAAM,QAAQ,SAAS,GAAA,CAAI,KAAK;CAChC,IAAI,CAAC,MACH,MAAM,IAAI,gBACR,4DACA,EAAE,UAAU,SAAS,CACvB;CACF,IAAI;CACJ,IAAI;EACF,MAAM,IAAI,IAAI,IAAI;CACpB,QAAQ;EACN,MAAM,IAAI,gBAAgB,gDAAgD,EACxE,UAAU,SACZ,CAAC;CACH;CACA,IAAI,IAAI,aAAa,WAAW,IAAI,aAAa,UAC/C,MAAM,IAAI,gBAAgB,gDAAgD,EACxE,UAAU,SACZ,CAAC;CACH,IAAI,IAAI,UAAU,IAAI,QAAQ,IAAI,YAAY,IAAI,UAChD,MAAM,IAAI,gBACR,qEACA,EAAE,UAAU,SAAS,CACvB;CACF,MAAM,OAAO,IAAI,SACd,QAAQ,QAAQ,EAAE,CAAC,CACnB,QAAQ,uBAAuB,EAAE;CACpC,OAAO,GAAG,IAAI,SAAS;AACzB;;;;;AAYA,SAAS,aACP,OACA,UACA,OACc;CACd,IACE,CAAC,SAAS,KAAK,KACf,OAAO,KAAK,KAAK,CAAC,CAAC,WAAW,SAAS,UACvC,SAAS,MAAM,QAAQ,EAAE,OAAO,MAAM,GAEtC,MAAM,QAAQ,GAAG,MAAM,yCAAyC;CAClE,MAAM,SAAS,OAAO,YACpB,SAAS,KAAK,QAAQ,CAAC,KAAK,YAAY,MAAM,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC,CACzE;CACA,MAAM,MAAM,OAAO,OAAO,MAAM,CAAC,CAAC,QAAQ,OAAO,SAAS,QAAQ,MAAM,CAAC;CACzE,MAAM,QAAQ,KAAK,IAAI,MAAM,CAAC;CAC9B,IAAI,SAAS,6BAA6B,OAAO,EAAE,OAAO;CAC1D,MAAM,UACJ,KAAK,IAAI,SAAS,SAAS,0BAA0B,oBAAoB,IACzE;CACF,IAAI,OAAO,KAAK,QAAQ,SAAS,MAAM,QAAQ,GAAG,MAAM,eAAe;CACvE,OAAO;EACL,QAAQ,OAAO,YACb,OAAO,QAAQ,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,UAAU,CAAC,KAAK,OAAO,GAAG,CAAC,CAC/D;EACA,KAAK;CACP;AACF;AAEA,SAAS,OACP,UACA,KACA,IACA,cACgB;CAChB,IAAI,CAAC,SAAS,GAAG,GAAG,MAAM,QAAQ,WAAW,GAAG,mBAAmB;CACnE,IAAI,SAAS,SAAS,aAAa;EACjC,IAAI,IAAI,SAAS,QACf,MAAM,QAAQ,WAAW,GAAG,+BAA+B;EAC7D,OAAO;GACL,MAAM;GACN,aAAa,YAAY,IAAI,MAAM,WAAW,GAAG,MAAM;EACzD;CACF;CACA,IAAI,IAAI,SAAS,SAAS,MACxB,MAAM,QAAQ,WAAW,GAAG,6BAA6B;CAC3D,IAAI,SAAS,SAAS,UAAU;EAC9B,MAAM,UAAU,OAAO,KAAK,SAAS,QAAQ;EAC7C,IAAI,OAAO,IAAI,WAAW,YAAY,CAAC,QAAQ,SAAS,IAAI,MAAM,GAChE,MAAM,QAAQ,WAAW,GAAG,kCAAkC;EAChE,MAAM,gBAAgB,aACpB,IAAI,eACJ,SACA,WAAW,GAAG,eAChB;EACA,IAAI,cAAc,KAAK,aAAa,MAAM,cAAc;EACxD,OAAO;GACL,MAAM;GACN,QAAQ,IAAI;GACZ,eAAe,cAAc;GAC7B,YAAY,YAAY,IAAI,YAAY,WAAW,GAAG,YAAY;EACpE;CACF;CACA,MAAM,SAAU,SAAmC;CACnD,MAAM,YAAY,OAAO,KAAK,GAAG,UAAU,OAAO,KAAK,CAAC;CACxD,MAAM,QAAQ,OAAO,IAAI,OAAO,WAAW,GAAG,OAAO;CACrD,IAAI,QAAQ,KAAK,QAAQ,OAAO,SAAS,GACvC,MAAM,QAAQ,WAAW,GAAG,uCAAuC;CACrE,MAAM,SAAS,IAAI;CACnB,IACE,CAAC,SAAS,MAAM,KAChB,UAAU,MAAM,KAAK,UAAU,CAAC,cAAc,OAAO,QAAQ,OAAO,IAAI,CAAC,GAEzE,MAAM,QAAQ,WAAW,GAAG,4CAA4C;CAC1E,MAAM,gBAAgB,aACpB,IAAI,eACJ,WACA,WAAW,GAAG,eAChB;CACA,IAAI,cAAc,KAAK,aAAa,MAAM,cAAc;CACxD,OAAO;EACL,MAAM;EACN;EACA,eAAe,cAAc;EAC7B,YAAY,YAAY,IAAI,YAAY,WAAW,GAAG,YAAY;EAClE;CACF;AACF;;AAGA,IAAa,eAAb,MAAiD;CAC/C;CACA;CACA;CAEA,YAAY,SAAsB;EAChC,KAAK,OAAO,WAAW,QAAQ,OAAO;EACtC,KAAK,SAAS,eAAe,QAAQ,QAAQ,QAAQ;EACrD,KAAK,UAAU,uBAAuB;GAAE,GAAG;GAAS,SAAS,KAAK;EAAK,CAAC;CAC1E;CAEA,MAAM,OACJ,SACA,UAA+B,CAAC,GACP;EACzB,gBAAgB,OAAO;EACvB,MAAM,SAAS,eAAe,QAAQ,QAAQ,QAAQ,KAAK,KAAK;EAChE,MAAM,WAAW,uBAAuB,KAAK,SAAS,OAAO;EAC7D,MAAM,YAAY,KAAK,IAAI;EAC3B,MAAM,iBACJ,QAAQ,SAAS,KAAK,QAAQ,gBAAgB,KAAA;EAChD,MAAM,OAAoB;GACxB,OAAO,QAAQ;GACf,WAAW,OAAO,YAChB,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,cAAc,CACxD,IACA,aAAa,QAAQ,CACvB,CAAC,CACH;GACA,GAAI,iBAAiB,EAAE,OAAO,eAAe,IAAI,CAAC;GAClD,GAAI,WAAW,KAAA,IAAY,EAAE,SAAS,OAAO,IAAI,CAAC;EACpD;EACA,IAAI;GACF,MAAM,WAAW,MAAM,MAAM,GAAG,KAAK,KAAK,gBAAgB;IACxD,QAAQ;IACR,UAAU;IACV,SAAS;KACP,GAAI,KAAK,QAAQ,SACb,EAAE,eAAe,UAAU,KAAK,QAAQ,SAAS,IACjD,CAAC;KACL,gBAAgB;KAChB,GAAG,KAAK,QAAQ;IAClB;IACA,MAAM,KAAK,UAAU,IAAI;IACzB,QAAQ,SAAS;GACnB,CAAC;GACD,IAAI,CAAC,SAAS,IAAI;IAChB,IAAI,SAAS,WAAW,KAAK,MAAM,IAAI,oBAAoB,QAAQ;IACnE,MAAM,OAAO,MAAM,SAAS,KAAK;IAGjC,IAAI,SAAS,WAAW,OAAO,SAAS,WAAW,KACjD,MAAM,mBACJ,UACA;KAAE,SAAS,SAAS;KAAS,SAAS;IAAK,GAC3C,EAAE,OAAO,eAAe,CAC1B;IACF,MAAM,IAAI,QACR,wBAAwB,SAAS,OAAO,KAAK,KAAK,MAAM,GAAG,GAAG,KAC9D,aACA,UACA,gBACA,SAAS,UAAU,GACrB;GACF;GACA,IAAI;GACJ,IAAI;IACF,OAAQ,MAAM,SAAS,KAAK;GAC9B,SAAS,OAAO;IACd,IAAI,iBAAiB,aACnB,MAAM,IAAI,QACR,wCACA,oBACA,UACA,cACF;IACF,MAAM;GACR;GACA,OAAO,KAAK,OACV,SACA,MACA,gBACA,QACA,SACA,SACF;EACF,SAAS,OAAO;GACd,IAAI,SAAS,WAAW,GACtB,MAAM,IAAI,QACR,gCAAgC,SAAS,QAAQ,KACjD,mBACA,UACA,gBACA,IACF;GACF,IAAI,SAAS,OAAO,WAAW,EAAE,iBAAiB,UAChD,MAAM,IAAI,QACR,4BACA,mBACA,UACA,cACF;GACF,IAAI,EAAE,iBAAiB,UACrB,MAAM,IAAI,QACR,+BACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAEvD,iBACA,UACA,gBACA,IACF;GAEF,MAAM;EACR,UAAU;GACR,SAAS,QAAQ;EACnB;CACF;CAEA,OACE,SACA,MACA,gBACA,QACA,SACA,WACgB;EAChB,IAAI,CAAC,SAAS,IAAI,GAAG,MAAM,QAAQ,mBAAmB;EAEtD,IAAI,OAAO,KAAK,UAAU,YAAY,CAAC,KAAK,OAC1C,MAAM,QAAQ,mBAAmB;EACnC,IAAI,CAAC,SAAS,KAAK,OAAO,GAAG,MAAM,QAAQ,qBAAqB;EAChE,MAAM,kBAAkB,KAAK;EAC7B,MAAM,MAAM,OAAO,KAAK,QAAQ,SAAS;EACzC,IACE,OAAO,KAAK,eAAe,CAAC,CAAC,WAAW,IAAI,UAC5C,IAAI,MAAM,OAAO,EAAE,MAAM,gBAAgB,GAEzC,MAAM,QAAQ,2CAA2C;EAC3D,MAAM,eAAuD,CAAC;EAC9D,MAAM,UAAU,OAAO,YACrB,IAAI,KAAK,OAAO,CACd,IACA,OAAO,QAAQ,UAAU,KAAK,gBAAgB,KAAK,IAAI,YAAY,CACrE,CAAC,CACH;EAEA,IAAI;EAGJ,MAAM,QAAuC,CAAC;EAC9C,IAAI,KAAK,UAAU,KAAA,GAAW;GAC5B,MAAM,YAAY,KAAK;GACvB,IACE,CAAC,SAAS,SAAS,KACnB,EAAE,kBAAkB,cACpB,EAAE,mBAAmB,YAErB,MAAM,QAAQ,mDAAmD;GACnE,MAAM,QAAQ,WAAW,UAAU,cAAc,oBAAoB;GACrE,MAAM,SAAS,WAAW,UAAU,eAAe,qBAAqB;GACxE,QAAQ;IACN,cAAc;IACd,kBAAkB;IAClB,aAAa,QAAQ;GACvB;GAEA,KAAK,MAAM,CAAC,KAAK,SAAS,CACxB,CAAC,gBAAgB,aAAa,GAC9B,CAAC,wBAAwB,oBAAoB,CAC/C,GACE,IAAI,UAAU,SAAS,KAAA,GACrB,MAAM,QAAQ,WAAW,UAAU,MAAM,SAAS,KAAK;GAC3D,IAAI,UAAU,cAAc,KAAA,GAAW;IACrC,IAAI,OAAO,UAAU,cAAc,WACjC,MAAM,QAAQ,mCAAmC;IACnD,MAAM,YAAY,UAAU;GAC9B;GACA,IAAI,UAAU,wBAAwB,KAAA,GAAW;IAC/C,MAAM,YAAY,UAAU;IAC5B,IACE,CAAC,MAAM,QAAQ,SAAS,KACxB,UAAU,MAAM,OAAO,OAAO,OAAO,QAAQ,GAE7C,MAAM,QAAQ,kDAAkD;IAClE,MAAM,qBAAqB;GAC7B;EACF;EAEA,IAAI;EACJ,IAAI,KAAK,YAAY,KAAA,GAAW;GAC9B,IAAI,CAAC,SAAS,KAAK,OAAO,GAAG,MAAM,QAAQ,2BAA2B;GACtE,aAAa,eAAe,KAAK,SAAS,SAAS,eAAe;GAClE,MAAM,OAAO,eAAe,KAAK,SAAS,QAAQ,cAAc;GAChE,MAAM,SAAS,eAAe,KAAK,SAAS,UAAU,gBAAgB;GACtE,IAAI,YAAY,MAAM,aAAa;GACnC,IAAI,MAAM,MAAM,iBAAiB;GACjC,IAAI,QAAQ,MAAM,cAAc;EAClC;EAKA,MAAM,QAAQ,cAAc,KAAK;EACjC,MAAM,kBAAkB,OAAO,KAAK,YAAY;EAChD,MAAM,UAAyC;GAC7C,aAAa,KAAK;GAClB,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;GAC3C,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;GACzC,GAAG;GACH,GAAI,gBAAgB,SAChB;IAAE,cAAc;IAAiB,kBAAkB;GAAa,IAChE,CAAC;EACP;EACA,UACE,KAAK,SACL,UACA,UACA,OACA,OACA,WACA,QAAQ,SACV;EACA,OAAO;GACL;GACA,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;GACzB,YAAY;IAAE,UAAU;IAAU;IAAO;GAAQ;GACjD;EACF;CACF;CAEA,MAAM,YAAgC;EAGpC,MAAM,cAA+C;GACnD;IAAC;IAAmB;IAA+B;GAAI;GACvD;IAAC;IAAW;IAAuB;GAAG;GACtC;IAAC;IAAgB;IAA4B;GAAI;EACnD;EACA,MAAM,aAAa,KAAK,QAAQ;EAChC,MAAM,SAAS,YAAY,KAAK,CAAC,IAAI,MAAM,oBAAoB;GAC7D;GACA;GACA,aAAa;GACb;GACA,cAAc,CAAC,WAAW;GAC1B,mBAAmB;GACnB,gBAAgB;EAClB,EAAE;EACF,IAAI,cAAc,CAAC,OAAO,MAAM,UAAU,MAAM,OAAO,UAAU,GAC/D,OAAO,KAAK;GACV,IAAI;GACJ,MAAM;GACN,aAAa;GACb,eAAe;GACf,cAAc,CAAC,WAAW;GAC1B,mBAAmB;GACnB,gBAAgB;EAClB,CAAC;EACH,OAAO;CACT;CACA,MAAM,kBAA2C;EAC/C,OAAO;GACL,WAAW;GACX,MAAM;GACN,YAAY;GACZ,YAAY;GACZ,WAAW;GACX,WAAW;GACX,QAAQ;GACR,YAAY;GACZ,iBAAiB;GACjB,iBAAiB;GACjB,iBAAiB;GACjB,KAAK;GACL,cAAc;GACd,aAAa;GACb,kBAAkB;GAClB,qBAAqB,CAAC,QAAQ;EAChC;CACF;CACA,cAA6B;EAC3B,MAAM,IAAI,QACR,uEACA,mBACA,QACF;CACF;CACA,MAAM,KAAK,IAAiB,IAAuC;EACjE,OAAO,KAAK,YAAY;CAC1B;CACA,MAAM,SAAS,IAAY,IAA6C;EACtE,OAAO,KAAK,YAAY;CAC1B;CACA,MAAM,QAAQ,IAAY,IAAsC;EAC9D,OAAO,KAAK,YAAY;CAC1B;CACA,MAAM,MACJ,IACA,IAC4B;EAC5B,OAAO,KAAK,YAAY;CAC1B;CACA,MAAM,WACJ,IACA,IAC4B;EAC5B,OAAO,KAAK,YAAY;CAC1B;CACA,MAAM,cACJ,IACA,IACA,IACiB;EACjB,OAAO,KAAK,YAAY;CAC1B;CACA,MAAM,cACJ,IACA,IACkC;EAClC,OAAO,KAAK,YAAY;CAC1B;CACA,OAAO,IAAiB,IAAyC;EAC/D,MAAM,QAAQ,IAAI,QAChB,uEACA,mBACA,QACF;EACA,OAAO,GACJ,OAAO,uBAAuB,EAAE,YAAY,QAAQ,OAAO,KAAK,EAAE,GACrE;CACF;CACA,MAAM,YAAY,IAA6B;EAC7C,OAAO,KAAK,YAAY;CAC1B;CACA,MAAM,yBACJ,IAC6B;EAC7B,OAAO,KAAK,YAAY;CAC1B;CACA,MAAM,sBACJ,IACsC;EACtC,OAAO,KAAK,YAAY;CAC1B;CACA,MAAM,2BACJ,IACgC;EAChC,OAAO,KAAK,YAAY;CAC1B;CACA,MAAM,yBAAyB,IAAuC;EACpE,OAAO,KAAK,YAAY;CAC1B;CACA,MAAM,gCAAkD;EACtD,OAAO,KAAK,YAAY;CAC1B;CACA,MAAM,iBAAiB,IAAY,IAAuC;EACxE,OAAO,KAAK,YAAY;CAC1B;CACA,aAAa,IAAY,IAAwC;EAC/D,MAAM,QAAQ,IAAI,QAChB,sEACA,mBACA,QACF;EACA,OAAO,GACJ,OAAO,uBAAuB,EAAE,YAAY,QAAQ,OAAO,KAAK,EAAE,GACrE;CACF;CACA,MAAM,WAAW,IAAuC;EACtD,OAAO,KAAK,YAAY;CAC1B;CACA,MAAM,YAAY,IAAwC;EACxD,OAAO,KAAK,YAAY;CAC1B;CACA,MAAM,UAAU,IAAyC;EACvD,OAAO,KAAK,YAAY;CAC1B;AACF"}
@@ -1,6 +1,6 @@
1
- import { c as normalizeImageGenerationOptions, s as normalizeChatOptions } from "./usage-B9gPCWSa.js";
2
- import { d as OpenAIProvider } from "./src-Cc5yFnnQ.js";
3
- import { a as LiteLLMAdmin, n as isSpeechModel, r as isTranscriptionModel, s as resolveGatewayAdminBaseUrl, t as isAudioModel } from "./gateway-audio-models-B1tGNv1H.js";
1
+ import { c as normalizeImageGenerationOptions, s as normalizeChatOptions } from "./usage-DS7uDhi1.js";
2
+ import { _ as OpenAIProvider } from "./src-DBah9G3i.js";
3
+ import { a as LiteLLMAdmin, n as isSpeechModel, r as isTranscriptionModel, s as resolveGatewayAdminBaseUrl, t as isAudioModel } from "./gateway-audio-models-DuXbi_2q.js";
4
4
  import { ValidationError } from "@happyvertical/utils";
5
5
  //#region src/shared/providers/litellm.ts
6
6
  /** Chat Completions has effort, not a generic reasoning budget/thoughts envelope. */
@@ -194,4 +194,4 @@ var LiteLLMProvider = class extends OpenAIProvider {
194
194
  //#endregion
195
195
  export { LiteLLMProvider };
196
196
 
197
- //# sourceMappingURL=litellm-BaGgWzHR.js.map
197
+ //# sourceMappingURL=litellm-C5Ek8B0K.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"litellm-BaGgWzHR.js","names":[],"sources":["../../src/shared/providers/litellm.ts"],"sourcesContent":["import { ValidationError } from '@happyvertical/utils';\n\nimport {\n normalizeChatOptions,\n normalizeImageGenerationOptions,\n} from '../safety';\nimport type {\n AICapabilities,\n AIMessage,\n AIModel,\n AIResponse,\n ChatOptions,\n EmbeddingOptions,\n EmbeddingResponse,\n ImageDescriptionOptions,\n ImageEmbeddingOptions,\n ImageGenerationOptions,\n ImageGenerationResponse,\n LiteLLMOptions,\n} from '../types';\nimport { LiteLLMAdmin, resolveGatewayAdminBaseUrl } from './gateway-admin';\nimport {\n isAudioModel,\n isSpeechModel,\n isTranscriptionModel,\n} from './gateway-audio-models';\nimport { type OpenAICompatibleProfile, OpenAIProvider } from './openai';\n\n/** Chat Completions has effort, not a generic reasoning budget/thoughts envelope. */\nfunction assertChatReasoningControls(\n options: Pick<ChatOptions, 'reasoning' | 'includeThoughts'>,\n): void {\n if (\n options.reasoning?.maxTokens !== undefined ||\n options.reasoning?.includeThoughts !== undefined ||\n options.includeThoughts !== undefined\n ) {\n throw new ValidationError(\n 'LiteLLM Chat Completions does not support generic reasoning.maxTokens or includeThoughts controls; use reasoning.effort and an output token limit',\n { provider: 'litellm' },\n );\n }\n}\n\nconst LITELLM_CAPABILITIES: AICapabilities = {\n chat: true,\n completion: true,\n embeddings: true,\n streaming: true,\n functions: true,\n vision: true,\n fineTuning: false,\n imageEmbeddings: true,\n imageGeneration: true,\n videoGeneration: false,\n tts: false,\n voiceCloning: false,\n voiceDesign: false,\n maxContextLength: 128000,\n supportedOperations: [\n 'chat',\n 'completion',\n 'embedding',\n 'streaming',\n 'functions',\n 'vision',\n 'image_embedding',\n 'image_generation',\n ],\n};\n\nfunction isEmbeddingModel(modelId: string): boolean {\n return /embed/i.test(modelId);\n}\n\nfunction isImageEmbeddingModel(modelId: string): boolean {\n return /titan-embed-image|multimodalembedding|image[-_]?embed|clip/i.test(\n modelId,\n );\n}\n\nfunction isImageGenerationModel(modelId: string): boolean {\n return /gpt-image|dall-e|imagen|stable[-_ ]diffusion|sdxl|flux|titan-image|image-generator/i.test(\n modelId,\n );\n}\n\nfunction isFilteredLiteLLMModel(modelId: string): boolean {\n return /moderation|rerank/i.test(modelId);\n}\n\nfunction inferLiteLLMContextLength(modelId: string): number {\n if (isEmbeddingModel(modelId)) return 8192;\n if (/gemini-1\\.5|gemini-2\\.0|gemini-2\\.5|gemini-3/i.test(modelId)) {\n return 1000000;\n }\n if (/claude/i.test(modelId)) return 200000;\n if (/gpt-4o|gpt-4\\.1|o1|o3|o4|llama|mistral|qwen|deepseek/i.test(modelId)) {\n return 128000;\n }\n return 32768;\n}\n\nfunction inferLiteLLMFunctions(modelId: string): boolean {\n if (isEmbeddingModel(modelId) || isAudioModel(modelId)) return false;\n return /gpt|claude|gemini|command|llama|mistral|qwen|deepseek|o1|o3|o4/i.test(\n modelId,\n );\n}\n\nfunction inferLiteLLMVision(modelId: string): boolean {\n if (isAudioModel(modelId)) return false;\n return /gpt-4o|gpt-4\\.1|vision|claude-3|gemini|pixtral|llava|qwen.*vl|vl-/i.test(\n modelId,\n );\n}\n\nfunction inferLiteLLMCapabilities(modelId: string): string[] {\n if (isTranscriptionModel(modelId)) {\n return ['transcription'];\n }\n\n if (isSpeechModel(modelId)) {\n return ['speech'];\n }\n\n if (isImageGenerationModel(modelId)) {\n return ['image_generation'];\n }\n\n if (isImageEmbeddingModel(modelId)) {\n return ['embeddings', 'image_embedding'];\n }\n\n if (isEmbeddingModel(modelId)) {\n return ['embeddings'];\n }\n\n const capabilities = ['text', 'chat'];\n\n if (inferLiteLLMFunctions(modelId)) {\n capabilities.push('functions');\n }\n\n if (inferLiteLLMVision(modelId)) {\n capabilities.push('vision');\n }\n\n return capabilities;\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n}\n\nfunction ensureLiteLLMOptions(options: LiteLLMOptions): LiteLLMOptions {\n if (!options.baseUrl?.trim()) {\n throw new ValidationError('LiteLLM baseUrl is required', {\n provider: 'litellm',\n hint: 'Pass baseUrl like https://llm.happyvertical.com/v1 or set HAVE_AI_BASE_URL / LITELLM_BASE_URL',\n });\n }\n\n return {\n ...options,\n baseUrl: normalizeBaseUrl(options.baseUrl.trim()),\n };\n}\n\nconst LITELLM_PROFILE: OpenAICompatibleProfile = {\n providerLabel: 'LiteLLM',\n providerName: 'litellm',\n defaultModel: 'gpt-4',\n capabilities: LITELLM_CAPABILITIES,\n describeModel: (modelId) => `LiteLLM model: ${modelId}`,\n getContextLength: inferLiteLLMContextLength,\n getModelCapabilities: inferLiteLLMCapabilities,\n shouldIncludeModel: (modelId) => !isFilteredLiteLLMModel(modelId),\n supportsFunctions: inferLiteLLMFunctions,\n supportsVision: inferLiteLLMVision,\n};\n\ntype LiteLLMResolvedCapability =\n | 'chat'\n | 'vision'\n | 'embeddings'\n | 'image_generation';\n\nfunction supportsCapability(\n model: AIModel,\n capability: LiteLLMResolvedCapability,\n): boolean {\n if (capability === 'vision') {\n return (\n model.capabilities.includes('vision') || model.supportsVision === true\n );\n }\n\n if (capability === 'embeddings') {\n return model.capabilities.includes('embeddings');\n }\n\n if (capability === 'image_generation') {\n return model.capabilities.includes('image_generation');\n }\n\n return model.capabilities.includes('chat');\n}\n\n/**\n * LiteLLM provider implementation.\n *\n * LiteLLM exposes an OpenAI-compatible API surface, so this provider reuses the\n * OpenAI transport while customizing provider identity, model discovery, and\n * capability heuristics for gateway-backed deployments.\n */\nexport class LiteLLMProvider extends OpenAIProvider {\n readonly admin: LiteLLMAdmin;\n private readonly configuredDefaultModel?: string;\n private readonly resolvedModelCache = new Map<\n LiteLLMResolvedCapability,\n Promise<string>\n >();\n\n constructor(options: LiteLLMOptions) {\n const normalized = ensureLiteLLMOptions(options);\n super(normalized, LITELLM_PROFILE);\n this.admin = new LiteLLMAdmin({\n provider: 'litellm',\n baseUrl: resolveGatewayAdminBaseUrl(\n normalized.baseUrl,\n normalized.adminUrl || normalized.adminBaseUrl,\n 'litellm',\n ),\n apiKey: normalized.adminApiKey || normalized.apiKey,\n headers: normalized.adminHeaders,\n timeout: normalized.timeout,\n });\n this.configuredDefaultModel = normalized.defaultModel;\n }\n\n private async resolveModel(\n capability: LiteLLMResolvedCapability,\n explicitModel?: string,\n ): Promise<string> {\n if (explicitModel) {\n return explicitModel;\n }\n\n if (\n this.configuredDefaultModel &&\n (capability === 'chat' || capability === 'vision')\n ) {\n return this.configuredDefaultModel;\n }\n\n const cached = this.resolvedModelCache.get(capability);\n if (cached) {\n return cached;\n }\n\n const pending = this.selectModel(capability).catch((error) => {\n this.resolvedModelCache.delete(capability);\n throw error;\n });\n this.resolvedModelCache.set(capability, pending);\n return pending;\n }\n\n private async selectModel(\n capability: LiteLLMResolvedCapability,\n ): Promise<string> {\n const models = await super.getModels();\n const model = models.find((candidate) =>\n supportsCapability(candidate, capability),\n );\n\n if (!model) {\n throw new ValidationError(\n `No ${capability} model is available from the LiteLLM gateway`,\n {\n provider: 'litellm',\n capability,\n hint: 'Pass defaultModel explicitly or ensure /models returns a compatible model for this key',\n },\n );\n }\n\n return model.id;\n }\n\n async chat(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): Promise<AIResponse> {\n assertChatReasoningControls(options);\n const safe = normalizeChatOptions(\n this.options,\n options,\n 'litellm',\n options.model || this.options.defaultModel,\n );\n return super.chat(messages, {\n ...safe,\n model: await this.resolveModel('chat', safe.model),\n });\n }\n\n async *stream(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): AsyncIterable<string> {\n assertChatReasoningControls(options);\n const safe = normalizeChatOptions(\n this.options,\n options,\n 'litellm',\n options.model || this.options.defaultModel,\n );\n yield* super.stream(messages, {\n ...safe,\n model: await this.resolveModel('chat', safe.model),\n });\n }\n\n async describeImage(\n image: string | Buffer,\n prompt?: string,\n options: ImageDescriptionOptions = {},\n ): Promise<string> {\n assertChatReasoningControls(options);\n const safe = normalizeChatOptions(\n this.options,\n options,\n 'litellm',\n options.model || this.options.defaultModel,\n );\n return super.describeImage(image, prompt, {\n ...safe,\n // The inherited image path calls this.chat(); do not reclassify the\n // normalization-inferred budget as an explicit caller control.\n reasoning: options.reasoning,\n model: await this.resolveModel('vision', safe.model),\n });\n }\n\n async embed(\n text: string | string[],\n options: EmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n return super.embed(text, {\n ...options,\n model: await this.resolveModel('embeddings', options.model),\n });\n }\n\n async embedImage(\n image: string | Buffer,\n options: ImageEmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n return super.embedImage(image, {\n ...options,\n model: await this.resolveModel('embeddings', options.model),\n });\n }\n\n async generateImage(\n prompt: string,\n options: ImageGenerationOptions = {},\n ): Promise<ImageGenerationResponse> {\n const safe = normalizeImageGenerationOptions(\n this.options,\n options,\n 'litellm',\n options.model,\n );\n return super.generateImage(prompt, {\n ...safe,\n model: await this.resolveModel('image_generation', safe.model),\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"litellm-C5Ek8B0K.js","names":[],"sources":["../../src/shared/providers/litellm.ts"],"sourcesContent":["import { ValidationError } from '@happyvertical/utils';\n\nimport {\n normalizeChatOptions,\n normalizeImageGenerationOptions,\n} from '../safety';\nimport type {\n AICapabilities,\n AIMessage,\n AIModel,\n AIResponse,\n ChatOptions,\n EmbeddingOptions,\n EmbeddingResponse,\n ImageDescriptionOptions,\n ImageEmbeddingOptions,\n ImageGenerationOptions,\n ImageGenerationResponse,\n LiteLLMOptions,\n} from '../types';\nimport { LiteLLMAdmin, resolveGatewayAdminBaseUrl } from './gateway-admin';\nimport {\n isAudioModel,\n isSpeechModel,\n isTranscriptionModel,\n} from './gateway-audio-models';\nimport { type OpenAICompatibleProfile, OpenAIProvider } from './openai';\n\n/** Chat Completions has effort, not a generic reasoning budget/thoughts envelope. */\nfunction assertChatReasoningControls(\n options: Pick<ChatOptions, 'reasoning' | 'includeThoughts'>,\n): void {\n if (\n options.reasoning?.maxTokens !== undefined ||\n options.reasoning?.includeThoughts !== undefined ||\n options.includeThoughts !== undefined\n ) {\n throw new ValidationError(\n 'LiteLLM Chat Completions does not support generic reasoning.maxTokens or includeThoughts controls; use reasoning.effort and an output token limit',\n { provider: 'litellm' },\n );\n }\n}\n\nconst LITELLM_CAPABILITIES: AICapabilities = {\n chat: true,\n completion: true,\n embeddings: true,\n streaming: true,\n functions: true,\n vision: true,\n fineTuning: false,\n imageEmbeddings: true,\n imageGeneration: true,\n videoGeneration: false,\n tts: false,\n voiceCloning: false,\n voiceDesign: false,\n maxContextLength: 128000,\n supportedOperations: [\n 'chat',\n 'completion',\n 'embedding',\n 'streaming',\n 'functions',\n 'vision',\n 'image_embedding',\n 'image_generation',\n ],\n};\n\nfunction isEmbeddingModel(modelId: string): boolean {\n return /embed/i.test(modelId);\n}\n\nfunction isImageEmbeddingModel(modelId: string): boolean {\n return /titan-embed-image|multimodalembedding|image[-_]?embed|clip/i.test(\n modelId,\n );\n}\n\nfunction isImageGenerationModel(modelId: string): boolean {\n return /gpt-image|dall-e|imagen|stable[-_ ]diffusion|sdxl|flux|titan-image|image-generator/i.test(\n modelId,\n );\n}\n\nfunction isFilteredLiteLLMModel(modelId: string): boolean {\n return /moderation|rerank/i.test(modelId);\n}\n\nfunction inferLiteLLMContextLength(modelId: string): number {\n if (isEmbeddingModel(modelId)) return 8192;\n if (/gemini-1\\.5|gemini-2\\.0|gemini-2\\.5|gemini-3/i.test(modelId)) {\n return 1000000;\n }\n if (/claude/i.test(modelId)) return 200000;\n if (/gpt-4o|gpt-4\\.1|o1|o3|o4|llama|mistral|qwen|deepseek/i.test(modelId)) {\n return 128000;\n }\n return 32768;\n}\n\nfunction inferLiteLLMFunctions(modelId: string): boolean {\n if (isEmbeddingModel(modelId) || isAudioModel(modelId)) return false;\n return /gpt|claude|gemini|command|llama|mistral|qwen|deepseek|o1|o3|o4/i.test(\n modelId,\n );\n}\n\nfunction inferLiteLLMVision(modelId: string): boolean {\n if (isAudioModel(modelId)) return false;\n return /gpt-4o|gpt-4\\.1|vision|claude-3|gemini|pixtral|llava|qwen.*vl|vl-/i.test(\n modelId,\n );\n}\n\nfunction inferLiteLLMCapabilities(modelId: string): string[] {\n if (isTranscriptionModel(modelId)) {\n return ['transcription'];\n }\n\n if (isSpeechModel(modelId)) {\n return ['speech'];\n }\n\n if (isImageGenerationModel(modelId)) {\n return ['image_generation'];\n }\n\n if (isImageEmbeddingModel(modelId)) {\n return ['embeddings', 'image_embedding'];\n }\n\n if (isEmbeddingModel(modelId)) {\n return ['embeddings'];\n }\n\n const capabilities = ['text', 'chat'];\n\n if (inferLiteLLMFunctions(modelId)) {\n capabilities.push('functions');\n }\n\n if (inferLiteLLMVision(modelId)) {\n capabilities.push('vision');\n }\n\n return capabilities;\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n}\n\nfunction ensureLiteLLMOptions(options: LiteLLMOptions): LiteLLMOptions {\n if (!options.baseUrl?.trim()) {\n throw new ValidationError('LiteLLM baseUrl is required', {\n provider: 'litellm',\n hint: 'Pass baseUrl like https://llm.happyvertical.com/v1 or set HAVE_AI_BASE_URL / LITELLM_BASE_URL',\n });\n }\n\n return {\n ...options,\n baseUrl: normalizeBaseUrl(options.baseUrl.trim()),\n };\n}\n\nconst LITELLM_PROFILE: OpenAICompatibleProfile = {\n providerLabel: 'LiteLLM',\n providerName: 'litellm',\n defaultModel: 'gpt-4',\n capabilities: LITELLM_CAPABILITIES,\n describeModel: (modelId) => `LiteLLM model: ${modelId}`,\n getContextLength: inferLiteLLMContextLength,\n getModelCapabilities: inferLiteLLMCapabilities,\n shouldIncludeModel: (modelId) => !isFilteredLiteLLMModel(modelId),\n supportsFunctions: inferLiteLLMFunctions,\n supportsVision: inferLiteLLMVision,\n};\n\ntype LiteLLMResolvedCapability =\n | 'chat'\n | 'vision'\n | 'embeddings'\n | 'image_generation';\n\nfunction supportsCapability(\n model: AIModel,\n capability: LiteLLMResolvedCapability,\n): boolean {\n if (capability === 'vision') {\n return (\n model.capabilities.includes('vision') || model.supportsVision === true\n );\n }\n\n if (capability === 'embeddings') {\n return model.capabilities.includes('embeddings');\n }\n\n if (capability === 'image_generation') {\n return model.capabilities.includes('image_generation');\n }\n\n return model.capabilities.includes('chat');\n}\n\n/**\n * LiteLLM provider implementation.\n *\n * LiteLLM exposes an OpenAI-compatible API surface, so this provider reuses the\n * OpenAI transport while customizing provider identity, model discovery, and\n * capability heuristics for gateway-backed deployments.\n */\nexport class LiteLLMProvider extends OpenAIProvider {\n readonly admin: LiteLLMAdmin;\n private readonly configuredDefaultModel?: string;\n private readonly resolvedModelCache = new Map<\n LiteLLMResolvedCapability,\n Promise<string>\n >();\n\n constructor(options: LiteLLMOptions) {\n const normalized = ensureLiteLLMOptions(options);\n super(normalized, LITELLM_PROFILE);\n this.admin = new LiteLLMAdmin({\n provider: 'litellm',\n baseUrl: resolveGatewayAdminBaseUrl(\n normalized.baseUrl,\n normalized.adminUrl || normalized.adminBaseUrl,\n 'litellm',\n ),\n apiKey: normalized.adminApiKey || normalized.apiKey,\n headers: normalized.adminHeaders,\n timeout: normalized.timeout,\n });\n this.configuredDefaultModel = normalized.defaultModel;\n }\n\n private async resolveModel(\n capability: LiteLLMResolvedCapability,\n explicitModel?: string,\n ): Promise<string> {\n if (explicitModel) {\n return explicitModel;\n }\n\n if (\n this.configuredDefaultModel &&\n (capability === 'chat' || capability === 'vision')\n ) {\n return this.configuredDefaultModel;\n }\n\n const cached = this.resolvedModelCache.get(capability);\n if (cached) {\n return cached;\n }\n\n const pending = this.selectModel(capability).catch((error) => {\n this.resolvedModelCache.delete(capability);\n throw error;\n });\n this.resolvedModelCache.set(capability, pending);\n return pending;\n }\n\n private async selectModel(\n capability: LiteLLMResolvedCapability,\n ): Promise<string> {\n const models = await super.getModels();\n const model = models.find((candidate) =>\n supportsCapability(candidate, capability),\n );\n\n if (!model) {\n throw new ValidationError(\n `No ${capability} model is available from the LiteLLM gateway`,\n {\n provider: 'litellm',\n capability,\n hint: 'Pass defaultModel explicitly or ensure /models returns a compatible model for this key',\n },\n );\n }\n\n return model.id;\n }\n\n async chat(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): Promise<AIResponse> {\n assertChatReasoningControls(options);\n const safe = normalizeChatOptions(\n this.options,\n options,\n 'litellm',\n options.model || this.options.defaultModel,\n );\n return super.chat(messages, {\n ...safe,\n model: await this.resolveModel('chat', safe.model),\n });\n }\n\n async *stream(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): AsyncIterable<string> {\n assertChatReasoningControls(options);\n const safe = normalizeChatOptions(\n this.options,\n options,\n 'litellm',\n options.model || this.options.defaultModel,\n );\n yield* super.stream(messages, {\n ...safe,\n model: await this.resolveModel('chat', safe.model),\n });\n }\n\n async describeImage(\n image: string | Buffer,\n prompt?: string,\n options: ImageDescriptionOptions = {},\n ): Promise<string> {\n assertChatReasoningControls(options);\n const safe = normalizeChatOptions(\n this.options,\n options,\n 'litellm',\n options.model || this.options.defaultModel,\n );\n return super.describeImage(image, prompt, {\n ...safe,\n // The inherited image path calls this.chat(); do not reclassify the\n // normalization-inferred budget as an explicit caller control.\n reasoning: options.reasoning,\n model: await this.resolveModel('vision', safe.model),\n });\n }\n\n async embed(\n text: string | string[],\n options: EmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n return super.embed(text, {\n ...options,\n model: await this.resolveModel('embeddings', options.model),\n });\n }\n\n async embedImage(\n image: string | Buffer,\n options: ImageEmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n return super.embedImage(image, {\n ...options,\n model: await this.resolveModel('embeddings', options.model),\n });\n }\n\n async generateImage(\n prompt: string,\n options: ImageGenerationOptions = {},\n ): Promise<ImageGenerationResponse> {\n const safe = normalizeImageGenerationOptions(\n this.options,\n options,\n 'litellm',\n options.model,\n );\n return super.generateImage(prompt, {\n ...safe,\n model: await this.resolveModel('image_generation', safe.model),\n });\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { b as extractTextContent, c as normalizeImageGenerationOptions, f as AuthenticationError, g as ModelNotFoundError, l as prepareRequestControls, m as ContextLengthError, o as normalizeBaseAIOptions, p as ContentFilterError, s as normalizeChatOptions, t as emitUsage, u as AIError } from "./usage-B9gPCWSa.js";
2
- import { n as rateLimitErrorFrom } from "./rate-limit-BkK4-hXY.js";
3
- import { n as resolveContinuation } from "./continuation-L5KnnE9R.js";
1
+ import { b as extractTextContent, c as normalizeImageGenerationOptions, f as AuthenticationError, g as ModelNotFoundError, l as prepareRequestControls, m as ContextLengthError, o as normalizeBaseAIOptions, p as ContentFilterError, s as normalizeChatOptions, t as emitUsage, u as AIError } from "./usage-DS7uDhi1.js";
2
+ import { n as rateLimitErrorFrom } from "./rate-limit-Dwyde1BY.js";
3
+ import { n as resolveContinuation } from "./continuation-BMGvMlzq.js";
4
4
  import { i as resolveToolResultName, n as indexToolCallNames } from "./tool-messages-0ND35mYX.js";
5
5
  import { ValidationError } from "@happyvertical/utils";
6
6
  //#region src/shared/providers/ollama.ts
@@ -669,4 +669,4 @@ var OllamaProvider = class {
669
669
  //#endregion
670
670
  export { OllamaProvider };
671
671
 
672
- //# sourceMappingURL=ollama-C3T3mn68.js.map
672
+ //# sourceMappingURL=ollama-CuDjAyTy.js.map