computer-use-ootb-internal 0.0.138__py3-none-any.whl → 0.0.140__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.
@@ -362,49 +362,89 @@ class GuardService(win32serviceutil.ServiceFramework):
362
362
 
363
363
  # --- Command Handlers --- Now call self. for helpers
364
364
 
365
- def handle_update(self):
366
- """Handles the update command by running the target executable with the 'update' argument."""
367
- self.log_info("Executing OOTB update...")
365
+ def _get_python_executable_from_target_exe(self):
366
+ """Attempts to find the python.exe associated with the target executable's env."""
368
367
  if not self.target_executable_path:
369
- self.log_error("Cannot update: Target executable path is not set.")
370
- return "failed_executable_not_found"
368
+ self.log_error("Cannot find python.exe: target executable path is not set.")
369
+ return None
370
+ try:
371
+ exe_path_unquoted = self.target_executable_path.strip('"')
372
+ scripts_dir = os.path.dirname(exe_path_unquoted)
373
+ # Assume target exe is in a 'Scripts' directory relative to env root
374
+ env_dir = os.path.dirname(scripts_dir)
375
+ if os.path.basename(scripts_dir.lower()) != 'scripts':
376
+ self.log_warning(f"Target executable {exe_path_unquoted} not in expected 'Scripts' directory. Cannot reliably find python.exe.")
377
+ # Fallback: maybe the target IS python.exe or next to it?
378
+ env_dir = scripts_dir # Try assuming it's env root
379
+
380
+ python_exe_path = os.path.join(env_dir, 'python.exe')
381
+ self.log_info(f"Checking for python.exe at: {python_exe_path}")
382
+ if os.path.exists(python_exe_path):
383
+ self.log_info(f"Found associated python.exe: {python_exe_path}")
384
+ if " " in python_exe_path and not python_exe_path.startswith('"'):
385
+ return f'"{python_exe_path}"'
386
+ return python_exe_path
387
+ else:
388
+ self.log_error(f"Associated python.exe not found at {python_exe_path}")
389
+ # Fallback: Check pythonw.exe?
390
+ pythonw_exe_path = os.path.join(env_dir, 'pythonw.exe')
391
+ if os.path.exists(pythonw_exe_path):
392
+ self.log_info(f"Found associated pythonw.exe as fallback: {pythonw_exe_path}")
393
+ if " " in pythonw_exe_path and not pythonw_exe_path.startswith('"'):
394
+ return f'"{pythonw_exe_path}"'
395
+ return pythonw_exe_path
396
+ else:
397
+ self.log_error(f"Associated pythonw.exe also not found.")
398
+ return None
399
+
400
+ except Exception as e:
401
+ self.log_error(f"Error finding associated python executable: {e}")
402
+ return None
403
+
404
+ def handle_update(self):
405
+ """Handles the update command by running pip install --upgrade directly."""
406
+ self.log_info("Executing OOTB update via pip...")
407
+
408
+ python_exe = self._get_python_executable_from_target_exe()
409
+ if not python_exe:
410
+ self.log_error("Cannot update: Could not find associated python.exe for pip.")
411
+ return "failed_python_not_found"
371
412
 
372
- # Construct the command: "C:\path\to\exe" update
373
- # self.target_executable_path should already be quoted if necessary
374
- update_command = f'{self.target_executable_path} update'
375
- # Determine the executable path without quotes for subprocess call if needed
376
- executable_for_run = self.target_executable_path.strip('"')
377
- args_for_run = ["update"]
413
+ # Package name needs to be defined (replace with actual package name)
414
+ package_name = "computer-use-ootb-internal" # Make sure this is correct
415
+
416
+ # Construct the command: "C:\path\to\python.exe" -m pip install --upgrade --no-cache-dir package_name
417
+ python_exe_unquoted = python_exe.strip('"')
418
+ pip_args = ["-m", "pip", "install", "--upgrade", "--no-cache-dir", package_name]
419
+ update_command_display = f'{python_exe} {" ".join(pip_args)}'
378
420
 
379
- self.log_info(f"Running update command: {update_command}")
421
+ self.log_info(f"Running update command: {update_command_display}")
380
422
  try:
