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
1

Basic ESM Import Setup

Use the SDK directly in your browser with ESM imports:

1// Import the SDK from ESM CDN
2import { AthenaIntelligenceClient, AthenaIntelligenceError } from 'https://esm.run/athena-intelligence';
3
4// Basic client initialization (uses default production API)
5const client = new AthenaIntelligenceClient({
6 apiKey: API_KEY, // Assumes API_KEY is defined globally
7});
8
9// Override baseUrl for custom API endpoints
10const 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
16const devClient = new AthenaIntelligenceClient({
17 apiKey: API_KEY,
18 baseUrl: 'http://localhost:8000', // Local development server
19});
20
21console.log('Athena Intelligence client initialized');
2

Simple Agent Interaction

Execute basic agent requests with full error handling:

1async 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
43runSimpleAgent().then(result => {
44 if (result) {
45 console.log('Success:', result);
46 }
47});
3

Multi-Tool Workflow

Combine multiple tools for complex tasks:

1async 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}
4

Conversational Interaction

Build interactive conversations with context preservation:

1class 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
89async 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}
5

Understanding AOP Execution

Important: Agent Operating Procedures (AOPs) can take minutes to complete. Always use asynchronous execution to prevent timeouts and enable real-time progress tracking.

How it works:

  1. executeAsync starts execution and returns immediately with a thread_id
  2. The AOP runs in the background on the server
  3. You poll threads.getStatus to monitor progress
  4. When status is completed, extract the final result
6

Basic Async AOP Execution

Execute AOPs asynchronously with proper monitoring:

