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-platformQuick 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=productionAdvanced 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
});