computer-use-ootb-internal 0.0.116__tar.gz → 0.0.118__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 (40) hide show
  1. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/PKG-INFO +1 -1
  2. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/pyproject.toml +1 -1
  3. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/app_teachmode.py +136 -66
  4. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/guard_service.py +23 -7
  5. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/.gitignore +0 -0
  6. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/deploy.sh +0 -0
  7. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/README.md +0 -0
  8. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/__init__.py +0 -0
  9. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/app_teachmode_gradio.py +0 -0
  10. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/animation/click_animation.py +0 -0
  11. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/animation/icons8-select-cursor-transparent-96.gif +0 -0
  12. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/animation/test_animation.py +0 -0
  13. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/executor/teachmode_executor.py +0 -0
  14. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/simple_parser/__init__.py +0 -0
  15. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/simple_parser/gui_capture.py +0 -0
  16. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/simple_parser/utils.py +0 -0
  17. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/uia_tools/__init__.py +0 -0
  18. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/uia_tools/screenshot_cli.py +0 -0
  19. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/uia_tools/screenshot_service.py +0 -0
  20. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/llm_utils.py +0 -0
  21. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/oai.py +0 -0
  22. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/run_litellm.py +0 -0
  23. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/run_llm.py +0 -0
  24. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/tools/__init__.py +0 -0
  25. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/tools/aws_request.py +0 -0
  26. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/tools/base.py +0 -0
  27. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/tools/bash.py +0 -0
  28. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/tools/collection.py +0 -0
  29. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/tools/colorful_text.py +0 -0
  30. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/tools/computer.py +0 -0
  31. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/tools/computer_marbot.py +0 -0
  32. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/tools/edit.py +0 -0
  33. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/tools/run.py +0 -0
  34. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/computer_use_demo/tools/screen_capture.py +0 -0
  35. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/dependency_check.py +0 -0
  36. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/preparation/__init__.py +0 -0
  37. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/preparation/star_rail_prepare.py +0 -0
  38. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/requirements-lite.txt +0 -0
  39. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/run_teachmode_ootb_args.py +0 -0
  40. {computer_use_ootb_internal-0.0.116 → computer_use_ootb_internal-0.0.118}/src/computer_use_ootb_internal/service_manager.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: computer-use-ootb-internal
3
- Version: 0.0.116
3
+ Version: 0.0.118
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.116"
7
+ version = "0.0.118"
8
8
  description = "Computer Use OOTB"
9
9
  authors = [{ name = "Siyuan Hu", email = "siyuan.hu.sg@gmail.com" }]
10
10
  requires-python = ">=3.11"
@@ -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
- requests.post(server_logging_url, json=logging_data)
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
- data = await request.json()
142
-
143
- if 'task' not in data:
144
- return JSONResponse(
145
- content={"status": "error", "message": "Missing required field: task"},
146
- status_code=400
147
- )
148
-
149
- shared_state.args = argparse.Namespace(**data)
150
- shared_state.task_updated = True
151
-
152
- # Update shared state when parameters change
153
- shared_state.model = getattr(shared_state.args, 'model', "teach-mode-gpt-4o")
154
- shared_state.task = getattr(shared_state.args, 'task', "Following the instructions to complete the task.")
155
- shared_state.selected_screen = getattr(shared_state.args, 'selected_screen', 0)
156
- shared_state.user_id = getattr(shared_state.args, 'user_id', "hero_cases")
157
- shared_state.trace_id = getattr(shared_state.args, 'trace_id', "build_scroll_combat")
158
- shared_state.api_keys = getattr(shared_state.args, 'api_keys', "sk-proj-1234567890")
159
- shared_state.server_url = getattr(shared_state.args, 'server_url', "http://ec2-44-234-43-86.us-west-2.compute.amazonaws.com")
160
-
161
- log_ootb_request(shared_state.server_url, "update_params", data)
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
- # Call the (now dynamic) preparation function here, after parameters are updated
164
- prepare_environment(shared_state)
207
+ # Call the (now dynamic) preparation function here, after parameters are updated
208
+ prepare_environment(shared_state)
165
209
 
