Sovant

JavaScript/TypeScript SDK

JavaScript/TypeScript SDK

Latest Version: 1.2.0 New

Official SDK for Node.js and browser environments with enterprise-grade reliability features.

What's New in v1.2.0

  • Retry logic with exponential backoff - Auto-retry on rate limits, server errors, timeouts
  • Telemetry hooks - Monitor SDK behavior with callbacks
  • Batch operations - Create multiple memories in one request
  • Recall alias - More intuitive semantic search method
  • Typed errors - Better error handling with specific error codes

Installation

npm install @sovant/sdk@1.2.0
# or
yarn add @sovant/sdk@1.2.0
# or
pnpm add @sovant/sdk@1.2.0

Quick Start

import { Sovant } from '@sovant/sdk';

// Initialize with basic config
const client = new Sovant({
  apiKey: process.env.SOVANT_API_KEY || 'sk_live_...'
});

// Create a memory
const memory = await client.memory.create({
  data: 'User prefers dark mode for all applications',
  type: 'preference',
  tags: ['ui', 'settings']
});

console.log('Created:', memory.id);

Advanced Initialization

const client = new Sovant({
  // Required
  apiKey: 'sk_live_your_api_key_here',

  // Optional settings
  baseUrl: 'https://sovant.ai',  // Default, can override for testing
  timeoutMs: 30000,               // Request timeout (default: 30s)
  maxRetries: 3,                  // Auto-retry attempts (default: 3)
  retryDelay: 1000,               // Initial retry delay (default: 1s, exponential backoff)

  // NEW: Telemetry hooks (v1.2.0)
  onRequest: (req) => {
    console.log(`→ ${req.method} ${req.path}`);
  },
  onResponse: (res) => {
    console.log(`← ${res.status} (${res.duration}ms)`);
  },
  onError: (err) => {
    console.error(`✗ ${err.code}: ${err.message}`);
  }
});

Memory Operations

Create Memory

const memory = await client.memory.create({
  data: 'User completed onboarding tutorial',  // Required: string or object
  type: 'observation',                         // Optional: memory type
  tags: ['onboarding', 'completed'],           // Optional: tags
  metadata: { importance: 0.7 },               // Optional: metadata
  thread_id: 'thread-uuid-here'                // Optional: thread ID
});

// Create with object data
const complexMemory = await client.memory.create({
  data: {
    event: 'onboarding_completed',
    decisions: ['completed-tutorial'],
    action_items: ['Send follow-up email']
  },
  type: 'journal',
  tags: ['milestone']
});

Get Memory

const memory = await client.memory.get('memory-id-here');
console.log(memory.content);
console.log(memory.type);
console.log(memory.tags);

Update Memory

const updated = await client.memory.update('memory-id-here', {
  data: 'Updated content',
  tags: ['updated', 'important'],
  metadata: { priority: 'high' }
});

Delete Memory

await client.memory.delete('memory-id-here');
// Returns nothing on success

Search / Semantic Search

// Semantic search with natural language
const results = await client.memory.search({
  query: 'what are my project preferences?',
  limit: 10,
  type: 'preference',
  tags: ['project'],
  from_date: '2025-01-01T00:00:00Z',
  to_date: '2025-12-31T23:59:59Z'
});

console.log(`Found ${results.total} memories`);
results.results?.forEach((r: any) => {
  console.log(`- ${r.content} (relevance: ${r.relevance_score})`);
});

Recall New

More intuitive alias for semantic search:

const recalled = await client.memory.recall({
  query: 'where am I located?',
  limit: 5
});

Batch Create New

Create multiple memories in a single request (max 100):

const result = await client.memory.createBatch([
  {
    data: 'Meeting with design team on Friday at 2 PM',
    type: 'task',
    tags: ['meeting', 'design']
  },
  {
    data: 'User is located in San Francisco, California',
    type: 'observation',
    tags: ['location', 'personal']
  },
  {
    data: 'Preferred programming language is TypeScript',
    type: 'preference',
    tags: ['development']
  }
]);

console.log(`Created ${result.summary.successful}/${result.summary.total} memories`);

// Check individual results
result.results.forEach((r, i) => {
  if (r.success) {
    console.log(`✓ Memory ${i}: ${r.id}`);
  } else {
    console.error(`✗ Memory ${i}: ${r.error?.message}`);
  }
});

Automatic Retry & Error Handling

Retry Logic New

The SDK automatically retries failed requests with exponential backoff:

// Automatic retry on:
// - 429 (Rate Limit)
// - 5xx (Server Errors)
// - Network errors
// - Timeouts

const client = new Sovant({
  apiKey: 'sk_live_...',
  maxRetries: 3,      // Will retry up to 3 times
  retryDelay: 1000    // Initial delay: 1s, then 2s, then 4s (exponential)
});

// This will auto-retry if it hits rate limits or server errors
const memory = await client.memory.create({ data: 'Test' });

Error Types New

import { Sovant, SovantError } from '@sovant/sdk';

