Sovant

JavaScript/TypeScript SDK

JavaScript/TypeScript SDK

Latest Version: 1.4.2 Stable

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

Features

  • Memory CRUD — create, retrieve, update, delete memories
  • Semantic Search — query memories with filters and ranking
  • Hybrid Recall — profile-aware pipeline for conversational queries
  • Threads — organize memories into conversations or sessions
  • Batch Operations — create multiple memories in one request
  • Retry with backoff — auto-retry on rate limits, server errors, timeouts
  • Telemetry hooks — monitor SDK behavior with callbacks
  • Typed errors — better error handling with specific error codes

Installation

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

Quick Start

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

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

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

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

Advanced Initialization

const sv = 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)

  // Telemetry hooks
  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 sv.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 sv.memory.create({
  data: {
    event: 'onboarding_completed',
    decisions: ['completed-tutorial'],
    action_items: ['Send follow-up email']
  },
  type: 'journal',
  tags: ['milestone']
});

Field mapping: The SDK accepts data and converts it to content for the API.

Get Memory

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

Update Memory

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

Delete Memory

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

Search / Semantic Search

// Semantic search with natural language
const results = await sv.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 (Hybrid Search)

Recall uses Sovant's hybrid pipeline (profile fast-path + thread-scoped lexical + vector semantic search). Use it for conversational queries like "What do you know about me?".

const recall = await sv.memory.recall({
  query: 'what do you know about me?',
  limit: 10,
  thread_id: 'thr_123'  // Optional: scope to a thread
});

// Response shape: { results: [...], total, query_type }
for (const mem of recall.results) {
  console.log(mem.content, mem.relevance);
}

When to use recall vs search:

  • memory.recall() — Conversational queries, profile awareness, hybrid pipeline
  • memory.search() — Topic-based lookup, pure vector similarity

Batch Create

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

const result = await sv.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}`);
  }
});

Thread Management

Threads organize related memories into conversations or sessions. Full thread support is available in the SDK (v1.4.0+).

Create a Thread

const thread = await sv.threads.create({
  title: 'Customer Support Chat #1234',
  description: 'Issue with dashboard loading',
  metadata: { priority: 'high' }
});

List Threads

const { threads, total, has_more } = await sv.threads.list({
  limit: 20,
  offset: 0,
  status: 'active'  // 'active' | 'archived' | 'completed'
});

Get Thread

const result = await sv.threads.get(thread.id, {
  include_memories: true,
  limit: 50
});
console.log(result.thread.title);
console.log(result.thread.memories);  // if include_memories is true

Update Thread

await sv.threads.update(thread.id, {
  title: 'Resolved: Dashboard Loading Issue',
  status: 'completed'
});

Delete Thread

// Delete thread only (keeps memories)
await sv.threads.delete(thread.id);

// Delete thread AND all its memories
await sv.threads.delete(thread.id, true);

Thread + Memory Workflow

// Create a thread
const thread = await sv.threads.create({
  title: 'Q1 Planning Session'
});

// Store memories in the thread
await sv.memory.create({
  data: 'Decided to launch in March',
  type: 'journal',
  thread_id: thread.id
});

await sv.memory.create({
  data: 'Budget approved: $50k',
  type: 'insight',
  thread_id: thread.id
});

// Recall from this thread specifically
const recall = await sv.memory.recall({
  query: 'launch date',
  thread_id: thread.id,
  limit: 10
});
console.log(recall.results);

Automatic Retry & Error Handling

Retry Logic

The SDK automatically retries failed requests with exponential backoff:

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

const sv = 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 sv.memory.create({ data: 'Test' });

Error Types

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

try {
  await sv.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

Monitor all SDK activity with callback hooks:

const sv = 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}`);
  }
});

TypeScript Types

import type { SovantClientOptions, SovantError } 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
  retryDelay?: number;                // Optional, default: 1000
  onRequest?: (req: { method: string; path: string; body?: any }) => void;
  onResponse?: (res: { method: string; path: string; status: number; duration: number }) => void;
  onError?: (err: SovantError) => void;
}

Best Practices

  1. Use environment variables for API keys

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

    const sv = 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 sv.memory.createBatch(memories);
    
    // Avoid: Multiple individual requests
    for (const mem of memories) {
      await sv.memory.create(mem);  // Slower
    }
    
  4. Handle errors gracefully

    try {
      await sv.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 sv = new Sovant({
      apiKey: 'sk_...',
      maxRetries: 5,      // More retries
      retryDelay: 2000    // Longer initial delay
    });
    

Support

Changelog

Current stable: v1.4.2

  • v1.4.2 — README sync, docs alignment
  • v1.4.0 — Full thread support (create, list, get, update, delete)
  • v1.3.0 — Hybrid recall with profile awareness
  • v1.2.0 — Retry logic, telemetry hooks, batch operations

See npm changelog for full version history.