feat(voice): the answer streams unless the body opts out
This commit is contained in:
+22
-8
@@ -33,6 +33,8 @@ ASK = {
|
||||
"request_id": "3fd0d6ed-a81b-489c-a1d2-3b97ba84892b",
|
||||
"content": "ало клод как дела",
|
||||
}
|
||||
PLAIN = {**ASK, "stream": False}
|
||||
"""То же, но одним JSON: без поля фронтенд стримит."""
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -161,7 +163,7 @@ async def test_the_payload_is_answered_and_its_fields_come_back() -> None:
|
||||
conversations = FakeConversations()
|
||||
frontend, _ = stand(conversations)
|
||||
async with client(frontend) as http:
|
||||
response = await http.post("/", json=ASK, headers=VOICE)
|
||||
response = await http.post("/", json=PLAIN, headers=VOICE)
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {
|
||||
"request_id": ASK["request_id"],
|
||||
@@ -177,9 +179,9 @@ async def test_the_first_ask_opens_the_branch_and_the_next_one_keeps_it() -> Non
|
||||
conversations = FakeConversations()
|
||||
frontend, _ = stand(conversations)
|
||||
async with client(frontend) as http:
|
||||
first = (await http.post("/", json=ASK, headers=VOICE)).json()
|
||||
first = (await http.post("/", json=PLAIN, headers=VOICE)).json()
|
||||
again = (
|
||||
await http.post("/", json={**ASK, "content": "а время?"}, headers=VOICE)
|
||||
await http.post("/", json={**PLAIN, "content": "а время?"}, headers=VOICE)
|
||||
).json()
|
||||
assert first["conversation"] == again["conversation"]
|
||||
assert len(conversations.spawned) == 1
|
||||
@@ -195,7 +197,7 @@ async def test_the_question_lands_in_the_branch_first() -> None:
|
||||
conversations = FakeConversations()
|
||||
frontend, _ = stand(conversations)
|
||||
async with client(frontend) as http:
|
||||
await http.post("/", json=ASK, headers=VOICE)
|
||||
await http.post("/", json=PLAIN, headers=VOICE)
|
||||
assert conversations.said == [("conv-2", "🎤 andreii · esp32-1\nало клод как дела")]
|
||||
|
||||
|
||||
@@ -204,8 +206,8 @@ async def test_two_rooms_at_once_open_one_branch() -> None:
|
||||
frontend, _ = stand(conversations)
|
||||
async with client(frontend) as http:
|
||||
await asyncio.gather(
|
||||
http.post("/", json=ASK, headers=VOICE),
|
||||
http.post("/", json={**ASK, "room": "кухня"}, headers=VOICE),
|
||||
http.post("/", json=PLAIN, headers=VOICE),
|
||||
http.post("/", json={**PLAIN, "room": "кухня"}, headers=VOICE),
|
||||
)
|
||||
assert len(conversations.spawned) == 1
|
||||
|
||||
@@ -273,13 +275,13 @@ def test_the_voice_agent_gets_no_recall_and_no_reply_log(tmp_path) -> None:
|
||||
assert not (tmp_path / "реплики").exists()
|
||||
|
||||
|
||||
async def test_a_streaming_ask_gets_the_answer_in_pieces() -> None:
|
||||
async def test_the_answer_streams_when_the_body_does_not_say_otherwise() -> None:
|
||||
conversations = FakeConversations()
|
||||
frontend, _ = stand(conversations)
|
||||
frames: list[tuple[str, dict[str, Any]]] = []
|
||||
async with (
|
||||
client(frontend) as http,
|
||||
http.stream("POST", "/", json={**ASK, "stream": True}, headers=VOICE) as sse,
|
||||
http.stream("POST", "/", json=ASK, headers=VOICE) as sse,
|
||||
):
|
||||
assert sse.status_code == 200
|
||||
assert sse.headers["content-type"].startswith("text/event-stream")
|
||||
@@ -292,3 +294,15 @@ async def test_a_streaming_ask_gets_the_answer_in_pieces() -> None:
|
||||
assert [f["text"] for _, f in frames[:2]] == ["живу, ", "слушаю"]
|
||||
assert frames[-1][1]["reply"] == "живу, слушаю"
|
||||
assert frames[-1][1]["request_id"] == ASK["request_id"]
|
||||
|
||||
|
||||
async def test_the_flag_is_read_as_a_word_not_as_a_truthy_string() -> None:
|
||||
frontend, _ = stand(FakeConversations())
|
||||
cases = ((True, True), ("true", True), (False, False), ("false", False), (0, False))
|
||||
async with client(frontend) as http:
|
||||
for value, streams in cases:
|
||||
response = await http.post(
|
||||
"/", json={**ASK, "stream": value}, headers=VOICE
|
||||
)
|
||||
kind = response.headers["content-type"]
|
||||
assert kind.startswith("text/event-stream") is streams, (value, kind)
|
||||
|
||||
Reference in New Issue
Block a user