computer-use-ootb-internal 0.0.160__tar.gz → 0.0.162__tar.gz

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.
Files changed (39) hide show
  1. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/PKG-INFO +1 -1
  2. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/pyproject.toml +1 -1
  3. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/guard_service.py +66 -114
  4. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/.gitignore +0 -0
  5. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/README.md +0 -0
  6. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/__init__.py +0 -0
  7. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/app_teachmode.py +0 -0
  8. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/animation/click_animation.py +0 -0
  9. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/animation/icons8-select-cursor-transparent-96.gif +0 -0
  10. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/animation/test_animation.py +0 -0
  11. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/executor/teachmode_executor.py +0 -0
  12. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/simple_parser/__init__.py +0 -0
  13. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/simple_parser/gui_capture.py +0 -0
  14. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/simple_parser/utils.py +0 -0
  15. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/uia_tools/__init__.py +0 -0
  16. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/uia_tools/screenshot_cli.py +0 -0
  17. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/uia_tools/screenshot_service.py +0 -0
  18. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/llm_utils.py +0 -0
  19. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/oai.py +0 -0
  20. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/run_litellm.py +0 -0
  21. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/run_llm.py +0 -0
  22. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/tools/__init__.py +0 -0
  23. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/tools/aws_request.py +0 -0
  24. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/tools/base.py +0 -0
  25. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/tools/bash.py +0 -0
  26. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/tools/collection.py +0 -0
  27. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/tools/colorful_text.py +0 -0
  28. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/tools/computer.py +0 -0
  29. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/tools/computer_marbot.py +0 -0
  30. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/tools/edit.py +0 -0
  31. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/tools/run.py +0 -0
  32. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/computer_use_demo/tools/screen_capture.py +0 -0
  33. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/dependency_check.py +0 -0
  34. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/preparation/__init__.py +0 -0
  35. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/preparation/star_rail_prepare.py +0 -0
  36. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/requirements-lite.txt +0 -0
  37. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/run_teachmode_ootb_args.py +0 -0
  38. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/service_manager.py +0 -0
  39. {computer_use_ootb_internal-0.0.160 → computer_use_ootb_internal-0.0.162}/src/computer_use_ootb_internal/signal_connection.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: computer-use-ootb-internal
3
- Version: 0.0.160
3
+ Version: 0.0.162
4
4
  Summary: Computer Use OOTB
5
5
  Author-email: Siyuan Hu <siyuan.hu.sg@gmail.com>
6
6
  Requires-Python: >=3.11
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "computer-use-ootb-internal"
7
- version = "0.0.160"
7
+ version = "0.0.162"
8
8
  description = "Computer Use OOTB"
9
9
  authors = [{ name = "Siyuan Hu", email = "siyuan.hu.sg@gmail.com" }]
10
10
  requires-python = ">=3.11"
@@ -226,9 +226,7 @@ class GuardService(win32serviceutil.ServiceFramework):
226
226
  self.log_info(f"Using target executable: {self.target_executable_path}")
227
227
 
228
228
  _service_instance = self
229
- # Determine path to the signal script
230
- self.signal_script_path = self._find_signal_script()
231
- self.log_info(f"Service initialized. Target executable: {self.target_executable_path}. Signal script: {self.signal_script_path}")
229
+ self.log_info(f"Service initialized. Target executable: {self.target_executable_path}.")
232
230
 
233
231
  def SvcStop(self):
234
232
  self.log_info(f"Service stop requested.")
@@ -710,7 +708,7 @@ class GuardService(win32serviceutil.ServiceFramework):
710
708
  try:
711
709
  # 1. Ensure scheduled task exists (still useful fallback/persistence)
712
710
  try:
713
- task_created = self.create_or_update_logon_task(user)
711
+ task_created = self.create_or_update_logon_task(user, calculated_port)
714
712
  task_created_status = "task_success" if task_created else "task_failed"
715
713
  except Exception as task_err:
716
714
  self.log_error(f"Internal trigger: Exception creating/updating task for {user}: {task_err}", exc_info=True)
@@ -758,74 +756,59 @@ class GuardService(win32serviceutil.ServiceFramework):
758
756
  self.log_error(f"Internal trigger: Error checking existing processes for {user}: {e}")