381
- # Execute the command directly. Running as LocalSystem should have rights to ProgramData.
382
- # Capture output for logging.
423
+ # Execute the pip command directly. Running as LocalSystem should have rights.
383
424
  result = subprocess.run(
384
- [executable_for_run] + args_for_run,
425
+ [python_exe_unquoted] + pip_args,
385
426
  capture_output=True,
386
427
  text=True,
387
- check=False, # Don't throw on non-zero exit, we check manually
428
+ check=False, # Check manually
388
429
  encoding='utf-8',
389
430
  errors='ignore'
390
431
  )
391
432
 
392
- # Log stdout/stderr regardless of exit code
393
433
  if result.stdout:
394
434
  self.log_info(f"Update process STDOUT:\n{result.stdout.strip()}")
395
435
  if result.stderr:
396
- self.log_warning(f"Update process STDERR:\n{result.stderr.strip()}") # Use warning for stderr
436
+ self.log_warning(f"Update process STDERR:\n{result.stderr.strip()}")
397
437
 
398
438
  if result.returncode == 0:
399
439
  self.log_info("Update process completed successfully (Exit Code 0).")
400
440
  return "success"
401
441
  else:
402
442
  self.log_error(f"Update process failed (Exit Code {result.returncode}).")
403
- return f"failed_update_exit_code_{result.returncode}"
443
+ return f"failed_pip_exit_code_{result.returncode}"
404
444
 
405
445
  except FileNotFoundError:
406
- self.log_error(f"Update failed: Executable not found at '{executable_for_run}'.")
407
- return "failed_executable_not_found"
446
+ self.log_error(f"Update failed: Python executable not found at '{python_exe_unquoted}'.")
447
+ return "failed_python_not_found"
408
448
  except Exception as e:
409
449
  self.log_error(f"Update failed with exception: {e}", exc_info=True)
410
450
  return "failed_exception"
@@ -448,135 +488,136 @@ class GuardService(win32serviceutil.ServiceFramework):
448
488
  return ootb_procs
449
489
 
450
490
  def handle_stop(self, target_user="all_active"):
491
+ """Stops the OOTB process for specified user(s). Uses psutil first, then taskkill fallback."""
451
492
  self.log_info(f"Executing stop OOTB for target '{target_user}'...")
