TypeScript SDK

Complete instrumentation for Node.js AI agents — tracing, custom metrics, governance, and configuration management.

Node.js 18+TypeScript 5+ESM & CJS

Installation

Terminal
npm install @turingpulse/sdk

# Or with yarn/pnpm
yarn add @turingpulse/sdk
pnpm add @turingpulse/sdk

Configuration

Basic Configuration

config.ts
import { init } from '@turingpulse/sdk';

init({
  apiKey: process.env.TURINGPULSE_API_KEY!,
  projectId: 'my-project',
  environment: 'production',
});

Full Configuration Options

full-config.ts
import { init, TuringPulseConfig } from '@turingpulse/sdk';

const config: TuringPulseConfig = {
  // Required
  apiKey: process.env.TURINGPULSE_API_KEY!,
  projectId: 'my-project',
  
  // Environment
  environment: 'production',
  serviceName: 'my-service',
  serviceVersion: '1.0.0',
  
  // Behavior
  enabled: true,
  debug: false,
  
  // Batching & Performance
  batchSize: 100,
  flushInterval: 5000,        // milliseconds
  maxQueueSize: 10000,
  
  // Sampling
  sampleRate: 1.0,            // 1.0 = 100%
  
  // Data Capture
  captureInputs: true,
  captureOutputs: true,
  maxPayloadSize: 65536,
  
  // Sensitive Data
  redactKeys: ['password', 'apiKey', 'secret', 'token'],
};

init(config);

Basic Instrumentation

basic.ts
import { instrument } from '@turingpulse/sdk';

const processQuery = instrument(
  { agentId: 'my-agent' },
  async (query: string) => {
    const response = await llm.chat(query);
    return response;
  }
);

// Call normally - traces are captured automatically
const result = await processQuery("What's the weather?");

With Full Options

full-options.ts
import { instrument, GovernanceDirective, KPIConfig } from '@turingpulse/sdk';

const handleQuery = instrument(
  {
    agentId: 'customer-support-agent',
    operation: 'handle_query',
    labels: { team: 'support', channel: 'web' },
    captureInput: true,
    captureOutput: true,
  },
  async (query: string, userId: string) => {
    const response = await llm.chat(query);
    return { response, tokens: response.usage.totalTokens };
  }
);

Custom Metrics & KPIs

kpis.ts
import { instrument, KPIConfig } from '@turingpulse/sdk';

const processDocument = instrument(
  {
    agentId: 'document-processor',
    kpis: [
      {
        kpiId: 'latency_ms',
        name: 'Response Latency',
        useDuration: true,
        unit: 'ms',
        alertThreshold: 5000,
        comparator: 'gt',
      },
      {
        kpiId: 'token_count',
        name: 'Token Usage',
        value: (ctx) => ctx.result?.tokens ?? 0,
        unit: 'tokens',
        alertThreshold: 8000,
        comparator: 'gt',
      },
      {
        kpiId: 'cost_usd',
        name: 'Execution Cost',
        value: (ctx) => ctx.metadata?.cost ?? 0,
        unit: 'USD',
        alertThreshold: 0.50,
        comparator: 'gt',
      },
    ] satisfies KPIConfig[],
  },
  async (doc: string) => {
    const result = await llm.analyze(doc);
    return {
      analysis: result.text,
      tokens: result.usage.totalTokens,
    };
  }
);

Manual Metric Recording

manual-metrics.ts
import { instrument, getCurrentTrace, recordMetric } from '@turingpulse/sdk';

const processRequest = instrument(
  { agentId: 'my-agent' },
  async (request: Request) => {
    const trace = getCurrentTrace();
    
    // Record metrics at any point
    recordMetric('input_size', request.body.length);
    
    const result = await llm.process(request);
    
    recordMetric('output_tokens', result.usage.completionTokens);
    recordMetric('confidence', result.confidence);
    
    return result;
  }
);

Governance & Human Oversight

Human-in-the-Loop (HITL)

hitl.ts
import { instrument, GovernanceDirective } from '@turingpulse/sdk';

const executeTrade = instrument(
  {
    agentId: 'trading-agent',
    governance: {
      hitl: true,
      reviewers: ['manager@company.com'],
      escalationTimeout: 3600,
      autoApproveAfter: null,
    } satisfies GovernanceDirective,
  },
  async (symbol: string, amount: number) => {
    // Execution pauses until human approves
    return await tradingApi.execute(symbol, amount);
  }
);

Human-after-the-Loop (HATL)

