Advanced Features

The TypeScript SDK includes powerful features beyond basic tracking to help you build production-ready AI applications.

Multimodal Support

The SDK automatically handles text and image inputs for supported providers.

Automatic Image Tracking

// Images in OpenAI calls are automatically tracked
const response = await openai.chat.completions.create({
  model: 'gpt-4-vision-preview',
  messages: [{
    role: 'user',
    content: [
      { type: 'text', text: 'Describe this chart' },
      { 
        type: 'image_url', 
        image_url: { url: 'data:image/png;base64,iVBORw0...' } 
      }
    ]
  }]
});

// The image is automatically:
// - Extracted from the request
// - Uploaded to Lucidic storage
// - Linked to the event

Data Masking

Protect sensitive information before it’s sent to Lucidic.

Built-in Masking

await lai.init({
  maskingFunction: (text: string) => {
    return text
      // Mask SSNs
      .replace(/\b\d{3}-\d{2}-\d{4}\b/g, '***-**-****')
      // Mask emails
      .replace(/\b[\w.-]+@[\w.-]+\.\w+\b/g, '***@***.***')
      // Mask credit cards
      .replace(/\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b/g, '**** **** **** ****')
      // Mask API keys
      .replace(/\b(sk-|api-|key-)[a-zA-Z0-9]{20,}\b/g, '$1***');
  }
});

Custom Masking Rules

interface SensitiveData {
  userId: string;
  accountNumber: string;
  apiKey: string;
}

await lai.init({ maskingFunction: (text: string) => {
  // Parse and mask JSON
  try {
    const data = JSON.parse(text);
    if (data.accountNumber) {
      data.accountNumber = '***MASKED***';
    }
    if (data.apiKey) {
      data.apiKey = data.apiKey.substring(0, 8) + '***';
    }
    return JSON.stringify(data);
  } catch {
    // Not JSON, apply text masks
    return text.replace(/Account: \d+/g, 'Account: ***');
  }
}) });

Mass Simulations

Run large-scale tests to understand agent behavior at scale.

Basic Mass Simulation (Pattern)

for (let i = 0; i < 100; i++) {
  const sessionId = await lai.init({ sessionName: `Load Test - ${i}` });
  
  await lai.createStep({
    state: `Test ${i}`,
    goal: 'Complete test scenario'
  });

  const response = await openai.chat.completions.create({
    model: 'gpt-4',
    messages: [{ role: 'user', content: `Test query ${i}` }]
  });

  await lai.endStep({
    evalScore: Math.random() > 0.1 ? 90 : 50,
    evalDescription: 'Test completed'
  });

  await lai.endSession({ isSuccessful: true });
}

Advanced Simulation with Variations (Pattern)

const testScenarios = [
  'Reset password',
  'Update billing info',
  'Cancel subscription',
  'Technical support'
];

for (let sessionNum = 0; sessionNum < 200; sessionNum++) {
  const scenario = testScenarios[sessionNum % testScenarios.length];
  await lai.init({ sessionName: `Customer Support Test - ${sessionNum}` });

  await lai.updateSession({
    task: `Testing: ${scenario}`,
    tags: [
      `scenario:${scenario}`,
      `testRun:${sessionNum}`
    ]
  });

  // Simulate different paths
  if (scenario === 'Reset password') {
    await handlePasswordReset();
  } else if (scenario === 'Technical support') {
    await handleTechnicalSupport();
  }
  // ... more scenarios

  await lai.endSession({ isSuccessful: true });
}

Prompt Management

Fetch and cache prompts from the Lucidic platform.

Basic Prompt Fetching

// Fetch a prompt (cached by default)
const prompt = await lai.getPrompt('customer-support-prompt');

// Use in your LLM call
const response = await openai.chat.completions.create({
  model: 'gpt-4',
  messages: [
    { role: 'system', content: prompt },
    { role: 'user', content: userMessage }
  ]
});

Cache Control

// Always fetch fresh
const freshPrompt = await lai.getPrompt({ promptName: 'dynamic-prompt', cacheTtl: 0 });

// Cache for 5 minutes (default)
const cachedPrompt = await lai.getPrompt({ promptName: 'stable-prompt', cacheTtl: 300 });

Prompt Versioning

In the Lucidic dashboard, you can:
  • Create multiple versions of prompts
  • A/B test different versions
  • Roll back to previous versions
  • Track which version was used in each session

Session Tags and Metadata

Add custom metadata to sessions for better organization.
// During initialization
await lai.init({ sessionName: 'Customer Chat' });

// Update during session
await lai.updateSession({
  task: 'Updated task description',
  tags: ['priority:high', 'department:technical', 'issueType:bug', 'customField:any-value']
});

Automatic Features Summary

The TypeScript SDK includes these automatic behaviors:

1. Auto Session Management

// No need to explicitly end sessions
import OpenAI from 'openai';
await lai.init({ instrumentModules: { OpenAI } });
// ... do work ...
// Session auto-ends on process exit

2. Auto Step Creation

// No active step? No problem!
const response = await openai.chat.completions.create({
  model: 'gpt-4',
  messages: [{ role: 'user', content: 'Hello!' }]
});
// Step is created automatically

3. Auto Event Creation

// Every LLM call becomes an event automatically
// No manual event creation needed for supported providers

4. Auto Cost Calculation

// Costs are calculated based on:
// - Model used
// - Token counts
// - Built-in pricing data

Error Handling

The SDK provides specific error types for better error handling:
import { APIError } from 'lucidicai';

try {
  await lai.init({ apiKey: 'invalid' });
} catch (error) {
  if (error instanceof APIError) {
    console.error('API error:', error.message);
    // Handle network issues, server errors, etc.
  }
}

// Session-specific errors
try {
  await lai.createStep({ state: 'Processing' });
} catch (error) {
  // Handle errors
}

Performance Considerations

Batching and Async Operations

// Good: Parallel operations
const [analysis, summary, translation] = await Promise.all([
  analyzeText(content),
  summarizeText(content),
  translateText(content)
]);

// Each LLM call is tracked independently

Memory Management

// For long-running processes
setInterval(async () => {
  // Periodically end and start new sessions
  await lai.endSession({ isSuccessful: true, isSuccessfulReason: 'Checkpoint reached' });
  await lai.init({ sessionName: 'Continued processing', task: 'Resume from checkpoint' });
}, 3600000); // Every hour

Next Steps