49758568bb
Start a periodic reflect loop from portal and MindSpace service bootstraps when EXPERIENCE_REFLECT_ENABLED=1, aggregating repeated task outcomes on a configurable interval. Co-authored-by: Cursor <cursoragent@cursor.com>
94 lines
2.8 KiB
JavaScript
94 lines
2.8 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import {
|
|
resolveExperienceReflectPolicy,
|
|
runExperienceReflectOnce,
|
|
startExperienceReflectWorker,
|
|
} from './experience-reflect-worker.mjs';
|
|
|
|
test('resolveExperienceReflectPolicy defaults to disabled with 6h interval', () => {
|
|
const policy = resolveExperienceReflectPolicy({});
|
|
assert.equal(policy.enabled, false);
|
|
assert.equal(policy.intervalMs, 6 * 3_600_000);
|
|
assert.equal(policy.minGroupSize, 3);
|
|
assert.deepEqual(policy.scopes, ['global']);
|
|
});
|
|
|
|
test('resolveExperienceReflectPolicy parses env overrides', () => {
|
|
const policy = resolveExperienceReflectPolicy({
|
|
EXPERIENCE_REFLECT_ENABLED: '1',
|
|
EXPERIENCE_REFLECT_INTERVAL_HOURS: '12',
|
|
EXPERIENCE_REFLECT_MIN_GROUP_SIZE: '4',
|
|
EXPERIENCE_REFLECT_SCOPES: 'global, team-a',
|
|
EXPERIENCE_REFLECT_RUN_ON_START: '0',
|
|
});
|
|
assert.equal(policy.enabled, true);
|
|
assert.equal(policy.intervalMs, 12 * 3_600_000);
|
|
assert.equal(policy.minGroupSize, 4);
|
|
assert.deepEqual(policy.scopes, ['global', 'team-a']);
|
|
assert.equal(policy.runOnStart, false);
|
|
});
|
|
|
|
test('runExperienceReflectOnce skips when disabled', async () => {
|
|
const result = await runExperienceReflectOnce({
|
|
experienceService: { reflect: async () => ({ created: 1 }) },
|
|
policy: resolveExperienceReflectPolicy({}),
|
|
});
|
|
assert.equal(result.skipped, true);
|
|
assert.equal(result.reason, 'disabled');
|
|
});
|
|
|
|
test('runExperienceReflectOnce reflects configured scopes', async () => {
|
|
const calls = [];
|
|
const result = await runExperienceReflectOnce({
|
|
experienceService: {
|
|
reflect: async (input) => {
|
|
calls.push(input);
|
|
return { ok: true, created: 1, archived: 3 };
|
|
},
|
|
},
|
|
policy: {
|
|
enabled: true,
|
|
minGroupSize: 3,
|
|
scopes: ['global', 'team-a'],
|
|
intervalMs: 1000,
|
|
runOnStart: true,
|
|
},
|
|
});
|
|
assert.equal(result.created, 2);
|
|
assert.equal(result.archived, 6);
|
|
assert.deepEqual(calls, [
|
|
{ scope: 'global', minGroupSize: 3 },
|
|
{ scope: 'team-a', minGroupSize: 3 },
|
|
]);
|
|
});
|
|
|
|
test('startExperienceReflectWorker schedules periodic runs', async () => {
|
|
let ticks = 0;
|
|
const timers = [];
|
|
const worker = startExperienceReflectWorker({
|
|
experienceService: {
|
|
reflect: async () => {
|
|
ticks += 1;
|
|
return { ok: true, created: 0, archived: 0 };
|
|
},
|
|
},
|
|
env: {
|
|
EXPERIENCE_REFLECT_ENABLED: '1',
|
|
EXPERIENCE_REFLECT_RUN_ON_START: '0',
|
|
},
|
|
setIntervalFn: (fn, ms) => {
|
|
assert.equal(ms, 6 * 3_600_000);
|
|
timers.push(fn);
|
|
return { unref() {} };
|
|
},
|
|
});
|
|
assert.equal(worker.policy.enabled, true);
|
|
assert.equal(ticks, 0);
|
|
await worker.runOnce();
|
|
assert.equal(ticks, 1);
|
|
await timers[0]();
|
|
assert.equal(ticks, 2);
|
|
worker.stop();
|
|
});
|