hatl.ts
const generateContent = instrument(
  {
    agentId: 'content-generator',
    governance: {
      hatl: true,
      reviewers: ['qa@company.com'],
      sampleRate: 0.1,  // Review 10%
    },
  },
  async (topic: string) => {
    return await contentLlm.generate(topic);
  }
);

Creating Configurations via SDK

Register Workflows

register-workflow.ts
import { registerWorkflow, WorkflowConfig } from '@turingpulse/sdk';

await registerWorkflow({
  workflowId: 'customer-support-agent',
  name: 'Customer Support Agent',
  description: 'Handles customer queries via chat',
  
  defaultLabels: {
    team: 'support',
    product: 'chat-bot',
  },
  
  kpis: [
    { kpiId: 'latency_ms', threshold: 5000, comparator: 'gt' },
    { kpiId: 'cost_usd', threshold: 0.10, comparator: 'gt' },
  ],
  
  governance: {
    hatl: true,
    sampleRate: 0.05,
    reviewers: ['qa@company.com'],
  },
  
  alertChannels: ['slack://support-alerts'],
} satisfies WorkflowConfig);

Configure Alert Channels

alert-channels.ts
import { configureAlertChannel } from '@turingpulse/sdk';

// Slack
await configureAlertChannel({
  channelId: 'slack-alerts',
  type: 'slack',
  webhookUrl: 'https://hooks.slack.com/services/...',
  name: 'Support Alerts',
  severityFilter: ['warning', 'critical'],
});

// Email
await configureAlertChannel({
  channelId: 'email-oncall',
  type: 'email',
  recipients: ['oncall@company.com'],
  name: 'On-Call Email',
  severityFilter: ['critical'],
});

Define Baselines

baselines.ts
import { createBaseline, createAnomalyRule } from '@turingpulse/sdk';

// Create baseline from historical data
await createBaseline({
  workflowId: 'my-agent',
  baselineId: 'latency-baseline',
  metric: 'latency_ms',
  method: 'percentile',
  percentile: 95,
  lookbackDays: 14,
  autoUpdate: true,
});

// Create anomaly rule
await createAnomalyRule({
  workflowId: 'my-agent',
  ruleId: 'latency-spike',
  metric: 'latency_ms',
  condition: 'exceeds_baseline',
  multiplier: 2.0,
  alertChannels: ['slack-alerts'],
});

Nested Spans

spans.ts
import { instrument, withSpan } from '@turingpulse/sdk';

const complexWorkflow = instrument(
  { agentId: 'multi-step-agent' },
  async (query: string) => {
    const context = await withSpan('retrieve_context', async (span) => {
      const docs = await vectorDb.search(query);
      span.setAttribute('doc_count', docs.length);
      return docs;
    });
    
    const response = await withSpan('generate_response', async (span) => {
      const result = await llm.chat(query, { context });
      span.setAttribute('tokens', result.usage.totalTokens);
      return result;
    });
    
    return response;
  }
);

Custom Metadata

metadata.ts
import { instrument, getCurrentTrace } from '@turingpulse/sdk';

const processWithMetadata = instrument(
  { agentId: 'enriched-agent' },
  async (query: string, userId: string) => {
    const trace = getCurrentTrace();
    
    // Set metadata
    trace.setMetadata('user_id', userId);
    trace.setMetadata('query_length', query.length);
    
    // Add tags for filtering
    trace.addTag('priority', 'high');
    trace.addTag('department', 'sales');
    
    const result = await llm.chat(query);
    
    trace.setMetadata('response_tokens', result.usage.completionTokens);
    
    return result.content;
  }
);

Express Middleware

express.ts
import express from 'express';
import { expressMiddleware } from '@turingpulse/sdk/express';

const app = express();

app.use(expressMiddleware({
  agentId: 'api-server',
  extractLabels: (req) => ({
    path: req.path,
    method: req.method,
    userAgent: req.headers['user-agent'],
  }),
}));

app.post('/chat', async (req, res) => {
  // Traces are automatically created per request
  const response = await handleChat(req.body);
  res.json(response);
});

Deploy Tracking

deploy.ts
import { registerDeploy } from '@turingpulse/sdk';

// Auto-detect from CI/CD
await registerDeploy({
  workflowId: 'my-agent',
  autoDetect: true,
});

// Or explicit values
await registerDeploy({
  workflowId: 'my-agent',
  version: 'v1.2.3',
  gitSha: 'abc123def',
  gitBranch: 'main',
  commitMessage: 'Improve prompt template',
  deployedBy: 'ci-bot',
});

Next Steps