1// Async AOP execution (recommended for production)
2async function executeAOP(assetId, userInputs = {}) {
3 try {
4 console.log(`๐Ÿš€ Starting async AOP execution: ${assetId}`);
5 console.log('User inputs:', userInputs);
6
7 // Step 1: Start async execution (returns immediately with thread_id)
8 const asyncResponse = await client.aop.executeAsync({
9 asset_id: assetId,
10 user_inputs: userInputs,
11 });
12
13 // executeAsync only STARTS the execution - it does NOT complete it
14 console.log('โœ… AOP execution initiated (running in background)');
15 console.log('Thread ID:', asyncResponse.thread_id);
16 console.log('Status:', asyncResponse.status); // Will be "started" or similar
17 console.log('AOP Title:', asyncResponse.aop_title);
18
19 // Step 2: Monitor execution until it actually completes
20 const result = await monitorExecution(asyncResponse.thread_id);
21
22 return result;
23 } catch (error) {
24 console.error('AOP execution failed:', error);
25
26 if (error instanceof AthenaIntelligenceError) {
27 return {
28 success: false,
29 error: `API Error: ${error.statusCode} - ${error.message}`,
30 statusCode: error.statusCode,
31 };
32 } else {
33 return {
34 success: false,
35 error: error.message || 'Unknown error',
36 };
37 }
38 }
39}
40
41// Progress monitoring function
42async function monitorExecution(threadId) {
43 const maxAttempts = 60; // 5 minutes with 5-second intervals
44 const pollInterval = 5000;
45 let consecutiveErrors = 0;
46 const maxConsecutiveErrors = 3;
47
48 console.log(`๐Ÿ“Š Starting progress monitoring for thread: ${threadId}`);
49
50 for (let attempt = 1; attempt <= maxAttempts; attempt++) {
51 try {
52 // Poll thread status
53 const status = await client.threads.getStatus(threadId);
54
55 // Reset error counter on successful response
56 consecutiveErrors = 0;
57
58 console.log(`[${attempt}/${maxAttempts}] Status: ${status.status} (Updated: ${status.updated_at})`);
59
60 // Check if execution completed
61 if (status.status === 'completed') {
62 console.log('๐ŸŽ‰ AOP execution completed successfully!');
63
64 // Extract final result safely
65 const conversationAsset = status.conversation_asset;
66 if (conversationAsset?.last_message?.content) {
67 const finalContent = conversationAsset.last_message.content;
68
69 // Handle string content
70 if (typeof finalContent === 'string') {
71 return {
72 success: true,
73 status: 'completed',
74 result: finalContent,
75 threadId,
76 conversationAssetId: conversationAsset.conversation_asset_id,
77 messageCount: conversationAsset.num_messages,
78 };
79 }
80
81 // Handle multimodal content (array)
82 if (Array.isArray(finalContent)) {
83 const textParts = finalContent
84 .filter(part => part.type === 'text' && part.text)
85 .map(part => part.text)
86 .join('\n');
87
88 return {
89 success: true,
90 status: 'completed',
91 result: textParts,
92 threadId,
93 conversationAssetId: conversationAsset.conversation_asset_id,
94 messageCount: conversationAsset.num_messages,
95 isMultimodal: true,
96 };
97 }
98 }
99
100 // Completed but no content
101 return {
102 success: true,
103 status: 'completed',
104 result: 'AOP completed but no final message available',
105 threadId,
106 };
107 } else if (status.status === 'failed') {
108 console.error('โŒ AOP execution failed');
109 return {
110 success: false,
111 status: 'failed',
112 error: 'AOP execution failed',
113 threadId,
114 };
115 }
116
117 // Still running - wait before next poll
118 console.log(`โณ Still running... (${status.status})`);
119 await new Promise(resolve => setTimeout(resolve, pollInterval));
120 } catch (error) {
121 consecutiveErrors++;
122 console.error(`Status check failed (${consecutiveErrors}/${maxConsecutiveErrors}):`, error.message);
123
124 // Fail fast if too many consecutive errors
125 if (consecutiveErrors >= maxConsecutiveErrors) {
126 return {
127 success: false,
128 status: 'error',
129 error: `Too many consecutive status check failures: ${error.message}`,
130 threadId,
131 };
132 }
133
134 // Wait before retrying
135 await new Promise(resolve => setTimeout(resolve, pollInterval));
136 }
137 }
138
139 // Timeout reached
140 console.warn('โฐ Polling timeout reached');
141 return {
142 success: false,
143 status: 'timeout',
144 error: 'Monitoring timeout reached - execution may still be running',
145 threadId,
146 };
147}
148
149// Example usage
150const marketAnalysisResult = await executeAOP(
151 'asset_market_research_aop',
152 {
153 company: 'Tesla',
154 quarter: 'Q3 2024',
155 analysis_type: 'comprehensive',
156 }
157);
158
159if (marketAnalysisResult.success) {
160 console.log('โœ… Market analysis result:', marketAnalysisResult.result);
161} else {
162 console.error('โŒ Market analysis failed:', marketAnalysisResult.error);
163}
7

Advanced: Custom Progress Callbacks

Add custom progress callbacks for UI updates and analytics:

