An AI integration package providing unified access to multiple AI providers including Anthropic (Claude), OpenAI, Ollama, and AWS Bedrock.
Installation
bunadd@stacksjs/ai
Basic Usage
import{anthropic,openai,ollama}from'@stacksjs/ai'// Using Anthropic Claudeconstresponse=awaitanthropic.chat({messages:[{role:'user',content:'Hello, Claude!'}]})// Using OpenAIconstgptResponse=awaitopenai.chat({messages:[{role:'user',content:'Hello, GPT!'}]})// Using Ollama (local models)constlocalResponse=awaitollama.chat({model:'llama2',messages:[{role:'user',content:'Hello, Llama!'}]})
import{anthropic}from'@stacksjs/ai'constresponse=awaitanthropic.chat({model:'claude-3-opus-20240229',messages:[{role:'user',content:'Explain quantum computing in simple terms.'}],maxTokens:1024,})console.log(response.content)
Streaming Responses
import{anthropic}from'@stacksjs/ai'conststream=awaitanthropic.stream({model:'claude-3-sonnet-20240229',messages:[{role:'user',content:'Write a short story about a robot.'}],})forawait(constchunkofstream){process.stdout.write(chunk.content||'')}
System Prompts
import{anthropic}from'@stacksjs/ai'constresponse=awaitanthropic.chat({model:'claude-3-opus-20240229',system:'You are a helpful coding assistant. Provide concise, accurate answers.',messages:[{role:'user',content:'How do I sort an array in TypeScript?'}],})
Multi-turn Conversations
import{anthropic}from'@stacksjs/ai'constconversation=[{role:'user',content:'What is the capital of France?'},{role:'assistant',content:'The capital of France is Paris.'},{role:'user',content:'What is its population?'}]constresponse=awaitanthropic.chat({messages:conversation,})// Claude knows "its" refers to Paris from context
Vision (Image Analysis)
import{anthropic}from'@stacksjs/ai'import{readFile}from'node:fs/promises'constimageData=awaitreadFile('image.png')constbase64Image=imageData.toString('base64')constresponse=awaitanthropic.chat({model:'claude-3-opus-20240229',messages:[{role:'user',content:[{type:'image',source:{type:'base64',media_type:'image/png',data:base64Image,},},{type:'text',text:'What do you see in this image?',},],},],})
OpenAI
Basic Chat
import{openai}from'@stacksjs/ai'constresponse=awaitopenai.chat({model:'gpt-4-turbo-preview',messages:[{role:'system',content:'You are a helpful assistant.'},{role:'user',content:'What is the meaning of life?'}],})console.log(response.choices[0].message.content)
Streaming
import{openai}from'@stacksjs/ai'conststream=awaitopenai.stream({model:'gpt-4-turbo-preview',messages:[{role:'user',content:'Tell me a joke.'}],})forawait(constchunkofstream){constcontent=chunk.choices[0]?.delta?.contentif(content)process.stdout.write(content)}
Function Calling
import{openai}from'@stacksjs/ai'constresponse=awaitopenai.chat({model:'gpt-4-turbo-preview',messages:[{role:'user',content:'What is the weather in San Francisco?'}],tools:[{type:'function',function:{name:'get_weather',description:'Get the current weather in a location',parameters:{type:'object',properties:{location:{type:'string',description:'The city and state, e.g. San Francisco, CA',},unit:{type:'string',enum:['celsius','fahrenheit'],},},required:['location'],},},},],})// Handle function callif(response.choices[0].message.tool_calls){consttoolCall=response.choices[0].message.tool_calls[0]constargs=JSON.parse(toolCall.function.arguments)// Call your weather APIconstweather=awaitgetWeather(args.location,args.unit)// Continue conversation with function resultconstfollowUp=awaitopenai.chat({model:'gpt-4-turbo-preview',messages:[...messages,response.choices[0].message,{role:'tool',tool_call_id:toolCall.id,content:JSON.stringify(weather),},],})}
Embeddings
import{openai}from'@stacksjs/ai'constembedding=awaitopenai.embed({model:'text-embedding-3-small',input:'The quick brown fox jumps over the lazy dog.',})console.log(embedding.data[0].embedding)// Vector of floats
Ollama (Local Models)
Basic Chat
import{ollama}from'@stacksjs/ai'constresponse=awaitollama.chat({model:'llama2',messages:[{role:'user',content:'Hello! How are you?'}],})console.log(response.message.content)
Available Models
import{ollama}from'@stacksjs/ai'// List installed modelsconstmodels=awaitollama.list()console.log(models)// Pull a new modelawaitollama.pull('mistral')// Use specific modelconstresponse=awaitollama.chat({model:'codellama',messages:[{role:'user',content:'Write a Python function to reverse a string.'}],})
import{createAgent}from'@stacksjs/ai'constagent=createAgent({name:'ResearchAssistant',model:'claude-3-opus-20240229',systemPrompt:`You are a research assistant. You help users find and summarize information.Youhaveaccesstowebsearchandcananalyzedocuments.`,tools:[{name:'web_search',description:'Search the web for information',execute:async(query:string)=>{// Implement web searchreturnsearchResults},},{name:'read_document',description:'Read and analyze a document',execute:async(path:string)=>{// Read documentreturndocumentContent},},],})constresult=awaitagent.run('Research the latest AI developments in 2024')
Agent Memory
import{createAgent,MemoryStore}from'@stacksjs/ai'constmemory=newMemoryStore()constagent=createAgent({name:'PersonalAssistant',model:'claude-3-sonnet-20240229',memory,})// Agent remembers previous conversationsawaitagent.run('My name is John')awaitagent.run('What is my name?')// Remembers "John"
Buddy - Voice AI Assistant
Using Buddy
import{Buddy,createBuddy}from'@stacksjs/ai'// Create Buddy instanceconstbuddy=createBuddy({name:'CodeAssistant',voice:{enabled:true,model:'whisper-1',},})// Voice inputconsttranscription=awaitbuddy.listen()// Process and respondconstresponse=awaitbuddy.respond(transcription)// Text-to-speech outputawaitbuddy.speak(response)
Text Utilities
Text Generation
import{generateText,summarize,translate}from'@stacksjs/ai'// Generate textconstgenerated=awaitgenerateText({prompt:'Write a product description for a smart watch',maxTokens:200,})// Summarize textconstsummary=awaitsummarize({text:longArticle,maxLength:100,})// Translate textconsttranslated=awaittranslate({text:'Hello, how are you?',from:'en',to:'es',})
Sentiment Analysis
import{analyzeSentiment}from'@stacksjs/ai'constsentiment=awaitanalyzeSentiment('I absolutely love this product! It exceeded all my expectations.')// Returns: { sentiment: 'positive', score: 0.95 }
Error Handling
import{anthropic}from'@stacksjs/ai'try{constresponse=awaitanthropic.chat({messages:[{role:'user',content:'Hello'}],})}catch(error){if(error.status===429){// Rate limitedconsole.log('Too many requests, waiting...')awaitdelay(error.headers['retry-after']_1000)}elseif(error.status===401){// Invalid API keyconsole.error('Invalid API key')}elseif(error.status===500){// Server errorconsole.error('AI provider error')}}
Edge Cases
Handling Long Conversations
import{anthropic}from'@stacksjs/ai'// Truncate or summarize old messages to stay within token limitsfunctiontrimConversation(messages:Message[],maxTokens:number){// Keep system message and recent messagesconstsystemMessage=messages.find(m=>m.role==='system')constrecentMessages=messages.slice(-10)returnsystemMessage?[systemMessage,...recentMessages]:recentMessages}consttrimmedMessages=trimConversation(conversation,4096)constresponse=awaitanthropic.chat({messages:trimmedMessages})