PatientChartCreation / chart_engine.py
sujataprakashdatycs's picture
Update chart_engine.py
72878ad verified
import yaml, json, os
from crewai import Agent, Task, Crew, Process
from langchain_openai import ChatOpenAI
class PatientChartCrewEngine:
def __init__(self, folder_path: str, measure_name: str):
if not measure_name.endswith(".yml"):
measure_name += ".yml"
file_path = os.path.join(folder_path, measure_name)
if not os.path.exists(file_path):
raise FileNotFoundError(f"Measure file not found at: {file_path}")
with open(file_path, 'r') as f:
self.cfg = yaml.safe_load(f)
# Using a slightly lower temperature for the Architect to ensure syntax stability
self.llm = ChatOpenAI(model="gpt-4o", temperature=0.5)
def run(self):
# AGENT 1: Scribe - Focuses on clinical density
scribe = Agent(
role="Senior Clinical Quality Scribe",
goal="Generate high-density clinical narratives for patient charts.",
backstory="""You are a senior scribe. You provide extremely detailed HPIs
and expanded Social Histories. You avoid symbols like & or %;
instead, you write 'and' or 'percent' to ensure data compatibility.""",
llm=self.llm,
allow_delegation=False
)
# AGENT 2: Architect - Focuses on LaTeX Syntax and escaping
architect = Agent(
role="LaTeX Document Architect",
goal="Convert clinical text into error-free, top-aligned LaTeX source code.",
backstory="""You are a LaTeX expert. You know that characters like %, &, $, #,
and _ must be escaped (e.g., \%) or the code will crash. You prioritize
structural integrity and use packages like 'geometry' and 'microtype'
to ensure professional formatting.""",
llm=self.llm,
allow_delegation=False
)
# TASK 1: Narrative Volume
content_task = Task(
description=f"""
RULES: {json.dumps(self.cfg.get('target_rules', {}), indent=2)}
1. IDENTITY: Unique Name and MRN (e.g., Emily Carter, 92837465).
2. DENSE HPI: Write a massive clinical narrative (minimum 800 words).
Focus on Transition to Hospice (Z51.5) and Hysterectomy (58150).
3. DATES: Use MM/DD/YYYY format for all entries.
""",
agent=scribe,
expected_output="A JSON-like structure containing the clinical narrative sections."
)
# TASK 2: Rigid LaTeX Construction
latex_task = Task(
description="""
Assemble the clinical text into a single RAW LaTeX document.
STRICT REQUIREMENTS:
- Start with \\documentclass{article}.
- Use \\usepackage[utf8]{inputenc} and \\usepackage[margin=0.8in]{geometry}.
- Include \\raggedbottom to keep all text top-aligned.
- ESCAPE special characters: Change '%' to '\%', '&' to '\&', and '_' to '\_'.
- Ensure there is a \\begin{document} and \\end{document}.
- OUTPUT ONLY THE RAW LATEX. DO NOT USE MARKDOWN CODE BLOCKS (```).
""",
agent=architect,
context=[content_task],
expected_output="Valid LaTeX source code starting with \\documentclass."
)
crew = Crew(
agents=[scribe, architect],
tasks=[content_task, latex_task],
process=Process.sequential
)
result = crew.kickoff()
return result.raw if hasattr(result, 'raw') else str(result)