@@ -1368,6 +1368,91 @@ def mock_llm(system, user):
13681368 answer = safe_solve ("What is 6 * 7?" , llm_fn = mock_llm )
13691369 assert answer == "42"
13701370
1371+ # ── safe_solve exact-answer enforcement ───────────────
1372+ print ("\n ── safe_solve exact-answer enforcement ─────────" )
1373+
1374+ @test ("safe_solve: strips markdown code fences" )
1375+ def _ ():
1376+ def mock_llm (s , u ): return "```\n 42\n ```"
1377+ assert safe_solve ("What is 6*7?" , llm_fn = mock_llm ) == "42"
1378+
1379+ @test ("safe_solve: strips code fence with language tag" )
1380+ def _ ():
1381+ def mock_llm (s , u ): return "```text\n HELLO\n ```"
1382+ assert safe_solve ("Reverse OLLEH" , llm_fn = mock_llm ) == "HELLO"
1383+
1384+ @test ("safe_solve: strips surrounding double quotes" )
1385+ def _ ():
1386+ def mock_llm (s , u ): return '"42"'
1387+ assert safe_solve ("What is 6*7?" , llm_fn = mock_llm ) == "42"
1388+
1389+ @test ("safe_solve: strips surrounding single quotes" )
1390+ def _ ():
1391+ def mock_llm (s , u ): return "'HELLO'"
1392+ assert safe_solve ("Reverse OLLEH" , llm_fn = mock_llm ) == "HELLO"
1393+
1394+ @test ("safe_solve: strips surrounding backticks" )
1395+ def _ ():
1396+ def mock_llm (s , u ): return "`42`"
1397+ assert safe_solve ("What is 6*7?" , llm_fn = mock_llm ) == "42"
1398+
1399+ @test ("safe_solve: multi-line takes first non-empty line" )
1400+ def _ ():
1401+ def mock_llm (s , u ): return "42\n This is my explanation"
1402+ assert safe_solve ("What is 6*7?" , llm_fn = mock_llm ) == "42"
1403+
1404+ @test ("safe_solve: extracts answer from 'the answer is X'" )
1405+ def _ ():
1406+ def mock_llm (s , u ): return "the answer is 42"
1407+ assert safe_solve ("What is 6*7?" , llm_fn = mock_llm ) == "42"
1408+
1409+ @test ("safe_solve: extracts answer from 'the result is: X'" )
1410+ def _ ():
1411+ def mock_llm (s , u ): return "the result is: HELLO"
1412+ assert safe_solve ("Reverse OLLEH" , llm_fn = mock_llm ) == "HELLO"
1413+
1414+ @test ("safe_solve: extracts answer from 'therefore X'" )
1415+ def _ ():
1416+ def mock_llm (s , u ): return "therefore 42"
1417+ assert safe_solve ("What is 6*7?" , llm_fn = mock_llm ) == "42"
1418+
1419+ @test ("safe_solve: strips quotes after explanation extraction" )
1420+ def _ ():
1421+ def mock_llm (s , u ): return 'the answer is "42"'
1422+ assert safe_solve ("What is 6*7?" , llm_fn = mock_llm ) == "42"
1423+
1424+ @test ("safe_solve: blocks import statement in answer" )
1425+ def _ ():
1426+ def mock_llm (s , u ): return "import os"
1427+ try :
1428+ safe_solve ("What is 2+2?" , llm_fn = mock_llm )
1429+ assert False , "Should have raised"
1430+ except ValueError as e :
1431+ assert "suspicious" in str (e ).lower ()
1432+
1433+ @test ("safe_solve: blocks require() in answer" )
1434+ def _ ():
1435+ def mock_llm (s , u ): return "require('fs')"
1436+ try :
1437+ safe_solve ("What is 2+2?" , llm_fn = mock_llm )
1438+ assert False , "Should have raised"
1439+ except ValueError as e :
1440+ assert "suspicious" in str (e ).lower ()
1441+
1442+ @test ("safe_solve: blocks __proto__ in answer" )
1443+ def _ ():
1444+ def mock_llm (s , u ): return "__proto__"
1445+ try :
1446+ safe_solve ("What is 2+2?" , llm_fn = mock_llm )
1447+ assert False , "Should have raised"
1448+ except ValueError as e :
1449+ assert "suspicious" in str (e ).lower ()
1450+
1451+ @test ("safe_solve: clean short answer passes through unchanged" )
1452+ def _ ():
1453+ def mock_llm (s , u ): return "KRPS"
1454+ assert safe_solve ("Reverse SPARK then remove vowels" , llm_fn = mock_llm ) == "KRPS"
1455+
13711456
13721457# ── prompt_builder Tests ──────────────────────────────
13731458print ("\n ── prompt_builder ──────────────────────────────" )
0 commit comments