Fix ai-service Dockerfile: bake in drug_entities.json, override its path

This commit is contained in:
2026-08-10 10:35:13 +07:00
parent a4b8e1c4db
commit 60b4397032
51 changed files with 4302 additions and 2087 deletions
@@ -339,3 +339,78 @@ def test_recommendation_intent_is_refused_at_policy_boundary():
)
assert result.decision == EvidenceDecision.ABSTAIN
assert result.reason == "recommendation_out_of_scope"
class _IndicationRetriever:
"""A fake exposing only `find_by_indication`/`search_indication` (the
Qdrant adapter's shape for the reverse-lookup path), so
`retrieve_by_indication`'s own orchestration — keyword first, dense
fallback only when keyword finds nothing — is what's under test here,
not the matching algorithm itself (that's `test_qdrant_adapter.py`'s job)."""
def __init__(
self,
keyword_hits: list[SearchHit] | None = None,
dense_hits: list[SearchHit] | None = None,
) -> None:
self._keyword_hits = keyword_hits or []
self._dense_hits = dense_hits or []
self.dense_called = False
def find_by_indication(self, indication_text, limit): # noqa: ARG002
return self._keyword_hits
def search_indication(self, query, limit): # noqa: ARG002
self.dense_called = True
return self._dense_hits
def _indication_hit(drug_id: str) -> SearchHit:
return SearchHit(
document=RetrievalDocument(
doc_id=f"{drug_id}__chi_dinh__0", drug_id=drug_id, kind="prose",
section_key="chi_dinh", text="Điều trị sốt.", source_refs=(SOURCE,),
),
score=1.0,
)
def test_retrieve_by_indication_uses_keyword_hits_without_trying_dense():
retriever = _IndicationRetriever(keyword_hits=[_indication_hit("paracetamol_acetaminophen")])
service = RetrievalService(retriever, InMemoryParentStore([]))
result = service.retrieve_by_indication("sốt")
assert result.decision == EvidenceDecision.ANSWERABLE
assert len(result.evidence) == 1
assert retriever.dense_called is False
def test_retrieve_by_indication_falls_back_to_dense_only_when_keyword_is_empty():
retriever = _IndicationRetriever(dense_hits=[_indication_hit("ibuprofen")])
service = RetrievalService(retriever, InMemoryParentStore([]))
result = service.retrieve_by_indication("thân nhiệt tăng")
assert result.decision == EvidenceDecision.ANSWERABLE
assert retriever.dense_called is True
def test_retrieve_by_indication_with_no_match_anywhere_abstains():
retriever = _IndicationRetriever()
service = RetrievalService(retriever, InMemoryParentStore([]))
result = service.retrieve_by_indication("bệnh chưa từng ghi nhận")
assert result.decision == EvidenceDecision.ABSTAIN
assert result.reason == "no_indication_match"
def test_retrieve_by_indication_with_blank_text_abstains_without_calling_retrieval():
retriever = _IndicationRetriever(keyword_hits=[_indication_hit("paracetamol_acetaminophen")])
service = RetrievalService(retriever, InMemoryParentStore([]))
result = service.retrieve_by_indication(" ")
assert result.decision == EvidenceDecision.ABSTAIN
assert result.reason == "missing_indication"