@matthew.ngo/ai-toolkit
Version:
A comprehensive AI toolkit with multi-provider support
189 lines (156 loc) • 59.3 kB
JavaScript
import {useState,useRef,useEffect,useCallback}from'react';import W from'@anthropic-ai/sdk';import {GoogleGenerativeAI}from'@google/generative-ai';import V from'openai';import {LRUCache}from'lru-cache';import Y from'crypto';import {z}from'zod';import ee from'@hapi/boom';import te from'verror';import E from'bottleneck';import re,{AbortError}from'p-retry';import {backOff}from'exponential-backoff';import {encode}from'gpt-tokenizer';import {encoding_for_model,get_encoding}from'tiktoken';var v=class{events=[];maxEvents=1e5;stats={tokensUsed:0,requestsCount:0,costEstimate:0,lastReset:new Date,byProvider:{},byModel:{},byCapability:{},errors:[]};trackEvent(e){let t={...e,timestamp:new Date};this.events.push(t),this.updateStats(t),this.events.length>this.maxEvents&&(this.events=this.events.slice(-this.maxEvents/2));}updateStats(e){if(!this.stats.byProvider){console.warn("No provider stats initialized.");return}e.type==="success"&&(this.stats.requestsCount++,e.tokens&&(this.stats.tokensUsed+=e.tokens.total),e.cost&&(this.stats.costEstimate+=e.cost)),this.stats.byProvider[e.provider]||(this.stats.byProvider[e.provider]={requests:0,tokens:0,cost:0,averageLatency:0,errorRate:0});let t=this.stats.byProvider[e.provider];if(!t){console.warn(`Unknown provider ${e.provider}.`);return}if((e.type==="success"||e.type==="error")&&t.requests++,e.type==="success"&&(e.tokens&&(t.tokens+=e.tokens.total),e.cost&&(t.cost+=e.cost),e.latency)){let r=t.averageLatency*(t.requests-1);t.averageLatency=(r+e.latency)/t.requests;}if(e.type==="error"&&(t.errorRate=this.calculateErrorRate(e.provider)),!this.stats.byModel){console.warn("No model stats initialized.");return}if(e.model){this.stats.byModel[e.model]||(this.stats.byModel[e.model]={requests:0,tokens:0,inputTokens:0,outputTokens:0,cost:0});let r=this.stats.byModel[e.model];if(!r){console.warn(`Unknown model ${e.model}.`);return}e.type==="success"&&(r.requests++,e.tokens&&(r.tokens+=e.tokens.total,r.inputTokens+=e.tokens.prompt,r.outputTokens+=e.tokens.completion),e.cost&&(r.cost+=e.cost));}if(!this.stats.byCapability){console.warn("No capability stats initialized.");return}this.stats.byCapability[e.operation]||(this.stats.byCapability[e.operation]=0),e.type==="success"&&this.stats.byCapability[e.operation]++,e.type==="error"&&e.error&&this.updateErrorStats(e);}calculateErrorRate(e){let t=this.events.filter(s=>s.provider===e),r=t.filter(s=>s.type==="error").length,n=t.filter(s=>s.type==="success"||s.type==="error").length;return n>0?r/n:0}updateErrorStats(e){if(!e.error)return;let t=this.stats.errors?.find(r=>r.error===e.error&&r.provider===e.provider);t?t.count++:this.stats.errors?.push({timestamp:e.timestamp,provider:e.provider,error:e.error,count:1}),this.stats.errors&&this.stats.errors.length>100&&(this.stats.errors=this.stats.errors.sort((r,n)=>n.timestamp.getTime()-r.timestamp.getTime()).slice(0,50));}getStats(){return {...this.stats,byProvider:{...this.stats.byProvider},byModel:{...this.stats.byModel},byCapability:{...this.stats.byCapability},errors:[...this.stats.errors||[]]}}getTrends(e="day",t=30){let r={hour:36e5,day:864e5,week:6048e5,month:2592e6}[e],n=Date.now(),s=[];for(let i=0;i<t;i++){let o=n-i*r,a=o-r,c=this.events.filter(p=>{let g=p.timestamp.getTime();return g>=a&&g<o}),m=c.filter(p=>p.type==="success");s.unshift({timestamp:new Date(o).toISOString(),requests:m.length,tokens:m.reduce((p,g)=>p+(g.tokens?.total||0),0),cost:m.reduce((p,g)=>p+(g.cost||0),0),errors:c.filter(p=>p.type==="error").length});}return s}getTopOperations(e=10){if(!this.stats.byCapability)return [];let t=Object.values(this.stats.byCapability).reduce((r,n)=>r+n,0);return Object.entries(this.stats.byCapability).map(([r,n])=>({operation:r,count:n,percentage:t>0?n/t*100:0})).sort((r,n)=>n.count-r.count).slice(0,e)}getCostBreakdown(){if(!this.stats.byProvider||!this.stats.byModel)return {};let e={};return this.events.filter(t=>t.type==="success"&&t.cost).forEach(t=>{e[t.operation]=(e[t.operation]||0)+(t.cost||0);}),{total:this.stats.costEstimate,byProvider:Object.entries(this.stats.byProvider).reduce((t,[r,n])=>(t[r]=n.cost,t),{}),byModel:Object.entries(this.stats.byModel).reduce((t,[r,n])=>(t[r]=n.cost,t),{}),byOperation:e}}getProviderComparison(){if(!this.stats.byProvider)return [];let e=Object.entries(this.stats.byProvider).map(([s,i])=>({provider:s,stats:i})),t=[...e].sort((s,i)=>s.stats.averageLatency-i.stats.averageLatency),r=[...e].sort((s,i)=>s.stats.errorRate-i.stats.errorRate),n=[...e].sort((s,i)=>s.stats.cost/s.stats.tokens-i.stats.cost/i.stats.tokens);return e.map(({provider:s,stats:i})=>{let o=t.findIndex(m=>m.provider===s)+1,a=r.findIndex(m=>m.provider===s)+1,c=n.findIndex(m=>m.provider===s)+1;return {provider:s,stats:i,rank:{speed:o,reliability:a,cost:c,overall:Math.round((o+a+c)/3)}}})}getRecommendations(){let e=[],t=this.getStats(),r=this.getProviderComparison();t.costEstimate>100&&e.push("Consider using cheaper models for simple tasks to reduce costs"),r.forEach(({provider:a,stats:c})=>{c.errorRate>.05&&e.push(`${a} has high error rate (${(c.errorRate*100).toFixed(1)}%). Consider using fallback providers.`),c.averageLatency>5e3&&e.push(`${a} has high latency. Enable caching for frequently used prompts.`);});let n=this.events.filter(a=>a.type==="cache_hit").length,s=t.requestsCount;return (s>0?n/s:0)<.2&&s>100&&e.push("Low cache hit rate. Consider increasing cache TTL or size."),this.events.filter(a=>a.type==="rate_limit").length>10&&e.push("Frequent rate limiting detected. Implement request queuing or upgrade API limits."),e}reset(){this.stats={tokensUsed:0,requestsCount:0,costEstimate:0,lastReset:new Date,byProvider:{},byModel:{},byCapability:{},errors:[]},this.events=[];}exportData(){return {stats:this.getStats(),trends:this.getTrends(),topOperations:this.getTopOperations(),costBreakdown:this.getCostBreakdown(),providerComparison:this.getProviderComparison(),recommendations:this.getRecommendations()}}};var x=class{metrics=new Map;history=[];maxHistorySize=1e4;windowSize=3e5;startOperation(e,t,r,n){this.metrics.set(e,{operationId:e,operation:t,provider:r,startTime:performance.now(),success:false,metadata:n});}endOperation(e,t=true,r){let n=this.metrics.get(e);if(!n)return null;n.endTime=performance.now(),n.duration=n.endTime-n.startTime,n.success=t,n.error=r;let s={operationId:n.operationId,operation:n.operation,provider:n.provider,duration:n.duration,success:n.success,error:n.error,timestamp:new Date().toISOString()};return this.history.push(s),this.metrics.delete(e),this.history.length>this.maxHistorySize&&(this.history=this.history.slice(-this.maxHistorySize/2)),s}getStats(e){let t=Date.now()-(e?.timeWindow||this.windowSize),r=this.history.filter(o=>new Date(o.timestamp).getTime()>t);if(e?.provider&&(r=r.filter(o=>o.provider===e.provider)),e?.operation&&(r=r.filter(o=>o.operation===e.operation)),r.length===0)return {averageLatency:0,minLatency:0,maxLatency:0,successRate:0,errorRate:0,throughput:0,percentiles:{p50:0,p90:0,p95:0,p99:0}};let n=r.map(o=>o.duration).sort((o,a)=>o-a),s=r.filter(o=>o.success).length,i=r.length;return {averageLatency:n.reduce((o,a)=>o+a,0)/n.length,minLatency:n[0]??0,maxLatency:n[n.length-1]??0,successRate:s/i,errorRate:(i-s)/i,throughput:i/((e?.timeWindow||this.windowSize)/1e3),percentiles:{p50:this.getPercentile(n,50),p90:this.getPercentile(n,90),p95:this.getPercentile(n,95),p99:this.getPercentile(n,99)}}}getStatsByProvider(){let e=new Set(this.history.map(r=>r.provider)),t={};for(let r of e)t[r]=this.getStats({provider:r});return t}getStatsByOperation(){let e=new Set(this.history.map(r=>r.operation)),t={};for(let r of e)t[r]=this.getStats({operation:r});return t}getTrends(e="hour",t=24){let r={minute:6e4,hour:36e5,day:864e5}[e],n=Date.now(),s=[];for(let i=0;i<t;i++){let o=n-i*r,a=o-r,c=this.getStats({timeWindow:n-a});s.unshift({timestamp:new Date(o).toISOString(),stats:c});}return s}getErrorAnalysis(){let e=this.history.filter(i=>!i.success&&i.error),t=new Map,r={};for(let i of e)i.error&&(t.set(i.error,(t.get(i.error)||0)+1),r[i.provider]=(r[i.provider]||0)+1);let n=Array.from(t.entries()).map(([i,o])=>({error:i,count:o})).sort((i,o)=>o.count-i.count).slice(0,10),s={timeout:0,rateLimit:0,authentication:0,network:0,other:0};for(let[i,o]of t)i.includes("timeout")?s.timeout=(s.timeout??0)+o:i.includes("rate limit")?s.rateLimit=(s.rateLimit??0)+o:i.includes("auth")||i.includes("401")?s.authentication=(s.authentication??0)+o:i.includes("network")?s.network=(s.network??0)+o:s.other=(s.other??0)+o;return {totalErrors:e.length,errorsByType:s,errorsByProvider:r,commonErrors:n}}getSlowOperations(e){let t=this.getStats().percentiles.p95,r=e||t||5e3;return this.history.filter(n=>n.duration>r).sort((n,s)=>s.duration-n.duration).slice(0,100)}getPercentile(e,t){let r=Math.ceil(t/100*e.length)-1;return e[Math.max(0,r)]??0}clearHistory(){this.history=[],this.metrics.clear();}exportData(){return {history:this.history,stats:this.getStats(),statsByProvider:this.getStatsByProvider(),statsByOperation:this.getStatsByOperation(),errorAnalysis:this.getErrorAnalysis()}}getActiveOperations(){return Array.from(this.metrics.values())}getHealthStatus(){let e=this.getStats(),t=[];return e.successRate<.95&&t.push(`Low success rate: ${(e.successRate*100).toFixed(1)}%`),e.percentiles.p95>5e3&&t.push(`High P95 latency: ${e.percentiles.p95.toFixed(0)}ms`),e.throughput<.1&&t.push(`Low throughput: ${e.throughput.toFixed(2)} req/s`),{status:t.length===0?"healthy":t.length===1?"degraded":"unhealthy",issues:t}}};var y=class{name;config;defaultModel;constructor(e){this.name=e.name,this.config=e,this.defaultModel=e.model||this.getDefaultModel();}validateApiKey(){if(!this.config.apiKey)throw new Error(`API key required for ${this.name} provider`)}getHeaders(e){return {"Content-Type":"application/json",...this.config.headers,...e}}async makeRequest(e,t){let r=this.config.timeout||3e4,n=new AbortController,s=setTimeout(()=>n.abort(),r);try{let i=await fetch(e,{...t,signal:n.signal});if(!i.ok)throw await this.parseError(i);return await i.json()}catch(i){throw i.name==="AbortError"?new Error(`Request timeout after ${r}ms`):i}finally{clearTimeout(s);}}async parseError(e){let t=`${this.name} API error: ${e.status} ${e.statusText}`;try{let n=await e.json();n.error?.message?t=n.error.message:n.message&&(t=n.message);}catch{}let r=new Error(t);return r.status=e.status,r.provider=this.name,r}getModel(e){return e?.model||this.config.model||this.defaultModel}async generateText(e,t){throw new Error(`Text generation not implemented for ${this.name} provider`)}async*generateStream(e,t){throw new Error(`Stream generation not implemented for ${this.name} provider`)}async generateEmbedding(e){throw new Error(`Embedding generation not implemented for ${this.name} provider`)}async classifyText(e,t){throw new Error(`Text classification not implemented for ${this.name} provider`)}async summarize(e,t){throw new Error(`Text summarization not implemented for ${this.name} provider`)}async analyzeSentiment(e){throw new Error(`Sentiment analysis not implemented for ${this.name} provider`)}async generateImage(e,t){throw new Error(`Image generation not implemented for ${this.name} provider`)}async analyzeImage(e,t){throw new Error(`Image analysis not implemented for ${this.name} provider`)}async transcribeAudio(e,t){throw new Error(`Audio transcription not implemented for ${this.name} provider`)}async generateSpeech(e,t){throw new Error(`Speech generation not implemented for ${this.name} provider`)}async generateCode(e,t){throw new Error(`Code generation not implemented for ${this.name} provider`)}async explainCode(e,t){throw new Error(`Code explanation not implemented for ${this.name} provider`)}};var k=class extends y{client;constructor(e){super(e),this.validateApiKey(),this.client=new W({apiKey:this.config.apiKey,baseURL:this.config.baseUrl,timeout:this.config.timeout,maxRetries:this.config.maxRetries||2});}getDefaultModel(){return "claude-3-sonnet-20240229"}async generateText(e,t){let r=this.getModel(t);return (await this.client.messages.create({model:r,messages:[{role:"user",content:e}],system:t?.systemPrompt,max_tokens:t?.maxTokens||1e3,temperature:t?.temperature,top_p:t?.topP,top_k:t?.topK,stop_sequences:t?.stopSequences,stream:false})).content.filter(i=>i.type==="text").map(i=>i.text).join(`
`)}async*generateStream(e,t){let r=this.getModel(t),n=await this.client.messages.create({model:r,messages:[{role:"user",content:e}],system:t?.systemPrompt,max_tokens:t?.maxTokens||1e3,temperature:t?.temperature,top_p:t?.topP,top_k:t?.topK,stop_sequences:t?.stopSequences,stream:true});for await(let s of n)s.type==="content_block_delta"&&s.delta.type==="text_delta"&&(yield s.delta.text);}async classifyText(e,t){let r=`Classify this text into exactly one category from: ${t.join(", ")}.
Text: "${e}"
Respond with a JSON object:
{
"label": "chosen category",
"confidence": 0.0-1.0,
"scores": { "category1": 0.0-1.0, ... }
}`,n=await this.generateText(r,{temperature:0,maxTokens:200});try{let i=n.match(/\{[\s\S]*\}/);if(i)return JSON.parse(i[0])}catch{}let s=t[0]??"";return {label:s,confidence:.5,scores:t.reduce((i,o)=>({...i,[o]:o===s?.5:.5/(t.length-1)}),{})}}async summarize(e,t){let n=`${{bullet:"Create a bullet-point summary with key points",paragraph:"Write a concise paragraph summary",tldr:"Write a one-sentence TL;DR","key-points":"Extract the most important key points",executive:"Write an executive summary for business leaders"}[t?.style||"paragraph"]} of the following text.
${t?.maxLength?`Keep it under ${t.maxLength} characters.`:""}
Text:
"${e}"
Summary:`;return this.generateText(n,{maxTokens:t?.maxLength?Math.ceil(t.maxLength/4):200,temperature:.3})}async analyzeSentiment(e){let t=`Analyze the sentiment of the following text. Respond with JSON:
{
"sentiment": "positive" | "negative" | "neutral" | "mixed",
"score": 0.0-1.0,
"aspects": [
{ "aspect": "...", "sentiment": "...", "score": 0.0-1.0 }
]
}
Text: "${e}"`,r=await this.generateText(t,{temperature:0,maxTokens:300});try{let n=r.match(/\{[\s\S]*\}/);if(n)return JSON.parse(n[0])}catch{}return {sentiment:"neutral",score:.5,aspects:[]}}async generateEmbedding(e){throw new Error("Embeddings not supported by Anthropic. Use a different provider.")}async generateCode(e,t){let r=`You are Claude, an expert programmer. Generate clean, efficient code.
${t?.includeComments?"Include helpful comments.":""}
${t?.includeTests?"Include unit tests.":""}
Always respond with valid JSON containing: code, language, explanation, and dependencies array.`,n=`Language: ${t?.language||"auto-detect"}
Framework: ${t?.framework||"none"}
Task: ${e}
Respond with JSON:
{
"code": "the generated code",
"language": "detected or specified language",
"explanation": "brief explanation",
${t?.includeTests?'"tests": "unit test code",':""}
"dependencies": ["required", "packages"]
}`,s=await this.generateText(n,{systemPrompt:r,temperature:.2,maxTokens:2e3});try{let i=s.match(/\{[\s\S]*\}/);if(i)return JSON.parse(i[0])}catch{}return {code:s,language:t?.language||"unknown",explanation:"Generated code",dependencies:[]}}async explainCode(e,t){let r=`Explain this ${t||"code"} in detail:
\`\`\`${t||""}
${e}
\`\`\`
Explain:
1. What it does
2. How it works
3. Key concepts/patterns
4. Potential improvements`;return this.generateText(r,{temperature:.3,maxTokens:1e3})}};var w=class extends y{client;constructor(e){super(e),this.validateApiKey(),this.client=new GoogleGenerativeAI(this.config.apiKey);}getDefaultModel(){return "gemini-pro"}async generateText(e,t){let r=this.getModel(t),n=this.client.getGenerativeModel({model:r}),s={maxOutputTokens:t?.maxTokens||1e3,temperature:t?.temperature||.7,topP:t?.topP||.95,topK:t?.topK||40,stopSequences:t?.stopSequences},i=t?.systemPrompt?`${t.systemPrompt}
${e}`:e;return (await(await n.generateContent({contents:[{role:"user",parts:[{text:i}]}],generationConfig:s})).response).text()}async*generateStream(e,t){let r=this.getModel(t),n=this.client.getGenerativeModel({model:r}),s={maxOutputTokens:t?.maxTokens||1e3,temperature:t?.temperature||.7,topP:t?.topP||.95,topK:t?.topK||40,stopSequences:t?.stopSequences},i=t?.systemPrompt?`${t.systemPrompt}
${e}`:e,o=await n.generateContentStream({contents:[{role:"user",parts:[{text:i}]}],generationConfig:s});for await(let a of o.stream){let c=a.text();c&&(yield c);}}async generateEmbedding(e){return (await this.client.getGenerativeModel({model:"embedding-001"}).embedContent(e)).embedding.values}async classifyText(e,t){let r=`Classify the following text into exactly one of these categories: ${t.join(", ")}.
Text: "${e}"
Respond with only JSON in this format:
{
"label": "chosen category",
"confidence": 0.95,
"scores": {
"category1": 0.95,
"category2": 0.03,
"category3": 0.02
}
}`,n=await this.generateText(r,{temperature:0,maxTokens:200});try{let i=n.match(/\{[\s\S]*\}/);if(i)return JSON.parse(i[0])}catch{}let s=t[0]||"unknown";return {label:s,confidence:.5,scores:t.reduce((i,o)=>({...i,[o]:o===s?.5:.5/(t.length-1)}),{})}}async summarize(e,t){let n=`${{bullet:"Create a concise bullet-point summary",paragraph:"Write a well-structured paragraph summary",tldr:"Provide a single sentence TL;DR","key-points":"List only the most critical key points",executive:"Write a professional executive summary"}[t?.style||"paragraph"]} of this text:
"${e}"
${t?.maxLength?`Limit to ${t.maxLength} characters.`:""}`;return this.generateText(n,{maxTokens:t?.maxLength?Math.ceil(t.maxLength/4):200,temperature:.3})}async analyzeImage(e,t){let r=this.client.getGenerativeModel({model:"gemini-pro-vision"}),n;if(e instanceof Blob){let m=await e.arrayBuffer();n=btoa(String.fromCharCode(...new Uint8Array(m)));}else n=e.replace(/^data:image\/\w+;base64,/,"");let s=t?.features||["description","objects","text"],i=`Analyze this image and provide a detailed response in JSON format with these features: ${s.join(", ")}.
Expected format:
{
${s.includes("description")?'"description": "detailed description",':""}
${s.includes("objects")?'"objects": [{"label": "object", "confidence": 0.9}],':""}
${s.includes("text")?'"text": [{"text": "extracted text", "confidence": 0.9}],':""}
${s.includes("colors")?'"colors": [{"hex": "#000000", "name": "black", "percentage": 30}],':""}
${s.includes("tags")?'"tags": ["tag1", "tag2"]':""}
}`,c=(await(await r.generateContent({contents:[{role:"user",parts:[{text:i},{inlineData:{mimeType:"image/jpeg",data:n}}]}]})).response).text();try{let m=c.match(/\{[\s\S]*\}/);if(m)return JSON.parse(m[0])}catch{}return {description:c,objects:[],text:[],colors:[],tags:[]}}async generateCode(e,t){let n=`${`You are an expert programmer. Generate high-quality code.
${t?.includeComments?"Include clear comments.":""}
${t?.includeTests?"Include comprehensive tests.":""}
Style: ${t?.style||"clean and efficient"}`}
Language: ${t?.language||"auto-detect"}
Framework: ${t?.framework||"none"}
Task: ${e}
Provide response as JSON:
{
"code": "complete code",
"language": "programming language",
"explanation": "what the code does",
${t?.includeTests?'"tests": "test code",':""}
"dependencies": ["list", "of", "dependencies"]
}`,s=await this.generateText(n,{temperature:.2,maxTokens:2e3});try{let i=s.match(/\{[\s\S]*\}/);if(i)return JSON.parse(i[0])}catch{}return {code:s,language:t?.language||"unknown",explanation:"Generated code"}}async explainCode(e,t){let r=`Analyze and explain this ${t||"code"}:
\`\`\`${t||""}
${e}
\`\`\`
Provide a comprehensive explanation covering:
1. Purpose and functionality
2. How it works step by step
3. Key algorithms or patterns used
4. Complexity analysis
5. Potential optimizations or issues`;return this.generateText(r,{temperature:.3,maxTokens:1500})}};var P=class extends y{delay;shouldFail;failureRate;responses;requestCount=0;constructor(e){super(e),this.delay=e.delay||100,this.shouldFail=e.shouldFail||false,this.failureRate=e.failureRate||0,this.responses=e.responses||new Map;}getDefaultModel(){return "mock-model-v1"}async simulateDelay(e){let t=e||this.delay;t>0&&await new Promise(r=>setTimeout(r,t));}shouldFailRequest(){return this.requestCount++,this.shouldFail?true:this.failureRate>0?Math.random()<this.failureRate:false}async generateText(e,t){if(await this.simulateDelay(),this.shouldFailRequest())throw new Error("Mock provider error: Simulated failure");let r=this.responses.get(e);if(r)return r;let s=(t?.temperature||.7)>.5?" (creative mode)":" (precise mode)";return `Mock response to: "${e.substring(0,50)}..."${s}
Model: ${this.getModel(t)}
Max tokens: ${t?.maxTokens||"default"}
System: ${t?.systemPrompt||"none"}
Generated at: ${new Date().toISOString()}`}async*generateStream(e,t){let n=(await this.generateText(e,t)).split(" ");for(let s of n)await this.simulateDelay(20),yield s+" ";}async generateEmbedding(e){if(await this.simulateDelay(),this.shouldFailRequest())throw new Error("Mock provider error: Embedding generation failed");let t=e.split("").reduce((n,s)=>n+s.charCodeAt(0),0);return new Array(1536).fill(0).map((n,s)=>Math.sin(t+s)*.1+Math.cos(t-s)*.05)}async classifyText(e,t){if(await this.simulateDelay(),this.shouldFailRequest())throw new Error("Mock provider error: Classification failed");let r=e.length,n=/good|great|excellent|happy|love/i.test(e),s=/bad|terrible|hate|awful|poor/i.test(e),i=r%t.length;n&&t.includes("positive")?i=t.indexOf("positive"):s&&t.includes("negative")&&(i=t.indexOf("negative"));let o=t.reduce((m,p,g)=>(m[p]=g===i?.8+Math.random()*.15:Math.random()*.2,m),{}),a=Object.values(o).reduce((m,p)=>m+p,0);Object.keys(o).forEach(m=>{o[m]=(o[m]??0)/a;});let c=t[i]??"unknown";return {label:c,confidence:o[c]??0,scores:o}}async summarize(e,t){if(await this.simulateDelay(),this.shouldFailRequest())throw new Error("Mock provider error: Summarization failed");let r=e.split(" ");switch(t?.style||"paragraph"){case "bullet":return `\u2022 First point about "${r.slice(0,5).join(" ")}..."
\u2022 Key insight from the middle section
\u2022 Final conclusion regarding "${r.slice(-5).join(" ")}"`;case "tldr":return `TL;DR: ${r.slice(0,10).join(" ")}... (${r.length} words total)`;case "key-points":return `Key Points:
1. Main topic: ${r[0]}
2. Important detail: ${r[Math.floor(r.length/2)]}
3. Conclusion: ${r[r.length-1]}`;case "executive":return `Executive Summary: This document discusses ${r.slice(0,5).join(" ")}.
The analysis reveals important insights about the subject matter.
Strategic recommendations include further investigation of key areas.`;default:return `Summary: ${r.slice(0,20).join(" ")}...
The text contains ${r.length} words and covers various topics.`}}async analyzeSentiment(e){if(await this.simulateDelay(),this.shouldFailRequest())throw new Error("Mock provider error: Sentiment analysis failed");let t=(e.match(/good|great|excellent|happy|love|wonderful/gi)||[]).length,r=(e.match(/bad|terrible|hate|awful|poor|horrible/gi)||[]).length,n,s;return t>r*2?(n="positive",s=.7+Math.random()*.25):r>t*2?(n="negative",s=.2+Math.random()*.2):t>0&&r>0?(n="mixed",s=.4+Math.random()*.2):(n="neutral",s=.45+Math.random()*.1),{sentiment:n,score:s,aspects:[{aspect:"tone",sentiment:n,score:s}]}}async generateImage(e,t){if(await this.simulateDelay(500),this.shouldFailRequest())throw new Error("Mock provider error: Image generation failed");let r=t?.size||"1024x1024",n=t?.style||"realistic";return {url:`https://picsum.photos/${r.split("x")[0]}/${r.split("x")[1]}?random=${Date.now()}`,base64:void 0,revisedPrompt:`Enhanced prompt: ${e} in ${n} style`,metadata:{model:"mock-dalle",size:r,style:n,seed:t?.seed||Math.floor(Math.random()*1e6)}}}async generateCode(e,t){if(await this.simulateDelay(),this.shouldFailRequest())throw new Error("Mock provider error: Code generation failed");let r=t?.language||"javascript",n=t?.includeComments??true,s=`${n?`// Mock generated code
`:""}
function mockFunction() {
${n?"// Implementation for: "+e.substring(0,50)+`
`:""}
console.log("This is mock generated code");
return {
prompt: "${e.substring(0,30)}...",
language: "${r}",
timestamp: new Date().toISOString()
};
}`,i=t?.includeTests?`
describe('mockFunction', () => {
it('should return expected output', () => {
const result = mockFunction();
expect(result).toBeDefined();
expect(result.language).toBe('${r}');
});
});`:void 0;return {code:s,language:r,explanation:`This is a mock implementation for: ${e}`,tests:i,dependencies:r==="javascript"?[]:["mock-dependency"]}}async explainCode(e,t){if(await this.simulateDelay(),this.shouldFailRequest())throw new Error("Mock provider error: Code explanation failed");let r=e.split(`
`).length,n=/function|=>|def|fn/.test(e),s=/class|struct|interface/.test(e);return `Mock Code Explanation:
This ${t||"code"} snippet contains ${r} lines.
Key observations:
${n?`- Contains function definitions
`:""}${s?`- Defines class or structural types
`:""}- Uses ${t||"modern programming"} syntax
- Implements mock functionality for testing
The code structure suggests it's designed for demonstration purposes.
In a real implementation, this would ${n?"execute the defined functions":"define the specified behavior"}.
Mock analysis completed at: ${new Date().toISOString()}`}configure(e){e.delay!==void 0&&(this.delay=e.delay),e.shouldFail!==void 0&&(this.shouldFail=e.shouldFail),e.failureRate!==void 0&&(this.failureRate=e.failureRate),e.responses&&e.responses.forEach((t,r)=>{this.responses.set(r,t);});}getStats(){return {totalRequests:this.requestCount,failureRate:this.failureRate,shouldFail:this.shouldFail,averageDelay:this.delay,predefinedResponses:this.responses.size}}reset(){this.requestCount=0,this.responses.clear(),this.shouldFail=false,this.failureRate=0;}};var T=class extends y{client;constructor(e){super(e),this.validateApiKey(),this.client=new V({apiKey:this.config.apiKey,baseURL:this.config.baseUrl,timeout:this.config.timeout,maxRetries:this.config.maxRetries||2});}getDefaultModel(){return "gpt-3.5-turbo"}async generateText(e,t){let r=this.getModel(t);return (await this.client.chat.completions.create({model:r,messages:[{role:"system",content:t?.systemPrompt||"You are a helpful assistant."},{role:"user",content:e}],max_tokens:t?.maxTokens,temperature:t?.temperature,top_p:t?.topP,frequency_penalty:t?.frequencyPenalty,presence_penalty:t?.presencePenalty,stop:t?.stopSequences,seed:t?.seed,response_format:t?.responseFormat,functions:t?.functions,stream:false})).choices[0]?.message?.content||""}async*generateStream(e,t){let r=this.getModel(t),n=await this.client.chat.completions.create({model:r,messages:[{role:"system",content:t?.systemPrompt||"You are a helpful assistant."},{role:"user",content:e}],max_tokens:t?.maxTokens,temperature:t?.temperature,top_p:t?.topP,frequency_penalty:t?.frequencyPenalty,presence_penalty:t?.presencePenalty,stop:t?.stopSequences,seed:t?.seed,stream:true});for await(let s of n){let i=s.choices[0]?.delta?.content;i&&(yield i);}}async generateEmbedding(e){return (await this.client.embeddings.create({model:"text-embedding-ada-002",input:e})).data[0]?.embedding||[]}async classifyText(e,t){let r=`Classify the following text into one of these categories: ${t.join(", ")}.
Text: "${e}"
Respond with a JSON object containing:
- label: the chosen category
- confidence: a number between 0 and 1
- scores: an object with confidence scores for each category
Response:`,n=await this.generateText(r,{temperature:0,maxTokens:200,responseFormat:{type:"json_object"}});try{return JSON.parse(n)}catch{let s=t[0]||"unknown";return {label:s,confidence:.5,scores:t.reduce((i,o)=>({...i,[o]:o===s?.5:.5/(t.length-1)}),{})}}}async summarize(e,t){let n=`${{bullet:"Create a bullet-point summary with key points.",paragraph:"Write a concise paragraph summary.",tldr:"Write a one-sentence TL;DR summary.","key-points":"Extract and list the most important key points.",executive:"Write an executive summary suitable for business leaders."}[t?.style||"paragraph"]}
Text to summarize:
"${e}"
Summary:`;return this.generateText(n,{maxTokens:t?.maxLength||200,temperature:.3})}async generateImage(e,t){let r=await this.client.images.generate({model:"dall-e-3",prompt:e,n:t?.n||1,size:t?.size||"1024x1024",quality:t?.quality||"standard",style:t?.style==="realistic"?"natural":"vivid",response_format:"url"});if(!r.data)throw new Error("No image data returned.");let n=r.data[0];return {url:n?.url||"",revisedPrompt:n?.revised_prompt||"",metadata:{model:"dall-e-3",size:t?.size||"1024x1024",quality:t?.quality||"standard"}}}async transcribeAudio(e,t){let r=new File([e],"audio.webm",{type:e.type}),n=await this.client.audio.transcriptions.create({file:r,model:"whisper-1",language:t?.language,response_format:t?.format==="json"?"verbose_json":"text",timestamp_granularities:t?.timestamps?["word"]:void 0});return typeof n=="string"?{text:n,language:t?.language}:{text:n.text,language:n.language,duration:n.duration,words:n.words?.map(s=>({word:s.word,start:s.start,end:s.end}))}}async generateSpeech(e,t){let n=await(await this.client.audio.speech.create({model:"tts-1",input:e,voice:t?.voice||"alloy",speed:t?.speed||1,response_format:t?.format||"mp3"})).arrayBuffer();return new Blob([n],{type:`audio/${t?.format||"mp3"}`})}async generateCode(e,t){let r=`You are an expert programmer. Generate clean, efficient, and well-documented code.
${t?.includeComments?"Include helpful comments.":"Minimize comments."}
${t?.includeTests?"Include unit tests.":""}
Style: ${t?.style||"concise"}`,n=`Language: ${t?.language||"auto-detect"}
Framework: ${t?.framework||"none"}
Task: ${e}
Respond with a JSON object containing:
- code: the generated code
- language: the programming language used
- explanation: brief explanation of the code
${t?.includeTests?"- tests: unit test code":""}
- dependencies: array of required dependencies`,s=await this.generateText(n,{systemPrompt:r,temperature:.2,maxTokens:2e3,responseFormat:{type:"json_object"}});try{return JSON.parse(s)}catch{return {code:s,language:t?.language||"unknown",explanation:"Generated code"}}}async explainCode(e,t){let r=`Explain the following ${t||"code"} in detail:
\`\`\`${t||""}
${e}
\`\`\`
Provide a clear explanation of:
1. What the code does
2. How it works
3. Any important concepts or patterns used
4. Potential improvements or issues`;return this.generateText(r,{temperature:.3,maxTokens:1e3})}};var R=class{cache;enabled;namespace;stats={hits:0,misses:0,evictions:0};constructor(e){this.enabled=e.enabled??true,this.namespace=e.namespace||"ai-toolkit";let t=(e.maxSize||100)*1024*1024;this.cache=new LRUCache({max:1e3,maxSize:t,sizeCalculation:r=>JSON.stringify(r).length,ttl:e.ttl||6e5,updateAgeOnGet:true,updateAgeOnHas:false,dispose:()=>{this.stats.evictions++;}}),this.setupCleanup();}generateKey(e,t,r){let n={namespace:this.namespace,method:e,params:t.map(i=>typeof i=="object"?JSON.stringify(i,Object.keys(i).sort()):String(i)),options:r?JSON.stringify(r,Object.keys(r).sort()):null},s=Y.createHash("sha256").update(JSON.stringify(n)).digest("hex");return `${this.namespace}:${e}:${s}`}async get(e){if(!this.enabled)return null;let t=this.cache.get(e);return t?(this.stats.hits++,t.hits++,t.value):(this.stats.misses++,null)}async set(e,t,r){if(!this.enabled)return;let n={key:e,value:t,timestamp:Date.now(),hits:0,metadata:r};this.cache.set(e,n);}async delete(e){return this.cache.delete(e)}async clear(){this.cache.clear(),this.stats={hits:0,misses:0,evictions:0};}has(e){return this.cache.has(e)}getStats(){let e=this.stats.hits+this.stats.misses>0?this.stats.hits/(this.stats.hits+this.stats.misses):0;return {...this.stats,hitRate:Math.round(e*100)/100,size:this.cache.size,calculatedSize:this.cache.calculatedSize,maxSize:this.cache.maxSize,itemCount:this.cache.size,enabled:this.enabled}}keys(){return Array.from(this.cache.keys())}entries(){let e=[];for(let[t,r]of this.cache.entries())e.push({key:t,metadata:r.metadata,age:Date.now()-r.timestamp});return e}prune(){let e=this.cache.size;return this.cache.purgeStale(),e-this.cache.size}setEnabled(e){this.enabled=e,e||this.clear();}updateTTL(e){let t=Array.from(this.cache.entries());this.cache=new LRUCache({max:this.cache.max,maxSize:this.cache.maxSize,ttl:e,updateAgeOnGet:true,updateAgeOnHas:false,sizeCalculation:r=>JSON.stringify(r).length,dispose:()=>{this.stats.evictions++;}});for(let[r,n]of t)this.cache.set(r,n);}getMemoryUsage(){return {used:this.cache.calculatedSize,max:this.cache.maxSize,percentage:Math.round(this.cache.calculatedSize/this.cache.maxSize*100)}}setupCleanup(){setInterval(()=>{this.prune();},5*60*1e3);}async wrap(e,t,r){let n=await this.get(e);if(n!==null)return n;let s=await t();return await this.set(e,s,r?.metadata),s}createTextGenerationKey(e,t,r,n){return this.generateKey("generateText",[e],{...t,provider:r,model:n})}createEmbeddingKey(e,t,r){return this.generateKey("generateEmbedding",[e],{provider:t,model:r})}export(){let e={};for(let[t,r]of this.cache.entries())e[t]={value:r.value,timestamp:r.timestamp,hits:r.hits,metadata:r.metadata};return e}import(e){this.clear();for(let[t,r]of Object.entries(e))r&&typeof r=="object"&&"value"in r&&this.cache.set(t,r);}};var Q=z.object({requestsPerMinute:z.number().optional(),tokensPerMinute:z.number().optional(),requestsPerHour:z.number().optional(),tokensPerHour:z.number().optional(),concurrent:z.number().default(5),strategy:z.enum(["fixed-window","sliding-window","token-bucket"]).default("sliding-window")}),X=z.object({enabled:z.boolean().default(true),ttl:z.number().default(6e5),maxSize:z.number().default(100),strategy:z.enum(["lru","fifo","lfu"]).default("lru")}),Z=z.object({maxAttempts:z.number().default(3),baseDelay:z.number().default(1e3),maxDelay:z.number().default(3e4),backoff:z.enum(["exponential","linear","fixed"]).default("exponential")}),q=z.object({provider:z.custom(),apiKey:z.string().optional(),apiKeys:z.record(z.string()).optional(),model:z.string().optional(),models:z.record(z.string()).optional(),baseUrl:z.string().optional(),headers:z.record(z.string()).optional(),maxRetries:z.number().optional(),timeout:z.number().optional(),cache:X.optional(),rateLimit:Q.optional(),retry:Z.optional(),fallbackProviders:z.array(z.custom()).optional()});var C=class{config;encryptedKeys=new Map;constructor(e){this.config=q.parse(e),this.config.apiKey&&this.encryptedKeys.set(this.config.provider,this.encryptApiKey(this.config.apiKey)),this.config.apiKeys&&Object.entries(this.config.apiKeys).forEach(([t,r])=>{this.encryptedKeys.set(t,this.encryptApiKey(r));});}getConfig(){return {...this.config}}getProviderConfig(e){let t=e||this.config.provider;return {provider:t,apiKey:this.getApiKey(t),model:this.getModel(t),baseUrl:this.config.baseUrl,headers:this.config.headers}}getApiKey(e){let t=e||this.config.provider,r=this.encryptedKeys.get(t);if(r)return this.decryptApiKey(r)}getModel(e){let t=e||this.config.provider;return this.config.models&&this.config.models[t]?this.config.models[t]:this.config.model}getCacheConfig(){return this.config.cache||{enabled:true,ttl:6e5,maxSize:100,strategy:"lru"}}getRateLimitConfig(){return this.config.rateLimit||{requestsPerMinute:60,strategy:"sliding-window",concurrent:5}}getRetryConfig(){return this.config.retry||{maxAttempts:3,baseDelay:1e3,maxDelay:3e4,backoff:"exponential"}}getFallbackProviders(){return this.config.fallbackProviders||[]}updateConfig(e){let t={...this.config,...e};this.config=q.parse(t),e.apiKey&&this.encryptedKeys.set(this.config.provider,this.encryptApiKey(e.apiKey)),e.apiKeys&&Object.entries(e.apiKeys).forEach(([r,n])=>{this.encryptedKeys.set(r,this.encryptApiKey(n));});}encryptApiKey(e){return Buffer.from(e).toString("base64")}decryptApiKey(e){return Buffer.from(e,"base64").toString("utf-8")}validateProvider(e){let t=[];return !this.getApiKey(e)&&e!=="local"&&e!=="mock"&&t.push(`API key required for provider: ${e}`),this.getModel(e)||t.push(`Model not specified for provider: ${e}`),{valid:t.length===0,errors:t}}exportConfig(){let{apiKey:e,apiKeys:t,...r}=this.config;return {...r,hasApiKey:!!e||!!t,configuredProviders:Array.from(this.encryptedKeys.keys())}}};var S=class{errorHistory=[];maxHistorySize=1e3;handleError(e,t){let r=this.enhanceError(e,t);return this.addToHistory(r,t),r}enhanceError(e,t){let r=new te({name:this.getErrorName(e),cause:e,info:{...t,originalError:{message:e.message,code:e.code,status:e.status}}},this.getErrorMessage(e,t));return r.code=e.code||this.inferErrorCode(e),r.status=e.status||this.inferStatusCode(e),r.category=this.categorizeError(e),r.userMessage=this.getUserFriendlyMessage(r),r.isRetryable=this.isRetryable(r),r.context=t,r.recommendations=this.getRecommendations(r),r.timestamp=new Date().toISOString(),r}getErrorName(e){let t=this.categorizeError(e);return {authentication:"AuthenticationError","rate-limit":"RateLimitError","invalid-request":"ValidationError","server-error":"ServerError",network:"NetworkError",timeout:"TimeoutError",billing:"BillingError","not-found":"NotFoundError",permission:"PermissionError"}[t]||"AIProviderError"}getErrorMessage(e,t){return `${t.operation} failed on ${t.provider}${t.model?` (model: ${t.model})`:""}: ${e.message}`}categorizeError(e){let t=e.message?.toLowerCase()||"",r=e.code||e.status;return r===401||t.includes("unauthorized")||t.includes("api key")?"authentication":r===429||t.includes("rate limit")||t.includes("quota exceeded")?"rate-limit":r===402||t.includes("billing")||t.includes("payment")?"billing":r===400||t.includes("invalid")||t.includes("validation")?"invalid-request":r===403||t.includes("forbidden")||t.includes("permission")?"permission":r===404||t.includes("not found")?"not-found":r>=500||t.includes("internal server")?"server-error":t.includes("network")||t.includes("econnrefused")||t.includes("enotfound")?"network":t.includes("timeout")||r==="ETIMEDOUT"?"timeout":"unknown"}inferErrorCode(e){if(e.code)return e.code;let t=this.categorizeError(e);return {authentication:"AUTH_ERROR","rate-limit":"RATE_LIMIT_ERROR","invalid-request":"VALIDATION_ERROR","server-error":"SERVER_ERROR",network:"NETWORK_ERROR",timeout:"TIMEOUT_ERROR",billing:"BILLING_ERROR","not-found":"NOT_FOUND",permission:"PERMISSION_DENIED"}[t]||"UNKNOWN_ERROR"}inferStatusCode(e){if(e.status)return e.status;let t=this.categorizeError(e);return {authentication:401,"rate-limit":429,"invalid-request":400,"server-error":500,network:503,timeout:504,billing:402,"not-found":404,permission:403}[t]||500}getUserFriendlyMessage(e){return {authentication:"Authentication failed. Please check your API key and ensure it has the necessary permissions.","rate-limit":"Rate limit exceeded. Please wait a moment before trying again.",billing:"There is an issue with your billing or quota. Please check your account status.","invalid-request":"The request contains invalid parameters. Please check your input and try again.","server-error":"The AI service is temporarily unavailable. Please try again later.",network:"Network connection issue. Please check your internet connection and try again.",timeout:"The request timed out. Please try again with a shorter prompt or wait a moment.","not-found":"The requested resource was not found. Please verify the endpoint or model name.",permission:"You do not have permission to perform this action.",unknown:"An unexpected error occurred. Please try again or contact support if the issue persists."}[e.category||"unknown"]}isRetryable(e){return ["rate-limit","server-error","network","timeout"].includes(e.category||"")}getRecommendations(e){let t=[];switch(e.category){case "authentication":t.push("Verify your API key is correct"),t.push("Check if the API key has been revoked or expired"),t.push("Ensure the API key has the necessary permissions");break;case "rate-limit":t.push("Implement request queuing or throttling"),t.push("Consider upgrading your API plan for higher limits"),t.push("Spread requests over time to avoid bursts");break;case "billing":t.push("Check your account balance and payment method"),t.push("Review your usage and adjust limits if needed"),t.push("Contact support if billing issues persist");break;case "invalid-request":t.push("Review the API documentation for correct parameters"),t.push("Validate input data before sending requests"),t.push("Check for any recent API changes or deprecations");break;case "network":t.push("Check your internet connection"),t.push("Verify firewall or proxy settings"),t.push("Try using a different network");break;case "timeout":t.push("Reduce the size of your request"),t.push("Increase timeout settings if possible"),t.push("Break large requests into smaller chunks");break}return e.context?.attempt&&e.context.attempt>2&&(t.push("Consider using a fallback provider"),t.push("Implement circuit breaker pattern")),t}addToHistory(e,t){this.errorHistory.push({timestamp:new Date,error:e,context:t,resolved:false}),this.errorHistory.length>this.maxHistorySize&&(this.errorHistory=this.errorHistory.slice(-this.maxHistorySize/2));}createHttpError(e){let t=ee.boomify(e,{statusCode:e.status||500,message:e.userMessage});return t.output.payload.code=e.code,t.output.payload.category=e.category,t.output.payload.isRetryable=e.isRetryable,t.output.payload.recommendations=e.recommendations,t}getErrorStats(e){let t=e?Date.now()-e:0,r=this.errorHistory.filter(i=>i.timestamp.getTime()>t),n={total:r.length,byCategory:{},byProvider:{},resolutionRate:0,recentErrors:[]};r.forEach(i=>{let o=i.error.category||"unknown";n.byCategory[o]=(n.byCategory[o]||0)+1;let a=i.context.provider;n.byProvider[a]=(n.byProvider[a]||0)+1,n.recentErrors.length<10&&n.recentErrors.push({timestamp:i.timestamp.toISOString(),category:o,provider:a,message:i.error.message});});let s=r.filter(i=>i.resolved).length;return n.resolutionRate=r.length>0?s/r.length:0,n}markResolved(e){let t=this.errorHistory.find(r=>r.timestamp.toISOString()===e);t&&(t.resolved=true);}clearHistory(){this.errorHistory=[];}exportHistory(){return this.errorHistory.map(e=>({timestamp:e.timestamp.toISOString(),error:{message:e.error.message,code:e.error.code,category:e.error.category,userMessage:e.error.userMessage,isRetryable:e.error.isRetryable,recommendations:e.error.recommendations},context:e.context,resolved:e.resolved}))}};var O=class{limiters=new Map;tokenBuckets=new Map;createLimiter(e){let t=this.limiters.get(e.id);if(t)return t;let r;switch(e.strategy){case "token-bucket":r=this.createTokenBucketConfig(e);break;case "fixed-window":r=this.createFixedWindowConfig(e);break;case "sliding-window":default:r=this.createSlidingWindowConfig(e);break}let n=new E(r);return n.on("error",s=>{console.error(`Rate limiter error for ${e.id}:`,s);}),n.on("failed",async s=>{console.warn(`Job failed in rate limiter ${e.id}:`,s);}),this.limiters.set(e.id,n),(e.tokensPerMinute||e.tokensPerHour)&&this.createTokenBucket(e),n}getLimiter(e){return this.limiters.get(e)}async schedule(e,t,r){let n=this.limiters.get(e);if(!n)throw new Error(`No rate limiter found with ID: ${e}`);let s={};return r!==void 0&&(s.priority=r),n.schedule(s,t)}async consumeTokens(e,t){let r=this.tokenBuckets.get(e);return r?r.consume(t):true}async getStats(e){let t=this.limiters.get(e);if(!t)return null;let r=await t.counts(),n=await t.currentReservoir();return {running:r.RUNNING,queued:r.QUEUED,done:r.DONE||0,failed:r.FAILED||0,reservoir:n}}async getAllStats(){let e={};for(let[t]of this.limiters){let r=await this.getStats(t);r&&(e[t]=r);}return e}async updateLimiter(e,t){let r=this.limiters.get(e);if(!r)throw new Error(`No rate limiter found with ID: ${e}`);let s={...await this.getLimiterConfig(e),...t,id:e};await r.stop(),this.limiters.delete(e),this.createLimiter(s);}async clearQueue(e){let t=this.limiters.get(e);t&&await t.stop({dropWaitingJobs:true});}async stopLimiter(e){let t=this.limiters.get(e);t&&(await t.stop(),this.limiters.delete(e));let r=this.tokenBuckets.get(e);r&&(r.stop(),this.tokenBuckets.delete(e));}async stopAll(){let e=[];for(let[t]of this.limiters)e.push(this.stopLimiter(t));await Promise.all(e);}createSlidingWindowConfig(e){let t=e.requestsPerMinute||60,r=Math.ceil(6e4/t);return {maxConcurrent:e.concurrent||5,minTime:r,highWater:Math.max(100,t*2),strategy:E.strategy.LEAK,rejectOnDrop:false}}createFixedWindowConfig(e){let t=e.requestsPerMinute||60;return {maxConcurrent:e.concurrent||5,reservoir:t,reservoirRefreshInterval:6e4,reservoirRefreshAmount:t,highWater:Math.max(100,t*2),strategy:E.strategy.LEAK}}createTokenBucketConfig(e){let t=e.requestsPerMinute||60,r=Math.ceil(t/60);return {maxConcurrent:e.concurrent||5,reservoir:t,reservoirRefreshInterval:1e3,reservoirRefreshAmount:r,highWater:Math.max(100,t*2),strategy:E.strategy.LEAK}}createTokenBucket(e){let t=new D(e);this.tokenBuckets.set(e.id,t);}async getLimiterConfig(e){return {requestsPerMinute:60,strategy:"sliding-window",concurrent:5}}},D=class{tokens;maxTokens;refillRate;lastRefill;interval;constructor(e){this.maxTokens=e.tokensPerMinute||1e5,this.tokens=this.maxTokens,this.refillRate=this.maxTokens/6e4,this.lastRefill=Date.now(),this.startRefillTimer();}consume(e){return this.refill(),this.tokens>=e?(this.tokens-=e,true):false}getAvailable(){return this.refill(),Math.floor(this.tokens)}refill(){let e=Date.now(),r=(e-this.lastRefill)*this.refillRate;this.tokens=Math.min(this.maxTokens,this.tokens+r),this.lastRefill=e;}startRefillTimer(){this.interval=setInterval(()=>{this.refill();},1e3);}stop(){this.interval&&clearInterval(this.interval);}};var A=class{config;constructor(e){this.config=e;}async execute(e,t,r){let n={...this.config,...r};return re(async s=>{try{return await e()}catch(i){let o=this.wrapError(i,t,s);throw this.shouldRetry(i,n)?(n.onRetry&&n.onRetry(o,s),o):new AbortError(o)}},{retries:n.maxAttempts-1,factor:n.backoff==="exponential"?2:1,minTimeout:n.baseDelay,maxTimeout:n.maxDelay,randomize:true,onFailedAttempt:s=>{console.warn(`Retry attempt ${s.attemptNumber} failed for ${t.operation}:`,s.message);}})}async executeWithBackoff(e,t,r){let n={...this.config,...r};try{return await backOff(e,{numOfAttempts:n.maxAttempts,startingDelay:n.baseDelay,maxDelay:n.maxDelay,jitter:"full",timeMultiple:2,retry:(s,i)=>{let o=this.shouldRetry(s,n);return o&&n.onRetry&&n.onRetry(s,i),o}})}catch(s){throw this.wrapError(s,t,n.maxAttempts)}}wrapError(e,t,r){return new te({name:"AIProviderError",cause:e,info:{...t,attempt:r,timestamp:new Date().toISOString(),errorCode:e.code||e.status,errorType:this.categorizeError(e)}},`Failed to execute ${t.operation} on ${t.provider} (attempt ${r})`)}shouldRetry(e,t){if(t.shouldRetry)return t.shouldRetry(e);switch(this.categorizeError(e)){case "authentication":case "invalid_request":case "not_found":case "permission_denied":return false;case "rate_limit":return true;case "server_error":case "network":case "timeout":return true;default:return true}}categorizeError(e){let t=e.message?.toLowerCase()||"",r=e.code||e.status;return r===401||t.includes("unauthorized")||t.includes("api key")||t.includes("authentication")?"authentication":r===429||t.includes("rate limit")?"rate_limit":r===400||t.includes("invalid")||t.includes("validation")?"invalid_request":r===404||t.includes("not found")?"not_found":r===403||t.includes("forbidden")?"permission_denied":r>=500||t.includes("internal server")?"server_error":t.includes("network")||t.includes("econnrefused")||t.includes("enotfound")||t.includes("econnreset")?"network":t.includes("timeout")||t.includes("etimedout")||r==="ETIMEDOUT"?"timeout":"unknown"}wrap(e,t,r){return async(...n)=>this.execute(()=>e(...n),t,r)}updateConfig(e){this.config={...this.config,...e};}getConfig(){return {...this.config}}calculateDelay(e,t){let r={...this.config,...t},n;switch(r.backoff){case "exponential":n=Math.min(r.baseDelay*Math.pow(2,e-1),r.maxDelay);break;case "linear":n=Math.min(r.baseDelay*e,r.maxDelay);break;case "fixed":default:n=r.baseDelay;break}let s=n*.2*Math.random();return Math.floor(n+s)}getRetryStats(e){let t=this.categorizeError(e),r=this.shouldRetry(e,this.config),n=this.config.baseDelay;return t==="rate_limit"&&(n=this.config.baseDelay*2),{shouldRetry:r,errorType:t,suggestedDelay:n,maxAttempts:this.config.maxAttempts}}};var I=class{tokenLimits={"gpt-4":8192,"gpt-4-32k":32768,"gpt-4-turbo":128e3,"gpt-4-turbo-preview":128e3,"gpt-3.5-turbo":4096,"gpt-3.5-turbo-16k":16384,"claude-3-opus":2e5,"claude-3-sonnet":2e5,"claude-3-haiku":2e5,"claude-2.1":2e5,"claude-2":1e5,"gemini-pro":30720,"gemini-pro-vision":30720,"palm-2":8192,default:4096};modelPricing={"gpt-4":{input:.03,output:.06},"gpt-4-turbo":{input:.01,output:.03},"gpt-3.5-turbo":{input:5e-4,output:.0015},"claude-3-opus":{input:.015,output:.075},"claude-3-sonnet":{input:.003,output:.015},"claude-3-haiku":{input:25e-5,output:.00125},"gemini-pro":{input:5e-4,output:.0015},default:{input:0,output:0}};async countTokens(e,t){try{return t.includes("gpt")||t.includes("davinci")||t.includes("turbo")?this.countTokensWithTiktoken(e,t):encode(e).length}catch{return this.estimateTokens(e)}}countTokensWithTiktoken(e,t){try{let r=encoding_for_model(t),s=r.encode(e).length;return r.free(),s}catch{let r=get_encoding("cl100k_base"),s=r.encode(e).length;return r.free(),s}}estimateTokens(e){return Math.ceil(e.length/4)}async getTokenInfo(e,t,r){let n=await this.countTokens(e,t),s=r??this.tokenLimits[t]??this.tokenLimits.default??4096;return {count:n,truncated:n>s,originalLength:e.length}}async validateTokenLimits(e,t,r,n=1e3){let s=await this.countTokens(e,t),i=this.tokenLimits[t]??this.tokenLimits.default??4096,o=r??i,c=s+n<=o,m=Math.max(0,o-s);return {valid:c,availableTokens:m}}async truncateToTokenLimit(e,t,r,n=false){if(await this.countTokens(e,t)<=r)return e;let i=0,o=e.length,a="";for(;i<=o;){let c=Math.floor((i+o)/2),m=n?e.slice(e.length-c):e.slice(0,c);await this.countTokens(m,t)<=r?(a=m,i=c+1):o=c-1;}return n?"..."+a:a+"..."}async splitIntoChunks(e,t,r,n=0){let s=[],i=this.splitIntoSentences(e),o="",a=0;for(let c of i){let m=await this.countTokens(c,t);a+m>r&&o?(s.push(o.trim()),n>0?(o=await this.getOverlapText(o,t,n)+" "+c,a=await this.countTokens(o,t)):(o=c