from tools.base import Tool import json from tools.utils import load_prompt, ToolExecutionError, logger def call_llm(prompt): # Placeholder for the actual LLM call return f"History for: {prompt}" from typing import Any class HistoryTakingTool(Tool): def openai_spec(self, legacy=False): return { "name": self.name, "description": self.description, "parameters": self.args_schema } """ Tool to gather patient history for a specific syndrome using a dynamic schema. This tool loads a knowledge base entry for a syndrome, builds a dynamic argument schema based on required consult questions, and generates a prompt for an LLM or rules engine. """ def __init__(self, syndrome_key: str) -> None: """ Initialize the HistoryTakingTool for a given syndrome. Args: syndrome_key (str): The key identifying the syndrome in the knowledge base. Raises: ValueError: If the syndrome key is not found in the knowledge base. """ super().__init__() self.name = "history_taking" # 1) Load the KB and pick the right syndrome entry import os # Try multiple possible locations for the knowledge base file possible_paths = [ "consult_kb_stepwise.json", os.path.join(os.path.dirname(__file__), "..", "consult_kb_stepwise.json"), os.path.join(os.path.dirname(__file__), "..", "archive", "consult_kb_stepwise.json") ] kb_file = None for path in possible_paths: if os.path.exists(path): kb_file = path break if not kb_file: raise FileNotFoundError("Could not find consult_kb_stepwise.json in any of the expected locations") with open(kb_file, 'r') as f: kb = json.load(f) entry = kb.get(syndrome_key) if not entry: raise ValueError(f"No KB entry for syndrome '{syndrome_key}'") self.description = f"Gather history for {entry['syndrome_name']}" # 2) Flatten all required questions reqs = [] for block in entry["common_consult_questions"]: reqs += block["required_information"] # 3) Build dynamic JSON schema props = { q.replace(" ", "_").lower(): {"type": "string", "description": q} for q in reqs } self.args_schema = { "type": "object", "properties": props, "required": list(props.keys()) } self._syndrome_query = entry["syndrome_name"] async def run(self, **kwargs: Any) -> str: """ Generate a history-taking prompt and return the LLM's response. Args: **kwargs: Answers to the required consult questions for the syndrome. Returns: str: The generated history-taking response from the LLM (placeholder). """ try: # All required fields are now in kwargs—render your final template prompt: str = load_prompt( "diagnostic_recommendation.j2", syndrome_query=self._syndrome_query, **kwargs ) return call_llm(prompt) except Exception as e: logger.error(f"HistoryTakingTool failed: {e}", exc_info=True) raise ToolExecutionError(f"HistoryTakingTool failed: {e}")