Spaces:
Sleeping
Sleeping
Update modules/orchestrator.py
Browse files- modules/orchestrator.py +80 -0
modules/orchestrator.py
CHANGED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# modules/orchestrator.py
|
2 |
+
"""
|
3 |
+
The main conductor. This module sequences the calls to APIs and the AI model.
|
4 |
+
It's the heart of the application's logic.
|
5 |
+
"""
|
6 |
+
import asyncio
|
7 |
+
import aiohttp
|
8 |
+
import ast
|
9 |
+
from . import gemini_handler, prompts
|
10 |
+
from .api_clients import umls_client, pubmed_client
|
11 |
+
|
12 |
+
async def run_symptom_synthesis(user_query: str, image_input=None):
|
13 |
+
"""
|
14 |
+
The complete pipeline for the Symptom Synthesizer tab.
|
15 |
+
"""
|
16 |
+
if not user_query:
|
17 |
+
return "Please enter your symptoms or query."
|
18 |
+
|
19 |
+
# --- Step 1: Extract Key Concepts with Gemini ---
|
20 |
+
term_extraction_prompt = prompts.get_term_extraction_prompt(user_query)
|
21 |
+
concepts_str = await gemini_handler.generate_gemini_response(term_extraction_prompt)
|
22 |
+
try:
|
23 |
+
# Safely evaluate the string representation of the list
|
24 |
+
concepts = ast.literal_eval(concepts_str)
|
25 |
+
if not isinstance(concepts, list):
|
26 |
+
concepts = [user_query] # Fallback
|
27 |
+
except (ValueError, SyntaxError):
|
28 |
+
concepts = [user_query] # Fallback if Gemini doesn't return a perfect list
|
29 |
+
|
30 |
+
search_query = " AND ".join(concepts)
|
31 |
+
|
32 |
+
# --- Step 2: Gather Evidence Asynchronously ---
|
33 |
+
async with aiohttp.ClientSession() as session:
|
34 |
+
# Create a UMLS client instance for this session
|
35 |
+
umls = umls_client.UMLSClient(session)
|
36 |
+
|
37 |
+
# Define all async tasks
|
38 |
+
tasks = {
|
39 |
+
"pubmed": pubmed_client.search_pubmed(session, search_query, max_results=3),
|
40 |
+
"umls_cui": umls.get_cui_for_term(concepts[0] if concepts else user_query),
|
41 |
+
# Add other clients here as they are built e.g.,
|
42 |
+
# "trials": clinicaltrials_client.find_trials(session, search_query),
|
43 |
+
# "fda": openfda_client.get_adverse_events(session, concepts)
|
44 |
+
}
|
45 |
+
|
46 |
+
# Run all tasks concurrently
|
47 |
+
results = await asyncio.gather(*tasks.values(), return_exceptions=True)
|
48 |
+
|
49 |
+
# Map results back to their keys, handling potential errors
|
50 |
+
api_data = dict(zip(tasks.keys(), results))
|
51 |
+
for key, value in api_data.items():
|
52 |
+
if isinstance(value, Exception):
|
53 |
+
print(f"Error fetching data from {key}: {value}")
|
54 |
+
api_data[key] = None # Nullify data if fetch failed
|
55 |
+
|
56 |
+
# --- Step 3: Format Data for the Synthesis Prompt ---
|
57 |
+
# Convert raw JSON/list data into clean, readable strings for the AI
|
58 |
+
pubmed_formatted = "\n".join([f"- Title: {a.get('title', 'N/A')}, PMID: {a.get('uid', 'N/A')}" for a in api_data.get('pubmed', [])])
|
59 |
+
|
60 |
+
# In a real implementation, you'd format trials and fda data here too
|
61 |
+
trials_formatted = "Trial data fetching is not yet fully implemented in this demo."
|
62 |
+
fda_formatted = "FDA data fetching is not yet fully implemented in this demo."
|
63 |
+
|
64 |
+
|
65 |
+
# --- Step 4: The Grand Synthesis with Gemini ---
|
66 |
+
synthesis_prompt = prompts.get_synthesis_prompt(
|
67 |
+
user_query,
|
68 |
+
concepts,
|
69 |
+
pubmed_data=pubmed_formatted,
|
70 |
+
trials_data=trials_formatted,
|
71 |
+
fda_data=fda_formatted
|
72 |
+
)
|
73 |
+
|
74 |
+
final_report = await gemini_handler.generate_gemini_response(synthesis_prompt)
|
75 |
+
|
76 |
+
# --- Step 5: Prepend Disclaimer and Return ---
|
77 |
+
return f"{prompts.DISCLAIMER}\n\n{final_report}"
|
78 |
+
|
79 |
+
# You would create similar orchestrator functions for other tabs
|
80 |
+
# e.g., async def run_drug_interaction_analysis(drug_list): ...
|