1// Execute AOP with custom progress tracking
2async function executeAOPWithProgress(assetId, userInputs = {}, onProgress = null) {
3 try {
4 console.log(`๐Ÿš€ Starting async AOP: ${assetId}`);
5
6 // Step 1: Start async execution (returns immediately)
7 const asyncResponse = await client.aop.executeAsync({
8 asset_id: assetId,
9 user_inputs: userInputs,
10 });
11
12 console.log('โœ… AOP execution initiated');
13 console.log('Thread ID:', asyncResponse.thread_id);
14 console.log('AOP Title:', asyncResponse.aop_title);
15
16 // Step 2: Monitor progress with callbacks
17 const result = await monitorWithCallback(asyncResponse.thread_id, onProgress);
18
19 return {
20 success: result.success,
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 with callback support
34async function monitorWithCallback(threadId, onProgress = null) {
35 const maxAttempts = 120; // 10 minutes for longer workflows
36 const pollInterval = 5000;
37 let consecutiveErrors = 0;
38 const maxConsecutiveErrors = 3;
39
40 for (let attempt = 1; attempt <= maxAttempts; attempt++) {
41 try {
42 const status = await client.threads.getStatus(threadId);
43
44 // Reset error counter
45 consecutiveErrors = 0;
46
47 // Call progress callback if provided
48 if (onProgress) {
49 onProgress({
50 attempt,
51 maxAttempts,
52 status: status.status,
53 updatedAt: status.updated_at,
54 threadId: status.thread_id,
55 });
56 }
57
58 console.log(`[${attempt}/${maxAttempts}] Status: ${status.status} (${status.updated_at})`);
59
60 if (status.status === 'completed') {
61 console.log('๐ŸŽ‰ AOP execution completed!');
62
63 // Extract final result
64 const conversationAsset = status.conversation_asset;
65 if (conversationAsset?.last_message?.content) {
66 const finalContent = conversationAsset.last_message.content;
67
68 // Handle string or array content
69 let resultText;
70 if (typeof finalContent === 'string') {
71 resultText = finalContent;
72 } else if (Array.isArray(finalContent)) {
73 resultText = finalContent
74 .filter(part => part.type === 'text' && part.text)
75 .map(part => part.text)
76 .join('\n');
77 } else {
78 resultText = JSON.stringify(finalContent);
79 }
80
81 return {
82 success: true,
83 status: 'completed',
84 result: resultText,
85 conversationAssetId: conversationAsset.conversation_asset_id,
86 messageCount: conversationAsset.num_messages,
87 threadStatus: status,
88 };
89 } else {
90 return {
91 success: true,
92 status: 'completed',
93 result: 'AOP completed but no final message available',
94 threadStatus: status,
95 };
96 }
97 } else if (status.status === 'failed') {
98 console.error('โŒ AOP execution failed');
99 return {
100 success: false,
101 status: 'failed',
102 error: 'AOP execution failed',
103 threadStatus: status,
104 };
105 }
106
107 // Continue polling
108 await new Promise(resolve => setTimeout(resolve, pollInterval));
109 } catch (error) {
110 consecutiveErrors++;
111 console.error(`Status check failed (${consecutiveErrors}/${maxConsecutiveErrors}):`, error.message);
112
113 // Fail fast if too many consecutive errors
114 if (consecutiveErrors >= maxConsecutiveErrors) {
115 return {
116 success: false,
117 status: 'error',
118 error: `Too many consecutive failures: ${error.message}`,
119 };
120 }
121
122 // Wait before retrying
123 await new Promise(resolve => setTimeout(resolve, pollInterval));
124 }
125 }
126
127 console.warn('โฐ Polling timeout reached');
128 return {
129 success: false,
130 status: 'timeout',
131 error: 'Monitoring timeout reached - execution may still be running',
132 };
133}
134
135// Example usage with progress tracking
136const progressCallback = (info) => {
137 console.log(`๐Ÿ“Š Progress: ${info.attempt}/${info.maxAttempts} - ${info.status}`);
138
139 // Update UI or send to analytics
140 if (typeof window !== 'undefined' && window.updateProgressUI) {
141 window.updateProgressUI({
142 percent: (info.attempt / info.maxAttempts) * 100,
143 status: info.status,
144 updatedAt: info.updatedAt,
145 });
146 }
147};
148
149const comprehensiveAnalysis = await executeAOPWithProgress(
150 'asset_comprehensive_research_aop',
151 {
152 company: 'OpenAI',
153 research_depth: 'comprehensive',
154 include_financials: 'true',
155 time_horizon: '2024-2025',
156 },
157 progressCallback
158);
159
160if (comprehensiveAnalysis.success) {
161 console.log('โœ… Comprehensive analysis result:', comprehensiveAnalysis.finalResult.result);
162} else {
163 console.error('โŒ Analysis failed:', comprehensiveAnalysis.error);
164}
8

Batch Processing with Async Execution

Process multiple AOPs concurrently using async execution:

1// Batch AOP execution with async pattern
2async function executeBatchAOPs(aopConfigs) {
3 console.log(`๐Ÿ”„ Starting ${aopConfigs.length} AOPs concurrently...`);
4
5 // Step 1: Start all AOPs asynchronously (all return immediately with thread_ids)
6 const startPromises = 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.executeAsync({
11 asset_id: config.assetId,
12 user_inputs: config.userInputs || {},
13 });
14
15 console.log(`โœ… ${config.name || 'AOP'} started with thread: ${response.thread_id}`);
16
17 return {
18 index,
19 name: config.name || `AOP ${index + 1}`,
20 threadId: response.thread_id,
21 aopTitle: response.aop_title,
22 success: true,
23 };
24 } catch (error) {
25 console.error(`โŒ Failed to start AOP ${index + 1}:`, error.message);
26 return {
27 index,
28 name: config.name || `AOP ${index + 1}`,
29 success: false,
30 error: error.message || 'Unknown error',
31 };
32 }
33 });
34
35 const startResults = await Promise.all(startPromises);
36
37 // Step 2: Monitor all successful starts until completion
38 console.log(`๐Ÿ“Š Monitoring ${startResults.filter(r => r.success).length} running AOPs...`);
39
40 const monitorPromises = startResults
41 .filter(result => result.success && result.threadId)
42 .map(async (result) => {
43 try {
44 const finalResult = await monitorExecution(result.threadId);
45 return {
46 ...result,
47 ...finalResult,
48 };
49 } catch (error) {
50 return {
51 ...result,
52 success: false,
53 status: 'error',
54 error: error.message || 'Monitoring failed',
55 };
56 }
57 });
58
59 const finalResults = await Promise.all(monitorPromises);
60
61 // Combine failed starts with monitoring results
62 const allResults = [
63 ...finalResults,
64 ...startResults.filter(r => !r.success),
65 ];
66
67 // Calculate summary
68 const successful = allResults.filter(r => r.success && r.status === 'completed');
69 const failed = allResults.filter(r => !r.success || r.status !== 'completed');
70
71 console.log(`\nโœ… Batch complete: ${successful.length} successful, ${failed.length} failed`);
72
73 return {
74 successful,
75 failed,
76 summary: {
77 total: aopConfigs.length,
78 successful: successful.length,
79 failed: failed.length,
80 },
81 };
82}
83
84// Example batch configuration
85const batchConfigs = [
86 {
87 name: 'Market Research',
88 assetId: 'asset_market_research_aop',
89 userInputs: { company: 'Apple', quarter: 'Q3 2024' },
90 },
91 {
92 name: 'Competitor Analysis',
93 assetId: 'asset_competitor_analysis_aop',
94 userInputs: { company: 'Apple', competitors: 'Samsung,Google,Microsoft' },
95 },
96 {
97 name: 'Financial Summary',
98 assetId: 'asset_financial_analysis_aop',
99 userInputs: { company: 'Apple', period: 'annual', year: '2024' },
100 },
101];
102
103const batchResults = await executeBatchAOPs(batchConfigs);
104
105console.log('\n=== Batch Results ===');
106batchResults.successful.forEach(result => {
107 console.log(`โœ… ${result.name}: ${result.result?.substring(0, 100)}...`);
108});
109batchResults.failed.forEach(result => {
110 console.log(`โŒ ${result.name}: ${result.error}`);
111});
112console.log(`\nSummary: ${batchResults.summary.successful}/${batchResults.summary.total} completed`);
9

