feat: 운영 안정성과 세션 음성 경험 개선
This commit is contained in:
parent
facc4ad2d9
commit
c788343467
95 changed files with 8431 additions and 1785 deletions
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import unittest
|
||||
from types import SimpleNamespace
|
||||
|
|
@ -609,6 +610,8 @@ class SessionTurnPersistenceTest(unittest.IsolatedAsyncioTestCase):
|
|||
principal,
|
||||
)
|
||||
await _consume_event_source(response)
|
||||
if sessions._STREAM_TURN_EVALUATION_TASKS:
|
||||
await asyncio.gather(*tuple(sessions._STREAM_TURN_EVALUATION_TASKS))
|
||||
|
||||
self.assertEqual(len(sess.turns), 2)
|
||||
learner_turn, client_turn = sess.turns
|
||||
|
|
@ -620,6 +623,65 @@ class SessionTurnPersistenceTest(unittest.IsolatedAsyncioTestCase):
|
|||
)
|
||||
self.assertIsNone(client_turn.evaluation)
|
||||
|
||||
async def test_stream_turn_done_does_not_wait_for_fast_loop_evaluation(
|
||||
self,
|
||||
) -> None:
|
||||
principal = _principal()
|
||||
sess = _session(principal)
|
||||
evaluation_started = asyncio.Event()
|
||||
release_evaluation = asyncio.Event()
|
||||
|
||||
async def successful_stream(ctx, engine, **kwargs):
|
||||
assert ctx.state_after is not None
|
||||
yield orchestrator.StreamEvent("token", {"text": "지금 답할게요."})
|
||||
yield orchestrator.StreamEvent(
|
||||
"done",
|
||||
{
|
||||
"session_id": ctx.session_id,
|
||||
"turn_seq": ctx.state_after.turn_seq,
|
||||
"safety_flagged": False,
|
||||
"llm_provider": "claude_cli",
|
||||
"model": "gateway-default",
|
||||
},
|
||||
)
|
||||
|
||||
async def slow_eval_hook(ctx, client_reply):
|
||||
evaluation_started.set()
|
||||
await release_evaluation.wait()
|
||||
return {
|
||||
"loop": "fast",
|
||||
"turn_seq": ctx.state_after.turn_seq,
|
||||
"stage": ctx.state_after.stage.value,
|
||||
"appropriateness": "pos",
|
||||
}
|
||||
|
||||
with (
|
||||
patch.object(sessions.orchestrator, "run_turn_stream", successful_stream),
|
||||
patch.object(
|
||||
sessions.evaluator,
|
||||
"make_eval_hook",
|
||||
return_value=slow_eval_hook,
|
||||
),
|
||||
):
|
||||
response = await sessions.stream_turn(
|
||||
sess.session_id,
|
||||
sessions.TurnRequest(text="평가를 기다리지 않는 발화"),
|
||||
principal,
|
||||
)
|
||||
consume_task = asyncio.create_task(_consume_event_source(response))
|
||||
await asyncio.wait_for(evaluation_started.wait(), timeout=1)
|
||||
body = await asyncio.wait_for(consume_task, timeout=0.2)
|
||||
|
||||
self.assertIn("'event': 'done'", body.decode("utf-8"))
|
||||
self.assertEqual(len(sess.turns), 2)
|
||||
self.assertIsNone(sess.turns[0].evaluation)
|
||||
|
||||
release_evaluation.set()
|
||||
if sessions._STREAM_TURN_EVALUATION_TASKS:
|
||||
await asyncio.gather(*tuple(sessions._STREAM_TURN_EVALUATION_TASKS))
|
||||
|
||||
self.assertEqual(sess.turns[0].evaluation["appropriateness"], "pos")
|
||||
|
||||
async def test_stream_turn_surfaces_fast_loop_evaluation_failure_on_review(
|
||||
self,
|
||||
) -> None:
|
||||
|
|
@ -662,6 +724,8 @@ class SessionTurnPersistenceTest(unittest.IsolatedAsyncioTestCase):
|
|||
principal,
|
||||
)
|
||||
await _consume_event_source(response)
|
||||
if sessions._STREAM_TURN_EVALUATION_TASKS:
|
||||
await asyncio.gather(*tuple(sessions._STREAM_TURN_EVALUATION_TASKS))
|
||||
|
||||
self.assertEqual(len(sess.turns), 2)
|
||||
learner_turn = sess.turns[0]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue