Update tools/bioportal_tool.py
Browse files- tools/bioportal_tool.py +41 -0
tools/bioportal_tool.py
CHANGED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from langchain.tools import BaseTool
|
2 |
+
from typing import Type, Optional
|
3 |
+
from pydantic import BaseModel, Field
|
4 |
+
from clinical_nlp.umls_bioportal import search_bioportal_term
|
5 |
+
from services.logger import app_logger
|
6 |
+
from services.metrics import log_tool_usage
|
7 |
+
|
8 |
+
class BioPortalInput(BaseModel):
|
9 |
+
term: str = Field(description="The medical term to search for.")
|
10 |
+
ontology: Optional[str] = Field(default="SNOMEDCT", description="The specific ontology to search within BioPortal (e.g., SNOMEDCT, ICD10, RxNorm). Defaults to SNOMEDCT.")
|
11 |
+
|
12 |
+
class BioPortalLookupTool(BaseTool):
|
13 |
+
name: str = "bioportal_lookup"
|
14 |
+
description: str = (
|
15 |
+
"Useful for searching medical terms, codes, and definitions across various ontologies "
|
16 |
+
"via BioPortal. Specify the term and optionally the ontology (e.g., SNOMEDCT, ICD10CM, RxNorm)."
|
17 |
+
)
|
18 |
+
args_schema: Type[BaseModel] = BioPortalInput
|
19 |
+
|
20 |
+
def _run(self, term: str, ontology: Optional[str] = "SNOMEDCT") -> str:
|
21 |
+
app_logger.info(f"BioPortal Tool called with term: {term}, ontology: {ontology}")
|
22 |
+
log_tool_usage(self.name)
|
23 |
+
results = search_bioportal_term(term, ontology=ontology or "SNOMEDCT")
|
24 |
+
if "error" in results:
|
25 |
+
return f"Error from BioPortal lookup: {results['error']}"
|
26 |
+
|
27 |
+
# Format results for LLM consumption
|
28 |
+
collection = results.get("collection", [])
|
29 |
+
if collection:
|
30 |
+
formatted_results = []
|
31 |
+
for item in collection[:3]: # Limit to 3 results
|
32 |
+
defs = item.get('definition', ['N/A'])
|
33 |
+
definition_str = "; ".join(defs) if defs else "N/A"
|
34 |
+
formatted_results.append(
|
35 |
+
f"- Term: {item.get('prefLabel', 'N/A')}, Definition: {definition_str}, CUIs: {item.get('cui', [])}"
|
36 |
+
)
|
37 |
+
return f"BioPortal Results (Ontology: {ontology}):\n" + "\n".join(formatted_results)
|
38 |
+
return f"No results found in BioPortal for ontology {ontology}."
|
39 |
+
|
40 |
+
async def _arun(self, term: str, ontology: Optional[str] = "SNOMEDCT") -> str:
|
41 |
+
return self._run(term, ontology)
|