File Upload and Processing

Upload files and process them with AOPs using async execution:

1// File upload and processing workflow with async execution
2async function uploadAndProcessFile(file, processingAOPId, processingInputs = {}) {
3 try {
4 console.log(`๐Ÿ“ Uploading file: ${file.name}`);
5
6 // Step 1: 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 // Step 2: Start async processing with AOP
16 console.log('๐Ÿ”„ Starting AOP processing...');
17
18 const asyncResponse = await client.aop.executeAsync({
19 asset_id: processingAOPId,
20 user_inputs: {
21 ...processingInputs,
22 file_asset_id: uploadResponse.asset_id,
23 },
24 });
25
26 console.log('โœ… Processing started with thread:', asyncResponse.thread_id);
27
28 // Step 3: Monitor processing until completion
29 const processingResult = await monitorExecution(asyncResponse.thread_id);
30
31 if (processingResult.success) {
32 return {
33 success: true,
34 uploadedAssetId: uploadResponse.asset_id,
35 processingResult: processingResult.result,
36 threadId: asyncResponse.thread_id,
37 conversationAssetId: processingResult.conversationAssetId,
38 };
39 } else {
40 return {
41 success: false,
42 uploadedAssetId: uploadResponse.asset_id,
43 error: processingResult.error || 'Processing failed',
44 threadId: asyncResponse.thread_id,
45 };
46 }
47 } catch (error) {
48 console.error('File processing failed:', error);
49 return {
50 success: false,
51 error: error.message || 'Unknown error',
52 };
53 }
54}
55
56// File input handler
57function handleFileUpload(inputElement, processingAOPId) {
58 inputElement.addEventListener('change', async (event) => {
59 const file = event.target.files?.[0];
60
61 if (!file) {
62 console.log('No file selected');
63 return;
64 }
65
66 console.log(`Selected file: ${file.name} (${file.size} bytes)`);
67
68 const result = await uploadAndProcessFile(
69 file,
70 processingAOPId,
71 {
72 analysis_type: 'comprehensive',
73 extract_insights: 'true',
74 }
75 );
76
77 if (result.success) {
78 console.log('File processing completed:', result.processingResult);
79 } else {
80 console.error('File processing failed:', result.error);
81 }
82 });
83}
10

