Docs
Integrations
JavaScript/TypeScript SDK

JavaScript/TypeScript SDK

The official Ants Platform JavaScript/TypeScript SDK for monitoring AI agents and LLM applications in Node.js and browser environments.

Choose Your Integration Method


Auto-Instrumentation (2 Minutes)

Use OpenLLMetry to automatically capture all LLM calls with zero code changes to your existing application.

Supported Providers: OpenAI, Anthropic (Claude), AWS Bedrock, Azure OpenAI, Google Vertex AI, Gemini, Cohere, Mistral, Groq, LangChain, LlamaIndex, and more.

Install Dependencies

npm install @traceloop/node-server-sdk
# or
yarn add @traceloop/node-server-sdk

Initialize Auto-Instrumentation

Add this setup code once at the start of your application (before any LLM calls):

import * as traceloop from "@traceloop/node-server-sdk";
 
const publicKey = process.env.ANTS_PLATFORM_PUBLIC_KEY;
const secretKey = process.env.ANTS_PLATFORM_SECRET_KEY;
const auth = Buffer.from(`${publicKey}:${secretKey}`).toString("base64");
 
// Initialize - this auto-instruments all LLM calls
traceloop.initialize({
  baseUrl: "https://app.agenticants.ai/api/public/otel",
  headers: { Authorization: `Basic ${auth}` },
});

Use Your LLM (No Changes Needed)

Your existing LLM code works as-is. All calls are automatically traced:

import OpenAI from "openai";
 
// Your existing code - no changes needed!
const openai = new OpenAI();
const response = await openai.chat.completions.create({
  model: "gpt-4",
  messages: [{ role: "user", content: "Hello, world!" }],
});
console.log(response.choices[0].message.content);
// ✅ This call is automatically traced with tokens, cost, latency, and I/O

That's it! Check your ANTS Platform Dashboard (opens in a new tab) to see your traces.


Full SDK Setup

Use the ANTS Platform SDK for full control over your traces with custom spans, metadata, and error handling.

Installation

npm install ants-platform
# or
yarn add ants-platform
# or
pnpm add ants-platform

Quick Start

import { AntsPlatform } from 'ants-platform';
 
// Initialize the client
const client = new AntsPlatform({
  publicKey: process.env.ANTS_PLATFORM_PUBLIC_KEY,
  secretKey: process.env.ANTS_PLATFORM_SECRET_KEY,
  host: process.env.ANTS_PLATFORM_HOST || 'https://api.agenticants.ai'
});
 
// Create a trace
async function processUserQuery(query: string) {
  const trace = await client.startAsCurrentSpan({
    name: 'customer-support-agent',
    input: { user_input: query },
    metadata: { agent: 'customer-support' }
  });
 
  try {
    // Your agent logic
    const result = await processQuery(query);
 
    // Update trace with output
    await client.updateCurrentTrace({
      status: 'success',
      outputData: { result }
    });
 
    return result;
  } catch (error) {
    await client.updateCurrentTrace({
      status: 'error',
      outputData: { error: error.message }
    });
    throw error;
  } finally {
    await trace.end();
  }
}

Core Features

Tracing

Track your AI agent executions with detailed tracing:

import { AntsPlatform } from 'ants-platform';
 
const client = new AntsPlatform({
  publicKey: process.env.ANTS_PLATFORM_PUBLIC_KEY,
  secretKey: process.env.ANTS_PLATFORM_SECRET_KEY
});
 
