computer-use-ootb-internal 0.0.136__py3-none-any.whl → 0.0.138__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.
- computer_use_ootb_internal/app_teachmode.py +18 -0
- computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/llm_utils.py +0 -1
- computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/oai.py +1 -13
- computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/run_litellm.py +1 -12
- computer_use_ootb_internal/guard_service.py +295 -221
- computer_use_ootb_internal/preparation/star_rail_prepare.py +1 -23
- computer_use_ootb_internal/run_teachmode_ootb_args.py +5 -1
- computer_use_ootb_internal/signal_connection.py +48 -0
- {computer_use_ootb_internal-0.0.136.dist-info → computer_use_ootb_internal-0.0.138.dist-info}/METADATA +1 -1
- {computer_use_ootb_internal-0.0.136.dist-info → computer_use_ootb_internal-0.0.138.dist-info}/RECORD +12 -11
- {computer_use_ootb_internal-0.0.136.dist-info → computer_use_ootb_internal-0.0.138.dist-info}/WHEEL +0 -0
- {computer_use_ootb_internal-0.0.136.dist-info → computer_use_ootb_internal-0.0.138.dist-info}/entry_points.txt +0 -0
@@ -190,6 +190,11 @@ async def update_parameters(request: Request):
|
|
190
190
|
status_code=400
|
191
191
|
)
|
192
192
|
|
193
|
+
# Clear message histories before updating parameters
|
194
|
+
shared_state.message_queue.clear()
|
195
|
+
shared_state.chatbot_messages.clear()
|
196
|
+
logging.info("Cleared message queue and chatbot messages.")
|
197
|
+
|
193
198
|
shared_state.args = argparse.Namespace(**data)
|
194
199
|
shared_state.task_updated = True
|
195
200
|
|
@@ -301,13 +306,26 @@ async def stop_processing(request: Request):
|
|
301
306
|
shared_state.should_stop = True
|
302
307
|
shared_state.stop_event.set()
|
303
308
|
|
309
|
+
# Clear message histories
|
310
|
+
shared_state.message_queue.clear()
|
311
|
+
shared_state.chatbot_messages.clear()
|
312
|
+
logging.info("Cleared message queue and chatbot messages during stop.")
|
313
|
+
|
304
314
|
# Send an immediate message to the queue to inform the user
|
305
315
|
stop_initiated_msg = {"role": "assistant", "content": f"Stopping task '{shared_state.task}'...", "type": "text", "action_type": ""}
|
316
|
+
# Append the stop message AFTER clearing, so it's the only one left
|
317
|
+
shared_state.message_queue.append(stop_initiated_msg)
|
318
|
+
shared_state.chatbot_messages.append(stop_initiated_msg)
|
319
|
+
|
306
320
|
return JSONResponse(
|
307
321
|
content={"status": "success", "message": "Task is being stopped, server will remain available for new tasks"},
|
308
322
|
status_code=200
|
309
323
|
)
|
310
324
|
else:
|
325
|
+
# Clear message histories even if not processing, to ensure clean state
|
326
|
+
shared_state.message_queue.clear()
|
327
|
+
shared_state.chatbot_messages.clear()
|
328
|
+
logging.info("Cleared message queue and chatbot messages (no active process to stop).")
|
311
329
|
return JSONResponse(
|
312
330
|
content={"status": "error", "message": "No active processing to stop"},
|
313
331
|
status_code=400
|
@@ -4,19 +4,7 @@ import logging
|
|
4
4
|
import base64
|
5
5
|
import requests
|
6
6
|
|
7
|
-
|
8
|
-
def is_image_path(text):
|
9
|
-
# Checking if the input text ends with typical image file extensions
|
10
|
-
image_extensions = (".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".tif")
|
11
|
-
if text.endswith(image_extensions):
|
12
|
-
return True
|
13
|
-
else:
|
14
|
-
return False
|
15
|
-
|
16
|
-
def encode_image(image_path):
|
17
|
-
"""Encode image file to base64."""
|
18
|
-
with open(image_path, "rb") as image_file:
|
19
|
-
return base64.b64encode(image_file.read()).decode("utf-8")
|
7
|
+
from .llm_utils import is_image_path, encode_image
|
20
8
|
|
21
9
|
|
22
10
|
|
@@ -4,19 +4,8 @@ import logging
|
|
4
4
|
import base64
|
5
5
|
from litellm import completion
|
6
6
|
|
7
|
+
from .llm_utils import is_image_path, encode_image
|
7
8
|
|
8
|
-
def is_image_path(text):
|
9
|
-
# Checking if the input text ends with typical image file extensions
|
10
|
-
image_extensions = (".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".tif")
|
11
|
-
if text.endswith(image_extensions):
|
12
|
-
return True
|
13
|
-
else:
|
14
|
-
return False
|
15
|
-
|
16
|
-
def encode_image(image_path):
|
17
|
-
"""Encode image file to base64."""
|
18
|
-
with open(image_path, "rb") as image_file:
|
19
|
-
return base64.b64encode(image_file.read()).decode("utf-8")
|
20
9
|
|
21
10
|
def run_litellm(messages: list, system: str, llm: str, max_tokens=256, temperature=0):
|
22
11
|
"""
|
@@ -86,6 +86,39 @@ def receive_command():
|
|
86
86
|
|
87
87
|
return jsonify({"message": f"Command {command_id} received and queued"}), 202 # Accepted
|
88
88
|
|
89
|
+
@flask_app.route('/internal/user_connected', methods=['POST'])
|
90
|
+
def user_connected_notification():
|
91
|
+
"""Internal endpoint triggered by the scheduled task helper script."""
|
92
|
+
global _service_instance
|
93
|
+
if not _service_instance:
|
94
|
+
logging.error("Received user_connected signal but service instance is not set.")
|
95
|
+
return jsonify({"error": "Service not ready"}), 503
|
96
|
+
|
97
|
+
if not request.is_json:
|
98
|
+
logging.warning("Received non-JSON user_connected signal.")
|
99
|
+
return jsonify({"error": "Request must be JSON"}), 400
|
100
|
+
|
101
|
+
data = request.get_json()
|
102
|
+
username = data.get("username")
|
103
|
+
if not username:
|
104
|
+
logging.error("Received user_connected signal with no username.")
|
105
|
+
return jsonify({"error": "Missing 'username' in data"}), 400
|
106
|
+
|
107
|
+
logging.info(f"Received user_connected signal for user: {username}")
|
108
|
+
|
109
|
+
# Call the internal start logic directly (non-blocking? or blocking?)
|
110
|
+
# Let's make it non-blocking by putting it on the main command queue
|
111
|
+
# This avoids holding up the signal script and uses the existing processor.
|
112
|
+
internal_command = {
|
113
|
+
"action": "_internal_start_ootb",
|
114
|
+
"target_user": username
|
115
|
+
}
|
116
|
+
internal_command_id = f"internal_{username}_{time.time():.0f}"
|
117
|
+
_service_instance.command_queue.put((internal_command_id, internal_command))
|
118
|
+
logging.info(f"Queued internal start command {internal_command_id} for user {username}.")
|
119
|
+
|
120
|
+
return jsonify({"message": "Signal received and queued"}), 202
|
121
|
+
|
89
122
|
# --- Helper Functions --- Only logging helpers needed adjustments
|
90
123
|
# Move these inside the class later
|
91
124
|
# def get_python_executable(): ...
|
@@ -193,7 +226,9 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
193
226
|
self.log_info(f"Using target executable: {self.target_executable_path}")
|
194
227
|
|
195
228
|
_service_instance = self
|
196
|
-
|
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}")
|
197
232
|
|
198
233
|
def SvcStop(self):
|
199
234
|
self.log_info(f"Service stop requested.")
|
@@ -263,9 +298,10 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
263
298
|
command_id, command = item
|
264
299
|
action = command.get("action")
|
265
300
|
target = command.get("target_user", "all_active")
|
266
|
-
status = "failed_unknown" # Default
|
301
|
+
status = "failed_unknown" # Default status for external commands
|
302
|
+
is_internal = action == "_internal_start_ootb"
|
267
303
|
|
268
|
-
self.log_info(f"Dequeued Command ID {command_id}: action='{action}', target='{target}'")
|
304
|
+
self.log_info(f"Dequeued {'Internal' if is_internal else 'External'} Command ID {command_id}: action='{action}', target='{target}'")
|
269
305
|
|
270
306
|
try:
|
271
307
|
if action == "update":
|
@@ -274,6 +310,11 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
274
310
|
status = self.handle_stop(target)
|
275
311
|
elif action == "start_ootb":
|
276
312
|
status = self.handle_start(target)
|
313
|
+
elif action == "_internal_start_ootb":
|
314
|
+
# Call the core start logic but don't report status back externally
|
315
|
+
internal_status = self._trigger_start_for_user(target)
|
316
|
+
self.log_info(f"Internal start for {target} finished with status: {internal_status}")
|
317
|
+
# No external status reporting for internal commands
|
277
318
|
else:
|
278
319
|
self.log_error(f"Unknown action in queue: {action}")
|
279
320
|
status = "failed_unknown_action"
|
@@ -281,7 +322,9 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
281
322
|
self.log_error(f"Exception processing Command ID {command_id} ({action}): {handler_ex}", exc_info=True)
|
282
323
|
status = "failed_exception"
|
283
324
|
finally:
|
284
|
-
|
325
|
+
# Only report status for non-internal commands
|
326
|
+
if not is_internal:
|
327
|
+
self.report_command_status(command_id, status)
|
285
328
|
self.command_queue.task_done()
|
286
329
|
|
287
330
|
except queue.Empty:
|
@@ -320,25 +363,50 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
320
363
|
# --- Command Handlers --- Now call self. for helpers
|
321
364
|
|
322
365
|
def handle_update(self):
|
366
|
+
"""Handles the update command by running the target executable with the 'update' argument."""
|
323
367
|
self.log_info("Executing OOTB update...")
|
324
368
|
if not self.target_executable_path:
|
325
|
-
self.log_error("Cannot update: Target executable not
|
369
|
+
self.log_error("Cannot update: Target executable path is not set.")
|
326
370
|
return "failed_executable_not_found"
|
327
371
|
|
328
|
-
|
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"]
|
378
|
+
|
329
379
|
self.log_info(f"Running update command: {update_command}")
|
330
380
|
try:
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
381
|
+
# Execute the command directly. Running as LocalSystem should have rights to ProgramData.
|
382
|
+
# Capture output for logging.
|
383
|
+
result = subprocess.run(
|
384
|
+
[executable_for_run] + args_for_run,
|
385
|
+
capture_output=True,
|
386
|
+
text=True,
|
387
|
+
check=False, # Don't throw on non-zero exit, we check manually
|
388
|
+
encoding='utf-8',
|
389
|
+
errors='ignore'
|
390
|
+
)
|
391
|
+
|
392
|
+
# Log stdout/stderr regardless of exit code
|
393
|
+
if result.stdout:
|
394
|
+
self.log_info(f"Update process STDOUT:\n{result.stdout.strip()}")
|
395
|
+
if result.stderr:
|
396
|
+
self.log_warning(f"Update process STDERR:\n{result.stderr.strip()}") # Use warning for stderr
|
397
|
+
|
398
|
+
if result.returncode == 0:
|
399
|
+
self.log_info("Update process completed successfully (Exit Code 0).")
|
400
|
+
return "success"
|
401
|
+
else:
|
402
|
+
self.log_error(f"Update process failed (Exit Code {result.returncode}).")
|
403
|
+
return f"failed_update_exit_code_{result.returncode}"
|
404
|
+
|
405
|
+
except FileNotFoundError:
|
406
|
+
self.log_error(f"Update failed: Executable not found at '{executable_for_run}'.")
|
407
|
+
return "failed_executable_not_found"
|
340
408
|
except Exception as e:
|
341
|
-
self.log_error(f"
|
409
|
+
self.log_error(f"Update failed with exception: {e}", exc_info=True)
|
342
410
|
return "failed_exception"
|
343
411
|
|
344
412
|
def _get_ootb_processes(self, target_user="all_active"):
|
@@ -511,218 +579,210 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
511
579
|
|
512
580
|
|
513
581
|
def handle_start(self, target_user="all_active"):
|
514
|
-
|
515
|
-
|
516
|
-
|
582
|
+
"""Handles external start command request (finds users, calls internal trigger)."""
|
583
|
+
self.log_info(f"External start requested for target '{target_user}'...")
|
584
|
+
# This function now primarily identifies target users and calls the internal trigger method.
|
585
|
+
# The status returned here reflects the process of identifying and triggering,
|
586
|
+
# not necessarily the final success/failure of the actual start (which happens async).
|
587
|
+
|
588
|
+
active_sessions = {} # user_lower: session_id
|
589
|
+
all_system_users = set() # user_lower
|
590
|
+
try:
|
591
|
+
# Use psutil for system user list, WTS for active sessions/IDs
|
592
|
+
for user_session in psutil.users():
|
593
|
+
username_lower = user_session.name.split('\\')[-1].lower()
|
594
|
+
all_system_users.add(username_lower)
|
595
|
+
|
596
|
+
sessions = win32ts.WTSEnumerateSessions(win32ts.WTS_CURRENT_SERVER_HANDLE)
|
597
|
+
for session in sessions:
|
598
|
+
if session['State'] == win32ts.WTSActive:
|
599
|
+
try:
|
600
|
+
user = win32ts.WTSQuerySessionInformation(win32ts.WTS_CURRENT_SERVER_HANDLE, session['SessionId'], win32ts.WTSUserName)
|
601
|
+
if user:
|
602
|
+
active_sessions[user.lower()] = session['SessionId']
|
603
|
+
except Exception as query_err:
|
604
|
+
self.log_error(f"Could not query session {session['SessionId']}: {query_err}")
|
605
|
+
except Exception as user_enum_err:
|
606
|
+
self.log_error(f"Error enumerating users/sessions: {user_enum_err}", exc_info=True)
|
607
|
+
return "failed_user_enumeration"
|
608
|
+
|
609
|
+
target_users_normalized = set()
|
610
|
+
if target_user == "all_active":
|
611
|
+
target_users_normalized = set(active_sessions.keys())
|
612
|
+
self.log_info(f"Targeting all active users for start: {target_users_normalized}")
|
613
|
+
else:
|
614
|
+
normalized_target = target_user.lower()
|
615
|
+
target_users_normalized.add(normalized_target)
|
616
|
+
self.log_info(f"Targeting specific user for start: {normalized_target}")
|
617
|
+
|
618
|
+
if not target_users_normalized:
|
619
|
+
self.log_info("No target users identified for start.")
|
620
|
+
return "failed_no_target_users"
|
621
|
+
|
622
|
+
trigger_results = {}
|
623
|
+
for user in target_users_normalized:
|
624
|
+
self.log_info(f"Calling internal start trigger for user: {user}")
|
625
|
+
# Call the core logic directly (this is now synchronous within the handler)
|
626
|
+
# Or queue it? Queuing might be better to avoid blocking the handler if many users.
|
627
|
+
# Let's stick to the queue approach from the internal endpoint:
|
628
|
+
internal_command = {
|
629
|
+
"action": "_internal_start_ootb",
|
630
|
+
"target_user": user
|
631
|
+
}
|
632
|
+
internal_command_id = f"external_{user}_{time.time():.0f}"
|
633
|
+
self.command_queue.put((internal_command_id, internal_command))
|
634
|
+
trigger_results[user] = "queued"
|
635
|
+
|
636
|
+
self.log_info(f"Finished queuing start triggers. Results: {trigger_results}")
|
637
|
+
# The status here just means we successfully queued the actions
|
638
|
+
# Actual success/failure happens in the command processor later.
|
639
|
+
# We might need a different way to report overall status if needed.
|
640
|
+
return f"success_queued::{json.dumps(trigger_results)}"
|
641
|
+
|
642
|
+
|
643
|
+
def _trigger_start_for_user(self, username):
|
644
|
+
"""Core logic to start OOTB for a single user. Called internally."""
|
645
|
+
user = username.lower() # Ensure lowercase
|
646
|
+
self.log_info(f"Internal trigger: Starting OOTB check for user '{user}'...")
|
647
|
+
task_created_status = "task_unknown"
|
648
|
+
immediate_start_status = "start_not_attempted"
|
649
|
+
final_status = "failed_unknown"
|
517
650
|
|
518
651
|
try:
|
519
|
-
#
|
520
|
-
|
521
|
-
|
652
|
+
# 1. Ensure scheduled task exists (still useful fallback/persistence)
|
653
|
+
try:
|
654
|
+
task_created = self.create_or_update_logon_task(user)
|
655
|
+
task_created_status = "task_success" if task_created else "task_failed"
|
656
|
+
except Exception as task_err:
|
657
|
+
self.log_error(f"Internal trigger: Exception creating/updating task for {user}: {task_err}", exc_info=True)
|
658
|
+
task_created_status = "task_exception"
|
659
|
+
# Don't necessarily fail the whole operation yet
|
660
|
+
|
661
|
+
# 2. Check if user is active
|
662
|
+
active_sessions = {} # Re-check active sessions specifically for this user
|
663
|
+
session_id = None
|
664
|
+
token = None
|
665
|
+
is_active = False
|
522
666
|
try:
|
523
|
-
# Use psutil for system user list, WTS for active sessions/IDs
|
524
|
-
for user_session in psutil.users():
|
525
|
-
username_lower = user_session.name.split('\\')[-1].lower()
|
526
|
-
all_system_users.add(username_lower)
|
527
|
-
|
528
667
|
sessions = win32ts.WTSEnumerateSessions(win32ts.WTS_CURRENT_SERVER_HANDLE)
|
529
668
|
for session in sessions:
|
530
669
|
if session['State'] == win32ts.WTSActive:
|
531
670
|
try:
|
532
|
-
|
533
|
-
if user:
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
target_users_normalized = set()
|
544
|
-
if target_user == "all_active":
|
545
|
-
# If targeting all_active, only target those CURRENTLY active
|
546
|
-
target_users_normalized = set(active_sessions.keys())
|
547
|
-
self.log_info(f"Targeting all active users: {target_users_normalized}")
|
548
|
-
else:
|
549
|
-
normalized_target = target_user.lower()
|
550
|
-
# Check if the target user actually exists on the system, even if inactive
|
551
|
-
# This check might be complex/unreliable. Rely on task scheduler potentially failing?
|
552
|
-
# Let's assume admin provides a valid username for specific targeting.
|
553
|
-
# if normalized_target in all_system_users: # Removing this check, assume valid user input
|
554
|
-
target_users_normalized.add(normalized_target)
|
555
|
-
self.log_info(f"Targeting specific user: {normalized_target}")
|
556
|
-
# else:
|
557
|
-
# log_error(f"Target user '{target_user}' does not appear to exist on this system based on psutil.")
|
558
|
-
# return "failed_user_does_not_exist"
|
559
|
-
|
560
|
-
if not target_users_normalized:
|
561
|
-
self.log_info("No target users identified (or none active for 'all_active').")
|
562
|
-
# If target was specific user but they weren't found active, still try task?
|
563
|
-
# Let's proceed to task creation anyway for specific user case.
|
564
|
-
if target_user != "all_active": target_users_normalized.add(target_user.lower())
|
565
|
-
if not target_users_normalized:
|
566
|
-
return "failed_no_target_users"
|
671
|
+
current_user = win32ts.WTSQuerySessionInformation(win32ts.WTS_CURRENT_SERVER_HANDLE, session['SessionId'], win32ts.WTSUserName)
|
672
|
+
if current_user and current_user.lower() == user:
|
673
|
+
session_id = session['SessionId']
|
674
|
+
is_active = True
|
675
|
+
self.log_info(f"Internal trigger: User '{user}' is active in session {session_id}.")
|
676
|
+
break
|
677
|
+
except Exception: pass # Ignore errors querying other sessions
|
678
|
+
except Exception as e:
|
679
|
+
self.log_error(f"Internal trigger: Error checking active sessions for {user}: {e}")
|
680
|
+
# Continue, assume inactive if check failed?
|
567
681
|
|
568
|
-
|
569
|
-
|
570
|
-
|
682
|
+
if not is_active:
|
683
|
+
self.log_info(f"Internal trigger: User '{user}' is not active. Skipping immediate start.")
|
684
|
+
immediate_start_status = "start_skipped_inactive"
|
685
|
+
final_status = task_created_status # Status depends only on task creation
|
686
|
+
return final_status # Exit early if inactive
|
687
|
+
|
688
|
+
# 3. Check if already running for this active user
|
689
|
+
is_running = False
|
571
690
|
try:
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
except Exception: pass
|
691
|
+
running_procs = self._get_ootb_processes(user)
|
692
|
+
if running_procs:
|
693
|
+
is_running = True
|
694
|
+
self.log_info(f"Internal trigger: OOTB already running for active user '{user}'. Skipping immediate start.")
|
695
|
+
immediate_start_status = "start_skipped_already_running"
|
696
|
+
final_status = "success_already_running" # Considered success
|
697
|
+
return final_status # Exit early if already running
|
580
698
|
except Exception as e:
|
581
|
-
self.log_error(f"Error checking existing processes: {e}")
|
582
|
-
|
583
|
-
|
584
|
-
# --- Process each target user ---
|
585
|
-
for user in target_users_normalized:
|
586
|
-
task_created_status = "task_unknown"
|
587
|
-
immediate_start_status = "start_not_attempted"
|
588
|
-
token = None # Ensure token is reset/defined
|
589
|
-
|
590
|
-
self.log_info(f"Processing start for user '{user}'...")
|
591
|
-
|
592
|
-
# 1. Always try to create/update the scheduled task
|
593
|
-
try:
|
594
|
-
task_created = self.create_or_update_logon_task(user)
|
595
|
-
task_created_status = "task_success" if task_created else "task_failed"
|
596
|
-
except Exception as task_err:
|
597
|
-
self.log_error(f"Exception creating/updating scheduled task for {user}: {task_err}", exc_info=True)
|
598
|
-
task_created_status = "task_exception"
|
599
|
-
failed_users.add(user)
|
600
|
-
# Continue to potentially try immediate start IF user is active?
|
601
|
-
# Or maybe skip if task creation failed badly?
|
602
|
-
# Let's skip immediate start if task creation had exception.
|
603
|
-
start_results[user] = (task_created_status, immediate_start_status)
|
604
|
-
continue
|
605
|
-
|
606
|
-
# 2. If user is active AND not already running, try immediate start
|
607
|
-
is_active = user in active_sessions
|
608
|
-
is_running = running_procs_by_user.get(user, 0) > 0
|
609
|
-
|
610
|
-
if is_active:
|
611
|
-
if not is_running:
|
612
|
-
immediate_start_status = "start_attempted"
|
613
|
-
self.log_info(f"User '{user}' is active and not running OOTB. Attempting immediate start...")
|
614
|
-
try:
|
615
|
-
session_id = active_sessions[user]
|
616
|
-
token = win32ts.WTSQueryUserToken(session_id)
|
617
|
-
env = win32profile.CreateEnvironmentBlock(token, False) # <-- Restore creating env block
|
618
|
-
startup = win32process.STARTUPINFO()
|
619
|
-
creation_flags = 0x00000010 # CREATE_NEW_CONSOLE
|
620
|
-
|
621
|
-
# --- Launch via cmd /K ---
|
622
|
-
lpApplicationName = None
|
623
|
-
lpCommandLine = f'cmd.exe /K "{self.target_executable_path}"'
|
624
|
-
cwd = os.path.dirname(self.target_executable_path.strip('"')) if os.path.dirname(self.target_executable_path.strip('"')) != '' else None
|
625
|
-
# --- End Launch via cmd /K ---
|
626
|
-
|
627
|
-
self.log_info(f"Calling CreateProcessAsUser to launch via cmd /K (Restored Environment Block):") # Updated log note
|
628
|
-
self.log_info(f" lpApplicationName: {lpApplicationName}")
|
629
|
-
self.log_info(f" lpCommandLine: {lpCommandLine}")
|
630
|
-
self.log_info(f" lpCurrentDirectory: {cwd if cwd else 'Default'}")
|
631
|
-
self.log_info(f" dwCreationFlags: {creation_flags} (CREATE_NEW_CONSOLE)")
|
632
|
-
|
633
|
-
# CreateProcessAsUser call with restored env
|
634
|
-
hProcess, hThread, dwPid, dwTid = win32process.CreateProcessAsUser(
|
635
|
-
token, # User token
|
636
|
-
lpApplicationName, # Application name (None)
|
637
|
-
lpCommandLine, # Command line (cmd.exe /K "...")
|
638
|
-
None, # Process attributes
|
639
|
-
None, # Thread attributes
|
640
|
-
False, # Inherit handles
|
641
|
-
creation_flags, # Creation flags (CREATE_NEW_CONSOLE)
|
642
|
-
env, # Environment block (Restored)
|
643
|
-
cwd, # Current directory for cmd.exe
|
644
|
-
startup # Startup info
|
645
|
-
)
|
646
|
-
|
647
|
-
self.log_info(f"CreateProcessAsUser call succeeded for user '{user}' (PID: {dwPid}). Checking existence...")
|
648
|
-
win32api.CloseHandle(hProcess)
|
649
|
-
win32api.CloseHandle(hThread)
|
650
|
-
|
651
|
-
time.sleep(1)
|
652
|
-
if psutil.pid_exists(dwPid):
|
653
|
-
self.log_info(f"Immediate start succeeded for user '{user}' (PID {dwPid}).")
|
654
|
-
immediate_start_status = "start_success"
|
655
|
-
else:
|
656
|
-
self.log_error(f"Immediate start failed for user '{user}': Process {dwPid} exited immediately.")
|
657
|
-
immediate_start_status = "start_failed_exited"
|
658
|
-
failed_users.add(user)
|
659
|
-
|
660
|
-
except Exception as proc_err:
|
661
|
-
self.log_error(f"Exception during immediate start for user '{user}': {proc_err}", exc_info=True)
|
662
|
-
immediate_start_status = "start_failed_exception"
|
663
|
-
failed_users.add(user)
|
664
|
-
finally:
|
665
|
-
if token:
|
666
|
-
try: win32api.CloseHandle(token)
|
667
|
-
except: pass
|
668
|
-
else: # User is active but already running
|
669
|
-
self.log_info(f"User '{user}' is active but OOTB is already running. Skipping immediate start.")
|
670
|
-
immediate_start_status = "start_skipped_already_running"
|
671
|
-
else: # User is not active
|
672
|
-
self.log_info(f"User '{user}' is not active. Skipping immediate start (task created/updated).")
|
673
|
-
immediate_start_status = "start_skipped_inactive"
|
674
|
-
|
675
|
-
# Record final results for this user
|
676
|
-
start_results[user] = (task_created_status, immediate_start_status)
|
699
|
+
self.log_error(f"Internal trigger: Error checking existing processes for {user}: {e}")
|
700
|
+
# Continue and attempt start despite error?
|
677
701
|
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
702
|
+
# 4. Attempt immediate start (User is active and not running)
|
703
|
+
immediate_start_status = "start_attempted"
|
704
|
+
self.log_info(f"Internal trigger: User '{user}' is active and not running. Attempting immediate start via CreateProcessAsUser...")
|
705
|
+
try:
|
706
|
+
token = win32ts.WTSQueryUserToken(session_id)
|
707
|
+
env = win32profile.CreateEnvironmentBlock(token, False)
|
708
|
+
startup = win32process.STARTUPINFO()
|
709
|
+
creation_flags = 0x00000010 # CREATE_NEW_CONSOLE
|
710
|
+
lpApplicationName = None
|
711
|
+
lpCommandLine = f'cmd.exe /K "{self.target_executable_path}"'
|
712
|
+
cwd = os.path.dirname(self.target_executable_path.strip('"')) if os.path.dirname(self.target_executable_path.strip('"')) != '' else None
|
713
|
+
|
714
|
+
# Log details before call
|
715
|
+
self.log_info(f"Internal trigger: Calling CreateProcessAsUser:")
|
716
|
+
self.log_info(f" lpCommandLine: {lpCommandLine}")
|
717
|
+
self.log_info(f" lpCurrentDirectory: {cwd if cwd else 'Default'}")
|
718
|
+
|
719
|
+
hProcess, hThread, dwPid, dwTid = win32process.CreateProcessAsUser(
|
720
|
+
token, lpApplicationName, lpCommandLine, None, None, False,
|
721
|
+
creation_flags, env, cwd, startup
|
722
|
+
)
|
723
|
+
self.log_info(f"Internal trigger: CreateProcessAsUser call succeeded for user '{user}' (PID: {dwPid}). Checking existence...")
|
724
|
+
win32api.CloseHandle(hProcess)
|
725
|
+
win32api.CloseHandle(hThread)
|
726
|
+
|
727
|
+
time.sleep(1)
|
728
|
+
if psutil.pid_exists(dwPid):
|
729
|
+
self.log_info(f"Internal trigger: Immediate start succeeded for user '{user}' (PID {dwPid}).")
|
730
|
+
immediate_start_status = "start_success"
|
731
|
+
final_status = "success" # Overall success
|
690
732
|
else:
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
733
|
+
self.log_error(f"Internal trigger: Immediate start failed for user '{user}': Process {dwPid} exited immediately.")
|
734
|
+
immediate_start_status = "start_failed_exited"
|
735
|
+
final_status = "failed_start_exited"
|
736
|
+
|
737
|
+
except Exception as proc_err:
|
738
|
+
self.log_error(f"Internal trigger: Exception during CreateProcessAsUser for user '{user}': {proc_err}", exc_info=True)
|
739
|
+
immediate_start_status = "start_failed_exception"
|
740
|
+
final_status = "failed_start_exception"
|
741
|
+
finally:
|
742
|
+
if token: win32api.CloseHandle(token)
|
743
|
+
|
744
|
+
# Combine results (though mostly determined by start attempt now)
|
745
|
+
# Example: final_status = f"{task_created_status}_{immediate_start_status}"
|
746
|
+
return final_status
|
700
747
|
|
701
748
|
except Exception as e:
|
702
|
-
self.log_error(f"
|
703
|
-
return "
|
749
|
+
self.log_error(f"Internal trigger: Unexpected error processing start for {username}: {e}", exc_info=True)
|
750
|
+
return "failed_trigger_exception"
|
751
|
+
|
704
752
|
|
705
753
|
def create_or_update_logon_task(self, username):
|
706
|
-
"""Creates/updates task to
|
707
|
-
if not self.
|
708
|
-
self.log_error(f"Cannot create task for {username}:
|
754
|
+
"""Creates/updates task to trigger the internal signal script on session connect."""
|
755
|
+
if not self.signal_script_path:
|
756
|
+
self.log_error(f"Cannot create task for {username}: Signal script path is not set.")
|
709
757
|
return False
|
758
|
+
if not sys.executable:
|
759
|
+
self.log_error(f"Cannot create task for {username}: sys.executable is not found.")
|
760
|
+
return False
|
761
|
+
|
762
|
+
# Use the python executable that the service itself is running under
|
763
|
+
python_exe = sys.executable
|
764
|
+
if ' ' in python_exe and not python_exe.startswith('"'):
|
765
|
+
python_exe = f'"{python_exe}"'
|
710
766
|
|
711
767
|
task_name = f"OOTB_UserConnect_{username}"
|
712
|
-
# Action:
|
713
|
-
action_executable =
|
714
|
-
|
715
|
-
|
716
|
-
|
768
|
+
# Action: Run python.exe with the signal script and username argument
|
769
|
+
action_executable = python_exe
|
770
|
+
# Ensure script path is quoted if needed
|
771
|
+
script_arg = self.signal_script_path # Should be quoted already by _find_signal_script
|
772
|
+
# Username might need quoting if it contains spaces, though unlikely
|
773
|
+
user_arg = username # Keep simple for now
|
774
|
+
action_arguments = f'{script_arg} "{user_arg}"' # Pass username as quoted arg
|
775
|
+
safe_action_executable = action_executable.replace("'", "''") # Escape for PS
|
776
|
+
safe_action_arguments = action_arguments.replace("'", "''") # Escape for PS
|
717
777
|
|
718
|
-
#
|
778
|
+
# Working directory for the script (likely its own directory)
|
719
779
|
try:
|
720
|
-
|
721
|
-
if not
|
722
|
-
safe_working_directory =
|
780
|
+
script_dir = os.path.dirname(self.signal_script_path.strip('"'))
|
781
|
+
if not script_dir: script_dir = "."
|
782
|
+
safe_working_directory = script_dir.replace("'", "''")
|
723
783
|
working_directory_setting = f"$action.WorkingDirectory = '{safe_working_directory}'"
|
724
784
|
except Exception as e:
|
725
|
-
self.log_error(f"Error determining working directory for task: {e}. WD will not be set.")
|
785
|
+
self.log_error(f"Error determining working directory for signal script task: {e}. WD will not be set.")
|
726
786
|
working_directory_setting = "# Could not set WorkingDirectory"
|
727
787
|
|
728
788
|
# PowerShell command construction
|
@@ -730,33 +790,29 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
730
790
|
$taskName = "{task_name}"
|
731
791
|
$principal = New-ScheduledTaskPrincipal -UserId "{username}" -LogonType Interactive
|
732
792
|
|
733
|
-
# Action: Run
|
793
|
+
# Action: Run python signal script
|
734
794
|
$action = New-ScheduledTaskAction -Execute '{safe_action_executable}' -Argument '{safe_action_arguments}'
|
735
|
-
{working_directory_setting}
|
795
|
+
{working_directory_setting}
|
736
796
|
|
737
|
-
#
|
797
|
+
# Trigger: On session connect (Event ID 21)
|
738
798
|
$logName = 'Microsoft-Windows-TerminalServices-LocalSessionManager/Operational'
|
739
799
|
$source = 'Microsoft-Windows-TerminalServices-LocalSessionManager'
|
740
|
-
|
741
|
-
$
|
742
|
-
|
743
|
-
#
|
744
|
-
# $trigger1.Delay = 'PT15S'
|
745
|
-
# $trigger2.Delay = 'PT15S'
|
800
|
+
$eventIDs = @(21, 25)
|
801
|
+
$trigger = New-ScheduledTaskTrigger -Event -LogName $logName -Source $source -EventId $eventIDs[0]
|
802
|
+
# Optional Delay: -Delay 'PT15S'
|
803
|
+
# $trigger.Delay = 'PT15S'
|
746
804
|
|
747
805
|
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit (New-TimeSpan -Days 9999) -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1)
|
748
|
-
$description = "
|
806
|
+
$description = "Triggers OOTB Guard Service for user {username} upon session connect via internal signal." # Updated description
|
749
807
|
|
750
|
-
# Unregister existing task first (force)
|
808
|
+
# Unregister existing task first (force)
|
751
809
|
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue
|
752
810
|
|
753
|
-
# Register the new task
|
754
|
-
Register-ScheduledTask -TaskName $taskName -Principal $principal -Action $action -Trigger $
|
755
|
-
|
811
|
+
# Register the new task
|
812
|
+
Register-ScheduledTask -TaskName $taskName -Principal $principal -Action $action -Trigger $trigger -Settings $settings -Description $description -Force
|
756
813
|
"""
|
757
|
-
self.log_info(f"Attempting to create/update task '{task_name}' for user '{username}' to run
|
814
|
+
self.log_info(f"Attempting to create/update task '{task_name}' for user '{username}' to run signal script.")
|
758
815
|
try:
|
759
|
-
# Need to actually run the powershell command here!
|
760
816
|
success = self.run_powershell_command(ps_command)
|
761
817
|
if success:
|
762
818
|
self.log_info(f"Successfully ran PowerShell command to create/update task '{task_name}'.")
|
@@ -805,6 +861,24 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
805
861
|
self.log_info(f"Attempted removal of scheduled task '{task_name}' for user '{username}'.")
|
806
862
|
return True
|
807
863
|
|
864
|
+
def _find_signal_script(self):
|
865
|
+
"""Finds the signal_connection.py script relative to this service file."""
|
866
|
+
try:
|
867
|
+
base_dir = os.path.dirname(os.path.abspath(__file__))
|
868
|
+
script_path = os.path.join(base_dir, "signal_connection.py")
|
869
|
+
if os.path.exists(script_path):
|
870
|
+
self.log_info(f"Found signal script at: {script_path}")
|
871
|
+
# Quote if needed?
|
872
|
+
if " " in script_path and not script_path.startswith('"'):
|
873
|
+
return f'"{script_path}"'
|
874
|
+
return script_path
|
875
|
+
else:
|
876
|
+
self.log_error(f"Signal script signal_connection.py not found near {base_dir}")
|
877
|
+
return None
|
878
|
+
except Exception as e:
|
879
|
+
self.log_error(f"Error finding signal script: {e}")
|
880
|
+
return None
|
881
|
+
|
808
882
|
# --- Main Execution Block ---
|
809
883
|
if __name__ == '__main__':
|
810
884
|
if len(sys.argv) > 1 and sys.argv[1] == 'debug':
|
@@ -1,7 +1,6 @@
|
|
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
|
5
4
|
import pyautogui
|
6
5
|
import webbrowser
|
7
6
|
import logging # Use logging instead of print for better practice
|
@@ -12,8 +11,7 @@ log = logging.getLogger(__name__)
|
|
12
11
|
def run_preparation(state):
|
13
12
|
"""
|
14
13
|
Performs environment preparation specific to Star Rail on Windows.
|
15
|
-
|
16
|
-
and performs initial clicks.
|
14
|
+
Opens the specified URL in Edge and performs initial clicks.
|
17
15
|
"""
|
18
16
|
if platform.system() != "Windows":
|
19
17
|
log.info("Star Rail preparation skipped: Not running on Windows.")
|
@@ -23,31 +21,11 @@ def run_preparation(state):
|
|
23
21
|
url = "https://sr.mihoyo.com/cloud/#/" # Consider making this configurable later
|
24
22
|
browser_opened = False
|
25
23
|
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
|
-
|
44
24
|
# Use only webbrowser.open
|
45
25
|
log.info(f"Attempting to open {url} using webbrowser.open()...")
|
46
26
|
if webbrowser.open(url):
|
47
27
|
log.info(f"Successfully requested browser to open {url} via webbrowser.open().")
|
48
28
|
browser_opened = True
|
49
|
-
# Keep original sleep time for browser load before clicks
|
50
|
-
time.sleep(5)
|
51
29
|
else:
|
52
30
|
log.warning("webbrowser.open() returned False, indicating potential failure.")
|
53
31
|
|
@@ -3,6 +3,7 @@ import time
|
|
3
3
|
import json
|
4
4
|
import platform
|
5
5
|
import uuid
|
6
|
+
import base64
|
6
7
|
import datetime
|
7
8
|
from datetime import datetime, timedelta, timezone
|
8
9
|
|
@@ -74,7 +75,10 @@ def simple_teachmode_sampling_loop(
|
|
74
75
|
# yield {"role": "assistant", "content": "screenshot", "type": "action", "action_type": "screenshot"}
|
75
76
|
|
76
77
|
if is_image_path(sc_path):
|
77
|
-
yield {"role": "assistant", "content": sc_path, "type": "image", "action_type": "screenshot"}
|
78
|
+
# yield {"role": "assistant", "content": sc_path, "type": "image", "action_type": "screenshot"}
|
79
|
+
with open(sc_path, "rb") as image_file:
|
80
|
+
sc_base64 = base64.b64encode(image_file.read()).decode('utf-8')
|
81
|
+
yield {"role": "assistant", "content": sc_base64, "type": "image_base64", "action_type": "screenshot"}
|
78
82
|
|
79
83
|
payload = {
|
80
84
|
"task_id": unique_task_id,
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Helper script to signal guard service about user connection
|
2
|
+
# Save as e.g., ootb_lite_pypi/ootb_lite_pypi/src/computer_use_ootb_internal/signal_connection.py
|
3
|
+
import sys
|
4
|
+
import requests
|
5
|
+
import logging
|
6
|
+
import os
|
7
|
+
import pathlib
|
8
|
+
|
9
|
+
# Basic logging for the script itself
|
10
|
+
LOG_DIR = pathlib.Path(os.environ.get('PROGRAMDATA', 'C:/ProgramData')) / "OOTBGuardService" / "SignalLogs"
|
11
|
+
LOG_DIR.mkdir(parents=True, exist_ok=True)
|
12
|
+
LOG_FILE = LOG_DIR / "signal_connection.log"
|
13
|
+
|
14
|
+
logging.basicConfig(
|
15
|
+
filename=LOG_FILE,
|
16
|
+
level=logging.INFO,
|
17
|
+
format='%(asctime)s %(levelname)s: %(message)s'
|
18
|
+
)
|
19
|
+
|
20
|
+
GUARD_SERVICE_URL = "http://localhost:14000/internal/user_connected"
|
21
|
+
|
22
|
+
if __name__ == "__main__":
|
23
|
+
if len(sys.argv) < 2:
|
24
|
+
logging.error("Username argument missing.")
|
25
|
+
sys.exit(1)
|
26
|
+
|
27
|
+
username = sys.argv[1]
|
28
|
+
logging.info(f"Signaling connection for user: {username}")
|
29
|
+
|
30
|
+
payload = {"username": username}
|
31
|
+
|
32
|
+
try:
|
33
|
+
response = requests.post(GUARD_SERVICE_URL, json=payload, timeout=10)
|
34
|
+
response.raise_for_status()
|
35
|
+
logging.info(f"Successfully signaled connection for user {username}. Status: {response.status_code}")
|
36
|
+
sys.exit(0)
|
37
|
+
except requests.exceptions.ConnectionError:
|
38
|
+
logging.error(f"Connection refused when trying to signal for user {username}. Guard service might not be running or accessible.")
|
39
|
+
sys.exit(2)
|
40
|
+
except requests.exceptions.Timeout:
|
41
|
+
logging.error(f"Timeout when trying to signal for user {username}.")
|
42
|
+
sys.exit(3)
|
43
|
+
except requests.exceptions.RequestException as e:
|
44
|
+
logging.error(f"Error signaling connection for user {username}: {e}")
|
45
|
+
sys.exit(4)
|
46
|
+
except Exception as e:
|
47
|
+
logging.error(f"Unexpected error for user {username}: {e}")
|
48
|
+
sys.exit(5)
|
{computer_use_ootb_internal-0.0.136.dist-info → computer_use_ootb_internal-0.0.138.dist-info}/RECORD
RENAMED
@@ -1,11 +1,12 @@
|
|
1
1
|
computer_use_ootb_internal/README.md,sha256=FxpW95lyub2iX73ZDfK6ML7SdEKg060H5I6Grub7li4,31
|
2
2
|
computer_use_ootb_internal/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
3
|
-
computer_use_ootb_internal/app_teachmode.py,sha256=
|
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=
|
5
|
+
computer_use_ootb_internal/guard_service.py,sha256=RjnfBIsLU0P4T1o2lMWFY1lSmAOILhJmhUiYzrTxg4A,47329
|
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=
|
7
|
+
computer_use_ootb_internal/run_teachmode_ootb_args.py,sha256=3ud1hvvOkODD3woc0Zwe5UG5p8x2KEHLks7JfdFRzCg,7579
|
8
8
|
computer_use_ootb_internal/service_manager.py,sha256=SD8jzfn0VVXBOr_nP6zmBWSC2TzrU_sp2e5JJkSlQFU,9734
|
9
|
+
computer_use_ootb_internal/signal_connection.py,sha256=8jPLOj0WSBXI_NElm5A-F146DTAE5LdL07lov7YXTNQ,1774
|
9
10
|
computer_use_ootb_internal/computer_use_demo/animation/click_animation.py,sha256=tP1gsayFy-CKk10UlrE9RlexwlHWiHQUe5Ogg4vQvSg,3234
|
10
11
|
computer_use_ootb_internal/computer_use_demo/animation/icons8-select-cursor-transparent-96.gif,sha256=4LfwsfFQnREXrNRs32aJU2jO65JXianJoL_8q7-8elg,30966
|
11
12
|
computer_use_ootb_internal/computer_use_demo/animation/test_animation.py,sha256=2R1u98OLKYalSZ5nt5vvyZ71FL5R5vLv-n8zM8jVdV8,1183
|
@@ -16,9 +17,9 @@ computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/simple_parser/
|
|
16
17
|
computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/uia_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
18
|
computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/uia_tools/screenshot_cli.py,sha256=hrUBH3aeUe9t4EDsMhaUZLPpNLKeEaG4ZvikrFy-bOU,1313
|
18
19
|
computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/uia_tools/screenshot_service.py,sha256=fJ8G4_-ZLGsHLdLgHCNgjVM1osbfz21L2w8QrcvnuhA,2738
|
19
|
-
computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/llm_utils.py,sha256=
|
20
|
-
computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/oai.py,sha256=
|
21
|
-
computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/run_litellm.py,sha256=
|
20
|
+
computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/llm_utils.py,sha256=ySvoB-ZndjKF-189ZUnRIOK5_hWYQDfc4dGgCjyuFOI,3984
|
21
|
+
computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/oai.py,sha256=ezsUlGiNGKh1qjcEw3sf8wxvlJJopKbcqFuMfb5aTGo,3753
|
22
|
+
computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/run_litellm.py,sha256=lKvobmbZ5mLsAxwUDdQ-RKQ1J9yiWu581tMbrO5QFOA,7346
|
22
23
|
computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/run_llm.py,sha256=fxC-7lg8TLAi9f69zs5y5Pwga8Y5mY7Yfc5NNZNRJgM,1558
|
23
24
|
computer_use_ootb_internal/computer_use_demo/tools/__init__.py,sha256=Pj8_5L4_PPQK298X4NV3KMbP-84t-bM0pbjEeb5_SJQ,343
|
24
25
|
computer_use_ootb_internal/computer_use_demo/tools/aws_request.py,sha256=12UVzeA2PmpZhpy2Pt5Vh48-_q1e8ZjVQux6r3pbAcw,2629
|
@@ -32,8 +33,8 @@ computer_use_ootb_internal/computer_use_demo/tools/edit.py,sha256=b0PwUitxckHCQq
|
|
32
33
|
computer_use_ootb_internal/computer_use_demo/tools/run.py,sha256=xhXdnBK1di9muaO44CEirL9hpGy3NmKbjfMpyeVmn8Y,1595
|
33
34
|
computer_use_ootb_internal/computer_use_demo/tools/screen_capture.py,sha256=L8qfvtUkPPQGt92N-2Zfw5ZTDBzLsDps39uMnX3_uSA,6857
|
34
35
|
computer_use_ootb_internal/preparation/__init__.py,sha256=AgtGHcBpiTkxJjF0xwcs3yyQ6SyUvhL3G0vD2XO-zJw,63
|
35
|
-
computer_use_ootb_internal/preparation/star_rail_prepare.py,sha256=
|
36
|
-
computer_use_ootb_internal-0.0.
|
37
|
-
computer_use_ootb_internal-0.0.
|
38
|
-
computer_use_ootb_internal-0.0.
|
39
|
-
computer_use_ootb_internal-0.0.
|
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,,
|
{computer_use_ootb_internal-0.0.136.dist-info → computer_use_ootb_internal-0.0.138.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|