fix: Task6质量审查修复(MOQ全称/warranty/装柜量触发词+NO_CONTACT_WEB常量引用+阿语回显豁免锁+测试残词)
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -38,7 +38,8 @@ BOUNDARY_TRIGGER_RE = re.compile(
|
||||
r"price|pricing|how\s+much|\bcost\b|discount|cheaper|expensive|\bfee\b|"
|
||||
r"quote|quotation|shipping\s+(fee|cost|time)|freight|tariff|customs\s+fee|"
|
||||
r"best\s+offer|any\s+offer|free\s+shipping|"
|
||||
r"sample|certificat|\bmoq\b|container\s+loading|"
|
||||
r"sample|certificat|\bmoq\b|minimum\s+order|min\s+order|"
|
||||
r"container\s+loading|fit\s+in|per\s+container|warranty|质保|保修|"
|
||||
r"book(ing)?\s|reserv|arrange|"
|
||||
r"delivery|lead\s+time|arriv|"
|
||||
r"how\s+long\s+(does|will|would|to).*(take|arriv|deliver|ship)|"
|
||||
@@ -591,8 +592,7 @@ class ConversationManager:
|
||||
"绝对禁止输出任何号码或邮箱。")
|
||||
else:
|
||||
contact_note = ("⚠️ 客户正在索要我方联系方式(最高意向信号)。请逐字使用这句指路:"
|
||||
"\"Just tap the WhatsApp button at the top of this chat — "
|
||||
"our manager will reply within 12 hours!\"(邮箱同理指 Email 按钮)。"
|
||||
f"\"{NO_CONTACT_WEB}\"(邮箱同理指 Email 按钮)。"
|
||||
"绝对禁止口头报出任何号码或邮箱。")
|
||||
|
||||
if not raw_info:
|
||||
|
||||
@@ -329,3 +329,16 @@ def test_no_auto_wording_left_in_any_pool():
|
||||
for t in (pool if isinstance(pool, list) else [pool]):
|
||||
assert "cars" not in t.lower(), f"{name}: {t}"
|
||||
assert "什么车" not in t, f"{name}: {t}"
|
||||
|
||||
|
||||
def test_arabic_echo_exemption_consistent():
|
||||
ar_num = "".join(chr(c) for c in
|
||||
(0x0669, 0x0666, 0x0666, 0x0665, 0x0660, 0x0661,
|
||||
0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667)) # 966501234567
|
||||
# 阿语回显豁免一致性锁定(Task 6 质量审查): 客户用阿语数字留号,AI 无论
|
||||
# 回显阿语还是 ASCII 形态都豁免——两侧均经 digits_only(内含 translate)。
|
||||
# 阿语数字用码位构造,避免源文件编码事故。
|
||||
hist = [{"role": "user", "content": "my whatsapp is " + ar_num}]
|
||||
assert not no_contact_value("Got it — messaging you at " + ar_num, hist)
|
||||
assert not no_contact_value("Got it — messaging you at +966501234567", hist)
|
||||
assert no_contact_value("Reach me at 11987654321", hist) # 不同号(11位)仍拦
|
||||
|
||||
@@ -43,7 +43,7 @@ class FakeAI:
|
||||
|
||||
|
||||
INTERESTED = {
|
||||
"intent_level": "interested", "reasoning": "预算国家车型齐全",
|
||||
"intent_level": "interested", "reasoning": "预算国家品类齐全",
|
||||
"contact_info": {}, "info_sufficient": True,
|
||||
}
|
||||
|
||||
@@ -487,7 +487,7 @@ def test_reminder_boundary_covers_delivery_and_arrangement():
|
||||
{}, "my budget is 20000, any recommendation?", [])
|
||||
|
||||
|
||||
def test_reminder_no_boundary_on_normal_car_questions():
|
||||
def test_reminder_no_boundary_on_normal_product_questions():
|
||||
# 规格/配置/库存类正常问题不得误触发
|
||||
assert "职能边界" not in ConversationManager._build_context_reminder(
|
||||
{}, "what is the pressure rating of the PE100 pipe?", [])
|
||||
@@ -562,7 +562,7 @@ def test_clean_stream_passes_through(async_db, monkeypatch):
|
||||
(manager, conv), _ = _setup(async_db, monkeypatch, ai=FakeAI())
|
||||
events = []
|
||||
async def run():
|
||||
async for e in manager.stream_process_message(conv.session_id, "what cars?"):
|
||||
async for e in manager.stream_process_message(conv.session_id, "what pipes?"):
|
||||
events.append(e)
|
||||
asyncio.run(run())
|
||||
streamed = "".join(e.get("content", "") for e in events if e["type"] == "stream_chunk")
|
||||
@@ -613,7 +613,7 @@ def test_sentence_gating_clean_multi_sentence_passthrough(async_db, monkeypatch)
|
||||
(manager, conv), _ = _setup(async_db, monkeypatch, ai=TwoSentenceAI())
|
||||
events = []
|
||||
async def run():
|
||||
async for e in manager.stream_process_message(conv.session_id, "what cars?"):
|
||||
async for e in manager.stream_process_message(conv.session_id, "what pipes?"):
|
||||
events.append(e)
|
||||
asyncio.run(run())
|
||||
streamed = "".join(e.get("content", "") for e in events if e["type"] == "stream_chunk")
|
||||
|
||||
Reference in New Issue
Block a user