Files
crypto_monitor/tests/test_ai_client_empty_content.py
T
dekun c2a40e3cc5 Fix empty AI review content from gemma reasoning token use.
Parse alternate reasoning fields, retry with a larger max_tokens budget, cap review images, and fall back to text-only when vision returns empty.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 13:21:06 +08:00

60 lines
1.8 KiB
Python

"""ai_client message parsing / empty-content retries."""
from __future__ import annotations
import sys
import unittest
from pathlib import Path
from unittest import mock
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
from lib.ai.ai_client import _openai_message_text, ai_review # noqa: E402
class TestOpenaiMessageText(unittest.TestCase):
def test_prefers_content(self):
self.assertEqual(
_openai_message_text({"content": "正文", "reasoning": "think"}),
"正文",
)
def test_falls_back_to_reasoning_content(self):
self.assertEqual(
_openai_message_text({"content": "", "reasoning_content": "备选正文"}),
"备选正文",
)
def test_skips_english_chain_of_thought(self):
self.assertEqual(
_openai_message_text(
{
"content": "",
"reasoning": "Here's a thinking process that leads to the answer...",
}
),
"",
)
class TestAiReviewImageCap(unittest.TestCase):
def test_caps_images_and_sets_max_tokens(self):
captured = {}
def fake_generate(prompt, **kwargs):
captured["prompt"] = prompt
captured.update(kwargs)
return "OK_REVIEW"
with mock.patch("lib.ai.ai_client.ai_generate", side_effect=fake_generate):
with mock.patch.dict("os.environ", {"AI_REVIEW_MAX_IMAGES": "2"}, clear=False):
out = ai_review("记录", "每日", image_paths=["a.png", "b.png", "c.png"])
self.assertIn("OK_REVIEW", out)
self.assertEqual(captured.get("image_paths"), ["a.png", "b.png"])
self.assertEqual(captured.get("max_tokens"), 8192)
self.assertIn("另跳过 1 张", out)
if __name__ == "__main__":
unittest.main()