189189 renderGraph(data);
190190 lastDataStr = dataStr;
191191 }
192+
193+ // set headline to include data.checkpoint_dir
194+ let title = "OpenEvolve Evolution Visualizer | Checkpoint: " + data.checkpoint_dir;
195+ document.querySelector('h1').textContent = title;
192196 });
193197 }
194198 fetchAndRender();
218222 </style>
219223 </head>
220224 <body>
221- <h1>Program ID: {{ program_data.id }}</h1>
225+ <h1>Checkpoint: {{checkpoint_dir}} | Program ID: {{ program_data.id }}</h1>
222226 <h2>Island: {{ program_data.island }}</h2>
223227 <h3>Generation: {{ program_data.generation }}</h3>
224228 <h3>Parent ID: {{ program_data.parent_id or 'None' }}</h3>
236240
237241logger = logging .getLogger ("openevolve.visualizer" )
238242
243+
239244def find_latest_checkpoint (base_folder ):
240245 # Check whether the base folder is itself a checkpoint folder
241- if os .path .basename (base_folder ).startswith (' checkpoint_' ):
246+ if os .path .basename (base_folder ).startswith (" checkpoint_" ):
242247 return base_folder
243248
244- checkpoint_folders = glob .glob (' **/checkpoint_*' , root_dir = base_folder , recursive = True )
249+ checkpoint_folders = glob .glob (" **/checkpoint_*" , root_dir = base_folder , recursive = True )
245250 if not checkpoint_folders :
246251 logger .info (f"No checkpoint folders found in { base_folder } " )
247252 return None
@@ -250,50 +255,55 @@ def find_latest_checkpoint(base_folder):
250255 logger .debug (f"Found checkpoint folder: { checkpoint_folders [0 ]} " )
251256 return checkpoint_folders [0 ]
252257
258+
253259def load_evolution_data (checkpoint_folder ):
254- meta_path = os .path .join (checkpoint_folder , ' metadata.json' )
255- programs_dir = os .path .join (checkpoint_folder , ' programs' )
260+ meta_path = os .path .join (checkpoint_folder , " metadata.json" )
261+ programs_dir = os .path .join (checkpoint_folder , " programs" )
256262 if not os .path .exists (meta_path ) or not os .path .exists (programs_dir ):
257263 logger .info (f"Missing metadata.json or programs dir in { checkpoint_folder } " )
258- return {"nodes" : [], "edges" : []}
264+ return {"nodes" : [], "edges" : [], "checkpoint_dir" : checkpoint_folder }
259265 with open (meta_path ) as f :
260266 meta = json .load (f )
261267
262268 nodes = []
263269 id_to_program = {}
264- for island_idx , id_list in enumerate (meta .get (' islands' , [])):
270+ for island_idx , id_list in enumerate (meta .get (" islands" , [])):
265271 for pid in id_list :
266272 prog_path = os .path .join (programs_dir , f"{ pid } .json" )
267273 if os .path .exists (prog_path ):
268274 with open (prog_path ) as pf :
269275 prog = json .load (pf )
270- prog [' island' ] = island_idx
276+ prog [" island" ] = island_idx
271277 nodes .append (prog )
272278 id_to_program [pid ] = prog
273279 else :
274280 logger .debug (f"Program file not found: { prog_path } " )
275281
276282 edges = []
277283 for prog in nodes :
278- parent_id = prog .get (' parent_id' )
284+ parent_id = prog .get (" parent_id" )
279285 if parent_id and parent_id in id_to_program :
280- edges .append ({"source" : parent_id , "target" : prog ['id' ]})
286+ edges .append ({"source" : parent_id , "target" : prog ["id" ]})
281287
282288 logger .info (f"Loaded { len (nodes )} nodes and { len (edges )} edges from { checkpoint_folder } " )
283- return {"nodes" : nodes , "edges" : edges }
289+ return {"nodes" : nodes , "edges" : edges , "checkpoint_dir" : checkpoint_folder }
284290
285- @app .route ('/' )
291+
292+ @app .route ("/" )
286293def index ():
287294 return render_template_string (HTML_TEMPLATE )
288295
296+
289297checkpoint_dir = None # Global variable to store the checkpoint directory
290- @app .route ('/api/data' )
298+
299+
300+ @app .route ("/api/data" )
291301def data ():
292- base_folder = os .environ .get (' EVOLVE_OUTPUT' , ' examples/' )
302+ base_folder = os .environ .get (" EVOLVE_OUTPUT" , " examples/" )
293303 checkpoint = find_latest_checkpoint (base_folder )
294304 if not checkpoint :
295305 logger .info (f"No checkpoints found in { base_folder } " )
296- return jsonify ({"nodes" : [], "edges" : []})
306+ return jsonify ({"nodes" : [], "edges" : [], "checkpoint_dir" : "" })
297307
298308 # Memorize checkpoint directory for usage in other routes
299309 global checkpoint_dir
@@ -318,27 +328,34 @@ def program_page(program_id):
318328 with open (program_path ) as f :
319329 program_data = json .load (f )
320330
321- return render_template_string (HTML_TEMPLATE_PROGRAM_PAGE , program_data = program_data )
331+ return render_template_string (HTML_TEMPLATE_PROGRAM_PAGE , program_data = program_data , checkpoint_dir = checkpoint_dir )
322332
323333
324- if __name__ == ' __main__' :
334+ if __name__ == " __main__" :
325335 import argparse
326336
327- parser = argparse .ArgumentParser (description = 'OpenEvolve Evolution Visualizer' )
328- parser .add_argument ('--path' , type = str , default = 'examples/' ,
329- help = 'Path to openevolve_output or checkpoints folder' )
330- parser .add_argument ('--host' , type = str , default = '127.0.0.1' )
331- parser .add_argument ('--port' , type = int , default = 8080 )
332- parser .add_argument ('--log-level' , type = str , default = 'INFO' ,
333- help = 'Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)' )
337+ parser = argparse .ArgumentParser (description = "OpenEvolve Evolution Visualizer" )
338+ parser .add_argument (
339+ "--path" ,
340+ type = str ,
341+ default = "examples/" ,
342+ help = "Path to openevolve_output or checkpoints folder" ,
343+ )
344+ parser .add_argument ("--host" , type = str , default = "127.0.0.1" )
345+ parser .add_argument ("--port" , type = int , default = 8080 )
346+ parser .add_argument (
347+ "--log-level" ,
348+ type = str ,
349+ default = "INFO" ,
350+ help = "Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)" ,
351+ )
334352 args = parser .parse_args ()
335353
336354 log_level = getattr (logging , args .log_level .upper (), logging .INFO )
337- logging .basicConfig (
338- level = log_level ,
339- format = '[%(asctime)s] %(levelname)s %(name)s: %(message)s'
340- )
355+ logging .basicConfig (level = log_level , format = "[%(asctime)s] %(levelname)s %(name)s: %(message)s" )
341356
342- os .environ ['EVOLVE_OUTPUT' ] = args .path
343- logger .info (f"Starting server at http://{ args .host } :{ args .port } with log level { args .log_level .upper ()} " )
357+ os .environ ["EVOLVE_OUTPUT" ] = args .path
358+ logger .info (
359+ f"Starting server at http://{ args .host } :{ args .port } with log level { args .log_level .upper ()} "
360+ )
344361 app .run (host = args .host , port = args .port , debug = True )
0 commit comments