Skip to content

TypeScript SDK Guide

Fresh

Source: docs.hindsight.vectorize.io/typescript-sdk

Installation

bash
npm install @vectorize-io/hindsight-client
# or
yarn add @vectorize-io/hindsight-client
# or
pnpm add @vectorize-io/hindsight-client

Quick Start

typescript
import { HindsightClient } from '@vectorize-io/hindsight-client';

const client = new HindsightClient({
  baseUrl: 'https://api.hindsight.vectorize.io',
  apiKey: 'your-api-key'
});

async function main() {
  const bank = await client.createBank('my-assistant', { name: 'My Assistant' });

  await client.retain('my-assistant', 'The user prefers concise responses and dark mode.');

  const result = await client.recall('my-assistant', "What are the user's preferences?");
  result.results.forEach(memory => console.log(memory.text));

  const response = await client.reflect('my-assistant', 'How should I format my responses?');
  console.log(response.text);
}

main();

Type Definitions

typescript
interface RecallResponse {
  results: RecallResult[];
  entities?: Entity[];
  trace?: TraceInfo;
}

interface RecallResult {
  text: string;
  type: 'world' | 'experience' | 'observation';
}

interface ReflectResponse {
  text: string;
  based_on: BasedOnItem[];
  structured_output?: Record<string, unknown>;
  usage?: { input_tokens: number; output_tokens: number; total_tokens: number; };
}

interface BankProfileResponse {
  bank_id: string;
  name?: string;
  background?: string;
  disposition?: { skepticism: number; literalism: number; empathy: number; };
}

Memory Banks

typescript
// Create
const bank = await client.createBank('customer-support', {
  name: 'Customer Support Agent',
  background: 'Handles customer inquiries',
  disposition: { skepticism: 3, literalism: 2, empathy: 4 }
});

// Get profile
const profile = await client.getBankProfile('my-assistant');

// List memories
const result = await client.listMemories('my-assistant', { limit: 100, offset: 0 });

Retain (Store)

typescript
// Basic
await client.retain('my-assistant', 'User prefers async communication.');

// With options
await client.retain('my-assistant', 'Customer reported a bug.', {
  context: 'Support ticket conversation',
  timestamp: new Date(),
  metadata: { ticketId: 'TKT-12345', priority: 'high' }
});

// Batch
const items = [
  { content: 'User is based in Pacific timezone' },
  { content: 'User prefers email over phone calls' }
];
await client.retainBatch('my-assistant', items);
typescript
// Basic
const result = await client.recall('my-assistant', 'What are user preferences?');
result.results.forEach(m => console.log(`[${m.type}] ${m.text}`));

// With options
const filtered = await client.recall('my-assistant', 'project deadlines', {
  maxTokens: 4096,
  budget: 'mid',
  types: ['observation']
});

// Include entities
const withEntities = await client.recall('my-assistant', 'Tell me about Alice', {
  includeEntities: true,
  maxEntityTokens: 1000
});

Reflect (Reason)

typescript
// Basic
const response = await client.reflect('my-assistant', 'What should I know before our call?');
console.log(response.text);

// With context and budget
const detailed = await client.reflect('my-assistant', 'What are their pain points?', {
  context: "We're preparing for a product review meeting",
  budget: 'high'
});

// Token usage
if (response.usage) {
  console.log(`Total tokens: ${response.usage.total_tokens}`);
}

Mental Models

typescript
// Create
const mm = await client.createMentalModel('my-assistant', 'User Profile', 'What do we know?');

// Create with options
const mmWithOpts = await client.createMentalModel('my-assistant', 'Team Directory',
  'Who works here?', { tags: ['team'], maxTokens: 4096, trigger: { refreshAfterConsolidation: true } }
);

// List
const models = await client.listMentalModels('my-assistant');
const filtered = await client.listMentalModels('my-assistant', { tags: ['team'] });

// Get
const model = await client.getMentalModel('my-assistant', 'mm_abc123');

// Refresh
await client.refreshMentalModel('my-assistant', 'mm_abc123');

// Update
await client.updateMentalModel('my-assistant', 'mm_abc123', {
  name: 'Updated Profile',
  trigger: { refreshAfterConsolidation: true }
});

// Delete
await client.deleteMentalModel('my-assistant', 'mm_abc123');

Framework Integration

Next.js

typescript
// app/api/chat/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { HindsightClient } from '@vectorize-io/hindsight-client';

const client = new HindsightClient({
  baseUrl: process.env.HINDSIGHT_BASE_URL!,
  apiKey: process.env.HINDSIGHT_API_KEY!
});

export async function POST(request: NextRequest) {
  const { bankId, message } = await request.json();
  await client.retain(bankId, `User said: ${message}`);
  const memories = await client.recall(bankId, message, { limit: 5 });
  const response = await client.reflect(bankId, `Respond to: ${message}`);
  return NextResponse.json({ response: response.text });
}

Express

typescript
import express from 'express';
import { HindsightClient } from '@vectorize-io/hindsight-client';

const app = express();
const client = new HindsightClient({
  baseUrl: process.env.HINDSIGHT_BASE_URL!,
  apiKey: process.env.HINDSIGHT_API_KEY!
});

app.use(express.json());

app.post('/api/memory', async (req, res) => {
  const { bankId, content } = req.body;
  try {
    await client.retain(bankId, content);
    res.json({ success: true });
  } catch (error) {
    res.status(500).json({ error: 'Failed to store memory' });
  }
});

app.listen(3000);

Best Practices

Singleton Pattern

typescript
// lib/hindsight.ts
import { HindsightClient } from '@vectorize-io/hindsight-client';

let client: HindsightClient | null = null;

export function getHindsightClient(): HindsightClient {
  if (!client) {
    client = new HindsightClient({
      baseUrl: process.env.HINDSIGHT_BASE_URL!,
      apiKey: process.env.HINDSIGHT_API_KEY!
    });
  }
  return client;
}

Graceful Degradation

typescript
async function getContext(bankId: string, query: string): Promise<string> {
  try {
    const result = await client.recall(bankId, query, { limit: 3 });
    return result.results.map(m => m.text).join('\n');
  } catch (error) {
    console.error('Failed to get context:', error);
    return '';
  }
}