lybic-guiagents 0.3.0__py3-none-any.whl → 0.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of lybic-guiagents might be problematic. Click here for more details.

gui_agents/cli_app.py CHANGED
@@ -107,7 +107,7 @@ def validate_backend_compatibility(backend, compatible_backends, incompatible_ba
107
107
  return True, backend, f"Unknown backend '{backend}', compatibility cannot be determined."
108
108
 
109
109
  logger = logging.getLogger()
110
- logger.setLevel(logging.DEBUG)
110
+ logger.setLevel(os.environ.get("LOG_LEVEL", "INFO").upper())
111
111
 
112
112
  datetime_str: str = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
113
113
 
@@ -258,7 +258,7 @@ def scale_screenshot_dimensions(screenshot: Image.Image, hwi_para: HardwareInter
258
258
 
259
259
  return screenshot
260
260
 
261
- def run_agent_normal(agent, instruction: str, hwi_para: HardwareInterface, max_steps: int = 50, enable_takeover: bool = False):
261
+ def run_agent_normal(agent, instruction: str, hwi_para: HardwareInterface, max_steps: int = 50, enable_takeover: bool = False, task_id: str | None = None, task_registry: Registry | None = None):
262
262
  """
263
263
  Run an agent in normal mode to iteratively observe, plan, and execute actions for a given instruction.
264
264
 
@@ -270,246 +270,271 @@ def run_agent_normal(agent, instruction: str, hwi_para: HardwareInterface, max_s
270
270
  hwi_para (HardwareInterface): Hardware interface used to capture screenshots and dispatch actions.
271
271
  max_steps (int): Maximum number of agent prediction/execute cycles to run.
272
272
  enable_takeover (bool): If True, the agent may request a user takeover that pauses execution until the user resumes.
273
+ task_id (str | None): Optional task ID for context.
274
+ task_registry (Registry | None): Optional task-specific registry.
273
275
  """
274
- import time
275
- obs = {}
276
- traj = "Task:\n" + instruction
277
- subtask_traj = ""
278
- global_state: GlobalState = Registry.get("GlobalStateStore") # type: ignore
279
- global_state.set_Tu(instruction)
280
- global_state.set_running_state("running")
281
- hwi = hwi_para
282
-
283
- total_start_time = time.time()
284
- for _ in range(max_steps):
285
- while global_state.get_running_state() == "stopped":
286
- user_input = input(
287
- "Agent execution is paused. Enter 'continue' to resume: ")
288
- if user_input == "continue":
289
- global_state.set_running_state("running")
290
- logger.info("Agent execution resumed by user")
291
- break
292
- time.sleep(0.5)
293
-
294
- screenshot: Image.Image = hwi.dispatch(Screenshot()) # type: ignore
295
- global_state.set_screenshot(
296
- scale_screenshot_dimensions(screenshot, hwi_para)) # type: ignore
297
- obs = global_state.get_obs_for_manager()
276
+ if task_registry:
277
+ Registry.set_task_registry(task_id, task_registry)
298
278
 
299
- predict_start = time.time()
300
- info, code = agent.predict(instruction=instruction, observation=obs)
301
- predict_time = time.time() - predict_start
302
- logger.info(
303
- f"[Step Timing] agent.predict execution time: {predict_time:.2f} seconds"
304
- )
279
+ try:
280
+ import time
281
+ obs = {}
282
+ traj = "Task:\n" + instruction
283
+ subtask_traj = ""
284
+ global_state: GlobalState = agent.global_state # type: ignore
285
+ global_state.set_Tu(instruction)
286
+ global_state.set_running_state("running")
287
+ hwi = hwi_para
288
+
289
+ total_start_time = time.time()
290
+ for _ in range(max_steps):
291
+ while global_state.get_running_state() == "stopped":
292
+ user_input = input(
293
+ "Agent execution is paused. Enter 'continue' to resume: ")
294
+ if user_input == "continue":
295
+ global_state.set_running_state("running")
296
+ logger.info("Agent execution resumed by user")
297
+ break
298
+ time.sleep(0.5)
299
+
300
+ # Check for cancellation
301
+ if global_state.is_cancelled():
302
+ logger.info("Agent execution cancelled by user request")
303
+ return
304
+
305
+ screenshot: Image.Image = hwi.dispatch(Screenshot()) # type: ignore
306
+ global_state.set_screenshot(
307
+ scale_screenshot_dimensions(screenshot, hwi_para)) # type: ignore
308
+ obs = global_state.get_obs_for_manager()
309
+
310
+ predict_start = time.time()
311
+ info, code = agent.predict(instruction=instruction, observation=obs)
312
+ predict_time = time.time() - predict_start
313
+ logger.info(
314
+ f"[Step Timing] agent.predict execution time: {predict_time:.2f} seconds"
315
+ )
305
316
 
306
- global_state.log_operation(module="agent",
307
- operation="agent.predict",
308
- data={"duration": predict_time})
317
+ global_state.log_operation(module="agent",
318
+ operation="agent.predict",
319
+ data={"duration": predict_time})
320
+
321
+ if "done" in code[0]["type"].lower() or "fail" in code[0]["type"].lower(
322
+ ):
323
+ if platform.system() == "Darwin":
324
+ os.system(
325
+ f'osascript -e \'display dialog "Task Completed" with title "OpenACI Agent" buttons "OK" default button "OK"\''
326
+ )
327
+ elif platform.system() == "Linux" and not (hwi_para.backend== "lybic" or isinstance(hwi_para.backend, LybicBackend)):
328
+ os.system(
329
+ f'zenity --info --title="OpenACI Agent" --text="Task Completed" --width=200 --height=100'
330
+ )
331
+
332
+ agent.update_narrative_memory(traj)
333
+ break
309
334
 
310
- if "done" in code[0]["type"].lower() or "fail" in code[0]["type"].lower(
311
- ):
312
- if platform.system() == "Darwin":
313
- os.system(
314
- f'osascript -e \'display dialog "Task Completed" with title "OpenACI Agent" buttons "OK" default button "OK"\''
335
+ if "next" in code[0]["type"].lower():
336
+ continue
337
+
338
+ if "wait" in code[0]["type"].lower():
339
+ time.sleep(5)
340
+ continue
341
+
342
+ if enable_takeover and "usertakeover" in code[0]["type"].lower():
343
+ message = code[0].get("message", "need user takeover")
344
+ logger.info(f"User takeover request: {message}")
345
+
346
+ global_state.set_running_state("stopped")
347
+
348
+ if platform.system() == "Darwin":
349
+ os.system(
350
+ f'osascript -e \'display dialog "{message}" with title "User takeover request" buttons "Continue" default button "Continue"\''
351
+ )
352
+ elif platform.system() == "Linux":
353
+ os.system(
354
+ f'zenity --info --title="User takeover request" --text="{message}" --width=300 --height=150'
355
+ )
356
+
357
+ logger.info("Agent execution paused waiting for user takeover")
358
+ continue
359
+ elif not enable_takeover and "usertakeover" in code[0]["type"].lower():
360
+ logger.info(
361
+ f"User takeover request received but takeover is disabled. Continuing execution."
315
362
  )
316
- elif platform.system() == "Linux" and not (hwi_para.backend== "lybic" or isinstance(hwi_para.backend, LybicBackend)):
317
- os.system(
318
- f'zenity --info --title="OpenACI Agent" --text="Task Completed" --width=200 --height=100'
319
- )
320
-
321
- agent.update_narrative_memory(traj)
322
- break
323
-
324
- if "next" in code[0]["type"].lower():
325
- continue
326
-
327
- if "wait" in code[0]["type"].lower():
328
- time.sleep(5)
329
- continue
330
-
331
- if enable_takeover and "usertakeover" in code[0]["type"].lower():
332
- message = code[0].get("message", "need user takeover")
333
- logger.info(f"User takeover request: {message}")
363
+ continue
334
364
 
335
- global_state.set_running_state("stopped")
336
-
337
- if platform.system() == "Darwin":
338
- os.system(
339
- f'osascript -e \'display dialog "{message}" with title "User takeover request" buttons "Continue" default button "Continue"\''
340
- )
341
- elif platform.system() == "Linux":
342
- os.system(
343
- f'zenity --info --title="User takeover request" --text="{message}" --width=300 --height=150'
365
+ else:
366
+ time.sleep(1.0)
367
+ logger.info(f"EXECUTING CODE: {code[0]}")
368
+
369
+ step_dispatch_start = time.time()
370
+ hwi.dispatchDict(code[0])
371
+ step_dispatch_time = time.time() - step_dispatch_start
372
+ logger.info(
373
+ f"[Step Timing] hwi.dispatchDict execution time: {step_dispatch_time:.2f} seconds"
344
374
  )
375
+ logger.info(f"HARDWARE INTERFACE: Executed")
376
+
377
+ # Record executed code and time
378
+ global_state.log_operation(module="hardware",
379
+ operation="executing_code",
380
+ data={"content": str(code[0])})
381
+ global_state.log_operation(module="hardware",
382
+ operation="hwi.dispatchDict",
383
+ data={"duration": step_dispatch_time})
384
+
385
+ time.sleep(1.0)
386
+
387
+ # Update task and subtask trajectories and optionally the episodic memory
388
+ traj += ("\n\nReflection:\n" + str(info.get("reflection", "")) +
389
+ "\n\n----------------------\n\nPlan:\n" +
390
+ info.get("executor_plan", ""))
391
+ subtask_traj = agent.update_episodic_memory(info, subtask_traj)
392
+
393
+ total_end_time = time.time()
394
+ total_duration = total_end_time - total_start_time
395
+ logger.info(
396
+ f"[Total Timing] Total execution time for this task: {total_duration:.2f} seconds"
397
+ )
398
+ global_state.log_operation(module="other",
399
+ operation="total_execution_time",
400
+ data={"duration": total_duration})
345
401
 
346
- logger.info("Agent execution paused waiting for user takeover")
347
- continue
348
- elif not enable_takeover and "usertakeover" in code[0]["type"].lower():
349
- logger.info(
350
- f"User takeover request received but takeover is disabled. Continuing execution."
351
- )
352
- continue
353
-
354
- else:
355
- time.sleep(1.0)
356
- logger.info(f"EXECUTING CODE: {code[0]}")
357
-
358
- step_dispatch_start = time.time()
359
- hwi.dispatchDict(code[0])
360
- step_dispatch_time = time.time() - step_dispatch_start
361
- logger.info(
362
- f"[Step Timing] hwi.dispatchDict execution time: {step_dispatch_time:.2f} seconds"
363
- )
364
- logger.info(f"HARDWARE INTERFACE: Executed")
365
-
366
- # Record executed code and time
367
- global_state.log_operation(module="hardware",
368
- operation="executing_code",
369
- data={"content": str(code[0])})
370
- global_state.log_operation(module="hardware",
371
- operation="hwi.dispatchDict",
372
- data={"duration": step_dispatch_time})
373
-
374
- time.sleep(1.0)
375
-
376
- # Update task and subtask trajectories and optionally the episodic memory
377
- traj += ("\n\nReflection:\n" + str(info.get("reflection", "")) +
378
- "\n\n----------------------\n\nPlan:\n" +
379
- info.get("executor_plan", ""))
380
- subtask_traj = agent.update_episodic_memory(info, subtask_traj)
381
-
382
- total_end_time = time.time()
383
- total_duration = total_end_time - total_start_time
384
- logger.info(
385
- f"[Total Timing] Total execution time for this task: {total_duration:.2f} seconds"
386
- )
387
- global_state.log_operation(module="other",
388
- operation="total_execution_time",
389
- data={"duration": total_duration})
390
-
391
- # Auto-analyze execution statistics after task completion
392
- timestamp_dir = os.path.join(log_dir, datetime_str)
393
- auto_analyze_execution(timestamp_dir)
402
+ # Auto-analyze execution statistics after task completion
403
+ timestamp_dir = os.path.join(log_dir, datetime_str)
404
+ auto_analyze_execution(timestamp_dir)
405
+ finally:
406
+ if task_registry:
407
+ Registry.remove_task_registry(task_id)
394
408
 
395
409
 
396
410
  def run_agent_fast(agent,
397
411
  instruction: str,
398
412
  hwi_para: HardwareInterface,
399
413
  max_steps: int = 50,
400
- enable_takeover: bool = False):
401
- import time
402
- obs = {}
403
- global_state: GlobalState = Registry.get("GlobalStateStore") # type: ignore
404
- global_state.set_Tu(instruction)
405
- global_state.set_running_state("running")
406
- hwi = hwi_para
407
-
408
- total_start_time = time.time()
409
- for step in range(max_steps):
410
- while global_state.get_running_state() == "stopped":
411
- user_input = input(
412
- "Agent execution is paused. Enter 'continue' to resume: ")
413
- if user_input == "continue":
414
- global_state.set_running_state("running")
415
- logger.info("[Fast Mode] Agent execution resumed by user")
416
- break
417
- time.sleep(0.5)
418
-
419
- screenshot: Image.Image = hwi.dispatch(Screenshot()) # type: ignore
420
- global_state.set_screenshot(
421
- scale_screenshot_dimensions(screenshot, hwi_para)) # type: ignore
422
- obs = global_state.get_obs_for_manager()
414
+ enable_takeover: bool = False, task_id: str | None = None, task_registry: Registry | None = None):
415
+ if task_registry:
416
+ Registry.set_task_registry(task_id, task_registry)
423
417
 
424
- predict_start = time.time()
425
- info, code = agent.predict(instruction=instruction,
426
- observation=obs)
427
- predict_time = time.time() - predict_start
428
- logger.info(
429
- f"[Fast Mode] [Step {step+1}] Prediction time: {predict_time:.2f} seconds"
430
- )
431
-
432
- global_state.log_operation(module="agent_fast",
433
- operation="agent.predict_fast",
434
- data={
435
- "duration": predict_time,
436
- "step": step + 1
437
- })
438
-
439
- if "done" in code[0]["type"].lower() or "fail" in code[0]["type"].lower(
440
- ):
418
+ try:
419
+ import time
420
+ obs = {}
421
+ global_state: GlobalState = agent.global_state # type: ignore
422
+ global_state.set_Tu(instruction)
423
+ global_state.set_running_state("running")
424
+ hwi = hwi_para
425
+
426
+ total_start_time = time.time()
427
+ for step in range(max_steps):
428
+ while global_state.get_running_state() == "stopped":
429
+ user_input = input(
430
+ "Agent execution is paused. Enter 'continue' to resume: ")
431
+ if user_input == "continue":
432
+ global_state.set_running_state("running")
433
+ logger.info("[Fast Mode] Agent execution resumed by user")
434
+ break
435
+ time.sleep(0.5)
436
+ # Check for cancellation
437
+ if global_state.is_cancelled():
438
+ logger.info("[Fast Mode] Agent execution cancelled by user request")
439
+ return
440
+
441
+ screenshot: Image.Image = hwi.dispatch(Screenshot()) # type: ignore
442
+ global_state.set_screenshot(
443
+ scale_screenshot_dimensions(screenshot, hwi_para)) # type: ignore
444
+ obs = global_state.get_obs_for_manager()
445
+
446
+ predict_start = time.time()
447
+ info, code = agent.predict(instruction=instruction,
448
+ observation=obs)
449
+ predict_time = time.time() - predict_start
441
450
  logger.info(
442
- f"[Fast Mode] Task {'completed' if 'done' in code[0]['type'].lower() else 'failed'}"
451
+ f"[Fast Mode] [Step {step+1}] Prediction time: {predict_time:.2f} seconds"
443
452
  )
444
- if platform.system() == "Darwin":
445
- os.system(
446
- f'osascript -e \'display dialog "Task Completed" with title "OpenACI Agent (Fast)" buttons "OK" default button "OK"\''
447
- )
448
- elif platform.system() == "Linux" and not (hwi_para.backend== "lybic" or isinstance(hwi_para.backend, LybicBackend)):
449
- os.system(
450
- f'zenity --info --title="OpenACI Agent (Fast)" --text="Task Completed" --width=200 --height=100'
451
- )
452
- break
453
-
454
- if "wait" in code[0]["type"].lower():
455
- wait_duration = code[0].get("duration", 5000) / 1000
456
- logger.info(f"[Fast Mode] Waiting for {wait_duration} seconds")
457
- time.sleep(wait_duration)
458
- continue
459
-
460
- if enable_takeover and "usertakeover" in code[0]["type"].lower():
461
- message = code[0].get("message", "need user takeover")
462
- logger.info(f"[Fast Mode] User takeover request: {message}")
463
453
 
464
- global_state.set_running_state("stopped")
465
-
466
- if platform.system() == "Darwin":
467
- os.system(
468
- f'osascript -e \'display dialog "{message}" with title "User takeover request (Fast)" buttons "Continue" default button "Continue"\''
454
+ global_state.log_operation(module="agent_fast",
455
+ operation="agent.predict_fast",
456
+ data={
457
+ "duration": predict_time,
458
+ "step": step + 1
459
+ })
460
+
461
+ if "done" in code[0]["type"].lower() or "fail" in code[0]["type"].lower(
462
+ ):
463
+ logger.info(
464
+ f"[Fast Mode] Task {'completed' if 'done' in code[0]['type'].lower() else 'failed'}"
469
465
  )
470
- elif platform.system() == "Linux":
471
- os.system(
472
- f'zenity --info --title="User takeover request (Fast)" --text="{message}" --width=300 --height=150'
466
+ if platform.system() == "Darwin":
467
+ os.system(
468
+ f'osascript -e \'display dialog "Task Completed" with title "OpenACI Agent (Fast)" buttons "OK" default button "OK"\''
469
+ )
470
+ elif platform.system() == "Linux" and not (hwi_para.backend== "lybic" or isinstance(hwi_para.backend, LybicBackend)):
471
+ os.system(
472
+ f'zenity --info --title="OpenACI Agent (Fast)" --text="Task Completed" --width=200 --height=100'
473
+ )
474
+ break
475
+
476
+ if "wait" in code[0]["type"].lower():
477
+ wait_duration = code[0].get("duration", 5000) / 1000
478
+ logger.info(f"[Fast Mode] Waiting for {wait_duration} seconds")
479
+ time.sleep(wait_duration)
480
+ continue
481
+
482
+ if enable_takeover and "usertakeover" in code[0]["type"].lower():
483
+ message = code[0].get("message", "need user takeover")
484
+ logger.info(f"[Fast Mode] User takeover request: {message}")
485
+
486
+ global_state.set_running_state("stopped")
487
+
488
+ if platform.system() == "Darwin":
489
+ os.system(
490
+ f'osascript -e \'display dialog "{message}" with title "User takeover request (Fast)" buttons "Continue" default button "Continue"\''
491
+ )
492
+ elif platform.system() == "Linux":
493
+ os.system(
494
+ f'zenity --info --title="User takeover request (Fast)" --text="{message}" --width=300 --height=150'
495
+ )
496
+
497
+ logger.info(
498
+ "[Fast Mode] Agent execution paused waiting for user takeover")
499
+ continue
500
+ elif not enable_takeover and "usertakeover" in code[0]["type"].lower():
501
+ logger.info(
502
+ f"[Fast Mode] User takeover request received but takeover is disabled. Continuing execution."
473
503
  )
504
+ continue
474
505
 
506
+ logger.info(f"[Fast Mode] Executing action: {code[0]}")
507
+ step_dispatch_start = time.time()
508
+ hwi.dispatchDict(code[0])
509
+ step_dispatch_time = time.time() - step_dispatch_start
475
510
  logger.info(
476
- "[Fast Mode] Agent execution paused waiting for user takeover")
477
- continue
478
- elif not enable_takeover and "usertakeover" in code[0]["type"].lower():
479
- logger.info(
480
- f"[Fast Mode] User takeover request received but takeover is disabled. Continuing execution."
511
+ f"[Fast Mode] Action execution time: {step_dispatch_time:.2f} seconds"
481
512
  )
482
- continue
483
513
 
484
- logger.info(f"[Fast Mode] Executing action: {code[0]}")
485
- step_dispatch_start = time.time()
486
- hwi.dispatchDict(code[0])
487
- step_dispatch_time = time.time() - step_dispatch_start
488
- logger.info(
489
- f"[Fast Mode] Action execution time: {step_dispatch_time:.2f} seconds"
490
- )
514
+ global_state.log_operation(module="hardware_fast",
515
+ operation="executing_code_fast",
516
+ data={
517
+ "content": str(code[0]),
518
+ "duration": step_dispatch_time,
519
+ "step": step + 1
520
+ })
491
521
 
492
- global_state.log_operation(module="hardware_fast",
493
- operation="executing_code_fast",
494
- data={
495
- "content": str(code[0]),
496
- "duration": step_dispatch_time,
497
- "step": step + 1
498
- })
499
-
500
- time.sleep(0.5)
501
-
502
- total_end_time = time.time()
503
- total_duration = total_end_time - total_start_time
504
- logger.info(
505
- f"[Fast Mode] Total execution time: {total_duration:.2f} seconds")
506
- global_state.log_operation(module="other",
507
- operation="total_execution_time_fast",
508
- data={"duration": total_duration})
509
-
510
- # Auto-analyze execution statistics after task completion
511
- timestamp_dir = os.path.join(log_dir, datetime_str)
512
- auto_analyze_execution(timestamp_dir)
522
+ time.sleep(0.5)
523
+
524
+ total_end_time = time.time()
525
+ total_duration = total_end_time - total_start_time
526
+ logger.info(
527
+ f"[Fast Mode] Total execution time: {total_duration:.2f} seconds")
528
+ global_state.log_operation(module="other",
529
+ operation="total_execution_time_fast",
530
+ data={"duration": total_duration})
531
+
532
+ # Auto-analyze execution statistics after task completion
533
+ timestamp_dir = os.path.join(log_dir, datetime_str)
534
+ auto_analyze_execution(timestamp_dir)
535
+ finally:
536
+ if task_registry:
537
+ Registry.remove_task_registry(task_id)
513
538
 
514
539
 
515
540
  def main():