feat: hand off upsell conversations to humans

This commit is contained in:
jjbrunton committed 2026-08-09 07:26:04 +01:00
1 parent 5ad7f1bf77
commit e8f56b42e6
4 files changed
+32 -2

No files matched your search

+15 -1
View File
@@ -2,7 +2,7 @@ import { describe, expect, it, vi } from 'vitest';
import { ConversationAutomationService } from '../src/services/conversation-automation.js';
import type { ConversationState } from '../src/services/conversation-state.js';
function harness() {
function harness(sellerKeywords: string[] = [], sellerDomains: string[] = []) {
let saved: ConversationState | undefined;
const chat = {
refreshTopChats: vi.fn().mockResolvedValue(undefined),
@@ -20,6 +20,7 @@ function harness() {
const logger = { info: vi.fn() };
const service = new ConversationAutomationService(
chat as never, ai as never, states as never, rateLimiter as never, logger as never,
false, sellerKeywords, sellerDomains,
);
return { service, chat, ai, states, getSaved: () => saved };
}
@@ -59,6 +60,19 @@ describe('conversation automation', () => {
expect(getSaved()?.automation.status).toBe('boundary');
});
it('flags a potential upsell for human handoff without generating a reply', async () => {
const { service, chat, ai, getSaved } = harness(['onlyfans'], ['fansly.com']);
const result = await service.processConversation(incoming(1, 'My Fansly is https://www.fansly.com/example'));
expect(result).toMatchObject({ kind: 'human-required', remainingTurns: 0 });
expect(ai.generateMediaAsk).not.toHaveBeenCalled();
expect(chat.sendChatMessage).not.toHaveBeenCalled();
expect(getSaved()?.automation).toMatchObject({
status: 'human-required',
handoffReason: 'Potential upsell detected (domain: fansly.com).',
});
});
it('completes when an inbound image is received', async () => {
const { service, chat, getSaved } = harness();
const result = await service.processConversation(incoming(1, '[Image]', [{