async function executeAgent(userQuery: string) {
  // Start a trace
  const trace = await client.startAsCurrentSpan({
    name: 'agent-execution',
    input: { user_query: userQuery },
    metadata: {
      user_id: 'user_123',
      session_id: 'session_abc',
      agent: 'my-agent'
    }
  });
 
  try {
    // Update trace with user and tags
    await client.updateCurrentTrace({
      userId: 'user_123',
      tags: ['agent:my-agent', 'service:my-service', 'version:1.0.0']
    });
 
    // Create spans for detailed tracking
    await client.createSpan({
      name: 'request_validation',
      inputData: { raw_input: userQuery },
      outputData: {
        validated_input: userQuery,
        input_length: userQuery.length
      },
      metadata: { step: 'validation' }
    });
 
    // Create generation span for LLM calls
    const llmResponse = await callLLM(userQuery);
    await client.createGeneration({
      name: 'gpt-4_llm_call',
      model: 'gpt-4',
      prompt: userQuery,
      completion: llmResponse.text,
      inputTokens: llmResponse.inputTokens,
      outputTokens: llmResponse.outputTokens,
      metadata: {
        step: 'llm_call',
        status: 'success',
        agent: 'my-agent'
      }
    });
 
    // Update trace with final results
    await client.updateCurrentTrace({
      status: 'success',
      outputData: { result: llmResponse.text },
      metadata: {
        input_tokens: llmResponse.inputTokens,
        output_tokens: llmResponse.outputTokens,
        total_tokens: llmResponse.inputTokens + llmResponse.outputTokens,
        status: 'success'
      }
    });
 
    return llmResponse.text;
  } catch (error) {
    // Log error span
    await client.createSpan({
      name: 'error_handling',
      inputData: { error: error.message },
      outputData: { error_response: error.message },
      metadata: {
        error_type: error.constructor.name,
        step: 'error_handling'
      }
    });
 
    await client.updateCurrentTrace({
      status: 'error',
      outputData: { error: error.message }
    });
 
    throw error;
  } finally {
    await trace.end();
  }
}

Error Handling

async function processWithErrorHandling(query: string) {
  const trace = await client.startAsCurrentSpan({
    name: 'agent-process',
    input: { query }
  });
 
  try {
    const result = await agent.process(query);
 
    await client.updateCurrentTrace({
      status: 'success',
      outputData: { result }
    });
 
    return result;
  } catch (error) {
    // Log error span
    await client.createSpan({
      name: 'error_handling',
      inputData: { error: error.message },
      outputData: { error_response: error.message },
      metadata: {
        error_type: error.constructor.name,
        step: 'error_handling'
      }
    });
 
    await client.updateCurrentTrace({
      status: 'error',
      outputData: { error: error.message }
    });
 
    throw error;
  } finally {
    await trace.end();
  }
}

Using the observe() Decorator

For TypeScript projects, use the @observe decorator for automatic tracing:

import { observe } from 'ants-platform';
 
class CustomerSupportAgent {
  @observe()
  async handleQuery(query: string): Promise<string> {
    const context = await this.getContext(query);
    const response = await this.generateResponse(query, context);
    return response;
  }
 
  @observe({ name: 'get-context' })
  async getContext(query: string): Promise<Context> {
    // Retrieve relevant context
    return await contextRetriever.get(query);
  }
 
  @observe({ name: 'generate-response' })
  async generateResponse(query: string, context: Context): Promise<string> {
    // Generate response using LLM
    return await llm.generate({ query, context });
  }
}
 
// Automatically traced!
const agent = new CustomerSupportAgent();
const result = await agent.handleQuery("Help with my order");

Configuration

Basic Configuration

import { AntsPlatform } from 'ants-platform';
 
const client = new AntsPlatform({
  publicKey: process.env.ANTS_PLATFORM_PUBLIC_KEY,
  secretKey: process.env.ANTS_PLATFORM_SECRET_KEY,
  host: process.env.ANTS_PLATFORM_HOST || 'https://api.agenticants.ai',
  environment: process.env.ANTS_PLATFORM_ENVIRONMENT || 'production'
});

Environment Variables

Create a .env file in your project root:

ANTS_PLATFORM_PUBLIC_KEY=your_public_key
ANTS_PLATFORM_SECRET_KEY=your_secret_key
ANTS_PLATFORM_HOST=https://api.agenticants.ai
ANTS_PLATFORM_ENVIRONMENT=production