759
757
  # Continue and attempt start despite error?
760
758
 
761
- # 4. Attempt immediate start (User is active and not running)
762
- immediate_start_status = "start_attempted"
763
- self.log_info(f"Internal trigger: User '{user}' is active and not running. Attempting immediate start via PowerShell elevation...")
764
-
765
- if not self.target_executable_path:
766
- self.log_error("Internal trigger: Cannot start process - target executable path not found.")
767
- final_status = "failed_exe_not_found"
768
- return final_status # Exit early if executable missing
759
+ # 4. Create/Update and Trigger Scheduled Task
760
+ immediate_start_status = "start_attempted_task_trigger"
761
+ self.log_info(f"Internal trigger: User '{user}' is active and not running. Attempting start via Task Scheduler...")
769
762
 
763
+ # --- Start Task Scheduler logic ---
770
764
  try:
771
- token = win32ts.WTSQueryUserToken(session_id)
772
- env = win32profile.CreateEnvironmentBlock(token, False)
773
- startup = win32process.STARTUPINFO()
774
- # Use CREATE_NEW_CONSOLE to make the PS window visible and potentially the UAC prompt
775
- creation_flags = win32con.CREATE_NEW_CONSOLE
776
-
777
- # Command to run PowerShell, which then elevates the target executable
778
- target_exe_unquoted = self.target_executable_path.strip('"')
779
- target_exe_for_ps = target_exe_unquoted.replace("'", "''") # Escape single quotes for PS strings
780
- target_exe_dir_for_ps = os.path.dirname(target_exe_unquoted).replace("'", "''")
781
-
782
- # 1. 准备 PowerShell 命令中需要的变量 (进行基本的 PowerShell 字符串转义)
783
- ps_target_exe = target_exe_for_ps
784
- ps_working_dir = target_exe_dir_for_ps
785
- # 用户名 'altair' 在最终命令里需要 ''altair'' 格式
786
- ps_user_arg_format = user.replace("'", "''") # 先转义用户名本身的单引号
787
-
788
- # 2. 构建最终的、完整的 PowerShell 命令字符串,严格按照模板
789
- # 模板: Start-Process -FilePath cmd.exe -ArgumentList @('/K', '"<exe_path>" --port <port> --target_user ''<username>''') -WorkingDirectory '<working_dir>' -Verb RunAs
790
- ps_command_string = f"Start-Process -FilePath cmd.exe -ArgumentList @('/K', '"""{ps_target_exe}""" --port {calculated_port} --target_user ''''{ps_user_arg_format}''''') -WorkingDirectory '{ps_working_dir}' -Verb RunAs"
791
-
792
- # 3. 为 powershell.exe -Command '...' 参数转义整个命令字符串中的单引号
793
- ps_command_string_escaped = ps_command_string.replace("'", "''")
794
-
795
- # 4. 生成最终传递给 CreateProcessAsUser 的命令行
796
- # 依然使用 powershell.exe -NoExit -Command '{ ... }' 以便观察,虽然不一定有效
797
- lpCommandLine = f"powershell.exe -NoProfile -ExecutionPolicy Bypass -NoExit -Command '{{ {ps_command_string_escaped} }}'"
765
+ # Step 4a: Ensure the task is created/updated correctly
766
+ # Pass calculated port to the task creation function
767
+ task_created = self.create_or_update_logon_task(user, calculated_port)
768
+ if not task_created:
769
+ self.log_error(f"Internal trigger: Failed to create/update scheduled task for user '{user}'. Cannot proceed with start.")
770
+ final_status = "failed_task_creation"
771
+ return final_status
798
772
 
799
- lpApplicationName = None # Must be None if using lpCommandLine
800
- cwd = os.path.dirname(target_exe_unquoted) if os.path.dirname(target_exe_unquoted) else None
773
+ # Step 4b: Trigger the task to run immediately
774
+ task_name = f"OOTB_UserConnect_{user}" # Must match the name used in create_or_update_logon_task
775
+ trigger_command = ["schtasks", "/Run", "/TN", task_name]
776
+ self.log_info(f"Internal trigger: Attempting to run task '{task_name}' immediately using: {trigger_command}")
777
+
778
+ result = subprocess.run(
779
+ trigger_command,
780
+ capture_output=True,
781
+ text=True,
782
+ check=False, # Check return code manually
783
+ encoding='utf-8',
784
+ errors='ignore'
785
+ )
801
786
 
802
- # Log details before call
803
- self.log_info(f"Internal trigger: Launching PowerShell directly for elevation:")
804
- self.log_info(f" lpCommandLine: {lpCommandLine}")
805
- self.log_info(f" lpCurrentDirectory: {cwd if cwd else 'Default'}")
787
+ if result.stdout:
788
+ self.log_info(f"Internal trigger: schtasks /Run STDOUT:\n{result.stdout.strip()}")
789
+ if result.stderr:
790
+ # schtasks often prints success message to stderr, log as info
791
+ self.log_info(f"Internal trigger: schtasks /Run STDERR:\n{result.stderr.strip()}")
806
792
 
807
- hProcess, hThread, dwPid, dwTid = win32process.CreateProcessAsUser(
808
- token, lpApplicationName, lpCommandLine, None, None, False,
809
- creation_flags, env, cwd, startup
810
- )
811
- # We get the PID of cmd.exe/powershell.exe here, not the final elevated process.
812
- # We can't easily track the elevated process PID across the UAC boundary.
813
- self.log_info(f"Internal trigger: CreateProcessAsUser call to initiate elevation succeeded for user '{user}' (Launcher PID: {dwPid}). UAC prompt expected if needed.")
814
- win32api.CloseHandle(hProcess)
815
- win32api.CloseHandle(hThread)
816
-
817
- # Assume success if the call didn't raise an exception.
818
- # We cannot easily verify if the *elevated* process actually started.
819
- immediate_start_status = "start_elevation_initiated"
820
- final_status = "success_elevation_initiated" # Report success based on initiating the elevation
821
-
822
- except Exception as proc_err:
823
- self.log_error(f"Internal trigger: Exception during CreateProcessAsUser for elevation attempt (user '{user}'): {proc_err}", exc_info=True)
824
- immediate_start_status = "start_failed_exception"
825
- final_status = "failed_start_exception"
826
- finally:
827
- if token: win32api.CloseHandle(token)
828
-
793
+ if result.returncode == 0 or "SUCCESS: Attempted to run the scheduled task" in result.stdout or "SUCCESS: Attempted to run the scheduled task" in result.stderr:
794
+ self.log_info(f"Internal trigger: Successfully triggered task '{task_name}' for user '{user}'.")
795
+ immediate_start_status = "start_success_task_triggered"
796
+ final_status = "success_task_triggered"
797
+ else:
798
+ self.log_error(f"Internal trigger: Failed to trigger task '{task_name}' (Exit Code: {result.returncode}).")
799
+ immediate_start_status = f"start_failed_task_trigger_code_{result.returncode}"
800
+ final_status = f"failed_task_trigger_code_{result.returncode}"
801
+
802
+ except FileNotFoundError:
803
+ self.log_error("Internal trigger: 'schtasks.exe' not found.")
804
+ immediate_start_status = "start_failed_schtasks_not_found"
805
+ final_status = "failed_schtasks_not_found"
806
+ except Exception as task_trigger_err:
807
+ self.log_error(f"Internal trigger: Exception during task trigger for user '{user}': {task_trigger_err}", exc_info=True)
808
+ immediate_start_status = "start_failed_task_trigger_exception"
809
+ final_status = "failed_task_trigger_exception"
810
+ # --- End Task Scheduler logic ---
811
+
829
812
  # Combine results (mostly determined by start attempt now)
830
813
  # Example: final_status = f"{task_created_status}_{immediate_start_status}"
831
814
  return final_status
@@ -835,48 +818,35 @@ class GuardService(win32serviceutil.ServiceFramework):
835
818
  return "failed_trigger_exception"
836
819
 
837
820
 
838
- def create_or_update_logon_task(self, username):
821
+ def create_or_update_logon_task(self, username, port):
839
822
  """Creates/updates task to trigger the internal signal script on session connect."""
840
- if not self.signal_script_path:
841
- self.log_error(f"Cannot create task for {username}: Signal script path is not set.")
823
+ if not self.target_executable_path:
824
+ self.log_error(f"Cannot create task for {username}: Target executable path not found.")
842
825
  return False
843
- if not sys.executable:
844
- self.log_error(f"Cannot create task for {username}: sys.executable is not found.")
845
- return False
846
-
847
- # Use the python executable that the service itself is running under
848
- python_exe = sys.executable
849
- if ' ' in python_exe and not python_exe.startswith('"'):
850
- python_exe = f'"{python_exe}"'
851
826
 
852
827
  task_name = f"OOTB_UserConnect_{username}"
853
- # Action: Run python.exe with the signal script and username argument
854
- action_executable = python_exe
855
- # Ensure script path is quoted if needed
856
- script_arg = self.signal_script_path # Should be quoted already by _find_signal_script
857
- # Username might need quoting if it contains spaces, though unlikely
858
- user_arg = username # Keep simple for now
859
- action_arguments = f'{script_arg} "{user_arg}"' # Pass username as quoted arg
860
- safe_action_executable = action_executable.replace("'", "''") # Escape for PS
861
- safe_action_arguments = action_arguments.replace("'", "''") # Escape for PS
862
-
863
- # Working directory for the script (likely its own directory)
828
+ target_exe_unquoted = self.target_executable_path.strip('"')
829
+ target_exe_for_ps = target_exe_unquoted.replace("'", "''")
830
+ action_arguments = f"--port {port} --target_user '{username}'".replace("'", "''") # Arguments for the target exe
831
+
832
+ # Working directory for the executable
864
833
  try:
865
- script_dir = os.path.dirname(self.signal_script_path.strip('"'))
866
- if not script_dir: script_dir = "."
867
- safe_working_directory = script_dir.replace("'", "''")
834
+ target_dir = os.path.dirname(target_exe_unquoted)
835
+ if not target_dir: target_dir = "."
836
+ safe_working_directory = target_dir.replace("'", "''")
868
837
  working_directory_setting = f"$action.WorkingDirectory = '{safe_working_directory}'"
869
838
  except Exception as e:
870
- self.log_error(f"Error determining working directory for signal script task: {e}. WD will not be set.")
839
+ self.log_error(f"Error determining working directory for target exe task: {e}. WD will not be set.")
871
840
  working_directory_setting = "# Could not set WorkingDirectory"
872
841
 
873
842
  # PowerShell command construction
874
843
  ps_command = f"""