452
- stop_results = {} # Track results per user {username: (task_status, immediate_status)}
453
- failed_users = set()
454
-
455
- try:
456
- # --- Get target users and active sessions ---
457
- active_sessions = {} # user_lower: session_id
458
- # No need for all_system_users for stop, we only care about active or the specific target
459
- try:
460
- sessions = win32ts.WTSEnumerateSessions(win32ts.WTS_CURRENT_SERVER_HANDLE)
461
- for session in sessions:
462
- if session['State'] == win32ts.WTSActive:
463
- try:
464
- user = win32ts.WTSQuerySessionInformation(win32ts.WTS_CURRENT_SERVER_HANDLE, session['SessionId'], win32ts.WTSUserName)
465
- if user:
466
- active_sessions[user.lower()] = session['SessionId']
467
- except Exception as query_err:
468
- self.log_error(f"Could not query session {session['SessionId']} during stop: {query_err}")
469
- except Exception as user_enum_err:
470
- self.log_error(f"Error enumerating users/sessions during stop: {user_enum_err}", exc_info=True)
471
- return "failed_user_enumeration"
472
-
473
- self.log_info(f"Stop target: '{target_user}'. Active sessions: {active_sessions}")
474
-
475
- target_users_normalized = set()
476
- if target_user == "all_active":
477
- # Target only currently active users for stop all
478
- target_users_normalized = set(active_sessions.keys())
479
- self.log_info(f"Stop targeting all active users: {target_users_normalized}")
480
- else:
481
- # Target the specific user, regardless of active status (for task removal)
482
- normalized_target = target_user.lower()
483
- target_users_normalized.add(normalized_target)
484
- self.log_info(f"Stop targeting specific user: {normalized_target}")
485
-
486
- if not target_users_normalized:
487
- self.log_info("No target users identified for stop.")
488
- return "failed_no_target_users" # Or success if none were targeted?
489
-
490
- # --- Process each target user ---
491
- for user in target_users_normalized:
492
- task_removed_status = "task_unknown"
493
- immediate_stop_status = "stop_not_attempted"
494
- stopped_count = 0
495
-
496
- self.log_info(f"Processing stop for user '{user}'...")
497
-
498
- # 1. Always try to remove the scheduled task
499
- try:
500
- # remove_logon_task always returns True for now, just logs attempt
501
- self.remove_logon_task(user)
502
- task_removed_status = "task_removed_attempted"
503
- except Exception as task_err:
504
- self.log_error(f"Exception removing scheduled task for {user}: {task_err}", exc_info=True)
505
- task_removed_status = "task_exception"
506
- failed_users.add(user)
507
- # Continue to try and stop process if active
508
-
509
- # 2. If user is active, try to terminate process
510
- is_active = user in active_sessions
511
-
512
- if is_active:
513
- immediate_stop_status = "stop_attempted"
514
- self.log_info(f"User '{user}' is active. Attempting to terminate OOTB process(es)...")
515
- # Pass the specific username to _get_ootb_processes
516
- procs_to_stop = self._get_ootb_processes(user)
517
-
518
- if not procs_to_stop:
519
- self.log_info(f"No running OOTB processes found for active user '{user}'.")
520
- immediate_stop_status = "stop_skipped_not_running"
521
- else:
522
- self.log_info(f"Found {len(procs_to_stop)} process(es) for user '{user}' to stop.")
523
- for proc in procs_to_stop:
524
- try:
525
- pid = proc.pid # Get pid before potential termination
526
- username = proc.info.get('username', 'unknown_user')
527
- self.log_info(f"Terminating process PID={pid}, User={username}")
528
- proc.terminate()
529
- try:
530
- proc.wait(timeout=3)
531
- self.log_info(f"Process PID={pid} terminated successfully.")
532
- stopped_count += 1
533
- except psutil.TimeoutExpired:
534
- self.log_error(f"Process PID={pid} did not terminate gracefully, killing.")
535
- proc.kill()
536
- stopped_count += 1
537
- except psutil.NoSuchProcess:
538
- self.log_info(f"Process PID={pid} already terminated.")
539
- # Don't increment stopped_count here as we didn't stop it now
540
- except psutil.AccessDenied:
541
- self.log_error(f"Access denied trying to terminate process PID={pid}.")
542
- failed_users.add(user) # Mark user as failed if stop fails
543
- except Exception as e:
544
- self.log_error(f"Error stopping process PID={pid}: {e}", exc_info=True)
545
- failed_users.add(user) # Mark user as failed
546
-
547
- # Determine status based on how many were found vs stopped
548
- if user in failed_users:
549
- immediate_stop_status = f"stop_errors_terminated_{stopped_count}_of_{len(procs_to_stop)}"
550
- elif stopped_count == len(procs_to_stop):
551
- immediate_stop_status = f"stop_success_terminated_{stopped_count}"
552
- else: # Should ideally not happen if NoSuchProcess doesn't count
553
- immediate_stop_status = f"stop_partial_terminated_{stopped_count}_of_{len(procs_to_stop)}"
554
-
555
- else: # User not active
556
- self.log_info(f"User '{user}' is not active. Skipping immediate process stop (task removal attempted).")
557
- immediate_stop_status = "stop_skipped_inactive"
558
-
559
- # Record final results for this user
560
- stop_results[user] = (task_removed_status, immediate_stop_status)
561
-
562
-
563
- # --- Consolidate status ---
564
- total_processed = len(target_users_normalized)
565
- final_status = "partial_success" if failed_users else "success"
566
- if not stop_results: final_status = "no_targets_processed"
567
- if len(failed_users) == total_processed and total_processed > 0 : final_status = "failed"
568
-
569
- self.log_info(f"Finished stopping OOTB. Overall Status: {final_status}. Results: {stop_results}")
493
+ stopped_count_psutil = 0
494
+ stopped_count_taskkill = 0
495
+ errors = []
496
+
497
+ target_users_lower = set()
498
+ if target_user == "all_active":
570
499
  try:
571
- details = json.dumps(stop_results)
572
- except Exception:
573
- details = str(stop_results) # Fallback
574
- return f"{final_status}::{details}" # Use :: as separator
500
+ for user_session in psutil.users():
501
+ username_lower = user_session.name.split('\\')[-1].lower()
502
+ target_users_lower.add(username_lower)
503
+ self.log_info(f"Targeting all users found by psutil: {target_users_lower}")
504
+ except Exception as e:
505
+ self.log_error(f"Could not list users via psutil for stop all: {e}")
506
+ errors.append("failed_user_enumeration")
507
+ target_users_lower = set() # Avoid proceeding if user list failed
508
+ else:
509
+ target_users_lower.add(target_user.lower())
510
+ self.log_info(f"Targeting specific user: {target_user.lower()}")
575
511
 
512
+ if not target_users_lower and target_user == "all_active":
513
+ self.log_info("No active users found to stop.")
514
+ # If specific user targeted, proceed even if psutil didn't list them (maybe inactive)
515
+
516
+ procs_to_kill_by_user = {user: [] for user in target_users_lower}
517
+
518
+ # --- Attempt 1: psutil find and terminate ---
519
+ self.log_info("Attempting stop using psutil...")
520
+ try:
521
+ all_running = self._get_ootb_processes("all") # Get all regardless of user first
522
+ for proc in all_running:
523
+ try:
524
+ proc_user = proc.info.get('username')
525
+ if proc_user:
526
+ user_lower = proc_user.split('\\')[-1].lower()
527
+ if user_lower in target_users_lower:
528
+ procs_to_kill_by_user[user_lower].append(proc)
529
+ except (psutil.NoSuchProcess, psutil.AccessDenied):
530
+ pass # Process ended or we can't access it
576
531
  except Exception as e:
577
- self.log_error(f"Error during combined stop OOTB process: {e}", exc_info=True)
578
- return "failed_exception"
532
+ self.log_error(f"Error getting process list for psutil stop: {e}")
533
+ errors.append("failed_psutil_list")
579
534
 