Real-time Data Processing

Process data streams and handle updates:

1// Real-time data processor
2class 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 with async execution
58 async processItem(item) {
59 try {
60 // Start async execution
61 const asyncResponse = await this.client.aop.executeAsync({
62 asset_id: this.aopAssetId,
63 user_inputs: {
64 input_data: JSON.stringify(item.data),
65 metadata: JSON.stringify(item.metadata),
66 timestamp: item.timestamp,
67 },
68 });
69
70 console.log(`Processing item with thread: ${asyncResponse.thread_id}`);
71
72 // Monitor execution (simplified for real-time processing)
73 const result = await this.monitorItemExecution(asyncResponse.thread_id);
74
75 return {
76 success: result.success,
77 result: result.result || 'No result content',
78 threadId: asyncResponse.thread_id,
79 originalData: item,
80 processedAt: new Date().toISOString(),
81 };
82 } catch (error) {
83 return {
84 success: false,
85 error: error.message || 'Processing failed',
86 originalData: item,
87 processedAt: new Date().toISOString(),
88 };
89 }
90 }
91
92 // Simplified monitoring for real-time items (shorter timeout)
93 async monitorItemExecution(threadId) {
94 const maxAttempts = 30; // 2.5 minutes for individual items
95 const pollInterval = 5000;
96
97 for (let attempt = 1; attempt <= maxAttempts; attempt++) {
98 try {
99 const status = await this.client.threads.getStatus(threadId);
100
101 if (status.status === 'completed') {
102 const conversationAsset = status.conversation_asset;
103 if (conversationAsset?.last_message?.content) {
104 const content = conversationAsset.last_message.content;
105 const result = typeof content === 'string'
106 ? content
107 : Array.isArray(content)
108 ? content.filter(p => p.type === 'text').map(p => p.text).join('\n')
109 : JSON.stringify(content);
110
111 return { success: true, result };
112 }
113 return { success: true, result: 'Completed with no content' };
114 } else if (status.status === 'failed') {
115 return { success: false, error: 'Execution failed' };
116 }
117
118 await new Promise(resolve => setTimeout(resolve, pollInterval));
119 } catch (error) {
120 if (attempt === maxAttempts) {
121 return { success: false, error: error.message };
122 }
123 }
124 }
125
126 return { success: false, error: 'Timeout' };
127 }
128
129 // Get processing results
130 getResults() {
131 return [...this.results];
132 }
133
134 // Clear results
135 clearResults() {
136 this.results = [];
137 }
138}
139
140// Usage example
141const dataProcessor = new RealTimeAOPProcessor(client, 'asset_data_analysis_aop');
142
143// Simulate data stream
144const sampleData = [
145 { temperature: 23.5, humidity: 45, location: 'NYC' },
146 { temperature: 21.2, humidity: 52, location: 'LA' },
147 { temperature: 18.7, humidity: 38, location: 'Chicago' },
148];
149
150// Add data items with metadata
151sampleData.forEach((data, index) => {
152 dataProcessor.addData(data, {
153 source: 'sensor_network',
154 batch_id: 'batch_001',
155 sequence: index + 1,
156 });
157});
158
159// Wait for processing to complete
160setTimeout(() => {
161 const results = dataProcessor.getResults();
162 console.log(`๐Ÿ“ˆ Processing complete: ${results.length} results`);
163 results.forEach((result, index) => {
164 console.log(`Result ${index + 1}:`, result.success ? result.result : result.error);
165 });
166}, 10000);
11

