diff --git a/agent/negotiation/chat/service/chat_engine.py b/agent/negotiation/chat/service/chat_engine.py index 77e1790..a0bcb99 100644 --- a/agent/negotiation/chat/service/chat_engine.py +++ b/agent/negotiation/chat/service/chat_engine.py @@ -173,20 +173,24 @@ class ChatEngine: return "가격협상" def _pick_wildcard(self, session: ChatSession) -> str: - """앵커가 살짝 초과 구간에서 인하 압박 카드 선택. - - 앵커가에 아주 근접(≤ anchor*1.02): 1% 인하 요청(wild_card_1pct) → 앵커가 이하로 유도. - - 그 외: 목표 매입가 맞춰달라(wild_card_budget). + """앵커가에 아주 근접(≤ anchor*1.02)한 구간에서만 1% 인하 요청(wild_card_1pct)으로 + 앵커가 이하로 유도한다. 그 외 구간은 일반 가격협상(카드 플레이)으로 돌린다. + + 과거 여기서 반환하던 '재원부족'(wild_card_budget) 하드코딩 카드는 제거했다 — + 견적에서 실제 선택한 와일드카드(중간값 절충·목표가 선제안 등)와 매핑되지 않은 채 + '와일드카드를 하나라도 골랐으면' 조건만으로 발동해, 선택하지도 않은 재원부족 멘트가 + 노출되는 오작동이 있었다. """ ctx = session.context price = ctx.get("input_price", 0) anchor = ctx.get("anchor_price", 0) - ctx["wildcard_used"] = True if anchor > 0 and price <= anchor * 1.02: + # 와일드카드는 실제로 노출할 때만 '사용됨'으로 마킹한다 — 가격협상으로 돌아가는 + # 경우에도 마킹하면 이후 라운드에서 정당한 1% 카드까지 억제된다. + ctx["wildcard_used"] = True ctx["offer_1pct"] = int(round(price * 0.99)) # 1% 인하가 return "wild_card_1pct" - if not ctx.get("allow_selected_wildcards", True): - return "가격협상" - return "wild_card_budget" + return "가격협상" # ---- render -------------------------------------------------------- def vars_for(self, session: ChatSession) -> Dict[str, Any]: diff --git a/agent/tests/test_p7_chat.py b/agent/tests/test_p7_chat.py index 42fce19..866a926 100644 --- a/agent/tests/test_p7_chat.py +++ b/agent/tests/test_p7_chat.py @@ -2,7 +2,7 @@ 1. 전체 대화: 서비스안내→담당자확인→협상품목안내→가격협상→와일드카드→협상완료→협상종료(chat_end). 2. 가격협상 턴에서 카드 선택 + 학습(card_id, updated_q). -3. 와일드카드 발동(wild_card_budget) + 종료 보상(success). +3. 와일드카드 발동(wild_card_1pct) + 종료 보상(success). 4. 브랜드 치환 테넌트별(데모상사 A/B), 클린룸(스크립트에 KT 흔적 없음). 5. 경험로그 적재 + 종료 후 진행 시 에러. 6. (HTTP) 헤더로 새 세션 시작 + 한 턴 진행. @@ -46,8 +46,9 @@ async def test_full_conversation_reaches_completion(db_engine): reset_sessions() eng = await _reg().get_engine("ktcommerce") svc = ChatService() - # anchor=9900, target=10000(기본). 11000(>10395)→가격협상(카드), 10200(9900~10395)→와일드카드, 9800(≤anchor)→우선협상 - turns = [None, "확인", "예", "확인", "11000", "예", "10200", "예", "9800", "예", + # anchor=9900, target=10000(기본). 11000(>anchor*1.02)→가격협상(카드), + # 10000(anchor