535
+ for user, procs in procs_to_kill_by_user.items():
536
+ if not procs:
537
+ self.log_info(f"psutil: No OOTB processes found running for user '{user}'.")
538
+ continue
539
+
540
+ self.log_info(f"psutil: Found {len(procs)} OOTB process(es) for user '{user}'. Attempting terminate...")
541
+ for proc in procs:
542
+ try:
543
+ pid = proc.pid
544
+ self.log_info(f"psutil: Terminating PID {pid} for user '{user}'...")
545
+ proc.terminate()
546
+ try:
547
+ proc.wait(timeout=3) # Wait a bit for termination
548
+ self.log_info(f"psutil: PID {pid} terminated successfully.")
549
+ stopped_count_psutil += 1
550
+ except psutil.TimeoutExpired:
551
+ self.log_warning(f"psutil: PID {pid} did not terminate within timeout. Will try taskkill.")
552
+ # No error append yet, let taskkill try
553
+ except (psutil.NoSuchProcess, psutil.AccessDenied):
554
+ self.log_info(f"psutil: PID {pid} already gone or access denied after terminate.")
555
+ stopped_count_psutil += 1 # Count it as stopped
556
+ except (psutil.NoSuchProcess, psutil.AccessDenied) as term_err:
557
+ self.log_warning(f"psutil: Error terminating PID {proc.pid if 'proc' in locals() and proc else 'unknown'}: {term_err}. It might be gone already.")
558
+ # If it's gone, count it?
559
+ stopped_count_psutil += 1 # Assume it's gone if NoSuchProcess
560
+ except Exception as term_ex:
561
+ self.log_error(f"psutil: Unexpected error terminating PID {proc.pid if 'proc' in locals() and proc else 'unknown'}: {term_ex}")
562
+ errors.append(f"failed_psutil_terminate_{user}")
563
+
564
+ # --- Attempt 2: taskkill fallback (for users where psutil didn't find/stop) ---
565
+ # Only run taskkill if psutil didn't stop anything for a specific user OR if target was specific user
566
+
567
+ if not self.target_executable_path:
568
+ errors.append("skipped_taskkill_no_exe_path")
569
+ else:
570
+ executable_name = os.path.basename(self.target_executable_path.strip('"'))
571
+ for user in target_users_lower:
572
+ run_taskkill = False
573
+ if user not in procs_to_kill_by_user or not procs_to_kill_by_user[user]:
574
+ # psutil didn't find anything for this user initially
575
+ run_taskkill = True
576
+ self.log_info(f"taskkill: psutil found no processes for '{user}', attempting taskkill as fallback.")
577
+ elif any(p.is_running() for p in procs_to_kill_by_user.get(user, []) if p): # Check if any psutil targets still running
578
+ run_taskkill = True
579
+ self.log_info(f"taskkill: Some processes for '{user}' may remain after psutil, attempting taskkill cleanup.")
580
+
581
+ if run_taskkill:
582
+ # Construct taskkill command
583
+ # Username format might need adjustment (e.g., DOMAIN\user). Try simple first.
584
+ taskkill_command = [
585
+ "taskkill", "/F", # Force
586
+ "/IM", executable_name, # Image name
587
+ "/FI", f"USERNAME eq {user}" # Filter by username
588
+ ]
589
+ self.log_info(f"Running taskkill command: {' '.join(taskkill_command)}")
590
+ try:
591
+ result = subprocess.run(taskkill_command, capture_output=True, text=True, check=False)
592
+ if result.returncode == 0:
593
+ self.log_info(f"taskkill successful for user '{user}' (Exit Code 0).")
594
+ # Can't easily count how many were killed here, assume success if exit 0
595
+ stopped_count_taskkill += 1 # Indicate taskkill ran successfully for user
596
+ elif result.returncode == 128: # Code 128: No tasks found matching criteria
597
+ self.log_info(f"taskkill: No matching processes found for user '{user}'.")
598
+ else:
599
+ self.log_error(f"taskkill failed for user '{user}' (Exit Code {result.returncode}).")
600
+ self.log_error(f" taskkill STDOUT: {result.stdout.strip()}")
601
+ self.log_error(f" taskkill STDERR: {result.stderr.strip()}")
602
+ errors.append(f"failed_taskkill_{user}")
603
+ except FileNotFoundError:
604
+ self.log_error("taskkill command not found.")
605
+ errors.append("failed_taskkill_not_found")
606
+ break # Stop trying taskkill if command is missing
607
+ except Exception as tk_ex:
608
+ self.log_error(f"Exception running taskkill for '{user}': {tk_ex}")
609
+ errors.append(f"failed_taskkill_exception_{user}")
610
+
611
+ # --- Consolidate status ---
612
+ final_status = "failed" # Default to failed if errors occurred
613
+ if stopped_count_psutil > 0 or stopped_count_taskkill > 0:
614
+ final_status = "success" if not errors else "partial_success"
615
+ elif not errors:
616
+ final_status = "success_no_processes_found"
617
+
618
+ details = f"psutil_stopped={stopped_count_psutil}, taskkill_users_attempted={stopped_count_taskkill}, errors={len(errors)}"
619
+ self.log_info(f"Finished stopping OOTB. Status: {final_status}. Details: {details}")
620
+ return f"{final_status}::{details}" # Return status and details
580
621
 
581
622
  def handle_start(self, target_user="all_active"):
582
623
  """Handles external start command request (finds users, calls internal trigger)."""
@@ -1,6 +1,7 @@
1
1
  # src/computer_use_ootb_internal/preparation/star_rail_prepare.py
2
2
  import time
3
3
  import platform
4
+ import subprocess # Added for taskkill
4
5
  import pyautogui
5
6
  import webbrowser
6
7
  import logging # Use logging instead of print for better practice
@@ -11,7 +12,8 @@ log = logging.getLogger(__name__)
11
12
  def run_preparation(state):
12
13
  """
13
14
  Performs environment preparation specific to Star Rail on Windows.
14
- Opens the specified URL in Edge and performs initial clicks.
15
+ Closes existing Edge browsers, opens the specified URL in a new Edge instance,
16
+ and performs initial clicks.
15
17
  """