875
844
  $taskName = "{task_name}"
876
- $principal = New-ScheduledTaskPrincipal -UserId "{username}" -LogonType Interactive
845
+ # Principal runs as the user, but with highest privileges
846
+ $principal = New-ScheduledTaskPrincipal -UserId "{username}" -LogonType Interactive -RunLevel Highest
877
847
 
878
- # Action: Run python signal script
879
- $action = New-ScheduledTaskAction -Execute '{safe_action_executable}' -Argument '{safe_action_arguments}'
848
+ # Action: Run the target executable directly with arguments
849
+ $action = New-ScheduledTaskAction -Execute '{target_exe_for_ps}' -Argument '{action_arguments}'
880
850
  {working_directory_setting}
881
851
 
882
852
  # Trigger: On session connect (Event ID 21)
@@ -946,24 +916,6 @@ class GuardService(win32serviceutil.ServiceFramework):
946
916
  self.log_info(f"Attempted removal of scheduled task '{task_name}' for user '{username}'.")
947
917
  return True
948
918
 
949
- def _find_signal_script(self):
950
- """Finds the signal_connection.py script relative to this service file."""
951
- try:
952
- base_dir = os.path.dirname(os.path.abspath(__file__))
953
- script_path = os.path.join(base_dir, "signal_connection.py")
954
- if os.path.exists(script_path):
955
- self.log_info(f"Found signal script at: {script_path}")
956
- # Quote if needed?
957
- if " " in script_path and not script_path.startswith('"'):
958
- return f'"{script_path}"'
959
- return script_path
960
- else:
961
- self.log_error(f"Signal script signal_connection.py not found near {base_dir}")
962
- return None
963
- except Exception as e:
964
- self.log_error(f"Error finding signal script: {e}")
965
- return None
966
-
967
919
  # --- Main Execution Block ---
968
920
  if __name__ == '__main__':
969
921
  if len(sys.argv) > 1 and sys.argv[1] == 'debug':