sujataprakashdatycs commited on
Commit
f6e6270
·
verified ·
1 Parent(s): ccadeb4

Upload 2 files

Browse files
Files changed (2) hide show
  1. chart_engine.py +70 -0
  2. pdf_renderer.py +26 -0
chart_engine.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import yaml, json, os
2
+ from crewai import Agent, Task, Crew, Process
3
+ from langchain_openai import ChatOpenAI
4
+
5
+ class PatientChartCrewEngine:
6
+ def __init__(self, folder_path: str, measure_name: str):
7
+ if not measure_name.endswith(".yml"):
8
+ measure_name += ".yml"
9
+
10
+ file_path = os.path.join(folder_path, measure_name)
11
+ if not os.path.exists(file_path):
12
+ raise FileNotFoundError(f"Measure file not found at: {file_path}")
13
+
14
+ with open(file_path, 'r') as f:
15
+ self.cfg = yaml.safe_load(f)
16
+
17
+ self.llm = ChatOpenAI(model="gpt-5.1", temperature=0.5)
18
+
19
+ def run(self):
20
+ scribe = Agent(
21
+ role="Senior Clinical Quality Scribe",
22
+ goal="Generate a dense, 2-page clinical encounter note with mandatory dates for all entries.",
23
+ backstory="""You are a senior scribe specializing in audit-ready records.
24
+ Every diagnosis, procedure, and immunization MUST have a specific date (MM/DD/YYYY).
25
+ You must use all YAML target_rules and expand the physical exam to hit 2 pages.""",
26
+ llm=self.llm,
27
+ allow_delegation=False
28
+ )
29
+
30
+ architect = Agent(
31
+ role="Medical Document Architect",
32
+ goal="Format clinical data into a professional 2-page LaTeX document.",
33
+ backstory="""You are a LaTeX expert. You invent unique clinic branding and
34
+ use high-density formatting (no whitespace) to ensure the chart is 2 pages long.""",
35
+ llm=self.llm,
36
+ allow_delegation=False
37
+ )
38
+
39
+ content_task = Task(
40
+ description=f"""
41
+ MEASURE RULES: {json.dumps(self.cfg.get('target_rules', {}), indent=2)}
42
+
43
+ DIRECTIONS FOR AUDIT VALIDITY:
44
+ 1. MANDATORY DATES: Every diagnosis (ICD-10), procedure (CPT/HCPCS), and
45
+ immunization MUST include a specific date of occurrence (MM/DD/YYYY).
46
+ 2. NARRATIVE VOLUME: Write a 10-sentence HPI and a 12-point Review of Systems (ROS).
47
+ 3. PHYSICAL EXAM: Include a comprehensive multi-system physical exam.
48
+ 4. PATIENT: John Thompson (DOB 05/09/1951).
49
+ """,
50
+ agent=scribe,
51
+ expected_output="Extensive clinical JSON with mandatory dates."
52
+ )
53
+
54
+ latex_task = Task(
55
+ description="""
56
+ Convert the output into professional LaTeX.
57
+ - BRANDING: Invent a UNIQUE clinic name/address (Never use ABC Medicine).
58
+ - PAGE FLOW: Ensure the content fills 2 full pages.
59
+ - CLEANLINESS: Output ONLY the LaTeX code. No summaries or conversational text.
60
+ - RETURN ONLY RAW LaTeX code starting with \\documentclass.
61
+ """,
62
+ agent=architect,
63
+ context=[content_task],
64
+ expected_output="Complete LaTeX source code."
65
+ )
66
+
67
+ crew = Crew(agents=[scribe, architect], tasks=[content_task, latex_task], process=Process.sequential)
68
+
69
+ result = crew.kickoff()
70
+ return result.raw if hasattr(result, 'raw') else str(result)
pdf_renderer.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os, subprocess, re, shutil
2
+
3
+ def render_pdf(latex_code, output_path):
4
+ # Strip AI conversation and isolate LaTeX block
5
+ match = re.search(r"```(?:latex)?\n?(.*?)\n?```", latex_code, re.DOTALL)
6
+ clean_code = match.group(1).strip() if match else latex_code.strip()
7
+
8
+ tex_filename = "final_output.tex"
9
+ with open(tex_filename, "w") as f:
10
+ f.write(clean_code)
11
+
12
+ try:
13
+ # pdflatex requires 2 passes for stable headers and page numbering
14
+ for _ in range(2):
15
+ subprocess.run(["pdflatex", "-interaction=nonstopmode", tex_filename],
16
+ check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
17
+
18
+ # Use shutil to move from local Colab disk to Google Drive
19
+ if os.path.exists("final_output.pdf"):
20
+ shutil.move("final_output.pdf", output_path)
21
+ return True
22
+ return False
23
+
24
+ except subprocess.CalledProcessError:
25
+ print("❌ LaTeX Error: The AI produced invalid syntax. Check the logs.")
26
+ return False