computer-use-ootb-internal 0.0.115__py3-none-any.whl → 0.0.117__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 +103 -51
- computer_use_ootb_internal/guard_service.py +23 -7
- computer_use_ootb_internal/service_manager.py +21 -11
- {computer_use_ootb_internal-0.0.115.dist-info → computer_use_ootb_internal-0.0.117.dist-info}/METADATA +1 -1
- {computer_use_ootb_internal-0.0.115.dist-info → computer_use_ootb_internal-0.0.117.dist-info}/RECORD +7 -7
- {computer_use_ootb_internal-0.0.115.dist-info → computer_use_ootb_internal-0.0.117.dist-info}/WHEEL +0 -0
- {computer_use_ootb_internal-0.0.115.dist-info → computer_use_ootb_internal-0.0.117.dist-info}/entry_points.txt +0 -0
@@ -11,11 +11,48 @@ import os # Import os for path joining
|
|
11
11
|
import logging # Import logging
|
12
12
|
import importlib # For dynamic imports
|
13
13
|
import pkgutil # To find modules
|
14
|
+
import sys # For logging setup
|
15
|
+
import traceback # For logging setup
|
16
|
+
from logging.handlers import RotatingFileHandler # For logging setup
|
14
17
|
from fastapi import FastAPI, Request
|
15
18
|
from fastapi.responses import JSONResponse
|
16
19
|
from fastapi.middleware.cors import CORSMiddleware
|
17
20
|
from computer_use_ootb_internal.computer_use_demo.tools.computer import get_screen_details
|
18
21
|
from computer_use_ootb_internal.run_teachmode_ootb_args import simple_teachmode_sampling_loop
|
22
|
+
import uvicorn # Assuming uvicorn is used to run FastAPI
|
23
|
+
|
24
|
+
# --- App Logging Setup ---
|
25
|
+
try:
|
26
|
+
# Log to user's AppData directory for better accessibility
|
27
|
+
log_dir_base = os.environ.get('APPDATA', os.path.expanduser('~'))
|
28
|
+
log_dir = os.path.join(log_dir_base, 'OOTBAppLogs')
|
29
|
+
os.makedirs(log_dir, exist_ok=True)
|
30
|
+
log_file = os.path.join(log_dir, 'ootb_app.log')
|
31
|
+
|
32
|
+
log_format = '%(asctime)s - %(levelname)s - %(process)d - %(threadName)s - %(message)s'
|
33
|
+
log_level = logging.INFO # Or logging.DEBUG for more detail
|
34
|
+
|
35
|
+
# Use rotating file handler
|
36
|
+
handler = RotatingFileHandler(log_file, maxBytes=5*1024*1024, backupCount=2, encoding='utf-8')
|
37
|
+
handler.setFormatter(logging.Formatter(log_format))
|
38
|
+
|
39
|
+
# Configure root logger
|
40
|
+
logging.basicConfig(level=log_level, handlers=[handler])
|
41
|
+
|
42
|
+
# Add stream handler to see logs if running interactively (optional)
|
43
|
+
# logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))
|
44
|
+
|
45
|
+
logging.info("="*20 + " OOTB App Starting " + "="*20)
|
46
|
+
logging.info(f"Running with args: {sys.argv}")
|
47
|
+
logging.info(f"Python Executable: {sys.executable}")
|
48
|
+
logging.info(f"Working Directory: {os.getcwd()}")
|
49
|
+
logging.info(f"User: {os.getenv('USERNAME')}")
|
50
|
+
|
51
|
+
except Exception as log_setup_e:
|
52
|
+
print(f"FATAL: Failed to set up logging: {log_setup_e}")
|
53
|
+
# Fallback logging might be needed here if file logging fails
|
54
|
+
|
55
|
+
# --- End App Logging Setup ---
|
19
56
|
|
20
57
|
app = FastAPI()
|
21
58
|
|
@@ -56,6 +93,8 @@ class RateLimiter:
|
|
56
93
|
|
57
94
|
|
58
95
|
def log_ootb_request(server_url, ootb_request_type, data):
|
96
|
+
logging.info(f"OOTB Request: Type={ootb_request_type}, Data={data}")
|
97
|
+
# Keep the requests post for now if it serves a specific purpose
|
59
98
|
logging_data = {
|
60
99
|
"type": ootb_request_type,
|
61
100
|
"data": data,
|
@@ -65,7 +104,10 @@ def log_ootb_request(server_url, ootb_request_type, data):
|
|
65
104
|
server_logging_url = server_url + "/update_ootb_logging"
|
66
105
|
else:
|
67
106
|
server_logging_url = server_url
|
68
|
-
|
107
|
+
try:
|
108
|
+
requests.post(server_logging_url, json=logging_data, timeout=5)
|
109
|
+
except Exception as req_log_e:
|
110
|
+
logging.warning(f"Could not log ootb request to server {server_logging_url}: {req_log_e}")
|
69
111
|
|
70
112
|
|
71
113
|
class SharedState:
|
@@ -138,35 +180,41 @@ def prepare_environment(state):
|
|
138
180
|
|
139
181
|
@app.post("/update_params")
|
140
182
|
async def update_parameters(request: Request):
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
183
|
+
logging.info("Received request to /update_params")
|
184
|
+
try:
|
185
|
+
data = await request.json()
|
186
|
+
|
187
|
+
if 'task' not in data:
|
188
|
+
return JSONResponse(
|
189
|
+
content={"status": "error", "message": "Missing required field: task"},
|
190
|
+
status_code=400
|
191
|
+
)
|
192
|
+
|
193
|
+
shared_state.args = argparse.Namespace(**data)
|
194
|
+
shared_state.task_updated = True
|
195
|
+
|
196
|
+
# Update shared state when parameters change
|
197
|
+
shared_state.model = getattr(shared_state.args, 'model', "teach-mode-gpt-4o")
|
198
|
+
shared_state.task = getattr(shared_state.args, 'task', "Following the instructions to complete the task.")
|
199
|
+
shared_state.selected_screen = getattr(shared_state.args, 'selected_screen', 0)
|
200
|
+
shared_state.user_id = getattr(shared_state.args, 'user_id', "hero_cases")
|
201
|
+
shared_state.trace_id = getattr(shared_state.args, 'trace_id', "build_scroll_combat")
|
202
|
+
shared_state.api_keys = getattr(shared_state.args, 'api_keys', "sk-proj-1234567890")
|
203
|
+
shared_state.server_url = getattr(shared_state.args, 'server_url', "http://ec2-44-234-43-86.us-west-2.compute.amazonaws.com")
|
204
|
+
|
205
|
+
log_ootb_request(shared_state.server_url, "update_params", data)
|
162
206
|
|
163
|
-
|
164
|
-
|
207
|
+
# Call the (now dynamic) preparation function here, after parameters are updated
|
208
|
+
prepare_environment(shared_state)
|
165
209
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
210
|
+
logging.info("Parameters updated successfully.")
|
211
|
+
return JSONResponse(
|
212
|
+
content={"status": "success", "message": "Parameters updated", "new_args": vars(shared_state.args)},
|
213
|
+
status_code=200
|
214
|
+
)
|
215
|
+
except Exception as e:
|
216
|
+
logging.error("Error processing /update_params:", exc_info=True)
|
217
|
+
return JSONResponse(content={"status": "error", "message": "Internal server error"}, status_code=500)
|
170
218
|
|
171
219
|
@app.post("/update_message")
|
172
220
|
async def update_message(request: Request):
|
@@ -332,6 +380,8 @@ async def get_status(request: Request):
|
|
332
380
|
)
|
333
381
|
|
334
382
|
def process_input():
|
383
|
+
global shared_state
|
384
|
+
logging.info("process_input thread started.")
|
335
385
|
shared_state.is_processing = True
|
336
386
|
shared_state.should_stop = False
|
337
387
|
shared_state.is_paused = False
|
@@ -412,8 +462,11 @@ def process_input():
|
|
412
462
|
shared_state.is_paused = False
|
413
463
|
shared_state.stop_event.clear()
|
414
464
|
print("Processing completed, ready for new tasks")
|
465
|
+
logging.info("process_input thread finished.")
|
415
466
|
|
416
467
|
def main():
|
468
|
+
# Logging is set up at the top level now
|
469
|
+
logging.info("App main() function starting setup.")
|
417
470
|
global app, shared_state, rate_limiter
|
418
471
|
|
419
472
|
parser = argparse.ArgumentParser(
|
@@ -431,36 +484,35 @@ def main():
|
|
431
484
|
default="http://ec2-44-234-43-86.us-west-2.compute.amazonaws.com",
|
432
485
|
help="Server URL for the session"
|
433
486
|
)
|
487
|
+
parser.add_argument("--host", type=str, default="127.0.0.1", help="Host to bind the server to")
|
488
|
+
parser.add_argument("--port", type=int, default=8000, help="Port to bind the server to") # Default port
|
434
489
|
|
435
490
|
args = parser.parse_args()
|
436
491
|
shared_state = SharedState(args)
|
437
492
|
rate_limiter = RateLimiter(interval_seconds=2)
|
438
493
|
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
port = 7888
|
459
|
-
|
460
|
-
uvicorn.run(app, host="0.0.0.0", port=port)
|
494
|
+
# Validate args or set defaults if needed
|
495
|
+
if not hasattr(args, 'model'): args.model = "default_model"
|
496
|
+
if not hasattr(args, 'task'): args.task = "default_task"
|
497
|
+
if not hasattr(args, 'selected_screen'): args.selected_screen = 0
|
498
|
+
if not hasattr(args, 'user_id'): args.user_id = "unknown_user"
|
499
|
+
if not hasattr(args, 'trace_id'): args.trace_id = "unknown_trace"
|
500
|
+
if not hasattr(args, 'api_keys'): args.api_keys = "none"
|
501
|
+
if not hasattr(args, 'server_url'): args.server_url = "none"
|
502
|
+
|
503
|
+
logging.info(f"Shared state initialized. Host={args.host}, Port={args.port}")
|
504
|
+
|
505
|
+
try:
|
506
|
+
logging.info(f"Starting Uvicorn server on {args.host}:{args.port}")
|
507
|
+
uvicorn.run(app, host=args.host, port=args.port)
|
508
|
+
logging.info("Uvicorn server stopped.")
|
509
|
+
except Exception as main_e:
|
510
|
+
logging.error("Error in main execution:", exc_info=True)
|
511
|
+
finally:
|
512
|
+
logging.info("App main() function finished.")
|
461
513
|
|
462
514
|
if __name__ == "__main__":
|
463
|
-
|
515
|
+
main()
|
464
516
|
|
465
517
|
# Test log_ootb_request
|
466
518
|
log_ootb_request("http://ec2-44-234-43-86.us-west-2.compute.amazonaws.com", "test_request", {"message": "Test message"})
|
@@ -34,7 +34,7 @@ _LISTEN_HOST = "0.0.0.0" # Listen on all interfaces
|
|
34
34
|
_LISTEN_PORT = 14000 # Port for server to POST commands TO
|
35
35
|
# _SHARED_SECRET = "YOUR_SECRET_HERE" # !! REMOVED !! - No secret check implemented now
|
36
36
|
# --- End Server POST Configuration ---
|
37
|
-
_SERVER_STATUS_REPORT_URL = "http://52.160.105.102:7000/
|
37
|
+
_SERVER_STATUS_REPORT_URL = "http://52.160.105.102:7000/guard/status" # URL to POST status back TO (Path changed)
|
38
38
|
_LOG_FILE = pathlib.Path(os.environ['PROGRAMDATA']) / "OOTBGuardService" / "guard_post_mode.log" # Different log file
|
39
39
|
# --- End Configuration ---
|
40
40
|
|
@@ -427,18 +427,34 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
427
427
|
token = win32ts.WTSQueryUserToken(session_id)
|
428
428
|
env = win32profile.CreateEnvironmentBlock(token, False)
|
429
429
|
startup = win32process.STARTUPINFO()
|
430
|
+
# Simplify startup flags: Run hidden, don't explicitly set desktop
|
430
431
|
startup.dwFlags = win32process.STARTF_USESHOWWINDOW
|
431
|
-
startup.wShowWindow = win32con.
|
432
|
-
startup.lpDesktop = 'winsta0\\default'
|
432
|
+
startup.wShowWindow = win32con.SW_HIDE
|
433
|
+
# startup.lpDesktop = 'winsta0\\default' # Removed
|
434
|
+
|
433
435
|
creation_flags = win32process.CREATE_NEW_CONSOLE | win32process.CREATE_UNICODE_ENVIRONMENT
|
436
|
+
# Define cwd as user's profile directory if possible
|
437
|
+
user_profile_dir = win32profile.GetUserProfileDirectory(token)
|
434
438
|
|
435
439
|
hProcess, hThread, dwPid, dwTid = win32process.CreateProcessAsUser(
|
436
440
|
token, self.python_exe, self.ootb_command,
|
437
|
-
None, None, False, creation_flags, env,
|
441
|
+
None, None, False, creation_flags, env,
|
442
|
+
user_profile_dir, # Set current directory
|
443
|
+
startup
|
438
444
|
)
|
439
|
-
log_info(f"
|
440
|
-
|
441
|
-
|
445
|
+
log_info(f"CreateProcessAsUser call succeeded for user '{user}' (PID: {dwPid}).")
|
446
|
+
|
447
|
+
# Add post-start check
|
448
|
+
time.sleep(1) # Small delay
|
449
|
+
if psutil.pid_exists(dwPid):
|
450
|
+
log_info(f"Process PID {dwPid} confirmed to exist shortly after creation.")
|
451
|
+
started_count += 1
|
452
|
+
target_users_started.add(user)
|
453
|
+
else:
|
454
|
+
log_warning(f"Process PID {dwPid} reported by CreateProcessAsUser does NOT exist shortly after creation. It likely exited immediately.")
|
455
|
+
users_failed_to_start.add(user)
|
456
|
+
# Attempt to get exit code? Difficult without waiting.
|
457
|
+
|
442
458
|
win32api.CloseHandle(hProcess)
|
443
459
|
win32api.CloseHandle(hThread)
|
444
460
|
|
@@ -107,19 +107,29 @@ def run_service_command(command_args, check_errors=True):
|
|
107
107
|
|
108
108
|
def install_and_start():
|
109
109
|
"""Installs and starts the Guard Service."""
|
110
|
-
print(f"Attempting to install
|
111
|
-
#
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
110
|
+
print(f"Attempting to install service: '{_SERVICE_NAME}' ('{_SERVICE_DISPLAY_NAME}')")
|
111
|
+
# Call 'install' command first.
|
112
|
+
# We pass check_errors=True to stop if installation fails fundamentally.
|
113
|
+
install_success = run_service_command(['--startup', 'auto', 'install'], check_errors=True)
|
114
|
+
|
115
|
+
if install_success:
|
116
|
+
# Note: Even if install_success is True, pywin32 might have printed internal errors
|
117
|
+
# like 'service already installed'. We proceed to start anyway in that case.
|
118
|
+
print(f"\nInstallation command finished. Attempting to start service: '{_SERVICE_NAME}' (waiting a few seconds first)")
|
119
|
+
time.sleep(3) # Give SCM time to register the install/update
|
120
|
+
start_success = run_service_command(['start'], check_errors=True)
|
121
|
+
|
122
|
+
if start_success:
|
123
|
+
# Similar caveat: start might succeed according to subprocess, but pywin32 could print internal errors.
|
124
|
+
print(f"\nService '{_SERVICE_NAME}' install command executed and start command executed.")
|
125
|
+
print(f"Please verify service status in 'services.msc' and check logs.")
|
117
126
|
else:
|
118
|
-
|
119
|
-
print(f"
|
120
|
-
print(f"
|
127
|
+
# This path is taken if run_service_command returned False (subprocess error occurred)
|
128
|
+
print(f"\nService '{_SERVICE_NAME}' installed/updated but the 'start' command failed with an error.", file=sys.stderr)
|
129
|
+
print(f" Check output above, service logs ('C:\ProgramData\OOTBGuardService\guard_post_mode.log'), or Windows Event Viewer.", file=sys.stderr)
|
121
130
|
else:
|
122
|
-
|
131
|
+
# This path is taken if the initial 'install' command failed critically (subprocess error)
|
132
|
+
print(f"\nService '{_SERVICE_NAME}' installation failed critically. See errors above.", file=sys.stderr)
|
123
133
|
|
124
134
|
|
125
135
|
def stop_and_remove():
|
{computer_use_ootb_internal-0.0.115.dist-info → computer_use_ootb_internal-0.0.117.dist-info}/RECORD
RENAMED
@@ -1,12 +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=GkgvBLRwp_kWM-wkTXPoSnxagfol_51Hqsga21LGFk4,20971
|
4
4
|
computer_use_ootb_internal/app_teachmode_gradio.py,sha256=cmFpBrkdlZxOQADWveVdIaaNqaBD8IVs-xNLJogU7F8,7909
|
5
5
|
computer_use_ootb_internal/dependency_check.py,sha256=y8RMEP6RXQzTgU1MS_1piBLtz4J-Hfn9RjUZg59dyvo,1333
|
6
|
-
computer_use_ootb_internal/guard_service.py,sha256=
|
6
|
+
computer_use_ootb_internal/guard_service.py,sha256=z9GQdPJCd_Ds1xwCUn7hJBqPuto_FLhE1F5xqrvgh98,23496
|
7
7
|
computer_use_ootb_internal/requirements-lite.txt,sha256=5DAHomz4A_P2BmTIXNkNqkHbnIF0AyZ4_1XAlb1LaYs,290
|
8
8
|
computer_use_ootb_internal/run_teachmode_ootb_args.py,sha256=7Dj0iY4GG7P03tRKYJ2x9Yvt-PE-b7uyjCAed3SaF3Y,7086
|
9
|
-
computer_use_ootb_internal/service_manager.py,sha256=
|
9
|
+
computer_use_ootb_internal/service_manager.py,sha256=xbLIxQ4jzMr8AdZdxKw-QcAGm2Y86vudDzSf3hGjOM4,7595
|
10
10
|
computer_use_ootb_internal/computer_use_demo/animation/click_animation.py,sha256=tP1gsayFy-CKk10UlrE9RlexwlHWiHQUe5Ogg4vQvSg,3234
|
11
11
|
computer_use_ootb_internal/computer_use_demo/animation/icons8-select-cursor-transparent-96.gif,sha256=4LfwsfFQnREXrNRs32aJU2jO65JXianJoL_8q7-8elg,30966
|
12
12
|
computer_use_ootb_internal/computer_use_demo/animation/test_animation.py,sha256=2R1u98OLKYalSZ5nt5vvyZ71FL5R5vLv-n8zM8jVdV8,1183
|
@@ -34,7 +34,7 @@ computer_use_ootb_internal/computer_use_demo/tools/run.py,sha256=xhXdnBK1di9muaO
|
|
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
36
|
computer_use_ootb_internal/preparation/star_rail_prepare.py,sha256=s1VWszcTnJAKxqCHFlaOEwPkqVSrkiFx_yKpWSnSbHs,2649
|
37
|
-
computer_use_ootb_internal-0.0.
|
38
|
-
computer_use_ootb_internal-0.0.
|
39
|
-
computer_use_ootb_internal-0.0.
|
40
|
-
computer_use_ootb_internal-0.0.
|
37
|
+
computer_use_ootb_internal-0.0.117.dist-info/METADATA,sha256=mUDjRU51iIamJDr2479tUSAiXKrCTTzpGQ-g4ZYfcWU,1048
|
38
|
+
computer_use_ootb_internal-0.0.117.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
39
|
+
computer_use_ootb_internal-0.0.117.dist-info/entry_points.txt,sha256=bXfyAU_qq-G1EiEgAQEioXvgEdRCFxaTooqdDD9Y4OA,258
|
40
|
+
computer_use_ootb_internal-0.0.117.dist-info/RECORD,,
|
{computer_use_ootb_internal-0.0.115.dist-info → computer_use_ootb_internal-0.0.117.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|