현재 작업 전체 반영
This commit is contained in:
parent
5560638e54
commit
c0dddab594
85 changed files with 11322 additions and 539 deletions
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue