lost-found-desk / tests /test_conversation.py
JacobLinCool's picture
Deploy Lost & Found Desk
f1164d7 verified
Raw
History Blame Contribute Delete
3.52 kB
from lost_found_desk.conversation import build_summary, detect_language, plan_turn
def test_detect_language():
assert detect_language("我掉了一個黑色水壺") == "zh"
assert detect_language("I lost a black bottle") == "en"
assert detect_language("カバンをなくしました") == "zh" # CJK family
def _user(content):
return {"role": "user", "content": content}
def _assistant(content):
return {"role": "assistant", "content": content}
def test_unparseable_answers_progress_without_repeat():
"""Regression: even answers we cannot machine-parse must advance the flow.
The old English-keyword gate left such claims stuck on the same question
forever. The brain tracks which attributes it already asked about, so it
asks each at most once and then becomes ready — never repeating a question.
"""
conversation = [_assistant("seed")]
collecting = []
final = None
for msg in ["aaa", "bbb", "ccc", "ddd"]:
plan = plan_turn(conversation, msg) # no inventory -> generic collection
assert plan["assistant_message"]
assert msg in plan["summary"]
if plan["readiness_state"] == "collecting":
collecting.append(plan["assistant_message"])
conversation += [_user(msg), _assistant(plan["assistant_message"])]
final = plan
assert len(collecting) == len(set(collecting)), "a question was repeated"
assert final["readiness_state"] == "ready_for_staff_review"
def test_chinese_attributes_are_understood():
"""A Chinese description that already gives type+color shouldn't be re-asked
for them — only the remaining distinguishing detail."""
plan = plan_turn([_assistant("seed")], "我掉了一個黑色的水壺", _TWO_BOTTLES)
assert plan["readiness_state"] == "collecting"
assert plan["target"] == "distinctive"
def test_summary_accumulates_user_words():
conversation = [_assistant("seed"), _user("a navy hoodie"), _assistant("q")]
assert build_summary(conversation, "with a small logo") == "a navy hoodie with a small logo"
_TWO_BOTTLES = [
{"item_id": "b1", "status": "unclaimed", "caption": "black water bottle with a silver cap", "found_location": ""},
{"item_id": "b2", "status": "unclaimed", "caption": "blue water bottle with a dinosaur sticker", "found_location": ""},
]
def test_inventory_driven_disambiguation_asks_a_distinguishing_attribute():
# Two bottles that differ in color; the claimant only gave the type, so the
# follow-up should target a distinguishing attribute, not a fixed script.
plan = plan_turn([_assistant("seed")], "I lost a bottle", _TWO_BOTTLES)
assert plan["readiness_state"] == "collecting"
assert plan["target"] in {"color", "distinctive"}
def test_specific_description_is_ready_immediately():
plan = plan_turn([_assistant("seed")], "a black water bottle with a silver cap and a sticker", _TWO_BOTTLES)
assert plan["readiness_state"] == "ready_for_staff_review"
def test_chinese_with_inventory_progresses_without_repeat():
conversation = [_assistant("seed")]
seen = set()
final = None
for msg in ["我掉了一個水壺", "黑色的", "上面有貼紙"]:
plan = plan_turn(conversation, msg, _TWO_BOTTLES)
assert plan["assistant_message"] not in seen
seen.add(plan["assistant_message"])
conversation += [_user(msg), _assistant(plan["assistant_message"])]
final = plan
assert final["readiness_state"] == "ready_for_staff_review"