46 lines
1.9 KiB
Python
46 lines
1.9 KiB
Python
from __future__ import annotations
|
||
|
||
from app.modules.rag.intent_router_v2.models import ConversationState, IntentDecision
|
||
|
||
|
||
class ConversationPolicy:
|
||
_SWITCH_MARKERS = (
|
||
"теперь",
|
||
"а теперь",
|
||
"давай теперь",
|
||
"переключ",
|
||
"new task",
|
||
"switch to",
|
||
"instead",
|
||
)
|
||
_DOCS_SIGNALS = ("документац", "readme", "docs/", ".md")
|
||
_CODE_SIGNALS = ("по коду", "класс", "метод", "файл", "блок кода", "function", "class")
|
||
|
||
def resolve(self, decision: IntentDecision, user_query: str, conversation_state: ConversationState) -> tuple[str, str]:
|
||
active_intent = conversation_state.active_intent
|
||
if active_intent is None:
|
||
return decision.intent, "START"
|
||
if active_intent == decision.intent:
|
||
return active_intent, "CONTINUE"
|
||
if self._has_explicit_switch(user_query):
|
||
return decision.intent, "SWITCH"
|
||
if self._is_hard_mismatch(active_intent, decision.intent, user_query):
|
||
return decision.intent, "SWITCH"
|
||
return active_intent, "CONTINUE"
|
||
|
||
def _has_explicit_switch(self, user_query: str) -> bool:
|
||
text = " ".join((user_query or "").lower().split())
|
||
return any(marker in text for marker in self._SWITCH_MARKERS)
|
||
|
||
def _is_hard_mismatch(self, active_intent: str, candidate_intent: str, user_query: str) -> bool:
|
||
if active_intent == candidate_intent:
|
||
return False
|
||
text = " ".join((user_query or "").lower().split())
|
||
if candidate_intent == "GENERATE_DOCS_FROM_CODE":
|
||
return True
|
||
if candidate_intent == "DOCS_QA":
|
||
return any(signal in text for signal in self._DOCS_SIGNALS)
|
||
if candidate_intent == "CODE_QA" and active_intent == "DOCS_QA":
|
||
return any(signal in text for signal in self._CODE_SIGNALS)
|
||
return False
|