Error Handling and Debugging

Comprehensive error handling patterns for browser environments:

1// Global error handler for SDK operations
2class 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 with async execution
86async function safeExecuteAOP(assetId, userInputs = {}) {
87 return await AthenaErrorHandler.withRetry(
88 async () => {
89 // Start async execution
90 const asyncResponse = await client.aop.executeAsync({
91 asset_id: assetId,
92 user_inputs: userInputs,
93 });
94
95 // Monitor until completion
96 const result = await monitorExecution(asyncResponse.thread_id);
97
98 if (!result.success) {
99 throw new Error(result.error || 'AOP execution failed');
100 }
101
102 return result;
103 },
104 3,
105 `AOP execution (${assetId})`
106 );
107}
108
109// Usage with comprehensive error handling
110try {
111 const result = await safeExecuteAOP('asset_analysis_aop', {
112 input: 'market data',
113 format: 'detailed',
114 });
115
116 console.log('Safe execution result:', result);
117} catch (errorInfo) {
118 console.error('Final error after retries:', errorInfo);
119
120 // Handle in UI
121 if (typeof window !== 'undefined' && window.showErrorMessage) {
122 window.showErrorMessage(`Failed to execute AOP: ${errorInfo.message}`);
123 }
124}
12

Debug and Development Utilities

Helpful utilities for debugging in browser console:

1// Debug utilities for browser development
2window.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 with async execution
35 async testAOP(assetId, userInputs = {}) {
36 console.log(`๐Ÿงช Testing AOP: ${assetId}`);
37 console.log('User inputs:', userInputs);
38
39 try {
40 // Start async execution
41 const asyncResponse = await client.aop.executeAsync({
42 asset_id: assetId,
43 user_inputs: userInputs,
44 });
45
46 console.log('AOP started:', {
47 threadId: asyncResponse.thread_id,
48 aopTitle: asyncResponse.aop_title,
49 status: asyncResponse.status,
50 });
51
52 // Monitor execution (short timeout for testing)
53 const maxAttempts = 30; // 2.5 minutes
54 const pollInterval = 5000;
55
56 for (let attempt = 1; attempt <= maxAttempts; attempt++) {
57 const status = await client.threads.getStatus(asyncResponse.thread_id);
58 console.log(`[${attempt}/${maxAttempts}] Status: ${status.status}`);
59
60 if (status.status === 'completed') {
61 console.log('โœ… Test completed successfully');
62 console.log('Final result:', {
63 conversationAssetId: status.conversation_asset?.conversation_asset_id,
64 messageCount: status.conversation_asset?.num_messages,
65 hasContent: !!status.conversation_asset?.last_message?.content,
66 });
67 return status;
68 } else if (status.status === 'failed') {
69 console.error('โŒ Test failed');
70 return status;
71 }
72
73 await new Promise(resolve => setTimeout(resolve, pollInterval));
74 }
75
76 console.warn('โฐ Test timeout reached');
77 return null;
78 } catch (error) {
79 console.error('AOP test failed:', error);
80 return null;
81 }
82 },
83
84 // Monitor thread
85 async monitorThread(threadId) {
86 try {
87 const status = await client.threads.getStatus(threadId);
88 console.log('Thread status:', {
89 id: threadId,
90 status: status.status,
91 updatedAt: status.updated_at,
92 hasConversationAsset: !!status.conversation_asset,
93 conversationState: status.conversation_asset?.state,
94 messageCount: status.conversation_asset?.num_messages,
95 });
96
97 return status;
98 } catch (error) {
99 console.error('Thread monitoring failed:', error);
100 return null;
101 }
102 },
103};
104
105// Development helper
106console.log('๐Ÿ› ๏ธ Athena Debug utilities available:');
107console.log(' athenaDebug.testConnection() - Test API connection');
108console.log(' athenaDebug.listAssets(limit) - List workspace assets');
109console.log(' athenaDebug.testAOP(assetId, inputs) - Test AOP execution');
110console.log(' athenaDebug.monitorThread(threadId) - Check thread status');
13

