feat: add agent API and operational analytics
This commit is contained in:
1 parent
720ea0652a
commit
e8b730b592
65 files changed
+2650
-1214
No files matched your search
@@ -0,0 +1,57 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import type {
|
||||
ConversationOutcomesRepository,
|
||||
MessagesRepository,
|
||||
SentMessageRecord,
|
||||
SuccessfulMessagesRepository,
|
||||
} from '../src/database/repositories.js';
|
||||
import { recordConversationReply } from '../src/services/conversation-outcome-recorder.js';
|
||||
import { createMockLogger } from './mockLogger.js';
|
||||
|
||||
function message(): SentMessageRecord {
|
||||
return {
|
||||
id: 1,
|
||||
postId: 'post-1',
|
||||
recipient: 'alice',
|
||||
subject: 'alice',
|
||||
message: 'Hello',
|
||||
sentAt: 1,
|
||||
gotResponse: false,
|
||||
gotImage: false,
|
||||
responseCheckedAt: null,
|
||||
strategyId: 'direct',
|
||||
chatRoomId: 'room-1',
|
||||
subreddit: 'example',
|
||||
};
|
||||
}
|
||||
|
||||
function dependencies() {
|
||||
return {
|
||||
messages: { markGotResponse: vi.fn() } as unknown as MessagesRepository,
|
||||
successful: { insert: vi.fn(), existsByMessage: vi.fn(() => false) } as unknown as SuccessfulMessagesRepository,
|
||||
outcomes: { record: vi.fn(), suppressRecipient: vi.fn() } as unknown as ConversationOutcomesRepository,
|
||||
logger: createMockLogger(),
|
||||
};
|
||||
}
|
||||
|
||||
describe('recordConversationReply', () => {
|
||||
it('records a first reply but excludes it from learning until engagement is reciprocal', () => {
|
||||
const deps = dependencies();
|
||||
expect(recordConversationReply(message(), 'Thanks!', { messageCount: 2, reciprocal: false }, deps)).toBe('unknown');
|
||||
expect(deps.messages.markGotResponse).toHaveBeenCalledWith(1);
|
||||
expect(deps.successful.insert).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('stores only reciprocal engaged conversations as learning examples', () => {
|
||||
const deps = dependencies();
|
||||
expect(recordConversationReply(message(), 'Tell me more', { messageCount: 4, reciprocal: true }, deps)).toBe('engaged');
|
||||
expect(deps.successful.insert).toHaveBeenCalledWith(expect.objectContaining({ sentMessageId: 1 }));
|
||||
});
|
||||
|
||||
it('permanently suppresses a recipient after a boundary response', () => {
|
||||
const deps = dependencies();
|
||||
expect(recordConversationReply(message(), 'Stop messaging me', { messageCount: 2 }, deps)).toBe('boundary');
|
||||
expect(deps.outcomes.suppressRecipient).toHaveBeenCalledWith('alice', 'boundary');
|
||||
expect(deps.successful.insert).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user