JavaScript SDK
Modern AI agent observability for Node.js applications. The Handit.ai JavaScript SDK provides comprehensive tracking and monitoring capabilities designed specifically for Node.js AI applications, with seamless integration for popular HTTP libraries like Axios and Fetch.
This guide covers everything you need to integrate and use the SDK effectively in your JavaScript/TypeScript AI applications.
The SDK automatically tracks HTTP requests, agent executions, and custom events, providing detailed insights into your AI application’s behavior with minimal setup required.
Installation
npm install handit-sdk
Quick Start
const handit = require('handit-sdk');
// Configure the SDK
handit.config({
apiKey: 'your-api-key',
trackingUrl: 'https://handit-api-299768392189.us-central1.run.app/api/track',
performanceUrl: 'https://handit-api-299768392189.us-central1.run.app/api'
});
// Start tracking your agent
const myAgent = handit.startAgentTracing(async (input) => {
// Your agent logic here
return result;
});
// Use the agent
await myAgent({ query: "Hello" });
Method Reference
Method | Purpose | Minimal Example | Step-by-Step Explanation |
---|---|---|---|
config({ apiKey, trackingUrl, performanceUrl }) | Initialize the SDK with your API key and optional custom URLs |
|
|
startAgentTracing(callback) | Root trace for each agent request (inputs, outputs, errors, duration) |
|
|
traceAgentNode({ agentNodeId, callback }) | Track individual agent nodes (functions, tools, etc.) |
|
|
captureModel({ modelId, requestBody, responseBody }) | Manually track model calls or custom events |
|
|
interceptAxiosRequest(axiosInstance) | Automatically track Axios HTTP requests |
|
|
interceptFetchRequest() | Automatically track Fetch API requests |
|
|
fetchOptimizedPrompt({ modelId }) | Get optimized prompts for models |
|
|
Core Methods Documentation
Configuration
config({ apiKey, trackingUrl, performanceUrl })
Initializes the SDK with your API key and optional custom URLs.
/**
* Configure the Handit.ai SDK
* @param {Object} options - Configuration options
* @param {string} options.apiKey - Your Handit.ai API key (required)
* @param {string} [options.trackingUrl] - Custom tracking server URL
* @param {string} [options.performanceUrl] - Custom performance server URL
* @throws {Error} If API key is not provided
*/
handit.config({
apiKey: 'your-api-key',
trackingUrl: 'https://custom-tracking-url.com',
performanceUrl: 'https://custom-performance-url.com'
});
What it does:
- Sets authentication credentials for all tracking operations
- Configures custom tracking and performance server endpoints
- Initializes internal state and URL tracking lists
- Must be called before using any other tracking functions
Agent-Level Tracing
startAgentTracing(callback)
Creates a traced version of an agent function for complete workflow tracking.
/**
* Create a traced version of an agent function
* @param {Function} callback - The agent function to trace
* @returns {Function} Traced version of the callback
*
* @example
* const agent = handit.startAgentTracing(async (input) => {
* // Agent logic here
* return result;
* });
*/
const agent = handit.startAgentTracing(async (input) => {
// Your agent logic here
return result;
});
Key capabilities:
- Creates execution context using AsyncLocalStorage
- Handles both async and sync callback functions
- Automatically tracks start/end events with timing
- Captures errors and stack traces for debugging
- Maintains context throughout the entire execution
Function-Level Tracing
traceAgentNode({ agentNodeId, callback, externalId })
Creates a traced version of individual functions within an agent workflow.
/**
* Create a traced version of a node function
* @param {Object} options - Node configuration
* @param {string} options.agentNodeId - Unique identifier for the node
* @param {Function} options.callback - The node function to trace
* @param {string} [options.externalId] - Optional external ID for the node
* @returns {Function} Traced version of the callback
*
* @example
* const node = handit.traceAgentNode({
* agentNodeId: 'search',
* callback: async (query) => {
* // Node logic here
* return results;
* }
* });
*/
const node = handit.traceAgentNode({
agentNodeId: 'search',
callback: async (query) => {
// Node logic here
return results;
}
});
Key capabilities:
- Links to parent agent execution context
- Captures input parameters and return values
- Handles errors automatically with full context
- Supports optional external IDs for integration
- Preserves original function signature and behavior
Model & Event Tracking
captureModel({ modelId, requestBody, responseBody })
Manually track model calls, API responses, or custom events.
/**
* Track a model call or custom event
* @param {Object} options - Tracking options
* @param {string} options.modelId - Identifier for the model/event
* @param {any} options.requestBody - Input data
* @param {any} options.responseBody - Output data
* @returns {Promise<void>}
*
* @example
* await handit.captureModel({
* modelId: 'gpt4',
* requestBody: { prompt: 'Hello' },
* responseBody: { text: 'Hi' }
* });
*/
await handit.captureModel({
modelId: 'gpt4',
requestBody: { prompt: 'Hello' },
responseBody: { text: 'Hi' }
});
Key capabilities:
- Manual event tracking for custom scenarios
- Links to current agent execution context
- Handles Axios response objects automatically
- Supports any custom event types
- Robust error handling and data sanitization
HTTP Request Tracking
interceptAxiosRequest(axiosInstance)
Automatically tracks Axios HTTP requests to configured URLs.
/**
* Add tracking to Axios requests
* @param {Object} axiosInstance - Axios instance to intercept
* @returns {void}
*
* @example
* const axios = require('axios');
* handit.interceptAxiosRequest(axios);
*/
const axios = require('axios');
handit.interceptAxiosRequest(axios);
Key capabilities:
- Adds request/response interceptors transparently
- URL-based tracking with server-managed lists
- Automatic context linking to agent executions
- Comprehensive error handling and logging
- Preserves all original Axios functionality
interceptFetchRequest()
Automatically tracks Fetch API requests to configured URLs.
/**
* Add tracking to Fetch API requests
* @returns {void}
*
* @example
* handit.interceptFetchRequest();
*/
handit.interceptFetchRequest();
Key capabilities:
- Global fetch function override
- URL-based tracking with dynamic configuration
- Automatic context linking to agent executions
- Error handling for failed requests
- Maintains original Fetch API behavior
Performance Optimization
fetchOptimizedPrompt({ modelId })
Retrieves optimized prompts based on performance data and A/B testing.
/**
* Fetch optimized prompt for a model
* @param {Object} options - Options
* @param {string} options.modelId - Model identifier
* @returns {Promise<Object>} Optimized prompt data
*
* @example
* const prompt = await handit.fetchOptimizedPrompt({
* modelId: 'gpt4'
* });
*/
const prompt = await handit.fetchOptimizedPrompt({
modelId: 'gpt4'
});
Key capabilities:
- Retrieves best-performing prompts from A/B testing
- API key authentication and validation
- Comprehensive error handling and response parsing
- Enables continuous optimization workflows
- Supports self-improving AI systems
All tracking methods automatically handle errors and maintain execution context, ensuring reliable operation even when exceptions occur in your application code.
Always configure the SDK with handit.config({ apiKey: "your-key" })
before using any tracking functions.
Real-World Use Cases
1. Chatbot with Axios Integration
const handit = require('handit-sdk');
const axios = require('axios');
// Configure SDK
handit.config({
apiKey: 'your-api-key'
});
// Intercept Axios requests
handit.interceptAxiosRequest(axios);
// Main chatbot function
const chatbot = handit.startAgentTracing(async (message) => {
try {
// Process message
const processedMessage = await processMessage(message);
// Get response from AI
const response = await getAIResponse(processedMessage);
return response;
} catch (error) {
// Errors are automatically tracked
throw error;
}
});
// Process message node
const processMessage = handit.traceAgentNode({
agentNodeId: 'message-processor',
callback: async (message) => {
// Message processing logic
return processedMessage;
}
});
// Get AI response node
const getAIResponse = handit.traceAgentNode({
agentNodeId: 'ai-response',
callback: async (message) => {
const response = await axios.post('https://api.openai.com/v1/chat/completions', {
model: 'gpt-4',
messages: [{ role: 'user', content: message }]
});
return response.data;
}
});
2. Document Processing Pipeline
const handit = require('handit-sdk');
const axios = require('axios');
// Configure SDK
handit.config({
apiKey: 'your-api-key'
});
// Main document processor
const processDocument = handit.startAgentTracing(async (document) => {
try {
// Process document in parallel
const [entities, summary, classification] = await Promise.all([
extractEntities(document),
generateSummary(document),
classifyDocument(document)
]);
// Combine results
const result = await combineResults({
entities,
summary,
classification
});
return result;
} catch (error) {
throw error;
}
});
// Extract entities node
const extractEntities = handit.traceAgentNode({
agentNodeId: 'entity-extractor',
callback: async (document) => {
// Entity extraction logic
return entities;
}
});
// Generate summary node
const generateSummary = handit.traceAgentNode({
agentNodeId: 'summary-generator',
callback: async (document) => {
// Summary generation logic
return summary;
}
});
// Classify document node
const classifyDocument = handit.traceAgentNode({
agentNodeId: 'document-classifier',
callback: async (document) => {
// Classification logic
return classification;
}
});
// Combine results node
const combineResults = handit.traceAgentNode({
agentNodeId: 'result-combiner',
callback: async (results) => {
// Result combination logic
return combinedResults;
}
});
3. API Client with Request Tracking
const handit = require('handit-sdk');
const axios = require('axios');
// Configure SDK
handit.config({
apiKey: 'your-api-key'
});
// Intercept Axios requests
handit.interceptAxiosRequest(axios);
class APIClient {
constructor(baseUrl) {
this.baseUrl = baseUrl;
this.client = axios.create({
baseURL: baseUrl
});
}
// Make request with tracking
async makeRequest(endpoint, method, data = null) {
return handit.traceAgentNode({
agentNodeId: 'api-request',
callback: async () => {
try {
const response = await this.client({
method,
url: endpoint,
data
});
return response.data;
} catch (error) {
// Errors are automatically tracked
throw error;
}
}
})();
}
// Example methods
async get(endpoint) {
return this.makeRequest(endpoint, 'GET');
}
async post(endpoint, data) {
return this.makeRequest(endpoint, 'POST', data);
}
}
4. Performance Monitoring
const handit = require('handit-sdk');
class PerformanceMonitor {
constructor(monitorId) {
this.monitorId = monitorId;
this.metrics = [];
}
// Track operation performance
async trackOperation(operation, data) {
return handit.traceAgentNode({
agentNodeId: 'performance-monitor',
callback: async () => {
const startTime = Date.now();
try {
// Execute operation
const result = await this._executeOperation(operation, data);
// Calculate metrics
const executionTime = Date.now() - startTime;
this.metrics.push(executionTime);
// Calculate statistics
const stats = {
current: executionTime,
average: this._calculateAverage(),
median: this._calculateMedian(),
min: Math.min(...this.metrics),
max: Math.max(...this.metrics)
};
// Track metrics
await handit.captureModel({
modelId: `${this.monitorId}-metrics`,
requestBody: {
operation,
data
},
responseBody: {
executionTime,
statistics: stats,
status: 'success'
}
});
return result;
} catch (error) {
const executionTime = Date.now() - startTime;
this.metrics.push(executionTime);
// Track error metrics
await handit.captureModel({
modelId: `${this.monitorId}-error`,
requestBody: {
operation,
data
},
responseBody: {
executionTime,
error: error.message,
status: 'error'
}
});
throw error;
}
}
})();
}
// Helper methods
_calculateAverage() {
return this.metrics.reduce((a, b) => a + b, 0) / this.metrics.length;
}
_calculateMedian() {
const sorted = [...this.metrics].sort((a, b) => a - b);
const middle = Math.floor(sorted.length / 2);
return sorted.length % 2 === 0
? (sorted[middle - 1] + sorted[middle]) / 2
: sorted[middle];
}
async _executeOperation(operation, data) {
// Implementation details...
return result;
}
}
5. Custom Event Tracking
const handit = require('handit-sdk');
class EventTracker {
constructor(trackerId) {
this.trackerId = trackerId;
}
// Track custom event
async trackEvent(eventType, data) {
return handit.traceAgentNode({
agentNodeId: 'event-tracker',
callback: async () => {
try {
// Process event
const processedData = await this._processEvent(eventType, data);
// Track event
await handit.captureModel({
modelId: `${this.trackerId}-${eventType}`,
requestBody: {
eventType,
data
},
responseBody: {
processedData,
timestamp: new Date().toISOString(),
status: 'success'
}
});
return processedData;
} catch (error) {
// Track error
await handit.captureModel({
modelId: `${this.trackerId}-error`,
requestBody: {
eventType,
data
},
responseBody: {
error: error.message,
timestamp: new Date().toISOString(),
status: 'error'
}
});
throw error;
}
}
})();
}
async _processEvent(eventType, data) {
// Implementation details...
return processedData;
}
}
These examples demonstrate real-world applications of the Handit.ai JavaScript SDK, showing how to effectively track and monitor AI applications in production environments.
Remember to replace "your-api-key"
with your actual Handit.ai API key in production code.