Ask several questions on one card
One `ask_user` call can now carry several questions, and they come back in a single submit. Asking one at a time cost a round trip and an interruption each, and by the third you had forgotten the first. Each question becomes an item with its own key; several items share a call index, because they belong to one call and one tool turn has to answer them all. Each answer is quoted beside the question it belongs to -- with four on a card, a bare list would leave the model matching them up by position and sometimes getting it wrong. Options are radios rather than submit buttons, so picking one does not send the form while two other questions are still blank. What you type beats what you picked: someone who writes in the box after clicking an option meant the writing. `_questions_in` also reads the shapes a small model actually sends -- a bare `question` string, a list of plain strings, one object where a list belonged. Getting that wrong costs a whole round trip and shows a card saying nothing. Two test fixes, both mine. `test_posting_a_message_stores_both_turns` raced the background generation it started: against a connection that refuses instantly the reply sometimes won, writing the error and marking the row complete before the assertions could read it. And the generation registry is module-global, so a test that started a reply left an entry -- and a Task belonging to a closed event loop -- for the rest of the session. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -58,6 +58,28 @@ def fresh_database(tmp_path: Path) -> Iterator[None]:
|
||||
reset_engine()
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def fresh_generation_registry() -> Iterator[None]:
|
||||
"""Empty the in-flight reply registry between tests.
|
||||
|
||||
`_RUNNING` and `_TASKS` are module-level dicts, so a test that starts a
|
||||
reply and does not wait for it leaves an entry behind for the rest of the
|
||||
session -- holding a Generation, and a Task belonging to an event loop that
|
||||
has since closed. `_prune()` will not clear it either: it only drops
|
||||
generations that have finished, and it runs on every `ensure()`.
|
||||
|
||||
Cheap, and it keeps a test that posts a message from meeting the leftovers
|
||||
of one that asked a question.
|
||||
"""
|
||||
from lembas.services import generation as generation_service
|
||||
|
||||
generation_service._RUNNING.clear()
|
||||
generation_service._TASKS.clear()
|
||||
yield
|
||||
generation_service._RUNNING.clear()
|
||||
generation_service._TASKS.clear()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def db() -> Iterator[Session]:
|
||||
session = get_session_factory()()
|
||||
|
||||
Reference in New Issue
Block a user