Advanced Configuration

const client = new AntsPlatform({
  publicKey: process.env.ANTS_PLATFORM_PUBLIC_KEY,
  secretKey: process.env.ANTS_PLATFORM_SECRET_KEY,
  host: 'https://api.agenticants.ai',
  environment: 'production',
 
  // Optional: Configure retry behavior
  retries: 3,
  retryDelay: 1000,
 
  // Optional: Configure timeout
  timeout: 30000,
 
  // Optional: Enable debug logging
  debug: process.env.NODE_ENV === 'development',
 
  // Optional: Custom headers
  headers: {
    'X-Custom-Header': 'value'
  }
});

Framework Integrations

Express.js

import express from 'express';
import { AntsPlatform } from 'ants-platform';
 
const app = express();
const client = new AntsPlatform({
  publicKey: process.env.ANTS_PLATFORM_PUBLIC_KEY,
  secretKey: process.env.ANTS_PLATFORM_SECRET_KEY
});
 
app.post('/api/chat', async (req, res) => {
  const trace = await client.startAsCurrentSpan({
    name: 'chat-endpoint',
    input: { message: req.body.message },
    metadata: {
      endpoint: '/api/chat',
      method: 'POST'
    }
  });
 
  try {
    const response = await processChat(req.body.message);
 
    await client.updateCurrentTrace({
      status: 'success',
      outputData: { response }
    });
 
    res.json({ response });
  } catch (error) {
    await client.updateCurrentTrace({
      status: 'error',
      outputData: { error: error.message }
    });
 
    res.status(500).json({ error: error.message });
  } finally {
    await trace.end();
  }
});

Next.js

// app/api/chat/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { AntsPlatform } from 'ants-platform';
 
const client = new AntsPlatform({
  publicKey: process.env.ANTS_PLATFORM_PUBLIC_KEY!,
  secretKey: process.env.ANTS_PLATFORM_SECRET_KEY!
});
 
export async function POST(request: NextRequest) {
  const body = await request.json();
 
  const trace = await client.startAsCurrentSpan({
    name: 'nextjs-chat-endpoint',
    input: { message: body.message },
    metadata: {
      framework: 'nextjs',
      route: '/api/chat'
    }
  });
 
  try {
    const response = await processChat(body.message);
 
    await client.updateCurrentTrace({
      status: 'success',
      outputData: { response }
    });
 
    return NextResponse.json({ response });
  } catch (error) {
    await client.updateCurrentTrace({
      status: 'error',
      outputData: { error: error instanceof Error ? error.message : 'Unknown error' }
    });
 
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 }
    );
  } finally {
    await trace.end();
  }
}

LangChain.js

import { ChatOpenAI } from '@langchain/openai';
import { AntsPlatform } from 'ants-platform';
 
const client = new AntsPlatform({
  publicKey: process.env.ANTS_PLATFORM_PUBLIC_KEY,
  secretKey: process.env.ANTS_PLATFORM_SECRET_KEY
});
 
async function runLangChainAgent(query: string) {
  const trace = await client.startAsCurrentSpan({
    name: 'langchain-agent',
    input: { query },
    metadata: { framework: 'langchain' }
  });
 
  try {
    const model = new ChatOpenAI({
      modelName: 'gpt-4',
      temperature: 0.7
    });
 
    // Track LLM call
    const response = await model.invoke(query);
 
    await client.createGeneration({
      name: 'langchain-llm-call',
      model: 'gpt-4',
      prompt: query,
      completion: response.content as string,
      inputTokens: response.response_metadata?.tokenUsage?.promptTokens || 0,
      outputTokens: response.response_metadata?.tokenUsage?.completionTokens || 0,
      metadata: { framework: 'langchain' }
    });
 
    await client.updateCurrentTrace({
      status: 'success',
      outputData: { response: response.content }
    });
 
    return response.content;
  } catch (error) {
    await client.updateCurrentTrace({
      status: 'error',
      outputData: { error: error instanceof Error ? error.message : 'Unknown error' }
    });
    throw error;
  } finally {
    await trace.end();
  }
}

