|
|
@@ -158,6 +158,50 @@ class VoiceTests(unittest.IsolatedAsyncioTestCase):
|
|
|
|
|
|
|
|
|
class CommandTests(unittest.IsolatedAsyncioTestCase):
|
|
|
+ async def test_voice_limits_history_and_disables_thinking_only_for_voice(self):
|
|
|
+ tree = ast.parse(Path(__file__).with_name('chatbot.py').read_text(encoding='utf-8'))
|
|
|
+ function = next(n for n in tree.body if isinstance(n, ast.AsyncFunctionDef)
|
|
|
+ and n.name == 'call_openai_api')
|
|
|
+ response = SimpleNamespace(choices=[SimpleNamespace(message=SimpleNamespace(
|
|
|
+ tool_calls=None, content='Bonjour'))])
|
|
|
+ create = AsyncMock(return_value=response)
|
|
|
+ history = [{'role': 'user', 'content': str(i)} for i in range(10)]
|
|
|
+ namespace = dict(transform_emote=lambda text, output: text, PERSONALITY_PROMPT='Personnalité',
|
|
|
+ conversation_history=history, search_web=AsyncMock(return_value=None),
|
|
|
+ WEB_SEARCH_ENABLED=True, MODEL='test', TEMPERATURE=1, logger=Mock(),
|
|
|
+ openai_client=SimpleNamespace(chat=SimpleNamespace(
|
|
|
+ completions=SimpleNamespace(create=create))),
|
|
|
+ add_to_conversation_history=AsyncMock())
|
|
|
+ exec(compile(ast.Module(body=[function], type_ignores=[]), '<api>', 'exec'), namespace)
|
|
|
+ await namespace['call_openai_api']('Bonjour', 'Alice', voice=True)
|
|
|
+ args = create.call_args.kwargs
|
|
|
+ self.assertEqual(args['messages'][1:-1], history[-5:])
|
|
|
+ self.assertEqual(args['extra_body']['options']['think'], False)
|
|
|
+ self.assertIn('une à trois phrases', args['messages'][0]['content'])
|
|
|
+ self.assertIn('search_web', args['messages'][0]['content'])
|
|
|
+ await namespace['call_openai_api']('Bonjour', 'Alice')
|
|
|
+ args = create.call_args.kwargs
|
|
|
+ self.assertEqual(args['messages'][1:-1], history)
|
|
|
+ self.assertNotIn('extra_body', args)
|
|
|
+
|
|
|
+ async def test_status_connected_and_disconnected(self):
|
|
|
+ tree = ast.parse(Path(__file__).with_name('chatbot.py').read_text(encoding='utf-8'))
|
|
|
+ function = next(n for n in tree.body if isinstance(n, ast.AsyncFunctionDef)
|
|
|
+ and n.name == 'handle_status')
|
|
|
+ namespace = dict(BOT_VERSION='test', MODEL='gemma', discord=discord)
|
|
|
+ exec(compile(ast.Module(body=[function], type_ignores=[]), '<status>', 'exec'), namespace)
|
|
|
+ message = SimpleNamespace(guild=None, channel=SimpleNamespace(send=AsyncMock()))
|
|
|
+ await namespace['handle_status'](message)
|
|
|
+ self.assertIn('déconnecté', message.channel.send.call_args.args[0])
|
|
|
+ sink = SimpleNamespace(responding=True, queue=asyncio.Queue(), pending=[1, 2],
|
|
|
+ last_stt_seconds=0.5, last_reply_seconds=None)
|
|
|
+ message.guild = SimpleNamespace(voice_client=SimpleNamespace(sink=sink, is_connected=lambda: True))
|
|
|
+ await namespace['handle_status'](message)
|
|
|
+ text = message.channel.send.call_args.args[0]
|
|
|
+ self.assertIn('transcriptions en attente : 2', text)
|
|
|
+ self.assertIn('0.5 s', text)
|
|
|
+ self.assertIn('pas encore mesuré', text)
|
|
|
+
|
|
|
async def test_join_replies_in_command_channel_and_quit_closes_sink(self):
|
|
|
# Charger uniquement la fonction : aucun token ni connexion Discord.
|
|
|
tree = ast.parse(Path(__file__).with_name('chatbot.py').read_text(encoding='utf-8'))
|