166
- return JSONResponse(
167
- content={"status": "success", "message": "Parameters updated", "new_args": vars(shared_state.args)},
168
- status_code=200
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,55 +462,75 @@ 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():
417
- global app, shared_state, rate_limiter
418
-
419
- parser = argparse.ArgumentParser(
420
- description="Run a synchronous sampling loop for assistant/tool interactions in teach-mode."
421
- )
422
- parser.add_argument("--model", default="teach-mode-gpt-4o")
423
- parser.add_argument("--task", default="Create a claim on the SAP system, using Receipt.pdf as attachment.")
424
- parser.add_argument("--selected_screen", type=int, default=0)
425
- parser.add_argument("--user_id", default="star_rail_dev")
426
- parser.add_argument("--trace_id", default="scroll")
427
- parser.add_argument("--api_key_file", default="api_key.json")
428
- parser.add_argument("--api_keys", default="")
429
- parser.add_argument(
430
- "--server_url",
431
- default="http://ec2-44-234-43-86.us-west-2.compute.amazonaws.com",
432
- help="Server URL for the session"
433
- )
468
+ # Logging is set up at the top level now
469
+ logging.info("App main() function starting setup.")
470
+ global app, shared_state, rate_limiter # Ensure app is global if needed by uvicorn
471
+ parser = argparse.ArgumentParser()
472
+ # Add arguments, but NOT host and port
473
+ parser.add_argument("--model", type=str, default="teach-mode-gpt-4o", help="Model name")
474
+ parser.add_argument("--task", type=str, default="Following the instructions to complete the task.", help="Initial task description")
475
+ parser.add_argument("--selected_screen", type=int, default=0, help="Selected screen index")
476
+ parser.add_argument("--user_id", type=str, default="hero_cases", help="User ID for the session")
477
+ parser.add_argument("--trace_id", type=str, default="build_scroll_combat", help="Trace ID for the session")
478
+ parser.add_argument("--api_keys", type=str, default="sk-proj-1234567890", help="API keys")
479
+ parser.add_argument("--server_url", type=str, default="http://ec2-44-234-43-86.us-west-2.compute.amazonaws.com", help="Server URL for the session")
434
480
 
435
481
  args = parser.parse_args()
482
+
483
+ # Validate args or set defaults if needed (keep these)
484
+ if not hasattr(args, 'model'): args.model = "default_model"
485
+ if not hasattr(args, 'task'): args.task = "default_task"
486
+ if not hasattr(args, 'selected_screen'): args.selected_screen = 0
487
+ if not hasattr(args, 'user_id'): args.user_id = "unknown_user"
488
+ if not hasattr(args, 'trace_id'): args.trace_id = "unknown_trace"
489
+ if not hasattr(args, 'api_keys'): args.api_keys = "none"
490
+ if not hasattr(args, 'server_url'): args.server_url = "none"
491
+
436
492
  shared_state = SharedState(args)
437
- rate_limiter = RateLimiter(interval_seconds=2)
493
+ rate_limiter = RateLimiter(interval_seconds=2) # Re-initialize rate limiter
494
+ logging.info(f"Shared state initialized for user: {args.user_id}")
438
495
 
439
- import uvicorn
440
- import platform
441
- import os
442
-
443
- # Default port
444
- port = 7888
496
+ # --- Restore original port calculation logic ---
497
+ port = 7888 # Default port
498
+ host = "0.0.0.0" # Listen on all interfaces
445
499
 
446
- # Determine port based on Windows username
447
500
  if platform.system() == "Windows":
448
- username = os.environ["USERNAME"].lower()
449
- if username == "altair":
450
- port = 14000
451
- elif username.startswith("guest") and username[5:].isdigit():
452
- num = int(username[5:])
453
- if 1 <= num <= 10:
454
- port = 14000 + num
501
+ try:
502
+ username = os.environ["USERNAME"].lower()
503
+ logging.info(f"Determining port based on Windows username: {username}")
504
+ if username == "altair":
505
+ port = 14000
506
+ elif username.startswith("guest") and username[5:].isdigit():
507
+ num = int(username[5:])
508
+ if 1 <= num <= 10: # Assuming max 10 guests for this range
509
+ port = 14000 + num
510
+ else:
511
+ logging.warning(f"Guest user number {num} out of range (1-10), using default port {port}.")
455
512
  else:
456
- port = 7888
457
- else:
458
- port = 7888
459
-
460
- uvicorn.run(app, host="0.0.0.0", port=port)
513
+ logging.info(f"Username '{username}' doesn't match specific rules, using default port {port}.")
514
+ except Exception as e:
515
+ logging.error(f"Error determining port from username: {e}. Using default port {port}.", exc_info=True)
516
+ else:
517
+ logging.info(f"Not running on Windows, using default port {port}.")
518
+ # --- End of restored port calculation ---
519
+
520
+ logging.info(f"Final Host={host}, Port={port}")
521
+
522
+ try:
523
+ logging.info(f"Starting Uvicorn server on {host}:{port}")
524
+ # Use the calculated port and specific host
525
+ uvicorn.run(app, host=host, port=port)
526
+ logging.info("Uvicorn server stopped.")
527
+ except Exception as main_e:
528
+ logging.error("Error in main execution:", exc_info=True)
529
+ finally:
530
+ logging.info("App main() function finished.")
461
531
 
462
532
  if __name__ == "__main__":
463
- # main()
533
+ main()
464
534
 
465
535
  # Test log_ootb_request
466
536
  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/api/guard/status" # URL to POST status back TO
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.SW_SHOW # Try showing the window
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, None, startup
441
+ None, None, False, creation_flags, env,
442
+ user_profile_dir, # Set current directory
443
+ startup
438
444
  )
439
- log_info(f"Successfully started OOTB for user '{user}' (PID: {dwPid}).")
440
- started_count += 1
441
- target_users_started.add(user)
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