Browser JavaScript (ESM)
This guide shows how to use the Athena Intelligence SDK directly in the browser using ESM imports from CDN. Perfect for rapid prototyping, demos, and simple web applications without build tools.
Key features:
- No build process required - works directly in the browser
- Full SDK functionality available via ESM imports
- Type safety with JSDoc comments
- Real-time interaction examples
- Production-ready patterns for browser applications
Basic ESM Import Setup
Use the SDK directly in your browser with ESM imports:
1 // Import the SDK from ESM CDN 2 import { AthenaIntelligenceClient, AthenaIntelligenceError } from 'https://esm.run/athena-intelligence'; 3 4 // Basic client initialization (uses default production API) 5 const client = new AthenaIntelligenceClient({ 6 apiKey: API_KEY, // Assumes API_KEY is defined globally 7 }); 8 9 // Override baseUrl for custom API endpoints 10 const customClient = new AthenaIntelligenceClient({ 11 apiKey: API_KEY, 12 baseUrl: 'https://your-custom-api.example.com', // Custom API endpoint 13 }); 14 15 // Use development/localhost environment 16 const devClient = new AthenaIntelligenceClient({ 17 apiKey: API_KEY, 18 baseUrl: 'http://localhost:8000', // Local development server 19 }); 20 21 console.log('Athena Intelligence client initialized');
Simple Agent Interaction
Execute basic agent requests with full error handling:
1 async function runSimpleAgent() { 2 try { 3 console.log('๐ค Running General Agent...'); 4 5 const response = await client.agents.general.invoke({ 6 config: { 7 model: 'gpt-4-turbo-preview', 8 enabled_tools: ['search'], 9 }, 10 messages: [ 11 { 12 content: 'Search for the latest news about artificial intelligence', 13 role: 'user', 14 type: 'user', 15 }, 16 ], 17 }); 18 19 console.log('โ Response received'); 20 21 // Extract the response content safely 22 const messages = response.messages || []; 23 const lastMessage = messages[messages.length - 1]; 24 25 if (lastMessage?.kwargs?.content) { 26 console.log('Agent Response:', lastMessage.kwargs.content); 27 return lastMessage.kwargs.content; 28 } else { 29 console.warn('No content in response'); 30 return null; 31 } 32 } catch (error) { 33 if (error instanceof AthenaIntelligenceError) { 34 console.error(`API Error: ${error.statusCode} - ${error.message}`); 35 } else { 36 console.error('Unexpected error:', error); 37 } 38 return null; 39 } 40 } 41 42 // Execute the function 43 runSimpleAgent().then(result => { 44 if (result) { 45 console.log('Success:', result); 46 } 47 });
Multi-Tool Workflow
Combine multiple tools for complex tasks:
1 async function runMultiToolWorkflow() { 2 try { 3 const request = { 4 config: { 5 enabled_tools: ['search', 'browse'], 6 system_prompt: 'You are a research assistant. Use search and browse tools to gather comprehensive information.', 7 model: 'gpt-4-turbo-preview', 8 }, 9 messages: [ 10 { 11 content: 'Research the latest developments in quantum computing and provide a detailed summary with sources.', 12 role: 'user', 13 type: 'user', 14 }, 15 ], 16 }; 17 18 console.log('๐ Starting multi-tool research...'); 19 const response = await client.agents.general.invoke(request); 20 21 // Process the response 22 const messages = response.messages || []; 23 24 messages.forEach((message, index) => { 25 console.log(`Message ${index + 1}:`); 26 console.log(` Type: ${message.type}`); 27 console.log(` Role: ${message.role || 'unknown'}`); 28 29 // Handle different content types 30 const content = message.kwargs?.content || message.content; 31 if (typeof content === 'string') { 32 console.log(` Content: ${content.substring(0, 200)}...`); 33 } else if (Array.isArray(content)) { 34 console.log(` Content: ${content.length} content parts`); 35 } 36 37 // Check for tool calls 38 if (message.kwargs?.tool_calls && message.kwargs.tool_calls.length > 0) { 39 console.log(` Tool Calls: ${message.kwargs.tool_calls.length}`); 40 } 41 }); 42 43 return response; 44 } catch (error) { 45 console.error('Multi-tool workflow failed:', error); 46 return null; 47 } 48 }
Conversational Interaction
Build interactive conversations with context preservation:
1 class ConversationManager { 2 constructor(client) { 3 this.client = client; 4 this.messages = []; 5 this.threadId = null; 6 } 7 8 // Add a system message 9 addSystemMessage(content) { 10 this.messages.push({ 11 content, 12 role: 'system', 13 type: 'system', 14 }); 15 } 16 17 // Add a user message 18 addUserMessage(content) { 19 this.messages.push({ 20 content, 21 role: 'user', 22 type: 'user', 23 }); 24 } 25 26 // Send messages and get response 27 async sendMessage(userInput, config = {}) { 28 try { 29 // Add user input to conversation 30 this.addUserMessage(userInput); 31 32 const defaultConfig = { 33 model: 'gpt-4-turbo-preview', 34 enabled_tools: ['search'], 35 }; 36 37 const request = { 38 config: { ...defaultConfig, ...config }, 39 messages: [...this.messages], 40 thread_id: this.threadId, 41 }; 42 43 console.log(`๐ฌ Sending message: "${userInput}"`); 44 const response = await this.client.agents.general.invoke(request); 45 46 // Extract assistant response and add to conversation 47 const responseMessages = response.messages || []; 48 const lastMessage = responseMessages[responseMessages.length - 1]; 49 50 if (lastMessage?.kwargs?.content) { 51 const assistantContent = lastMessage.kwargs.content; 52 53 // Add assistant response to conversation history 54 this.messages.push({ 55 content: assistantContent, 56 role: 'assistant', 57 type: 'assistant', 58 }); 59 60 console.log('๐ค Assistant response received'); 61 return { 62 content: assistantContent, 63 fullResponse: response, 64 conversationLength: this.messages.length, 65 }; 66 } else { 67 console.warn('No assistant content in response'); 68 return null; 69 } 70 } catch (error) { 71 console.error('Conversation error:', error); 72 return null; 73 } 74 } 75 76 // Get conversation history 77 getHistory() { 78 return [...this.messages]; 79 } 80 81 // Clear conversation 82 clear() { 83 this.messages = []; 84 this.threadId = null; 85 } 86 } 87 88 // Usage example 89 async function runConversation() { 90 const conversation = new ConversationManager(client); 91 92 // Set up conversation context 93 conversation.addSystemMessage('You are a helpful AI assistant specializing in technology and business analysis.'); 94 95 // First message 96 const response1 = await conversation.sendMessage( 97 'What are the key trends in AI for 2024?', 98 { enabled_tools: ['search'] } 99 ); 100 101 if (response1) { 102 console.log('Response 1:', response1.content); 103 } 104 105 // Follow-up message with context 106 const response2 = await conversation.sendMessage( 107 'Can you provide specific examples of companies implementing these trends?' 108 ); 109 110 if (response2) { 111 console.log('Response 2:', response2.content); 112 console.log(`Total conversation length: ${response2.conversationLength} messages`); 113 } 114 115 // Show full conversation history 116 console.log('Full conversation:', conversation.getHistory()); 117 }
AOP Execution in Browser
Execute Agent Operating Procedures with proper async handling:
1 // AOP execution with comprehensive error handling 2 async function executeAOP(assetId, userInputs = {}) { 3 try { 4 console.log(`๐ Executing AOP: ${assetId}`); 5 console.log('User inputs:', userInputs); 6 7 const response = await client.aop.execute({ 8 asset_id: assetId, 9 user_inputs: userInputs, 10 }); 11 12 console.log('โ AOP execution completed'); 13 console.log('Status:', response.status); 14 console.log('Thread ID:', response.thread_id); 15 16 // Safe access to conversation data 17 if (response.conversation) { 18 const conv = response.conversation; 19 console.log(`๐ Conversation: ${conv.num_messages} messages`); 20 21 // Get the final result safely 22 if (conv.last_assistant_message?.content) { 23 const finalContent = conv.last_assistant_message.content; 24 25 if (typeof finalContent === 'string') { 26 console.log('Final Result:', finalContent); 27 return { 28 success: true, 29 result: finalContent, 30 conversationId: conv.conversation_id, 31 messageCount: conv.num_messages, 32 }; 33 } else if (Array.isArray(finalContent)) { 34 // Handle multimodal content 35 const textParts = finalContent 36 .filter(part => part.type === 'text') 37 .map(part => part.text) 38 .join('\n'); 39 40 console.log('Final Result (multimodal):', textParts); 41 return { 42 success: true, 43 result: textParts, 44 conversationId: conv.conversation_id, 45 messageCount: conv.num_messages, 46 isMultimodal: true, 47 }; 48 } 49 } else { 50 console.warn('No final assistant message available'); 51 return { 52 success: false, 53 error: 'No final response from assistant', 54 conversationId: conv.conversation_id, 55 }; 56 } 57 } else { 58 console.warn('No conversation data in response'); 59 return { 60 success: false, 61 error: 'No conversation data available', 62 threadId: response.thread_id, 63 }; 64 } 65 } catch (error) { 66 console.error('AOP execution failed:', error); 67 68 if (error instanceof AthenaIntelligenceError) { 69 return { 70 success: false, 71 error: `API Error: ${error.statusCode} - ${error.message}`, 72 statusCode: error.statusCode, 73 }; 74 } else { 75 return { 76 success: false, 77 error: error.message || 'Unknown error', 78 }; 79 } 80 } 81 } 82 83 // Example usage 84 const marketAnalysisResult = await executeAOP( 85 'asset_market_research_aop', 86 { 87 company: 'Tesla', 88 quarter: 'Q3 2024', 89 analysis_type: 'comprehensive', 90 } 91 ); 92 93 console.log('Market analysis result:', marketAnalysisResult);
Async AOP with Progress Tracking
Handle long-running AOPs with real-time progress updates:
1 // Async AOP execution with progress tracking 2 async function executeAOPAsync(assetId, userInputs = {}, onProgress = null) { 3 try { 4 console.log(`๐ Starting async AOP: ${assetId}`); 5 6 // Start async execution 7 const asyncResponse = await client.aop.executeAsync({ 8 asset_id: assetId, 9 user_inputs: userInputs, 10 }); 11 12 console.log('โ AOP execution started'); 13 console.log('Thread ID:', asyncResponse.thread_id); 14 console.log('Message:', asyncResponse.message); 15 16 // Monitor progress 17 const result = await monitorAOPProgress(asyncResponse.thread_id, onProgress); 18 19 return { 20 success: true, 21 startResponse: asyncResponse, 22 finalResult: result, 23 }; 24 } catch (error) { 25 console.error('Async AOP execution failed:', error); 26 return { 27 success: false, 28 error: error.message || 'Unknown error', 29 }; 30 } 31 } 32 33 // Progress monitoring function 34 async function monitorAOPProgress(threadId, onProgress = null) { 35 const maxAttempts = 60; // 5 minutes with 5-second intervals 36 const pollInterval = 5000; 37 38 for (let attempt = 1; attempt <= maxAttempts; attempt++) { 39 try { 40 const status = await client.threads.getStatus(threadId); 41 42 const progressInfo = { 43 attempt, 44 maxAttempts, 45 status: status.status, 46 updatedAt: status.updated_at, 47 threadId: status.thread_id, 48 }; 49 50 // Call progress callback if provided 51 if (onProgress) { 52 onProgress(progressInfo); 53 } 54 55 console.log(`[${attempt}/${maxAttempts}] Status: ${status.status} (${status.updated_at})`); 56 57 if (status.status === 'completed') { 58 console.log('๐ AOP execution completed!'); 59 60 // Extract final result safely 61 const asset = status.conversation_asset; 62 if (asset?.last_message?.content) { 63 const finalContent = asset.last_message.content; 64 return { 65 status: 'completed', 66 result: typeof finalContent === 'string' ? finalContent : JSON.stringify(finalContent), 67 conversationAssetId: asset.conversation_asset_id, 68 messageCount: asset.num_messages, 69 threadStatus: status, 70 }; 71 } else { 72 return { 73 status: 'completed', 74 result: 'No final message content available', 75 threadStatus: status, 76 }; 77 } 78 } else if (status.status === 'failed') { 79 console.error('โ AOP execution failed'); 80 return { 81 status: 'failed', 82 error: 'AOP execution failed', 83 threadStatus: status, 84 }; 85 } 86 87 // Continue polling 88 await new Promise(resolve => setTimeout(resolve, pollInterval)); 89 } catch (error) { 90 console.error('Status check failed:', error); 91 return { 92 status: 'error', 93 error: error.message || 'Status check failed', 94 }; 95 } 96 } 97 98 console.warn('โฐ Polling timeout reached'); 99 return { 100 status: 'timeout', 101 error: 'Monitoring timeout reached - execution may still be running', 102 }; 103 } 104 105 // Example usage with progress tracking 106 const progressCallback = (info) => { 107 console.log(`Progress: ${info.attempt}/${info.maxAttempts} - ${info.status}`); 108 109 // Update UI or send to analytics 110 if (typeof window !== 'undefined' && window.updateProgressUI) { 111 window.updateProgressUI(info); 112 } 113 }; 114 115 const comprehensiveAnalysis = await executeAOPAsync( 116 'asset_comprehensive_research_aop', 117 { 118 company: 'OpenAI', 119 research_depth: 'comprehensive', 120 include_financials: 'true', 121 time_horizon: '2024-2025', 122 }, 123 progressCallback 124 ); 125 126 console.log('Comprehensive analysis result:', comprehensiveAnalysis);
Batch Processing
Process multiple requests efficiently in the browser:
1 // Batch AOP execution 2 async function executeBatchAOPs(aopConfigs) { 3 console.log(`๐ Processing ${aopConfigs.length} AOPs in batch...`); 4 5 const results = await Promise.allSettled( 6 aopConfigs.map(async (config, index) => { 7 try { 8 console.log(`Starting AOP ${index + 1}: ${config.name || config.assetId}`); 9 10 const response = await client.aop.execute({ 11 asset_id: config.assetId, 12 user_inputs: config.userInputs || {}, 13 }); 14 15 // Extract result safely 16 const content = response.conversation?.last_assistant_message?.content; 17 18 return { 19 index, 20 name: config.name || `AOP ${index + 1}`, 21 success: true, 22 result: content || 'No content available', 23 threadId: response.thread_id, 24 status: response.status, 25 }; 26 } catch (error) { 27 console.error(`AOP ${index + 1} failed:`, error); 28 return { 29 index, 30 name: config.name || `AOP ${index + 1}`, 31 success: false, 32 error: error.message || 'Unknown error', 33 }; 34 } 35 }) 36 ); 37 38 // Process results 39 const successful = results.filter(r => r.status === 'fulfilled' && r.value.success); 40 const failed = results.filter(r => r.status === 'rejected' || !r.value.success); 41 42 console.log(`โ Batch complete: ${successful.length} successful, ${failed.length} failed`); 43 44 return { 45 successful: successful.map(r => r.value), 46 failed: failed.map(r => r.status === 'fulfilled' ? r.value : { error: r.reason }), 47 summary: { 48 total: aopConfigs.length, 49 successful: successful.length, 50 failed: failed.length, 51 }, 52 }; 53 } 54 55 // Example batch configuration 56 const batchConfigs = [ 57 { 58 name: 'Market Research', 59 assetId: 'asset_market_research_aop', 60 userInputs: { company: 'Apple', quarter: 'Q3 2024' }, 61 }, 62 { 63 name: 'Competitor Analysis', 64 assetId: 'asset_competitor_analysis_aop', 65 userInputs: { company: 'Apple', competitors: 'Samsung,Google,Microsoft' }, 66 }, 67 { 68 name: 'Financial Summary', 69 assetId: 'asset_financial_analysis_aop', 70 userInputs: { company: 'Apple', period: 'annual', year: '2024' }, 71 }, 72 ]; 73 74 const batchResults = await executeBatchAOPs(batchConfigs); 75 console.log('Batch processing complete:', batchResults);
File Upload and Processing
Upload files and process them with AOPs:
1 // File upload and processing workflow 2 async function uploadAndProcessFile(file, processingAOPId, processingInputs = {}) { 3 try { 4 console.log(`๐ Uploading file: ${file.name}`); 5 6 // Upload the file 7 const uploadResponse = await client.tools.saveAsset({ file }); 8 9 if (!uploadResponse.asset_id) { 10 throw new Error('File upload failed - no asset ID returned'); 11 } 12 13 console.log('โ File uploaded:', uploadResponse.asset_id); 14 15 // Process with AOP 16 console.log('๐ Processing file with AOP...'); 17 18 const processingResponse = await client.aop.execute({ 19 asset_id: processingAOPId, 20 user_inputs: { 21 ...processingInputs, 22 file_asset_id: uploadResponse.asset_id, 23 }, 24 }); 25 26 // Extract processing result 27 const result = processingResponse.conversation?.last_assistant_message?.content; 28 29 return { 30 success: true, 31 uploadedAssetId: uploadResponse.asset_id, 32 processingResult: result || 'No processing result available', 33 threadId: processingResponse.thread_id, 34 }; 35 } catch (error) { 36 console.error('File processing failed:', error); 37 return { 38 success: false, 39 error: error.message || 'Unknown error', 40 }; 41 } 42 } 43 44 // File input handler 45 function handleFileUpload(inputElement, processingAOPId) { 46 inputElement.addEventListener('change', async (event) => { 47 const file = event.target.files?.[0]; 48 49 if (!file) { 50 console.log('No file selected'); 51 return; 52 } 53 54 console.log(`Selected file: ${file.name} (${file.size} bytes)`); 55 56 const result = await uploadAndProcessFile( 57 file, 58 processingAOPId, 59 { 60 analysis_type: 'comprehensive', 61 extract_insights: 'true', 62 } 63 ); 64 65 if (result.success) { 66 console.log('File processing completed:', result.processingResult); 67 } else { 68 console.error('File processing failed:', result.error); 69 } 70 }); 71 }
Real-time Data Processing
Process data streams and handle updates:
1 // Real-time data processor 2 class RealTimeAOPProcessor { 3 constructor(client, aopAssetId) { 4 this.client = client; 5 this.aopAssetId = aopAssetId; 6 this.processing = false; 7 this.queue = []; 8 this.results = []; 9 } 10 11 // Add data to processing queue 12 addData(data, metadata = {}) { 13 this.queue.push({ 14 data, 15 metadata, 16 timestamp: new Date().toISOString(), 17 }); 18 19 console.log(`๐ Added data to queue. Queue length: ${this.queue.length}`); 20 21 // Auto-process if not currently processing 22 if (!this.processing) { 23 this.processQueue(); 24 } 25 } 26 27 // Process queued data 28 async processQueue() { 29 if (this.processing || this.queue.length === 0) { 30 return; 31 } 32 33 this.processing = true; 34 console.log(`๐ Processing ${this.queue.length} items...`); 35 36 while (this.queue.length > 0) { 37 const item = this.queue.shift(); 38 39 try { 40 const result = await this.processItem(item); 41 this.results.push(result); 42 console.log(`โ Processed item: ${result.success ? 'success' : 'failed'}`); 43 } catch (error) { 44 console.error('Item processing error:', error); 45 this.results.push({ 46 success: false, 47 error: error.message, 48 originalData: item, 49 }); 50 } 51 } 52 53 this.processing = false; 54 console.log('๐ Queue processing complete'); 55 } 56 57 // Process individual item 58 async processItem(item) { 59 try { 60 const response = await this.client.aop.execute({ 61 asset_id: this.aopAssetId, 62 user_inputs: { 63 input_data: JSON.stringify(item.data), 64 metadata: JSON.stringify(item.metadata), 65 timestamp: item.timestamp, 66 }, 67 }); 68 69 const result = response.conversation?.last_assistant_message?.content; 70 71 return { 72 success: true, 73 result: result || 'No result content', 74 threadId: response.thread_id, 75 originalData: item, 76 processedAt: new Date().toISOString(), 77 }; 78 } catch (error) { 79 return { 80 success: false, 81 error: error.message || 'Processing failed', 82 originalData: item, 83 processedAt: new Date().toISOString(), 84 }; 85 } 86 } 87 88 // Get processing results 89 getResults() { 90 return [...this.results]; 91 } 92 93 // Clear results 94 clearResults() { 95 this.results = []; 96 } 97 } 98 99 // Usage example 100 const dataProcessor = new RealTimeAOPProcessor(client, 'asset_data_analysis_aop'); 101 102 // Simulate data stream 103 const sampleData = [ 104 { temperature: 23.5, humidity: 45, location: 'NYC' }, 105 { temperature: 21.2, humidity: 52, location: 'LA' }, 106 { temperature: 18.7, humidity: 38, location: 'Chicago' }, 107 ]; 108 109 // Add data items with metadata 110 sampleData.forEach((data, index) => { 111 dataProcessor.addData(data, { 112 source: 'sensor_network', 113 batch_id: 'batch_001', 114 sequence: index + 1, 115 }); 116 }); 117 118 // Wait for processing to complete 119 setTimeout(() => { 120 const results = dataProcessor.getResults(); 121 console.log(`๐ Processing complete: ${results.length} results`); 122 results.forEach((result, index) => { 123 console.log(`Result ${index + 1}:`, result.success ? result.result : result.error); 124 }); 125 }, 10000);
Error Handling and Debugging
Comprehensive error handling patterns for browser environments:
1 // Global error handler for SDK operations 2 class AthenaErrorHandler { 3 static handleError(error, context = '') { 4 console.error(`โ Error in ${context}:`, error); 5 6 if (error instanceof AthenaIntelligenceError) { 7 const errorInfo = { 8 type: 'AthenaIntelligenceError', 9 statusCode: error.statusCode, 10 message: error.message, 11 context, 12 timestamp: new Date().toISOString(), 13 }; 14 15 // Log for debugging 16 console.error('Athena API Error Details:', errorInfo); 17 18 // Handle specific error codes 19 switch (error.statusCode) { 20 case 401: 21 console.error('๐ Authentication failed - check your API key'); 22 break; 23 case 404: 24 console.error('๐ Resource not found - check asset IDs'); 25 break; 26 case 400: 27 console.error('๐ Bad request - check your input parameters'); 28 break; 29 case 429: 30 console.error('๐ฆ Rate limit exceeded - slow down requests'); 31 break; 32 case 500: 33 console.error('๐ฅ Server error - try again later'); 34 break; 35 default: 36 console.error(`๐คท Unknown API error: ${error.statusCode}`); 37 } 38 39 return errorInfo; 40 } else { 41 const errorInfo = { 42 type: 'UnknownError', 43 message: error.message || 'Unknown error occurred', 44 context, 45 timestamp: new Date().toISOString(), 46 }; 47 48 console.error('Unknown Error Details:', errorInfo); 49 return errorInfo; 50 } 51 } 52 53 // Retry wrapper with exponential backoff 54 static async withRetry(asyncFn, maxRetries = 3, context = '') { 55 let lastError; 56 57 for (let attempt = 1; attempt <= maxRetries; attempt++) { 58 try { 59 console.log(`๐ Attempt ${attempt}/${maxRetries} for ${context}`); 60 const result = await asyncFn(); 61 console.log(`โ Success on attempt ${attempt} for ${context}`); 62 return result; 63 } catch (error) { 64 lastError = error; 65 66 // Don't retry on client errors (4xx) 67 if (error instanceof AthenaIntelligenceError && 68 error.statusCode >= 400 && error.statusCode < 500) { 69 console.error('โ Client error - not retrying'); 70 break; 71 } 72 73 if (attempt < maxRetries) { 74 const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000); 75 console.log(`โณ Waiting ${delay}ms before retry...`); 76 await new Promise(resolve => setTimeout(resolve, delay)); 77 } 78 } 79 } 80 81 throw this.handleError(lastError, context); 82 } 83 } 84 85 // Safe execution wrapper 86 async function safeExecuteAOP(assetId, userInputs = {}) { 87 return await AthenaErrorHandler.withRetry( 88 () => client.aop.execute({ 89 asset_id: assetId, 90 user_inputs: userInputs, 91 }), 92 3, 93 `AOP execution (${assetId})` 94 ); 95 } 96 97 // Usage with comprehensive error handling 98 try { 99 const result = await safeExecuteAOP('asset_analysis_aop', { 100 input: 'market data', 101 format: 'detailed', 102 }); 103 104 console.log('Safe execution result:', result); 105 } catch (errorInfo) { 106 console.error('Final error after retries:', errorInfo); 107 108 // Handle in UI 109 if (typeof window !== 'undefined' && window.showErrorMessage) { 110 window.showErrorMessage(`Failed to execute AOP: ${errorInfo.message}`); 111 } 112 }
Debug and Development Utilities
Helpful utilities for debugging in browser console:
1 // Debug utilities for browser development 2 window.athenaDebug = { 3 // Test connection 4 async testConnection() { 5 try { 6 const userInfo = await client.me.get(); 7 console.log('โ Connection successful:', userInfo); 8 return true; 9 } catch (error) { 10 console.error('โ Connection failed:', error); 11 return false; 12 } 13 }, 14 15 // List available assets 16 async listAssets(limit = 10) { 17 try { 18 const assets = await client.assets.list({ limit }); 19 console.log(`๐ Found ${assets.total} assets (showing first ${limit}):`); 20 21 assets.items.forEach((asset, index) => { 22 console.log(`${index + 1}. ${asset.title} (${asset.athena_original_type})`); 23 console.log(` ID: ${asset.id}`); 24 console.log(` Created: ${asset.created_at}`); 25 }); 26 27 return assets; 28 } catch (error) { 29 console.error('Failed to list assets:', error); 30 return null; 31 } 32 }, 33 34 // Quick AOP test 35 async testAOP(assetId, userInputs = {}) { 36 console.log(`๐งช Testing AOP: ${assetId}`); 37 console.log('User inputs:', userInputs); 38 39 try { 40 const response = await client.aop.execute({ 41 asset_id: assetId, 42 user_inputs: userInputs, 43 }); 44 45 console.log('Test result:', { 46 status: response.status, 47 threadId: response.thread_id, 48 hasConversation: !!response.conversation, 49 hasFinalMessage: !!response.conversation?.last_assistant_message, 50 messageCount: response.conversation?.num_messages || 0, 51 }); 52 53 return response; 54 } catch (error) { 55 console.error('AOP test failed:', error); 56 return null; 57 } 58 }, 59 60 // Monitor thread 61 async monitorThread(threadId) { 62 try { 63 const status = await client.threads.getStatus(threadId); 64 console.log('Thread status:', { 65 id: threadId, 66 status: status.status, 67 updatedAt: status.updated_at, 68 hasConversationAsset: !!status.conversation_asset, 69 conversationState: status.conversation_asset?.state, 70 messageCount: status.conversation_asset?.num_messages, 71 }); 72 73 return status; 74 } catch (error) { 75 console.error('Thread monitoring failed:', error); 76 return null; 77 } 78 }, 79 }; 80 81 // Development helper 82 console.log('๐ ๏ธ Athena Debug utilities available:'); 83 console.log(' athenaDebug.testConnection() - Test API connection'); 84 console.log(' athenaDebug.listAssets(limit) - List workspace assets'); 85 console.log(' athenaDebug.testAOP(assetId, inputs) - Test AOP execution'); 86 console.log(' athenaDebug.monitorThread(threadId) - Check thread status');
Complete Browser Example
Hereโs a complete working example that demonstrates all patterns:
1 // Complete browser implementation 2 import { AthenaIntelligenceClient, AthenaIntelligenceError } from 'https://esm.run/athena-intelligence'; 3 4 async function initializeAthenaApp() { 5 try { 6 // Initialize client with optional baseUrl override 7 const client = new AthenaIntelligenceClient({ 8 apiKey: API_KEY, 9 // Optional: override baseUrl for custom environments 10 // baseUrl: 'https://your-custom-api.example.com', // Custom API 11 // baseUrl: 'http://localhost:8000', // Local development 12 }); 13 14 console.log('๐ Athena Intelligence SDK loaded'); 15 16 // Test connection 17 const userInfo = await client.me.get(); 18 console.log('๐ค User:', userInfo.email); 19 console.log('๐ข Workspace:', userInfo.workspace_name); 20 21 // Example: Quick agent interaction 22 const quickResponse = await client.agents.general.invoke({ 23 config: { model: 'gpt-4-turbo-preview' }, 24 messages: [ 25 { 26 content: 'Hello! Can you help me understand how AOPs work?', 27 role: 'user', 28 type: 'user', 29 }, 30 ], 31 }); 32 33 const agentResponse = quickResponse.messages?.[quickResponse.messages.length - 1]?.kwargs?.content; 34 console.log('๐ค Agent says:', agentResponse); 35 36 // Example: AOP execution 37 const aopResult = await client.aop.execute({ 38 asset_id: 'asset_example_aop', 39 user_inputs: { 40 topic: 'browser SDK usage', 41 format: 'comprehensive', 42 }, 43 }); 44 45 console.log('๐ AOP Result Status:', aopResult.status); 46 47 if (aopResult.conversation?.last_assistant_message?.content) { 48 console.log('๐ AOP Output:', aopResult.conversation.last_assistant_message.content); 49 } else { 50 console.log('โ ๏ธ No final output from AOP'); 51 } 52 53 // Make client available globally for debugging 54 window.athenaClient = client; 55 console.log('๐ Client available as window.athenaClient'); 56 57 return { 58 client, 59 userInfo, 60 ready: true, 61 }; 62 } catch (error) { 63 console.error('โ Initialization failed:', error); 64 65 if (error instanceof AthenaIntelligenceError) { 66 console.error(`API Error: ${error.statusCode} - ${error.message}`); 67 } 68 69 return { 70 client: null, 71 ready: false, 72 error: error.message, 73 }; 74 } 75 } 76 77 // Initialize when DOM is ready 78 if (document.readyState === 'loading') { 79 document.addEventListener('DOMContentLoaded', initializeAthenaApp); 80 } else { 81 initializeAthenaApp(); 82 }