UNPKG

memq-ai-memory

Version:

Memory SDK with Vercel AI SDK integration

394 lines 13.8 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MemoryClient = void 0; const axios_1 = __importDefault(require("axios")); const uuid_1 = require("uuid"); const crypto = __importStar(require("crypto")); class MemoryClient { constructor(config) { this.config = { baseUrl: 'http://localhost:8000', timeout: 30000, retryAttempts: 3, retryDelay: 1000, enableLogging: false, ...config }; this.sessionId = (0, uuid_1.v4)(); // Derive user_id from API key (like mem0 client does) this.derivedUserId = crypto.createHash('md5').update(this.config.apiKey).digest('hex'); this.client = axios_1.default.create({ baseURL: this.config.baseUrl, timeout: this.config.timeout, headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.config.apiKey}`, 'X-Session-ID': this.sessionId, // Provide API key via header expected by backend API key auth 'x-api-key': this.config.apiKey } }); // Add request interceptor for logging if (this.config.enableLogging) { this.client.interceptors.request.use((config) => { console.log(`[MemorySDK] Request: ${config.method?.toUpperCase()} ${config.url}`); return config; }, (error) => { console.error('[MemorySDK] Request Error:', error); return Promise.reject(error); }); this.client.interceptors.response.use((response) => { console.log(`[MemorySDK] Response: ${response.status} ${response.config.url}`); return response; }, (error) => { console.error('[MemorySDK] Response Error:', error.response?.status, error.response?.data); return Promise.reject(error); }); } } /** * Validate the API key by making a test request */ async validateApiKey() { try { const response = await this.client.get('/health'); return response.status === 200; } catch (error) { return false; } } /** * Create a new memory (automatically uses derived user_id) */ async createMemory(memory) { try { const response = await this.client.post('/memory/smart', { ...memory, user_id: memory.user_id || this.actualUserId || this.derivedUserId, // Prefer actual user id over derived session_id: memory.session_id || this.sessionId }); return response.data; } catch (error) { throw this.handleError(error, 'Failed to create memory'); } } /** * Get all memories (automatically uses derived user_id) */ async getAllMemories(userId, limit = 50) { try { const actualUserId = userId || this.actualUserId || this.derivedUserId; const response = await this.client.get(`/memories/${encodeURIComponent(actualUserId)}?limit=${limit}`); return response.data; } catch (error) { throw this.handleError(error, 'Failed to get memories'); } } /** * Search memories (automatically uses derived user_id) */ async searchMemories(request) { try { const params = new URLSearchParams(); const userId = request.user_id || this.actualUserId || this.derivedUserId; if (userId) { params.append('user_id', userId); } const response = await this.client.post(`/query/smart?${params.toString()}`, { prompt: request.query, limit: request.limit || 10, ...request.filters }); return response.data; } catch (error) { throw this.handleError(error, 'Failed to search memories'); } } /** * Get workflow memories for a user */ async getWorkflowMemories(userId, limit = 50) { try { const response = await this.client.get(`/workflow-memories/${encodeURIComponent(userId)}?limit=${limit}`); return response.data; } catch (error) { throw this.handleError(error, 'Failed to get workflow memories'); } } /** * Get user facts (automatically uses derived user_id if not provided) */ async getUserFacts(userId, category, limit = 20) { try { const actualUserId = userId || this.actualUserId || this.derivedUserId; const categoryParam = category ? `&category=${encodeURIComponent(category)}` : ''; const response = await this.client.get(`/facts/${actualUserId}?limit=${limit}${categoryParam}`); return response.data; } catch (error) { throw this.handleError(error, 'Failed to get user facts'); } } /** * Get user prompt structures (automatically uses derived user_id if not provided) */ async getUserPromptStructures(userId, isComplete, limit = 20) { try { const actualUserId = userId || this.actualUserId || this.derivedUserId; const completeParam = isComplete !== undefined ? `&is_complete=${isComplete}` : ''; const response = await this.client.get(`/prompt/structures/user/${actualUserId}?limit=${limit}${completeParam}`); return response.data; } catch (error) { throw this.handleError(error, 'Failed to get prompt structures'); } } /** * Delete a memory */ async deleteMemory(memoryId) { try { const response = await this.client.delete(`/memory/${memoryId}`); return response.data; } catch (error) { throw this.handleError(error, 'Failed to delete memory'); } } /** * Get collection statistics */ async getStats() { try { const response = await this.client.get('/stats'); return response.data; } catch (error) { throw this.handleError(error, 'Failed to get stats'); } } /** * Health check */ async healthCheck() { try { const response = await this.client.get('/health'); return response.data; } catch (error) { throw this.handleError(error, 'Failed to perform health check'); } } /** * Get recent activity for a user (automatically uses derived user_id if not provided) */ async getRecentActivity(userId, limit = 10) { try { const actualUserId = userId || this.derivedUserId; const [memories, facts, structures] = await Promise.all([ this.searchMemories({ query: 'recent activity', user_id: actualUserId, limit }), this.getUserFacts(actualUserId, undefined, limit), this.getUserPromptStructures(actualUserId, undefined, limit) ]); return { memories: memories.memories, facts: facts.facts, prompt_structures: structures.structures }; } catch (error) { throw this.handleError(error, 'Failed to get recent activity'); } } /** * Create a new API key */ async createApiKey(request) { try { const response = await this.client.post('/api-keys', request); return response.data; } catch (error) { throw this.handleError(error, 'Failed to create API key'); } } /** * Get user's API keys */ async getApiKeys() { try { const response = await this.client.get('/api-keys'); return response.data; } catch (error) { throw this.handleError(error, 'Failed to get API keys'); } } /** * Revoke an API key */ async revokeApiKey(keyId) { try { const response = await this.client.delete(`/api-keys/${keyId}`); return response.data; } catch (error) { throw this.handleError(error, 'Failed to revoke API key'); } } /** * Update API key details */ async updateApiKey(keyId, updates) { try { const response = await this.client.put(`/api-keys/${keyId}`, updates); return response.data; } catch (error) { throw this.handleError(error, 'Failed to update API key'); } } /** * Get the current session ID */ getSessionId() { return this.sessionId; } /** * Set a new session ID */ setSessionId(sessionId) { this.sessionId = sessionId; this.client.defaults.headers['X-Session-ID'] = sessionId; } /** * Get derived user_id */ getDerivedUserId() { return this.derivedUserId; } /** * Get actual user_id resolved from API key, if available */ getActualUserId() { return this.actualUserId; } /** * Initialize actual user_id by validating API key against backend * Uses /api-keys/test/protected which returns user_id when x-api-key is valid */ async initializeUserFromApiKey() { try { if (this.config.enableLogging) { console.log('[MemorySDK] Attempting to resolve actual user ID from API key...'); } const response = await this.client.get('/api-keys/test/protected'); if (this.config.enableLogging) { console.log('[MemorySDK] API key validation response:', response.data); } const userId = (response.data && (response.data.user_id || response.data.userId)); if (userId) { this.actualUserId = userId; if (this.config.enableLogging) { console.log(`[MemorySDK] Successfully resolved actual user ID: ${userId}`); } } else { if (this.config.enableLogging) { console.log('[MemorySDK] No user_id found in API key validation response'); } } } catch (error) { if (this.config.enableLogging) { console.log('[MemorySDK] Failed to resolve actual user ID from API key:', error); } // Silently ignore and fall back to derived user id } } /** * Handle API errors */ handleError(error, defaultMessage) { if (error.response) { const errorData = error.response.data; const message = errorData?.detail || errorData?.error || defaultMessage; const customError = new Error(message); customError.status = error.response.status; customError.data = errorData; return customError; } else if (error.request) { return new Error('Network error: No response received'); } else { return new Error(`Request error: ${error.message}`); } } /** * Retry a request with exponential backoff */ async retryRequest(requestFn, attempts = this.config.retryAttempts || 3) { let lastError; for (let i = 0; i < attempts; i++) { try { return await requestFn(); } catch (error) { lastError = error; // Don't retry on client errors (4xx) if (error.status && error.status >= 400 && error.status < 500) { throw error; } if (i < attempts - 1) { const delay = (this.config.retryDelay || 1000) * Math.pow(2, i); await new Promise(resolve => setTimeout(resolve, delay)); } } } throw lastError; } } exports.MemoryClient = MemoryClient; //# sourceMappingURL=MemoryClient.js.map