Skip to content

tracemem/tracemem-ts

Repository files navigation

@tracemem/ts-sdk

TypeScript SDK for TraceMem - Decision tracking and traceability for AI agents and automation systems.

Quick Start (60 seconds)

import { TraceMemClient } from '@tracemem/ts-sdk';

// Create client (only apiKey required)
const client = new TraceMemClient({
  apiKey: process.env.TRACEMEM_API_KEY!,
});

// Open a decision from an action
const decision = await client.open('refactor', {
  automationMode: 'propose',
});

// Add context
await decision.note({
  kind: 'info',
  message: 'Starting refactoring work',
});

// Close the decision
await decision.close({
  outcome: 'commit',
  reason: 'Refactoring completed successfully',
});

Installation

npm install @tracemem/ts-sdk

Configuration

The SDK requires only an API key to get started:

const client = new TraceMemClient({
  apiKey: 'your-api-key-here',
});

Optional Configuration

const client = new TraceMemClient({
  apiKey: 'your-api-key-here',
  mcpUrl: 'https://mcp.tracemem.com', // Default
  timeoutMs: 30000, // Default: 30 seconds
  sanitize: true, // Default: true (redacts secrets, truncates large data)
  defaultActor: 'my-agent', // Default: 'tracemem-ts'
  defaultAutomationMode: 'propose', // Default: 'propose'
  actionIntentMap: { // Extend default action->intent mapping
    'custom_action': 'custom.intent.execute',
  },
});

Decision Lifecycle

Opening a Decision

Use open() to create a decision from a common action (automatically maps to intent):

const decision = await client.open('edit_files', {
  automationMode: 'propose',
  actor: 'my-agent',
  metadata: {
    project: 'my-project',
    branch: 'main',
  },
});

Creating a Decision with Explicit Intent

Use createDecision() for explicit intent control:

const decision = await client.createDecision('code.change.apply', {
  automationMode: 'execute',
  actor: 'my-agent',
  instance: 'instance-123',
  version: '1.0.0',
  metadata: {
    custom: 'data',
  },
});

Adding Context/Notes

await decision.note({
  kind: 'info',
  message: 'Starting work',
  data: {
    files: ['file1.ts', 'file2.ts'],
  },
});

Reading from Data Products

const result = await decision.read('pg_customers_v1', 'order_validation', {
  query: {
    customer_id: '12345',
  },
  resultMode: 'single', // or 'multiple'
});

Evaluating Policies

const evaluation = await decision.evaluate('discount_cap_v1', {
  inputs: {
    proposed_discount: 0.15,
    customer_tier: 'premium',
  },
});

Requesting Approval

await decision.requestApproval({
  kind: 'discount_approval',
  message: 'Customer requesting 25% discount, exceeds policy limit',
});

Writing to Data Products

await decision.write('pg_orders_v1', 'order_creation', {
  operation: 'insert',
  records: [
    {
      order_id: 'ord_123',
      customer_id: 'cust_456',
      amount: 99.99,
    },
  ],
}, {
  idempotencyKey: 'order_123_unique',
});

Getting Trace and Receipt

// Get full trace of decision activities
const trace = await decision.trace();

// Get receipt (summary)
const receipt = await decision.receipt();

Closing a Decision

await decision.close({
  outcome: 'commit', // or 'abort'
  reason: 'Order successfully processed',
});

Approvals Example

const decision = await client.open('secrets', {
  automationMode: 'propose',
});

// Evaluate policy
const evaluation = await decision.evaluate('secrets_change_policy', {
  inputs: {
    secret_name: 'DATABASE_PASSWORD',
    change_type: 'update',
  },
});

// Request approval if needed
if (evaluation.requiresApproval) {
  await decision.requestApproval({
    kind: 'secrets_change',
    message: 'Updating production database password',
  });
  
  // Wait for approval (poll or webhook)
  // ... approval logic ...
}

// Proceed with change
await decision.write('secrets_v1', 'secret_update', {
  operation: 'update',
  name: 'DATABASE_PASSWORD',
  value: 'new-secure-password',
});

await decision.close({
  outcome: 'commit',
  reason: 'Secret updated after approval',
});

Product Discovery

// List all products
const productsText = await client.products.list();
// Parse JSON if needed
const products = JSON.parse(productsText);

// Get specific product
const productText = await client.products.get('pg_customers_v1');
const product = JSON.parse(productText);

Using Client Methods Directly

You can also use client methods directly (useful when working with multiple decisions):

const decisionId = 'dec_abc123';

await client.note(decisionId, {
  kind: 'info',
  message: 'Note',
});

const result = await client.read(decisionId, {
  product: 'pg_customers_v1',
  purpose: 'order_validation',
  query: { customer_id: '123' },
});

Security and Data Sanitization

By default, the SDK automatically sanitizes data before sending to TraceMem:

  • Secret Redaction: Keys matching patterns like password, api_key, token, secret, etc. are redacted
  • String Truncation: Strings longer than 1000 characters are truncated
  • Array Truncation: Arrays longer than 100 items are truncated
  • Object Key Limits: Objects with more than 100 keys are truncated
  • Depth Limits: Nested structures deeper than 10 levels are truncated

To disable sanitization:

const client = new TraceMemClient({
  apiKey: 'your-key',
  sanitize: false, // Disable sanitization
});

Note: Disabling sanitization may expose sensitive data. Use with caution.

Error Handling

The SDK provides typed error classes:

import {
  TraceMemError,
  TraceMemNetworkError,
  TraceMemValidationError,
  TraceMemTimeoutError,
} from '@tracemem/ts-sdk';

try {
  await client.createDecision('code.change.apply');
} catch (error) {
  if (error instanceof TraceMemNetworkError) {
    // Handle network error
    console.error('Network error:', error.message);
  } else if (error instanceof TraceMemValidationError) {
    // Handle validation error
    console.error('Validation error:', error.message);
  } else if (error instanceof TraceMemTimeoutError) {
    // Handle timeout
    console.error('Request timed out:', error.message);
  } else if (error instanceof TraceMemError) {
    // Handle other TraceMem errors
    console.error('TraceMem error:', error.code, error.message);
  }
}

Action to Intent Mapping

The SDK automatically maps common actions to intents:

Action Intent
edit_files code.change.apply
refactor code.refactor.execute
run_command ops.command.execute
deploy deploy.release.execute
secrets secrets.change.propose
db_change data.change.apply
review code.review.assist

Unknown actions are used as-is (no mapping).

TypeScript Support

The SDK is written in TypeScript and includes full type definitions. All methods and interfaces are fully typed.

Requirements

  • Node.js >= 18.0.0
  • TypeScript >= 5.0 (for TypeScript projects)

License

Apache-2.0

About

TypeScript SDK for TraceMem - Decision tracking and traceability for AI agents and automation systems

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors