"""Expression guardrails and deterministic receipts; no live API or user data.""" from pathlib import Path import sys from types import SimpleNamespace import unittest from unittest.mock import MagicMock BASE = Path(__file__).resolve().parents[1] sys.path[:0] = [str(BASE / 'bot-utility'), str(BASE)] import agent_loop from agent import ToolExecutor, ToolContext from chat import engine class AntiDialogueStyleTests(unittest.IsolatedAsyncioTestCase): def test_all_requested_counterexamples_and_templates_are_explicit(self): prompt = engine.load_instruction('style_instructions.txt') phrases = ['这句话稳', '比之前的都重', '我记下了', '我记得了', '我记住了', '这个账我记住了', '比之前的都轻', '睡吧,我守着', '你去,我跟', '问别人还是问自己', '行,xxx', '什么心思都写着xx上', '这句话接的漂亮', '行,我认', '这句话我不接', 'xx比xx沉', 'xx比xx重', 'xx比xx稳', 'xx比xx轻', '没接你的xxx', '比之前的都强', '他记得这事', '这话我留着', '很平', '稳', '我不拦', '我跟', '回去睡', '你这句话我记着', '认你', '我不催你', '这话是ta告诉你的,还是你自己想明白的', '认下来', '声音没抖,但比刚才稳', '比刚才轻', '比刚才重', '比刚才平', '很直', '这话我记下了', '这话我收下了', '说的比谁都响', '认这个', '收不回去', '认得实', 'xx就是认了', '你自己掂量', '没接你那句xx', '不催', '你掂量'] for phrase in phrases: with self.subTest(phrase=phrase): self.assertIn(phrase, prompt) for principle in ('同义改写', '按共同结构识别', '即使历史里的白花曾这样说', '直接谈具体对象', '不是可模仿', '单个汉字全部封禁', '用户既定称呼', '不知道该怎么接', '不要评论自己如何接话'): self.assertIn(principle, prompt) def test_builtin_default_is_exactly_the_deployed_expression_file(self): actual = engine.load_instruction('style_instructions.txt') self.assertEqual(actual.strip(), engine.DEFAULT_STYLE_INSTRUCTIONS.strip()) self.assertIn('禁用:关系暗语式短应答与话语评断腔', engine.BASE_PROMPT) def test_success_fallback_does_not_repeat_memory_acknowledgements(self): result = {'tool':'wardrobe', 'action':'add', 'ok':True, 'data':{'item':{'id':'internal-id', 'name':'蓝色短裙', 'description':'不复述的完整细节'}}} output = agent_loop._message_text(agent_loop._fallback_parsed([result])) self.assertIn('蓝色短裙已经在衣柜里', output) for phrase in ('我记', '这话', '我认', '行,', 'internal-id', '不复述的完整细节', '{'): self.assertNotIn(phrase, output) def test_polishing_summary_describes_saved_outcome_not_relationship(self): output = agent_loop._polish_facts([{'tool':'wardrobe', 'action':'add', 'ok':True, 'data':{'item':{'id':'internal', 'name':'蓝色短裙'}}}]) self.assertIn('保存衣物到衣柜', output) self.assertNotIn('记住衣物', output) async def test_tool_receipt_is_factual_not_a_memory_performance(self): item = {'id':'123456789abc', 'name':'蓝色短裙', 'category':'短裙', 'description':'白色环绕条纹'} store = SimpleNamespace(add=lambda *args: item) executor = ToolExecutor(artifacts=MagicMock(), modules={'wardrobe':SimpleNamespace(wardrobe=store)}) ctx = ToolContext(SimpleNamespace(name='tg'), 'private', 42, 42) result = await executor.execute('wardrobe', {'action':'add','params':{'name':'蓝色短裙'}}, ctx) self.assertTrue(result.ok) self.assertIn('已保存到衣柜', result.safe_message) self.assertNotIn('记住', result.safe_message) self.assertEqual(result.data['item']['description'], '白色环绕条纹') if __name__ == '__main__': unittest.main()