16
18
  if platform.system() != "Windows":
17
19
  log.info("Star Rail preparation skipped: Not running on Windows.")
@@ -21,11 +23,31 @@ def run_preparation(state):
21
23
  url = "https://sr.mihoyo.com/cloud/#/" # Consider making this configurable later
22
24
  browser_opened = False
23
25
  try:
26
+ # Attempt to close existing Microsoft Edge processes
27
+ log.info("Attempting to close existing Microsoft Edge processes...")
28
+ try:
29
+ # /F forces termination, /IM specifies image name
30
+ result = subprocess.run(['taskkill', '/F', '/IM', 'msedge.exe'],
31
+ capture_output=True, text=True, check=False)
32
+ if result.returncode == 0:
33
+ log.info("Successfully sent termination signal to msedge.exe processes.")
34
+ elif "not found" in result.stderr.lower() or "not found" in result.stdout.lower():
35
+ log.info("No running msedge.exe processes found to close.")
36
+ else:
37
+ log.warning(f"taskkill command finished with return code {result.returncode}. Output: {result.stdout} Stderr: {result.stderr}")
38
+ time.sleep(2) # Give processes time to close
39
+ except FileNotFoundError:
40
+ log.error("Error: 'taskkill' command not found. Make sure it's in the system PATH.")
41
+ except Exception as e:
42
+ log.error(f"Error occurred while trying to close Edge: {e}", exc_info=True)
43
+
24
44
  # Use only webbrowser.open
25
45
  log.info(f"Attempting to open {url} using webbrowser.open()...")
26
46
  if webbrowser.open(url):
27
47
  log.info(f"Successfully requested browser to open {url} via webbrowser.open().")
28
48
  browser_opened = True
49
+ # Ensure sleep time for browser load before clicks is present
50
+ time.sleep(5)
29
51
  else:
30
52
  log.warning("webbrowser.open() returned False, indicating potential failure.")
31
53
 
