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.TP_API_KEY!,
  workflowName: 'My Workflow',
});

Full Configuration Options

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

init({
  // Required
  apiKey: process.env.TP_API_KEY!,
  workflowName: 'My Workflow',
  
  // Endpoint (optional — defaults to https://api.turingpulse.ai)
  // endpoint: 'https://api.turingpulse.ai',  // Or TP_ENDPOINT env var
  
  // Data Capture
  captureArguments: false,
  captureReturnValue: false,
  
  // Security — redact sensitive fields before telemetry leaves your environment
  redactFields: ['password', 'apiKey', 'secret', 'token'],
  
  // Network Tuning
  timeoutMs: 10_000,            // HTTP timeout (max 120_000)
  maxRetries: 3,                // Retry attempts
  
  // Governance defaults (applied to all instrumented functions)
  // governanceDefaults: { hitl: false, reviewers: [] },
});
💡
Environment Variables
Set TP_API_KEY as an environment variable instead of hardcoding. The SDK also supports TP_WORKFLOW_NAME and TP_ENDPOINT.
⚠️
Security Features
The SDK includes built-in security: SSRF protection blocks private/internal endpoints, CRLF characters are stripped from API keys, and the SDK never retries on authentication failures (401/403). Always use HTTPS endpoints in production.

Basic Instrumentation

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

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

const result = await processQuery("What's the weather?");

With Full Options

full-options.ts
import { withInstrumentation } from '@turingpulse/sdk';

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

Custom Metrics & KPIs

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

const processDocument = withInstrumentation(
  async (doc: string) => {
    const result = await llm.analyze(doc);
    return {
      analysis: result.text,
      tokens: result.usage.totalTokens,
    };
  },
  {
    name: 'document-processor',
    kpis: [
      {
        kpiId: 'latency_ms',
        description: 'Response Latency',
        useDuration: true,
        alertThreshold: 5000,
        comparator: 'gt',
      },
      {
        kpiId: 'token_count',
        description: 'Token Usage',
        value: (ctx) => ctx.result?.tokens ?? 0,
        alertThreshold: 8000,
        comparator: 'gt',
      },
      {
        kpiId: 'cost_usd',
        description: 'Execution Cost',
        fromResultPath: 'cost',
        alertThreshold: 0.50,
        comparator: 'gt',
      },
    ] satisfies KPIConfig[],
  }
);
💡
KPIs Replace Manual Metrics
Use KPIConfig on your instrumented functions instead of recording metrics manually. KPIs are evaluated automatically after each run and can trigger alerts when thresholds are breached.

Governance & Human Oversight

Human-in-the-Loop (HITL)

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

const executeTrade = withInstrumentation(
  async (symbol: string, amount: number) => {
    return await tradingApi.execute(symbol, amount);
  },
  {
    name: 'trading-agent',
    governance: new GovernanceDirective({
      hitl: true,
      reviewers: ['manager@company.com'],
      escalationChannels: ['pagerduty://critical'],
      autoEscalateAfterSeconds: 3600,
    }),
  }
);

Human-after-the-Loop (HATL)

hatl.ts
const generateContent = withInstrumentation(
  async (topic: string) => {
    return await contentLlm.generate(topic);
  },
  {
    name: 'content-generator',
    governance: new GovernanceDirective({
      hatl: true,
      reviewers: ['qa@company.com'],
      severity: 'medium',
    }),
  }
);
💡
Sample Rate
To review only a percentage of runs, configure a sample-rate condition in the platform under Governance → Policies.

Platform Configuration

Alert channels, baselines, and anomaly rules are configured through the TuringPulse platform UI or REST API, not the SDK. This keeps operational configuration separate from your application code.

Nested Spans

spans.ts
import { withInstrumentation } from '@turingpulse/sdk';

const retrieveContext = withInstrumentation(
  async (query: string) => {
    return await vectorDb.search(query);
  },
  { name: 'retrieve-context' }
);

const generateResponse = withInstrumentation(
  async (query: string, context: unknown) => {
    return await llm.chat(query, { context });
  },
  { name: 'generate-response' }
);

const complexWorkflow = withInstrumentation(
  async (query: string) => {
    const context = await retrieveContext(query);
    const response = await generateResponse(query, context);
    return response;
  },
  { name: 'multi-step-agent' }
);

Custom Metadata

metadata.ts
import { withInstrumentation } from '@turingpulse/sdk';

const processWithMetadata = withInstrumentation(
  async (query: string, userId: string) => {
    const result = await llm.chat(query);
    return result.content;
  },
  {
    name: 'enriched-agent',
    labels: { priority: 'high', department: 'sales' },
  }
);
💡
Static vs Dynamic Metadata
Static labels are passed via the instrument() options. For dynamic values computed at runtime, use KPIConfig with value extractors.

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',
  commitMessage: 'Improve prompt template',
});

Next Steps