Add hybrid R4R media conversation mode

This commit is contained in:
jjbrunton committed 2026-08-09 11:45:45 +01:00
1 parent 927636ec8b
commit b73e305cf3
15 files changed
+357 -35

No files matched your search

+35
View File
@@ -3,6 +3,7 @@ import type OpenAI from 'openai';
import { OpenRouterClient, stripDashes } from '../src/ai/openrouter.js';
import { createMockLogger } from '../tests/mockLogger.js';
import { getTestConfig } from '../tests/testUtils.js';
import { buildConversationState, createConversationAutomationState } from '../src/services/conversation-state.js';
describe('OpenRouterClient', () => {
let client: OpenRouterClient;
@@ -728,6 +729,40 @@ describe('OpenRouterClient', () => {
});
});
describe('generateR4RMediaAsk', () => {
it('requests one optional non-explicit image after rapport', async () => {
mockCreate.mockResolvedValueOnce({
choices: [{ message: { content: 'You sound lovely, would you be comfortable sharing a selfie?' } }],
});
const state = buildConversationState([
{ sender: 'me', text: '32M UK, fancy a chat?', isSelf: true },
{ sender: 'them', text: 'I love live music.', isSelf: false },
]);
state.automation = createConversationAutomationState('r4r-media', 6, 3);
state.automation.turnsUsed = 3;
const result = await client.generateR4RMediaAsk(
[{ sender: 'them', text: 'I love live music.', isSelf: false }],
'them',
state,
);
expect(result).toContain('comfortable sharing a selfie');
const prompt = mockCreate.mock.calls[0][0].messages[1].content as string;
expect(prompt).toContain('single image invitation');
expect(prompt).toContain('Do not ask for nudity');
});
it('rejects an explicit media request', async () => {
mockCreate.mockResolvedValueOnce({ choices: [{ message: { content: 'Send me a nude.' } }] });
const state = buildConversationState([]);
state.automation = createConversationAutomationState('r4r-media', 6, 3);
await expect(client.generateR4RMediaAsk([], 'them', state))
.rejects.toThrow('hybrid output safeguards');
});
});
it('records model, token, cost, latency, and outcome for each request attempt', async () => {
const usageRecorder = vi.fn();
const config = getTestConfig();