TypeScript/JavaScript SDK Guide¶
The ALMA TypeScript SDK provides a type-safe client for interacting with ALMA Memory from JavaScript and TypeScript applications.
Installation¶
Quick Start¶
import { ALMA } from 'alma-memory';
// Create client
const alma = new ALMA({
baseUrl: 'http://localhost:8765',
projectId: 'my-project'
});
// Retrieve memories
const memories = await alma.retrieve({
query: 'authentication flow',
agent: 'dev-agent',
topK: 5
});
// Learn from outcomes
await alma.learn({
agent: 'dev-agent',
task: 'Implement OAuth',
outcome: 'success',
strategyUsed: 'Used passport.js middleware'
});
Configuration¶
Basic Configuration¶
import { ALMA, ALMAConfig } from 'alma-memory';
const config: ALMAConfig = {
baseUrl: 'http://localhost:8765',
projectId: 'my-project'
};
const alma = new ALMA(config);
With Retry Configuration¶
const alma = new ALMA({
baseUrl: 'http://localhost:8765',
projectId: 'my-project',
retry: {
maxRetries: 3,
baseDelay: 1000, // 1 second
maxDelay: 30000, // 30 seconds
backoffMultiplier: 2
}
});
With Custom Timeout¶
const alma = new ALMA({
baseUrl: 'http://localhost:8765',
projectId: 'my-project',
timeout: 30000 // 30 seconds
});
API Reference¶
retrieve(options)¶
Get relevant memories for a task.
import { RetrieveOptions, MemorySlice } from 'alma-memory';
const options: RetrieveOptions = {
query: 'user authentication',
agent: 'dev-agent',
topK: 5,
userId: 'user-123', // Optional: for user preferences
includeShared: true // Optional: include inherited memories
};
const memories: MemorySlice = await alma.retrieve(options);
// Access different memory types
console.log('Heuristics:', memories.heuristics);
console.log('Outcomes:', memories.outcomes);
console.log('Preferences:', memories.preferences);
console.log('Knowledge:', memories.domainKnowledge);
console.log('Anti-patterns:', memories.antiPatterns);
learn(options)¶
Record task outcome and optionally create a heuristic.
import { LearnOptions, LearnResponse } from 'alma-memory';
const options: LearnOptions = {
agent: 'dev-agent',
task: 'Implement OAuth 2.0',
outcome: 'success', // 'success' | 'failure' | 'partial'
strategyUsed: 'Used passport.js with Google provider',
context: { // Optional metadata
duration: '2h',
complexity: 'medium'
}
};
const result: LearnResponse = await alma.learn(options);
console.log('Outcome ID:', result.outcomeId);
console.log('Heuristic created:', result.heuristicCreated);
addPreference(options)¶
Add a user preference.
import { AddPreferenceOptions } from 'alma-memory';
await alma.addPreference({
userId: 'user-123',
category: 'code_style',
preference: 'Use TypeScript strict mode',
confidence: 0.9, // Optional: 0.0 to 1.0
source: 'explicit' // Optional: 'explicit' | 'inferred'
});
addKnowledge(options)¶
Add domain knowledge.
import { AddKnowledgeOptions } from 'alma-memory';
await alma.addKnowledge({
agent: 'dev-agent',
domain: 'authentication',
fact: 'API uses JWT with 24-hour expiry',
confidence: 0.95,
source: 'documentation'
});
forget(options)¶
Remove old or low-confidence memories.
import { ForgetOptions, ForgetResponse } from 'alma-memory';
const result: ForgetResponse = await alma.forget({
agent: 'dev-agent',
olderThanDays: 90, // Remove memories older than 90 days
belowConfidence: 0.3 // Remove memories with confidence < 0.3
});
console.log('Memories removed:', result.removedCount);
stats()¶
Get memory statistics.
const stats = await alma.stats();
console.log('Total memories:', stats.totalMemories);
console.log('By type:', stats.byType);
console.log('By agent:', stats.byAgent);
health()¶
Check server health.
const health = await alma.health();
console.log('Status:', health.status); // 'healthy' | 'degraded' | 'unhealthy'
console.log('Version:', health.version);
Memory Types¶
Heuristic¶
Learned strategies that worked.
interface Heuristic {
id: string;
agent: string;
projectId: string;
category: string;
strategy: string;
confidence: number;
successCount: number;
failureCount: number;
metadata: Record<string, unknown>;
createdAt: Date;
updatedAt: Date;
}
Outcome¶
Results of completed tasks.
interface Outcome {
id: string;
agent: string;
projectId: string;
task: string;
outcome: 'success' | 'failure' | 'partial';
strategyUsed: string;
metadata: Record<string, unknown>;
createdAt: Date;
}
UserPreference¶
User-specific preferences.
interface UserPreference {
id: string;
userId: string;
projectId: string;
category: string;
preference: string;
confidence: number;
source: 'explicit' | 'inferred';
createdAt: Date;
}
DomainKnowledge¶
Accumulated facts about the domain.
interface DomainKnowledge {
id: string;
agent: string;
projectId: string;
domain: string;
fact: string;
confidence: number;
source: string;
metadata: Record<string, unknown>;
createdAt: Date;
}
AntiPattern¶
Things to avoid.
interface AntiPattern {
id: string;
agent: string;
projectId: string;
pattern: string;
whyBad: string;
betterAlternative: string;
occurrences: number;
metadata: Record<string, unknown>;
createdAt: Date;
}
Error Handling¶
The SDK provides typed errors for different failure modes.
import {
ALMAError,
ConnectionError,
ValidationError,
NotFoundError,
ScopeViolationError,
TimeoutError,
ServerError,
isConnectionError,
isValidationError
} from 'alma-memory';
try {
await alma.retrieve({ query: 'test', agent: '' });
} catch (error) {
if (isValidationError(error)) {
console.error('Invalid input:', error.message);
} else if (isConnectionError(error)) {
console.error('Cannot reach server:', error.message);
} else if (error instanceof ALMAError) {
console.error('ALMA error:', error.message, error.code);
} else {
throw error;
}
}
Error Types¶
| Error | Description |
|---|---|
ConnectionError |
Cannot connect to ALMA server |
ValidationError |
Invalid input parameters |
NotFoundError |
Requested resource not found |
ScopeViolationError |
Agent tried to learn outside scope |
TimeoutError |
Request timed out |
ServerError |
Internal server error |
Framework Integration¶
React¶
import { useState, useEffect } from 'react';
import { ALMA, MemorySlice } from 'alma-memory';
const alma = new ALMA({
baseUrl: process.env.NEXT_PUBLIC_ALMA_URL!,
projectId: 'my-app'
});
function useMemories(query: string, agent: string) {
const [memories, setMemories] = useState<MemorySlice | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
setLoading(true);
alma.retrieve({ query, agent, topK: 5 })
.then(setMemories)
.catch(setError)
.finally(() => setLoading(false));
}, [query, agent]);
return { memories, loading, error };
}
Node.js / Express¶
import express from 'express';
import { ALMA } from 'alma-memory';
const app = express();
const alma = new ALMA({
baseUrl: process.env.ALMA_URL!,
projectId: 'api-server'
});
app.post('/api/chat', async (req, res) => {
const { message, agent } = req.body;
// Get relevant memories
const memories = await alma.retrieve({
query: message,
agent,
topK: 5
});
// Use memories in your LLM prompt
const context = memories.heuristics
.map(h => `Strategy: ${h.strategy}`)
.join('\n');
// ... rest of chat logic
});
Next.js API Route¶
// pages/api/memories.ts
import type { NextApiRequest, NextApiResponse } from 'next';
import { ALMA } from 'alma-memory';
const alma = new ALMA({
baseUrl: process.env.ALMA_URL!,
projectId: 'my-app'
});
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
const { query, agent } = req.body;
try {
const memories = await alma.retrieve({ query, agent, topK: 5 });
res.status(200).json(memories);
} catch (error) {
res.status(500).json({ error: 'Failed to retrieve memories' });
}
}
Starting the MCP Server¶
The TypeScript SDK communicates with ALMA via the MCP server. Start it with:
Or add to your package.json:
Best Practices¶
- Singleton Client: Create one ALMA instance and reuse it
- Error Handling: Always wrap calls in try-catch
- Appropriate topK: Use 5-10 for most cases
- Batch Learning: Record outcomes immediately after tasks
- Type Safety: Use TypeScript for compile-time validation