Add engagement-only conversation mode

This commit is contained in:
jjbrunton committed 2026-08-14 15:07:54 +01:00
1 parent b7fcc7db05
commit 7af7b211fa
24 files changed
+204 -23

No files matched your search

+27 -4
View File
@@ -11,7 +11,7 @@ function harness(
sellerDomains: string[] = [],
openerSentAt: number | null = 0,
subredditConversation?: {
mode: 'legacy' | 'r4r' | 'r4r-media' | 'manual';
mode: 'legacy' | 'engagement' | 'r4r' | 'r4r-media' | 'manual';
maxAutomatedTurns: number;
rapportTurnsBeforeMediaAsk?: number;
},
@@ -739,14 +739,14 @@ describe('conversation automation', () => {
expect(ai.generateMediaAsk).not.toHaveBeenCalled();
expect(chat.sendChatMessage).toHaveBeenCalledTimes(2);
expect(getSaved()?.automation).toMatchObject({
policyMode: 'r4r', policyVersion: 4, maxAutomatedTurns: 2, turnsUsed: 2,
policyMode: 'r4r', policyVersion: 5, maxAutomatedTurns: 2, turnsUsed: 2,
});
expect(getSaved()?.askedForMedia).toBe(false);
});
it('snapshots the r4r policy so later configuration changes do not switch an active conversation', async () => {
const behaviour: {
mode: 'legacy' | 'r4r' | 'r4r-media' | 'manual';
mode: 'legacy' | 'engagement' | 'r4r' | 'r4r-media' | 'manual';
maxAutomatedTurns: number;
} = {
mode: 'r4r', maxAutomatedTurns: 2,
@@ -774,6 +774,29 @@ describe('conversation automation', () => {
expect(await service.processConversation(incoming(1))).toBeNull();
});
it('completes engagement mode on the first reply without generating, sending, or handing off', async () => {
const { service, ai, chat, claims, triage, getSaved } = harness(
[], [], 0, { mode: 'engagement', maxAutomatedTurns: 3 },
);
const result = await service.processConversation(incoming(1));
expect(result).toMatchObject({ kind: 'engaged', remainingTurns: 0 });
expect(getSaved()?.automation).toMatchObject({
policyMode: 'engagement',
status: 'engaged',
turnsUsed: 0,
lastIncomingKey: 'in-1',
handoffReason: 'The recipient replied; the engagement goal is complete.',
});
expect(claims.markSuperseded).toHaveBeenCalledWith('room-alice', 'in-1');
expect(triage.setStatus).toHaveBeenCalledWith('room-alice', 'done', null, 1_000);
expect(ai.generateReply).not.toHaveBeenCalled();
expect(ai.generateMediaAsk).not.toHaveBeenCalled();
expect(chat.sendChatMessage).not.toHaveBeenCalled();
expect(await service.processConversation(incoming(1))).toBeNull();
});
it('hands r4r conversations to a human when age or contact safety gates trigger', async () => {
const underage = harness([], [], 0, { mode: 'r4r', maxAutomatedTurns: 5 });
const result = await underage.service.processConversation(incoming(1, "I'm 17, what about you?"));
@@ -844,7 +867,7 @@ describe('conversation automation', () => {
expect(fixture.getSaved()?.askedForMedia).toBe(true);
expect(fixture.getSaved()?.automation).toMatchObject({
policyMode: 'r4r-media',
policyVersion: 4,
policyVersion: 5,
rapportTurnsBeforeMediaAsk: 2,
hybridPhase: 'post-media-ask',
turnsUsed: 4,