회기 연속성과 멀티 케이스 계약을 영속화
This commit is contained in:
parent
be08c0b573
commit
72353ecd82
26 changed files with 2170 additions and 127 deletions
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue