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.

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