feat: add local SQLite memory store
This commit is contained in:
@@ -30,6 +30,7 @@ import {
|
||||
getNewMessagesBySeq,
|
||||
getOpenWorkItem,
|
||||
getPendingServiceHandoffs,
|
||||
recallMemories,
|
||||
getRegisteredAgentTypesForJid,
|
||||
getMessagesSince,
|
||||
getNewMessages,
|
||||
@@ -46,6 +47,7 @@ import {
|
||||
setSession,
|
||||
setRouterStateForService,
|
||||
setExplicitRoomMode,
|
||||
rememberMemory,
|
||||
storeChatMetadata,
|
||||
storeMessage,
|
||||
updateRegisteredGroupName,
|
||||
@@ -1280,6 +1282,68 @@ describe('message seq cursors', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('memories', () => {
|
||||
it('recalls scoped memories through FTS and exact keyword matching', () => {
|
||||
rememberMemory({
|
||||
scopeKind: 'room',
|
||||
scopeKey: 'room:test-group',
|
||||
content: '세션 재시작 후에도 방 메모리를 주입한다.',
|
||||
keywords: ['room:test-group', 'session-reset'],
|
||||
sourceKind: 'compact',
|
||||
sourceRef: 'compact:1',
|
||||
});
|
||||
rememberMemory({
|
||||
scopeKind: 'room',
|
||||
scopeKey: 'room:test-group',
|
||||
content: '이 메모리는 다른 검색어다.',
|
||||
keywords: ['room:test-group'],
|
||||
sourceKind: 'compact',
|
||||
sourceRef: 'compact:2',
|
||||
});
|
||||
|
||||
const byText = recallMemories({
|
||||
scopeKind: 'room',
|
||||
scopeKey: 'room:test-group',
|
||||
text: 'session reset',
|
||||
limit: 5,
|
||||
});
|
||||
expect(byText).toHaveLength(1);
|
||||
expect(byText[0].content).toContain('방 메모리를 주입한다');
|
||||
|
||||
const byKeyword = recallMemories({
|
||||
scopeKind: 'room',
|
||||
scopeKey: 'room:test-group',
|
||||
keywords: ['session-reset'],
|
||||
limit: 5,
|
||||
});
|
||||
expect(byKeyword).toHaveLength(1);
|
||||
expect(byKeyword[0].content).toContain('방 메모리를 주입한다');
|
||||
});
|
||||
|
||||
it('archives old memories when a scope exceeds its bounded limit', () => {
|
||||
for (let index = 0; index < 305; index += 1) {
|
||||
rememberMemory({
|
||||
scopeKind: 'room',
|
||||
scopeKey: 'room:bounded',
|
||||
content: `memory-${index}`,
|
||||
keywords: ['room:bounded'],
|
||||
sourceKind: 'compact',
|
||||
sourceRef: `compact:${index}`,
|
||||
});
|
||||
}
|
||||
|
||||
const recalled = recallMemories({
|
||||
scopeKind: 'room',
|
||||
scopeKey: 'room:bounded',
|
||||
limit: 500,
|
||||
});
|
||||
|
||||
expect(recalled).toHaveLength(300);
|
||||
expect(recalled.some((memory) => memory.content === 'memory-0')).toBe(false);
|
||||
expect(recalled.some((memory) => memory.content === 'memory-304')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('work items', () => {
|
||||
it('tracks produced, retry, and delivered states', () => {
|
||||
const item = createProducedWorkItem({
|
||||
|
||||
Reference in New Issue
Block a user