Fix live multi-turn: pass the resolved drug, stop did-you-mean garbage

This commit is contained in:
2026-08-05 16:54:35 +07:00
parent ef08b4929e
commit 1e8cbdb586
29 changed files with 2013 additions and 83 deletions
+39 -6
View File
@@ -181,12 +181,10 @@ class QueryRoutingService:
self._retrieval = retrieval
self._resolver = resolver
def retrieve(
self,
query: str,
subject_scope: SubjectScope = SubjectScope.UNKNOWN,
intent: QueryIntent = QueryIntent.UNKNOWN,
) -> RetrievalResult:
@staticmethod
def _scope_gate(
subject_scope: SubjectScope, intent: QueryIntent
) -> RetrievalResult | None:
# Scope comes from the API/policy layer. Unknown is deliberately
# fail-closed; retrieval must not infer clinical scope from keywords.
if subject_scope == SubjectScope.NON_HUMAN:
@@ -197,6 +195,41 @@ class QueryRoutingService:
return RetrievalResult(EvidenceDecision.ABSTAIN, "recommendation_out_of_scope")
if intent == QueryIntent.UNKNOWN:
return RetrievalResult(EvidenceDecision.ABSTAIN, "query_intent_unknown")
return None
def retrieve_for_drug(
self,
query: str,
drug_id: str,
subject_scope: SubjectScope = SubjectScope.UNKNOWN,
intent: QueryIntent = QueryIntent.UNKNOWN,
) -> RetrievalResult:
"""Retrieve for an ALREADY-resolved drug, skipping name resolution.
The conversational layer has already resolved (and possibly inherited)
the drug; re-resolving from the rewritten turn text is what produced the
`drug_resolution_ambiguous` empty answers on follow-ups. The query text
still drives section routing and the intro/overview decision.
"""
gate = self._scope_gate(subject_scope, intent)
if gate is not None:
return gate
result = self._retrieval.retrieve(query, drug_id)
return replace(
result,
resolved_drug_id=drug_id,
drug_resolution_status=DrugResolutionStatus.RESOLVED,
)
def retrieve(
self,
query: str,
subject_scope: SubjectScope = SubjectScope.UNKNOWN,
intent: QueryIntent = QueryIntent.UNKNOWN,
) -> RetrievalResult:
gate = self._scope_gate(subject_scope, intent)
if gate is not None:
return gate
resolution = self._resolver.resolve(query)
if resolution.status == DrugResolutionStatus.NOT_FOUND:
return RetrievalResult(