회기 연속성과 멀티 케이스 계약을 영속화

This commit is contained in:
Yun Chan 2026-09-01 11:45:16 +09:00
parent be08c0b573
commit 72353ecd82
26 changed files with 2170 additions and 127 deletions

View file

@ -9,6 +9,7 @@ from typing import Any
from unittest.mock import AsyncMock, patch
from .config import settings
from . import session_evaluation_timeout
from .routes import sessions
from .services import notifications, state_machine
from .services.persona import P1
@ -209,6 +210,39 @@ class NotificationTriggerTest(unittest.IsolatedAsyncioTestCase):
self.assertEqual(saved_write.status, "error")
self.assertEqual(saved_write.error, "session evaluation timeout after 1s")
async def test_session_evaluation_forwards_transport_and_audit_budget_after_deep_deadline(self) -> None:
sess = _ended_session()
result = sessions.evaluator.SessionEvaluation(
session_id=sess.session_id,
stage=sess.state.stage.value,
scope="session_end",
turns_evaluated=len(sess.turns),
)
with (
patched_settings(session_evaluation_timeout=300.0, db_command_timeout=30.0),
patch.object(
sessions.evaluator,
"evaluate_session",
AsyncMock(return_value=result),
) as evaluate_session,
patch.object(
sessions.session_persistence,
"save_session_evaluation",
AsyncMock(return_value=True),
),
patch.object(
sessions.notifications,
"enqueue_session_review_ready",
AsyncMock(),
),
patch.object(sessions.asyncio, "wait_for", wraps=asyncio.wait_for) as wait_for,
):
await sessions._generate_and_save_session_evaluation(sess)
self.assertEqual(evaluate_session.await_args.kwargs["timeout"], 330.0)
self.assertEqual(wait_for.await_args.kwargs["timeout"], 365.0)
async def test_scheduled_session_evaluation_task_crash_is_observed(self) -> None:
sess = _ended_session()
@ -245,11 +279,30 @@ class NotificationTriggerTest(unittest.IsolatedAsyncioTestCase):
) as schedule_evaluation,
):
scheduled = await sessions.recover_missing_session_evaluations(limit=2)
expected_stale_after = session_evaluation_timeout.session_evaluation_stale_after_seconds()
self.assertEqual(scheduled, 1)
list_missing.assert_awaited_once_with(older_than_seconds=40.0, limit=2)
list_missing.assert_awaited_once_with(
older_than_seconds=expected_stale_after,
limit=2,
)
schedule_evaluation.assert_called_once_with(sess)
def test_stale_deadline_follows_outer_completion_and_db_save_budget(self) -> None:
with patched_settings(session_evaluation_timeout=300.0, db_command_timeout=30.0):
self.assertEqual(
session_evaluation_timeout.session_evaluation_transport_timeout_seconds(),
330.0,
)
self.assertEqual(
session_evaluation_timeout.session_evaluation_outer_timeout_seconds(),
365.0,
)
self.assertEqual(
session_evaluation_timeout.session_evaluation_stale_after_seconds(),
400.0,
)
async def test_missing_session_evaluation_recovery_requires_durable_store(self) -> None:
sess = _ended_session()