TypeScript SDK Guide
FreshSource: 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-clientQuick 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);Recall (Search)
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 '';
}
}