API Reference

AntsPlatform Class

class AntsPlatform {
  constructor(config: {
    publicKey: string;
    secretKey: string;
    host?: string;
    environment?: string;
    retries?: number;
    retryDelay?: number;
    timeout?: number;
    debug?: boolean;
    headers?: Record<string, string>;
  });
 
  startAsCurrentSpan(options: {
    name: string;
    input?: Record<string, any>;
    output?: Record<string, any>;
    metadata?: Record<string, any>;
  }): Promise<Trace>;
 
  createSpan(options: {
    traceId?: string;
    name: string;
    inputData: Record<string, any>;
    outputData: Record<string, any>;
    metadata?: Record<string, any>;
  }): Promise<void>;
 
  createGeneration(options: {
    traceId?: string;
    name: string;
    model: string;
    prompt: string;
    completion: string;
    inputTokens: number;
    outputTokens: number;
    metadata?: Record<string, any>;
  }): Promise<void>;
 
  updateCurrentTrace(options: {
    status?: 'success' | 'error' | 'pending';
    userId?: string;
    tags?: string[];
    outputData?: Record<string, any>;
    metadata?: Record<string, any>;
  }): Promise<void>;
}

Trace Object

interface Trace {
  id: string;
  end(): Promise<void>;
  update(data: {
    output?: Record<string, any>;
    metadata?: Record<string, any>;
  }): Promise<void>;
}

Best Practices

1. Use Try-Finally Blocks

Always ensure traces are ended, even if errors occur:

const trace = await client.startAsCurrentSpan({ name: 'operation', input: data });
try {
  const result = await doWork();
  await client.updateCurrentTrace({ status: 'success', outputData: { result } });
} catch (error) {
  await client.updateCurrentTrace({ status: 'error', outputData: { error: error.message } });
  throw error;
} finally {
  await trace.end();
}

2. Add Rich Metadata

Include relevant context in your traces:

await client.updateCurrentTrace({
  userId: 'user_123',
  tags: ['agent:my-agent', 'service:my-service', 'version:1.0.0'],
  metadata: {
    user_id: 'user_123',
    model: 'gpt-4',
    version: '1.0.0',
    environment: process.env.NODE_ENV
  }
});

3. Handle Errors Properly

Log errors with detailed context:

try {
  // Your code
} catch (error) {
  await client.createSpan({
    name: 'error_handling',
    inputData: { error: error.message },
    outputData: { error_response: error.message },
    metadata: {
      error_type: error.constructor.name,
      stack_trace: error.stack
    }
  });
  await client.updateCurrentTrace({ status: 'error', outputData: { error: error.message } });
  throw error;
}

4. Use Decorators for Clean Code

Leverage TypeScript decorators for automatic instrumentation:

class MyAgent {
  @observe({ name: 'process-query' })
  async process(query: string) {
    // Automatically traced
    return await this.doWork(query);
  }
}

5. Implement Helper Functions

Create wrapper functions for cleaner API usage:

// Helper functions
async function createTrace(name: string, input: any, metadata?: any) {
  return client.startAsCurrentSpan({
    name,
    input,
    metadata: metadata || {}
  });
}
 
async function createSpan(name: string, inputData: any, outputData: any, metadata?: any) {
  return client.createSpan({
    name,
    inputData,
    outputData,
    metadata: metadata || {}
  });
}
 
// Usage
const trace = await createTrace('my-operation', { query: 'test' });
await createSpan('validation', { input: 'data' }, { valid: true });
await trace.end();

TypeScript Support

The SDK is written in TypeScript and provides full type definitions:

import { AntsPlatform, Trace, Span, Generation } from 'ants-platform';
 
