export const MEMORY_V2_PLUGIN_BACKEND_SPECS = [ { name: 'pgvector', category: 'semantic', role: 'primary-vector-store', capabilities: ['resolve'], flag: 'MEMORY_VECTOR_ENABLED', }, { name: 'qdrant', category: 'semantic', role: 'scale-out-vector-store', capabilities: ['resolve'], flag: 'MEMORY_QDRANT_ENABLED', }, { name: 'weaviate', category: 'semantic', role: 'knowledge-graph-fusion', capabilities: ['resolve'], flag: 'MEMORY_WEAVIATE_ENABLED', }, { name: 'mem0', category: 'extraction', role: 'automatic-memory-generation', capabilities: ['write', 'compact'], flag: 'MEMORY_MEM0_ENABLED', }, { name: 'letta', category: 'lifecycle', role: 'long-short-term-memory-os', capabilities: ['resolve', 'write', 'compact'], flag: 'MEMORY_LETTA_ENABLED', }, { name: 'neo4j', category: 'behavior', role: 'behavior-graph', capabilities: ['resolve', 'write'], flag: 'MEMORY_NEO4J_ENABLED', }, { name: 'redis-streams', category: 'behavior', role: 'event-tracking', capabilities: ['write'], flag: 'MEMORY_REDIS_STREAMS_ENABLED', }, { name: 'langgraph', category: 'policy', role: 'routing-reasoning-policy', capabilities: ['resolve'], flag: 'MEMORY_LANGGRAPH_ENABLED', }, ]; function normalizeSpec(spec) { const name = String(spec?.name ?? '').trim(); if (!name) throw new Error('Memory V2 plugin backend requires a name'); return { name, category: String(spec?.category ?? 'plugin'), role: String(spec?.role ?? 'optional-plugin'), capabilities: Array.isArray(spec?.capabilities) ? spec.capabilities : [], flag: spec?.flag == null ? null : String(spec.flag), }; } export function createUnavailableMemoryBackend(spec, { reason = 'not_configured' } = {}) { const normalized = normalizeSpec(spec); const backend = { name: normalized.name, category: normalized.category, role: normalized.role, flag: normalized.flag, unavailableReason: reason, isAvailable() { return false; }, getUnavailableReason() { return reason; }, }; if (normalized.capabilities.includes('resolve')) { backend.resolve = async () => ({ memories: [], semanticMemories: [], behaviorSummary: null, activeGoals: [], }); } if (normalized.capabilities.includes('write')) { backend.write = async () => ({ saved: 0, analyzed: 0, memories: 0 }); } if (normalized.capabilities.includes('compact')) { backend.compact = async () => ({ analyzed: 0, memories: 0 }); } return backend; } export function createMemoryV2PluginBackends({ specs = MEMORY_V2_PLUGIN_BACKEND_SPECS, exclude = [], reason = 'not_configured', } = {}) { const excluded = new Set(exclude); return specs .map((spec) => normalizeSpec(spec)) .filter((spec) => !excluded.has(spec.name)) .map((spec) => createUnavailableMemoryBackend(spec, { reason })); }