@@ -21,7 +21,7 @@ def simple_teachmode_sampling_loop(
21
21
  model: str,
22
22
  task: str,
23
23
  api_keys: dict = None,
24
- action_history: list[dict] = [],
24
+ action_history: list[dict] = None,
25
25
  selected_screen: int = 0,
26
26
  user_id: str = None,
27
27
  trace_id: str = None,
@@ -31,6 +31,10 @@ def simple_teachmode_sampling_loop(
31
31
  """
32
32
  Synchronous sampling loop for assistant/tool interactions in 'teach mode'.
33
33
  """
34
+ # Initialize action_history if it's None
35
+ if action_history is None:
36
+ action_history = []
37
+
34
38
  # if platform.system() != "Windows":
35
39
  # raise ValueError("Teach mode is only supported on Windows.")
36
40
 
@@ -42,7 +46,7 @@ def simple_teachmode_sampling_loop(
42
46
  if "star_rail" in user_id or "star_rail" in user_id:
43
47
  full_screen_game_mode = 1
44
48
 
45
- if "star_rail_dev" in trace_id or "star_rail_dev" in user_id or "hero_case" in user_id or "offical" in user_id:
49
+ if "star_rail_dev" in trace_id or "star_rail_dev" in user_id or "hero_case" in user_id or "official" in user_id:
46
50
  full_screen_game_mode = 2
47
51
 
48
52
  print(f"Full Screen Game Mode: {full_screen_game_mode}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: computer-use-ootb-internal
3
- Version: 0.0.138
3
+ Version: 0.0.140
4
4
  Summary: Computer Use OOTB
5
5
  Author-email: Siyuan Hu <siyuan.hu.sg@gmail.com>
6
6
  Requires-Python: >=3.11
@@ -2,9 +2,9 @@ computer_use_ootb_internal/README.md,sha256=FxpW95lyub2iX73ZDfK6ML7SdEKg060H5I6G
2
2
  computer_use_ootb_internal/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
3
3
  computer_use_ootb_internal/app_teachmode.py,sha256=76JbhRhhB-PohVJ-PJSpqMPMqvLGH8QwKTZnPRXYO3w,23176
4
4
  computer_use_ootb_internal/dependency_check.py,sha256=y8RMEP6RXQzTgU1MS_1piBLtz4J-Hfn9RjUZg59dyvo,1333
5
- computer_use_ootb_internal/guard_service.py,sha256=RjnfBIsLU0P4T1o2lMWFY1lSmAOILhJmhUiYzrTxg4A,47329
5
+ computer_use_ootb_internal/guard_service.py,sha256=0-lUbJO02XAT9t5zUPgrfjbv1Uy8KAJjVeK2mLp5mHk,49990
6
6
  computer_use_ootb_internal/requirements-lite.txt,sha256=5DAHomz4A_P2BmTIXNkNqkHbnIF0AyZ4_1XAlb1LaYs,290
7
- computer_use_ootb_internal/run_teachmode_ootb_args.py,sha256=3ud1hvvOkODD3woc0Zwe5UG5p8x2KEHLks7JfdFRzCg,7579
7
+ computer_use_ootb_internal/run_teachmode_ootb_args.py,sha256=eUPpfA7bB3bdBBiIBIxKJSS-Jpz2G6R46fpDO440Jyo,7687
8
8
  computer_use_ootb_internal/service_manager.py,sha256=SD8jzfn0VVXBOr_nP6zmBWSC2TzrU_sp2e5JJkSlQFU,9734
9
9
  computer_use_ootb_internal/signal_connection.py,sha256=8jPLOj0WSBXI_NElm5A-F146DTAE5LdL07lov7YXTNQ,1774
10
10
  computer_use_ootb_internal/computer_use_demo/animation/click_animation.py,sha256=tP1gsayFy-CKk10UlrE9RlexwlHWiHQUe5Ogg4vQvSg,3234
@@ -33,8 +33,8 @@ computer_use_ootb_internal/computer_use_demo/tools/edit.py,sha256=b0PwUitxckHCQq
33
33
  computer_use_ootb_internal/computer_use_demo/tools/run.py,sha256=xhXdnBK1di9muaO44CEirL9hpGy3NmKbjfMpyeVmn8Y,1595
34
34
  computer_use_ootb_internal/computer_use_demo/tools/screen_capture.py,sha256=L8qfvtUkPPQGt92N-2Zfw5ZTDBzLsDps39uMnX3_uSA,6857
35
35
  computer_use_ootb_internal/preparation/__init__.py,sha256=AgtGHcBpiTkxJjF0xwcs3yyQ6SyUvhL3G0vD2XO-zJw,63
36
- computer_use_ootb_internal/preparation/star_rail_prepare.py,sha256=s1VWszcTnJAKxqCHFlaOEwPkqVSrkiFx_yKpWSnSbHs,2649
37
- computer_use_ootb_internal-0.0.138.dist-info/METADATA,sha256=ssU5RYeRr30uWirpkatg1lBgY0ANtqnIQ3KL_dtM0t4,1048
38
- computer_use_ootb_internal-0.0.138.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
39
- computer_use_ootb_internal-0.0.138.dist-info/entry_points.txt,sha256=bXfyAU_qq-G1EiEgAQEioXvgEdRCFxaTooqdDD9Y4OA,258
40
- computer_use_ootb_internal-0.0.138.dist-info/RECORD,,
36
+ computer_use_ootb_internal/preparation/star_rail_prepare.py,sha256=xbzlTxPL20RRroVlUcZPEUBbDoVH7Jhy22cE7umecGk,3982
37
+ computer_use_ootb_internal-0.0.140.dist-info/METADATA,sha256=IS02NcZA6PwhvETkeIikM0peDaaf1rWhSH-H4bLep6Q,1048
38
+ computer_use_ootb_internal-0.0.140.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
39
+ computer_use_ootb_internal-0.0.140.dist-info/entry_points.txt,sha256=bXfyAU_qq-G1EiEgAQEioXvgEdRCFxaTooqdDD9Y4OA,258
40
+ computer_use_ootb_internal-0.0.140.dist-info/RECORD,,