@@ -160,6 +160,25 @@ def run_paper_iteration(self) -> bool:
160160 page_images = self ._maybe_generate_page_images ()
161161 visual_review_section = ""
162162 if page_images :
163+ # Load figure manifest to tell reviewer which figures are AI-generated
164+ figure_types_section = ""
165+ try :
166+ from ark .figure_manifest import load_manifest , get_protected_files
167+ manifest = load_manifest (self .figures_dir )
168+ figures = manifest .get ("figures" , {})
169+ ai_figs = [f for f , info in figures .items ()
170+ if info .get ("source" ) in ("paperbanana" , "nano_banana" )]
171+ mpl_figs = [f for f , info in figures .items ()
172+ if info .get ("source" ) == "matplotlib" ]
173+ if ai_figs or mpl_figs :
174+ figure_types_section = "\n \n Figure sources (for review guidance):\n "
175+ if ai_figs :
176+ figure_types_section += f"- AI-generated concept figures (do not flag for matplotlib style): { ', ' .join (ai_figs )} \n "
177+ if mpl_figs :
178+ figure_types_section += f"- Matplotlib data plots (can flag for code fixes): { ', ' .join (mpl_figs )} \n "
179+ except Exception :
180+ pass
181+
163182 visual_review_section = f"""
164183
165184## Visual Review
@@ -172,7 +191,7 @@ def run_paper_iteration(self) -> bool:
172191- Is the layout professional (alignment, spacing, margins)?
173192- Is the information density appropriate?
174193- Does the overall visual quality meet research publication standards?
175- """
194+ { figure_types_section } """
176195
177196 # 2. Reviewer Agent
178197 step_num += 1
@@ -1109,14 +1128,18 @@ def _run_dev_phase(self):
11091128 self .log_section ("✏️ Writing Initial Paper Draft" )
11101129 self ._send_dev_phase_telegram ("writing" , 0 , 0 )
11111130
1112- # Generate figures from results
1131+ # Generate matplotlib figures from results (fast, do first)
11131132 self .log_step ("Generating figures from experiment results..." , "progress" )
11141133 self .generate_figures ()
11151134
1116- # Generate AI concept figures (Nano Banana) if enabled
1135+ # Start AI concept figure generation in background (slow, ~7min/fig)
1136+ # Writer can proceed in parallel — it writes text first, figures are \includegraphics refs
1137+ nano_banana_future = None
11171138 if self .config .get ("figure_generation" ) == "nano_banana" :
1118- self .log_step ("Generating AI concept figures (Nano Banana)..." , "progress" )
1119- self ._generate_nano_banana_figures ()
1139+ from concurrent .futures import ThreadPoolExecutor
1140+ self ._nano_banana_executor = ThreadPoolExecutor (max_workers = 1 )
1141+ self .log_step ("Starting AI concept figure generation (background)..." , "progress" )
1142+ nano_banana_future = self ._nano_banana_executor .submit (self ._generate_nano_banana_figures )
11201143
11211144 # Writer produces complete initial draft
11221145 paper_requirements = self .load_paper_requirements ()
@@ -1182,6 +1205,17 @@ def _run_dev_phase(self):
11821205
11831206 self .run_agent ("writer" , prompt , timeout = 3600 )
11841207
1208+ # Wait for background AI figure generation to complete (if running)
1209+ if nano_banana_future is not None :
1210+ self .log_step ("Waiting for AI concept figures to complete..." , "progress" )
1211+ try :
1212+ nano_banana_future .result (timeout = 1200 ) # 20 min max
1213+ self .log_step ("AI concept figures ready" , "success" )
1214+ except Exception as e :
1215+ self .log (f"AI concept figure generation failed: { e } " , "WARN" )
1216+ finally :
1217+ self ._nano_banana_executor .shutdown (wait = False )
1218+
11851219 # Compile initial draft
11861220 self .log_step ("Compiling initial draft..." , "progress" )
11871221 if self .compile_latex ():
0 commit comments