Complete Browser Example

Hereโ€™s a complete working example that demonstrates all patterns:

1// Complete browser implementation
2import { AthenaIntelligenceClient, AthenaIntelligenceError } from 'https://esm.run/athena-intelligence';
3
4async 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: Async AOP execution
37 console.log('๐Ÿš€ Starting async AOP execution...');
38 const asyncResponse = await client.aop.executeAsync({
39 asset_id: 'asset_example_aop',
40 user_inputs: {
41 topic: 'browser SDK usage',
42 format: 'comprehensive',
43 },
44 });
45
46 console.log('โœ… AOP initiated with thread:', asyncResponse.thread_id);
47 console.log('๐Ÿ“‹ AOP Title:', asyncResponse.aop_title);
48
49 // Monitor execution (simplified example)
50 console.log('๐Ÿ“Š Monitoring execution...');
51 const maxAttempts = 30;
52 const pollInterval = 5000;
53
54 for (let attempt = 1; attempt <= maxAttempts; attempt++) {
55 const status = await client.threads.getStatus(asyncResponse.thread_id);
56 console.log(`[${attempt}/${maxAttempts}] Status: ${status.status}`);
57
58 if (status.status === 'completed') {
59 console.log('๐ŸŽ‰ AOP execution completed!');
60 const finalContent = status.conversation_asset?.last_message?.content;
61
62 if (finalContent) {
63 const result = typeof finalContent === 'string'
64 ? finalContent
65 : Array.isArray(finalContent)
66 ? finalContent.filter(p => p.type === 'text').map(p => p.text).join('\n')
67 : JSON.stringify(finalContent);
68
69 console.log('๐Ÿ“ AOP Output:', result);
70 } else {
71 console.log('โš ๏ธ No final output from AOP');
72 }
73 break;
74 } else if (status.status === 'failed') {
75 console.error('โŒ AOP execution failed');
76 break;
77 }
78
79 if (attempt < maxAttempts) {
80 await new Promise(resolve => setTimeout(resolve, pollInterval));
81 }
82 }
83
84 // Make client available globally for debugging
85 window.athenaClient = client;
86 console.log('๐ŸŒ Client available as window.athenaClient');
87
88 return {
89 client,
90 userInfo,
91 ready: true,
92 };
93 } catch (error) {
94 console.error('โŒ Initialization failed:', error);
95
96 if (error instanceof AthenaIntelligenceError) {
97 console.error(`API Error: ${error.statusCode} - ${error.message}`);
98 }
99
100 return {
101 client: null,
102 ready: false,
103 error: error.message,
104 };
105 }
106}
107
108// Initialize when DOM is ready
109if (document.readyState === 'loading') {
110 document.addEventListener('DOMContentLoaded', initializeAthenaApp);
111} else {
112 initializeAthenaApp();
113}