File size: 1,347 Bytes
95a8a23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import ast
import re
import unittest
from pathlib import Path


def load_sanitizer():
    source = Path(__file__).resolve().parents[1] / "ui_server.py"
    tree = ast.parse(source.read_text(encoding="utf-8"))
    function = next(
        node
        for node in tree.body
        if isinstance(node, ast.FunctionDef) and node.name == "_sanitize_final_answer"
    )
    namespace = {"re": re}
    exec(compile(ast.Module(body=[function], type_ignores=[]), str(source), "exec"), namespace)
    return namespace["_sanitize_final_answer"]


sanitize = load_sanitizer()


class OutputSanitizerTests(unittest.TestCase):
    def test_rejects_literal_function_call_markup(self):
        raw = '''我需要查询数据,让我调用工具。<function_calls>
<invoke name="mcp_marine_fisheries_inventory">
<parameter name="query">IATTC</parameter>
</invoke>
</function_calls>'''
        self.assertEqual(sanitize(raw), "")

    def test_keeps_final_answer_and_removes_trailing_markup(self):
        raw = '''【FINAL】IATTC 数据已确认存在。
<function_calls><invoke name="x"></invoke></function_calls>'''
        self.assertEqual(sanitize(raw), "IATTC 数据已确认存在。")

    def test_keeps_normal_answer(self):
        self.assertEqual(sanitize("【FINAL】正常回答"), "正常回答")


if __name__ == "__main__":
    unittest.main()