// Full TypeScript IntelliSense and type checking
const client: AntsPlatform = new AntsPlatform({
  publicKey: process.env.ANTS_PLATFORM_PUBLIC_KEY!,
  secretKey: process.env.ANTS_PLATFORM_SECRET_KEY!
});
 
const trace: Trace = await client.startAsCurrentSpan({
  name: 'typed-operation',
  input: { query: 'test' }
});

Examples

Complete Agent Example

import { AntsPlatform } from 'ants-platform';
import { ChatOpenAI } from '@langchain/openai';
 
const client = new AntsPlatform({
  publicKey: process.env.ANTS_PLATFORM_PUBLIC_KEY!,
  secretKey: process.env.ANTS_PLATFORM_SECRET_KEY!
});
 
class CustomerSupportAgent {
  private llm: ChatOpenAI;
 
  constructor() {
    this.llm = new ChatOpenAI({ modelName: 'gpt-4' });
  }
 
  async handleQuery(query: string, userId: string) {
    const trace = await client.startAsCurrentSpan({
      name: 'customer-support-agent',
      input: { query, userId },
      metadata: { agent: 'customer-support', userId }
    });
 
    try {
      // Validate input
      await client.createSpan({
        name: 'validate-input',
        inputData: { query },
        outputData: { valid: true },
        metadata: { step: 'validation' }
      });
 
      // Get context
      const context = await this.getContext(query);
      await client.createSpan({
        name: 'retrieve-context',
        inputData: { query },
        outputData: { context },
        metadata: { step: 'context-retrieval' }
      });
 
      // Generate response
      const response = await this.llm.invoke(
        `Context: ${context}\n\nQuery: ${query}`
      );
 
      await client.createGeneration({
        name: 'generate-response',
        model: 'gpt-4',
        prompt: `Context: ${context}\n\nQuery: ${query}`,
        completion: response.content as string,
        inputTokens: response.response_metadata?.tokenUsage?.promptTokens || 0,
        outputTokens: response.response_metadata?.tokenUsage?.completionTokens || 0,
        metadata: { step: 'generation' }
      });
 
      await client.updateCurrentTrace({
        status: 'success',
        userId,
        tags: ['agent:customer-support', 'status:success'],
        outputData: { response: response.content }
      });
 
      return response.content as string;
    } catch (error) {
      await client.createSpan({
        name: 'error-handling',
        inputData: { error: error instanceof Error ? error.message : 'Unknown' },
        outputData: { handled: true },
        metadata: {
          error_type: error instanceof Error ? error.constructor.name : 'Unknown',
          step: 'error-handling'
        }
      });
 
      await client.updateCurrentTrace({
        status: 'error',
        outputData: { error: error instanceof Error ? error.message : 'Unknown error' }
      });
 
      throw error;
    } finally {
      await trace.end();
    }
  }
 
  private async getContext(query: string): Promise<string> {
    // Retrieve relevant context from database or vector store
    return 'Relevant context...';
  }
}
 
// Usage
const agent = new CustomerSupportAgent();
const response = await agent.handleQuery(
  "What's the status of my order?",
  "user_123"
);

Troubleshooting

Common Issues

"Authentication failed" error

  • Verify your public and secret keys are correct
  • Ensure environment variables are properly loaded
  • Check that keys have not expired

"Network timeout" error

  • Verify the host URL is correct
  • Check your network connectivity
  • Increase the timeout in client configuration

Traces not appearing in dashboard

  • Ensure you're calling trace.end() to finalize traces
  • Check that the client is properly initialized
  • Verify your API keys have the correct permissions

Debug Mode

Enable debug logging to troubleshoot issues:

const client = new AntsPlatform({
  publicKey: process.env.ANTS_PLATFORM_PUBLIC_KEY!,
  secretKey: process.env.ANTS_PLATFORM_SECRET_KEY!,
  debug: true
});

Next Steps