feat(memory): add gated agent recall and lifecycle controls
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { createMemoryV2LifecycleService, resolveMemoryV2LifecyclePolicy } from './memory-v2-lifecycle.mjs';
|
||||
|
||||
test('lifecycle policy defaults to safe disabled workers', () => {
|
||||
const policy = resolveMemoryV2LifecyclePolicy({});
|
||||
assert.equal(policy.enabled, false);
|
||||
assert.equal(policy.promotionEnabled, false);
|
||||
assert.equal(policy.compactionEnabled, false);
|
||||
assert.equal(policy.reflectionEnabled, false);
|
||||
assert.equal(policy.rolloutMode, 'off');
|
||||
});
|
||||
|
||||
test('lifecycle canary only runs for configured users', async () => {
|
||||
const lifecycle = createMemoryV2LifecycleService({
|
||||
env: {
|
||||
MEMORY_LIFECYCLE_ENABLED: '1',
|
||||
MEMORY_LIFECYCLE_ROLLOUT_MODE: 'canary',
|
||||
MEMORY_LIFECYCLE_ROLLOUT_USER_IDS: 'u-1',
|
||||
MEMORY_PROMOTION_ENABLED: '1',
|
||||
},
|
||||
});
|
||||
assert.equal(lifecycle.canRun('u-1'), true);
|
||||
assert.equal(lifecycle.canRun('u-2'), false);
|
||||
assert.equal((await lifecycle.promote({ userId: 'u-2' })).skipped, true);
|
||||
});
|
||||
|
||||
test('forget is fail-safe when lifecycle is disabled', async () => {
|
||||
const lifecycle = createMemoryV2LifecycleService({ env: { MEMORY_LIFECYCLE_ENABLED: '0' } });
|
||||
assert.deepEqual(await lifecycle.forgetMemory({ userId: 'u-1', memoryId: 'm-1' }), {
|
||||
ok: true, updated: false, skipped: true, reason: 'disabled',
|
||||
});
|
||||
});
|
||||
|
||||
test('list and forget use user-scoped SQL', async () => {
|
||||
const calls = [];
|
||||
const pool = { query: async (sql, params) => {
|
||||
calls.push({ sql, params });
|
||||
if (sql.startsWith('SELECT')) return [[{ id: 'm-1', user_id: 'u-1', label: 'fact', memory_text: 'x', status: 'active', confidence: 0.9, created_at: 1, updated_at: 2 }]];
|
||||
return [{ affectedRows: 1 }];
|
||||
} };
|
||||
const lifecycle = createMemoryV2LifecycleService({ pool, env: { MEMORY_LIFECYCLE_ENABLED: '1', MEMORY_LIFECYCLE_FORGETTING_ENABLED: '1' } });
|
||||
assert.equal((await lifecycle.listMemories({ userId: 'u-1' }))[0].id, 'm-1');
|
||||
assert.equal((await lifecycle.forgetMemory({ userId: 'u-1', memoryId: 'm-1' })).updated, true);
|
||||
assert.match(calls[0].sql, /user_id = \?/);
|
||||
assert.match(calls[1].sql, /user_id = \?/);
|
||||
});
|
||||
Reference in New Issue
Block a user