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/sdkConfiguration
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',
});