현재 작업 전체 반영

This commit is contained in:
Yun Chan 2026-06-27 16:08:41 +09:00
parent 5560638e54
commit c0dddab594
85 changed files with 11322 additions and 539 deletions

View file

@ -32,6 +32,17 @@ class FakeEvaluationConn:
raise AssertionError(f"unexpected fetchval query: {query}")
class FakeAcquire:
def __init__(self, conn: FakeEvaluationConn) -> None:
self.conn = conn
async def __aenter__(self) -> FakeEvaluationConn:
return self.conn
async def __aexit__(self, exc_type: object, exc: object, tb: object) -> None:
return None
class EvaluationPersistenceMappingTest(unittest.TestCase):
def test_feedback_rows_preserve_review_scalar_contract(self) -> None:
evaluation = {
@ -126,6 +137,13 @@ class EvaluationPersistenceMappingTest(unittest.TestCase):
},
}
],
alternative_rows=[
{
"turn_id": "11111111-1111-1111-1111-111111111111",
"suggestion": "감정을 먼저 반영해 보세요.",
"rationale": None,
}
],
)
ev = rebuilt["11111111-1111-1111-1111-111111111111"]
@ -137,6 +155,7 @@ class EvaluationPersistenceMappingTest(unittest.TestCase):
self.assertEqual(ev["techniques"][0]["rationale"], "정서 반영이 포함됐다.")
self.assertEqual(ev["client_state_read"][0]["label_ko"], "방어")
self.assertEqual(ev["intent_deviation"]["dimension"], "pacing")
self.assertEqual(ev["alternative_utterances"], ["감정을 먼저 반영해 보세요."])
def test_evaluation_rls_blocks_raw_learner_writes(self) -> None:
root = Path(__file__).resolve().parents[3]
@ -158,6 +177,43 @@ class EvaluationPersistenceMappingTest(unittest.TestCase):
class EvaluationPersistenceIOTest(unittest.IsolatedAsyncioTestCase):
async def test_record_llm_call_audit_inserts_metadata_only(self) -> None:
conn = FakeEvaluationConn()
payload = {
"session_id": "11111111-1111-1111-1111-111111111111",
"provider": "claude_cli",
"model": "sonnet",
"tokens_in": 120,
"tokens_out": 45,
"cost_usd": 0.0123,
"inference_geo": "us",
"latency_ms": 345,
"messages": [{"content": "raw prompt must not be persisted"}],
}
with (
patch.object(session_persistence, "get_pool", return_value=object()),
patch.object(session_persistence, "acquire", return_value=FakeAcquire(conn)) as acquire,
):
ok = await session_persistence.record_llm_call_audit(payload)
self.assertTrue(ok)
acquire.assert_called_once_with(ai_context=True, ai_view="evaluator")
self.assertEqual(len(conn.executed), 1)
query, args = conn.executed[0]
self.assertIn("INSERT INTO audit.llm_call_log", query)
self.assertNotIn("raw prompt", query)
self.assertNotIn("messages", query)
self.assertEqual(args[0], "11111111-1111-1111-1111-111111111111")
self.assertIsNone(args[1])
self.assertEqual(args[2], "claude_cli")
self.assertEqual(args[3], "sonnet")
self.assertEqual(args[4], 120)
self.assertEqual(args[5], 45)
self.assertEqual(args[6], 0.0123)
self.assertEqual(args[7], "us")
self.assertEqual(args[8], 345)
async def test_persist_turn_evaluation_uses_evaluator_context_and_real_fast_tables(self) -> None:
conn = FakeEvaluationConn()
evaluation = {
@ -187,6 +243,7 @@ class EvaluationPersistenceIOTest(unittest.IsolatedAsyncioTestCase):
"actual": "조언",
"severity": "minor",
},
"alternative_utterances": ["감정을 먼저 반영해 보세요."],
}
await session_persistence._persist_turn_evaluation(
@ -202,7 +259,8 @@ class EvaluationPersistenceIOTest(unittest.IsolatedAsyncioTestCase):
self.assertIn("INSERT INTO app.turn_technique", executed_sql)
self.assertIn("INSERT INTO app.turn_client_state", executed_sql)
self.assertIn("INSERT INTO app.supervisor_comment", executed_sql)
self.assertNotIn("app.alternative_utterance", executed_sql)
self.assertIn("DELETE FROM app.alternative_utterance", executed_sql)
self.assertIn("INSERT INTO app.alternative_utterance", executed_sql)
async def test_route_loader_only_hydrates_when_requested(self) -> None:
principal = Principal(