import assert from 'node:assert/strict'; import test from 'node:test'; import { inspectMemoryV2Backend } from './memory-v2-backend-contract.mjs'; import { createLettaHttpClient, createLettaMemoryBackend } from './memory-v2-letta.mjs'; test('letta backend is disabled by default and passes contract gate', async () => { const backend = createLettaMemoryBackend(); const report = inspectMemoryV2Backend(backend); assert.equal(backend.name, 'letta'); assert.equal(backend.category, 'lifecycle'); assert.equal(backend.role, 'long-short-term-memory-os'); assert.equal(backend.flag, 'MEMORY_LETTA_ENABLED'); assert.equal(backend.isAvailable(), false); assert.equal(backend.getUnavailableReason(), 'not_configured'); assert.equal(report.ok, true); assert.deepEqual(await backend.resolve({}), { memories: [], semanticMemories: [], behaviorSummary: null, activeGoals: [], }); assert.deepEqual(await backend.write({}), { saved: 0, analyzed: 0, memories: 0 }); assert.deepEqual(await backend.compact({}), { analyzed: 0, memories: 0 }); }); test('letta backend reports api key and client configuration reasons', () => { assert.equal( createLettaMemoryBackend({ enabled: true }).getUnavailableReason(), 'api_key_not_configured', ); assert.equal( createLettaMemoryBackend({ enabled: true, apiKey: 'secret', projectId: 'memind_project', agentId: 'agent_1', }).getUnavailableReason(), 'client_not_configured', ); }); test('letta backend validates project and agent ids', () => { assert.throws( () => createLettaMemoryBackend({ projectId: 'bad project id' }), /Invalid MEMORY_LETTA_PROJECT_ID/, ); assert.throws( () => createLettaMemoryBackend({ agentId: 'bad agent id' }), /Invalid MEMORY_LETTA_AGENT_ID/, ); }); test('letta backend delegates only when explicitly wired with a full client', async () => { const calls = []; const backend = createLettaMemoryBackend({ enabled: true, apiKey: 'secret', projectId: 'memind_project', agentId: 'agent_1', client: { async resolve(input) { calls.push(['resolve', input]); return { memories: [{ id: 1, type: 'goal', content: 'keep long-term context tidy' }], activeGoals: ['memory-v2'], }; }, async write(input) { calls.push(['write', input]); return { saved: 2, analyzed: 1, memories: 1 }; }, async compact(input) { calls.push(['compact', input]); return { analyzed: 3, memories: 2 }; }, }, }); assert.equal(backend.isAvailable(), true); assert.equal(backend.getUnavailableReason(), null); assert.deepEqual(await backend.resolve({ userId: 'u1' }), { memories: [{ id: '1', label: 'goal', text: 'keep long-term context tidy', createdAt: null, }], semanticMemories: ['keep long-term context tidy'], behaviorSummary: null, activeGoals: ['memory-v2'], profile: null, }); assert.deepEqual(await backend.write({ userId: 'u1' }), { saved: 2, analyzed: 1, memories: 1, }); assert.deepEqual(await backend.compact({ userId: 'u1' }), { analyzed: 3, memories: 2, }); assert.deepEqual(calls.map(([name, input]) => [name, input.projectId, input.agentId]), [ ['resolve', 'memind_project', 'agent_1'], ['write', 'memind_project', 'agent_1'], ['compact', 'memind_project', 'agent_1'], ]); }); test('letta HTTP client resolves, writes, and compacts with agent-scoped paths', async () => { const calls = []; const client = createLettaHttpClient({ apiKey: 'secret', baseUrl: 'https://letta.local', agentId: 'agent_1', projectId: 'memind_project', modelProviderKeyId: 'key_letta', model: 'gpt-4.1', modelApiType: 'chat', async fetchImpl(url, options) { calls.push({ url, headers: options.headers, body: options.body ? JSON.parse(options.body) : null }); return { ok: true, async json() { if (url.endsWith('/memory')) return { memories: ['letta memory'] }; return { saved: 1, analyzed: 1, memories: 1 }; }, }; }, }); assert.deepEqual(await client.resolve({ userId: 'u1', query: 'hello' }), { memories: ['letta memory'], }); assert.deepEqual(await client.write({ userId: 'u1', sessionId: 's1', messages: [] }), { saved: 1, analyzed: 1, memories: 1, }); assert.deepEqual(await client.compact({ userId: 'u1' }), { analyzed: 1, memories: 1, }); assert.deepEqual(calls.map((call) => call.url), [ 'https://letta.local/v1/agents/agent_1/memory', 'https://letta.local/v1/agents/agent_1/messages', 'https://letta.local/v1/agents/agent_1/memory/compact', ]); assert.equal(calls[0].headers.authorization, 'Bearer secret'); assert.equal(calls[0].body.project_id, 'memind_project'); assert.equal(calls[0].body.model_provider_key_id, 'key_letta'); assert.equal(calls[0].body.model, 'gpt-4.1'); assert.equal(calls[0].body.model_api_type, 'chat'); assert.equal(calls[1].body.model_provider_key_id, 'key_letta'); assert.equal(calls[2].body.model_api_type, 'chat'); });