Skip to Content
🎉 Welcome to handit.ai Documentation!
TracingSDKsJavaScript

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

terminal
npm install handit-sdk

Quick Start

app.js
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

MethodPurposeMinimal ExampleStep-by-Step Explanation
config({ apiKey, trackingUrl, performanceUrl })Initialize the SDK with your API key and optional custom URLs
handit.config({ apiKey: 'your-api-key', trackingUrl: 'custom-url' });
  1. Validates API key presence.
  2. Sets up tracking and performance URLs.
  3. Initializes internal state.
startAgentTracing(callback)Root trace for each agent request (inputs, outputs, errors, duration)
const agent = handit.startAgentTracing(async (input) => { // Agent logic });
  1. Creates agentLogId in AsyncLocalStorage.
  2. Executes callback with context.
  3. Sends start/end events automatically.
traceAgentNode({ agentNodeId, callback })Track individual agent nodes (functions, tools, etc.)
const node = handit.traceAgentNode({ agentNodeId: 'search', callback: async (query) => { // Node logic } });
  1. Links to active agentLogId.
  2. Tracks input/output.
  3. Handles errors automatically.
captureModel({ modelId, requestBody, responseBody })Manually track model calls or custom events
await handit.captureModel({ modelId: 'gpt4', requestBody: { prompt: 'Hello' }, responseBody: { text: 'Hi' } });
  1. Sends tracking data to server.
  2. Links to current agentLogId.
  3. Handles response data.
interceptAxiosRequest(axiosInstance)Automatically track Axios HTTP requests
const axios = require('axios'); handit.interceptAxiosRequest(axios);
  1. Adds request/response interceptors.
  2. Tracks matching URLs.
  3. Preserves original functionality.
interceptFetchRequest()Automatically track Fetch API requests
handit.interceptFetchRequest();
  1. Overrides global fetch.
  2. Tracks matching URLs.
  3. Maintains original behavior.
fetchOptimizedPrompt({ modelId })Get optimized prompts for models
const prompt = await handit.fetchOptimizedPrompt({ modelId: 'gpt4' });
  1. Queries performance endpoint.
  2. Returns best prompt.
  3. Requires API key.

Core Methods Documentation

Configuration

config({ apiKey, trackingUrl, performanceUrl })

Initializes the SDK with your API key and optional custom URLs.

config.js
/** * 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.

agent.js
/** * 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.

node.js
/** * 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.

model.js
/** * 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.

axios.js
/** * 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.

fetch.js
/** * 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.

optimization.js
/** * 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

chatbot.js
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

document_processor.js
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

api_client.js
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

performance_monitor.js
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

event_tracker.js
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.

Last updated on