Include utility modules, shared channels, prompts, read-only skills, wardrobe memory and regression tests. Externalize legacy credentials and exclude private runtime state.
68 lines
4.1 KiB
Python
68 lines
4.1 KiB
Python
"""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()
|