try {
  await client.memory.create({ data: 'Test' });
} catch (error) {
  if (error instanceof SovantError) {
    switch (error.code) {
      case 'TIMEOUT':
        console.error('Request timed out after retries');
        break;
      case 'NETWORK_ERROR':
        console.error('Network connection failed');
        break;
      case 'MAX_RETRIES':
        console.error('Max retries exceeded');
        break;
      case 'INVALID_API_KEY':
        console.error('Invalid API key');
        break;
      case 'RATE_LIMIT_EXCEEDED':
        console.error('Rate limit hit (after retries)');
        break;
      default:
        console.error(`${error.code}: ${error.message}`);
    }
  }
}

Telemetry & Monitoring New

Monitor all SDK activity with callback hooks:

const client = new Sovant({
  apiKey: 'sk_live_...',

  onRequest: (req) => {
    // Called before each request (including retries)
    console.log(`[${new Date().toISOString()}] → ${req.method} ${req.path}`);
    if (req.body) {
      console.log('Body:', req.body);
    }
  },

  onResponse: (res) => {
    // Called after successful responses
    console.log(`[${res.duration}ms] ← ${res.method} ${res.path} - ${res.status}`);

    // Track slow requests
    if (res.duration > 2000) {
      console.warn('Slow request detected!');
    }
  },

  onError: (err) => {
    // Called when errors occur (even after retries)
    console.error(`✗ ${err.code}: ${err.message}`);

    // Send to error tracking service
    // trackError(err);
  }
});

// Example: Integrate with logging service
const client = new Sovant({
  apiKey: 'sk_live_...',
  onRequest: (req) => logger.info('sovant_request', req),
  onResponse: (res) => logger.info('sovant_response', res),
  onError: (err) => logger.error('sovant_error', err)
});

Chat with Streaming

// Create session
const session = await client.chat.createSession({
  title: 'Support chat',
  provider: 'openai',
  model: 'gpt-4o-mini'
});

// Send message with SSE streaming
const stream = await client.chat.sendMessage(session.id, {
  message: 'Hello, I need help',
  stream: true,
  useMemory: true
});

// Process stream
for await (const event of stream) {
  switch (event.type) {
    case 'delta':
      process.stdout.write(event.data || '');
      break;
    case 'done':
      console.log('\nStream complete');
      break;
    case 'error':
      console.error('Stream error:', event.error);
      break;
  }
}

// Get chat history
const messages = await client.chat.getMessages(session.id);

TypeScript Types

import type {
  MemoryResponse,
  CreateMemoryInput,
  SearchParams,
  Session,
  Message,
  StreamEvent,
  SovantError,
  BatchResponse
} from '@sovant/sdk';

interface SovantClientOptions {
  apiKey: string;                     // Required
  baseUrl?: string;                   // Optional, default: 'https://sovant.ai'
  timeoutMs?: number;                 // Optional, default: 30000
  maxRetries?: number;                // Optional, default: 3 (NEW v1.2.0)
  retryDelay?: number;                // Optional, default: 1000 (NEW v1.2.0)
  onRequest?: (req: RequestInfo) => void;    // Optional (NEW v1.2.0)
  onResponse?: (res: ResponseInfo) => void;  // Optional (NEW v1.2.0)
  onError?: (err: SovantError) => void;      // Optional (NEW v1.2.0)
}

Migration from v1.0.x

v1.2.0 is 100% backward compatible with v1.0.x. All existing code works unchanged.

Before (v1.0.x):

const client = new Sovant({ apiKey: 'sk_...' });
await client.memory.create({ data: 'Test' });

After (v1.2.0) - Same code works, OR add new features:

const client = new Sovant({
  apiKey: 'sk_...',
  maxRetries: 3,  // NEW: optional
  onRequest: (req) => console.log(req)  // NEW: optional
});

// Existing methods work unchanged
await client.memory.create({ data: 'Test' });

// NEW methods available
await client.memory.createBatch([...]);
await client.memory.recall({ query: '...' });

Best Practices

  1. Use environment variables for API keys

    const client = new Sovant({
      apiKey: process.env.SOVANT_API_KEY!
    });
    
  2. Enable telemetry in production

    const client = new Sovant({
      apiKey: process.env.SOVANT_API_KEY!,
      onError: (err) => errorTracker.capture(err),
      onResponse: (res) => metrics.track('sovant_api_latency', res.duration)
    });
    
  3. Use batch operations for multiple memories

    // Good: Single batch request
    await client.memory.createBatch(memories);
    
    // Avoid: Multiple individual requests
    for (const mem of memories) {
      await client.memory.create(mem);  // Slower
    }
    
  4. Handle errors gracefully

    try {
      await client.memory.create({ data: 'Test' });
    } catch (error) {
      if (error instanceof SovantError) {
        // SDK automatically retried, this is final failure
        console.error(`Final error after retries: ${error.code}`);
      }
    }
    

Rate Limits

  • The SDK automatically retries on rate limit errors (429)
  • Default retry strategy: 3 retries with exponential backoff (1s → 2s → 4s)
  • Customize retry behavior:
    const client = new Sovant({
      apiKey: 'sk_...',
      maxRetries: 5,      // More retries
      retryDelay: 2000    // Longer initial delay
    });
    

Support

Changelog

Current stable: v1.2.0

See npm changelog for full version history.