cua-agent 0.1.32__tar.gz → 0.1.34__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.

Potentially problematic release.


This version of cua-agent might be problematic. Click here for more details.

Files changed (84) hide show
  1. {cua_agent-0.1.32 → cua_agent-0.1.34}/PKG-INFO +1 -1
  2. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/openai/loop.py +3 -10
  3. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/ui/gradio/app.py +147 -43
  4. {cua_agent-0.1.32 → cua_agent-0.1.34}/pyproject.toml +3 -3
  5. {cua_agent-0.1.32 → cua_agent-0.1.34}/README.md +0 -0
  6. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/__init__.py +0 -0
  7. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/__init__.py +0 -0
  8. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/agent.py +0 -0
  9. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/base.py +0 -0
  10. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/callbacks.py +0 -0
  11. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/experiment.py +0 -0
  12. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/factory.py +0 -0
  13. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/messages.py +0 -0
  14. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/provider_config.py +0 -0
  15. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/telemetry.py +0 -0
  16. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/tools/__init__.py +0 -0
  17. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/tools/base.py +0 -0
  18. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/tools/bash.py +0 -0
  19. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/tools/collection.py +0 -0
  20. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/tools/computer.py +0 -0
  21. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/tools/edit.py +0 -0
  22. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/tools/manager.py +0 -0
  23. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/tools.py +0 -0
  24. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/types.py +0 -0
  25. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/core/visualization.py +0 -0
  26. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/__init__.py +0 -0
  27. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/__init__.py +0 -0
  28. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/api/client.py +0 -0
  29. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/api/logging.py +0 -0
  30. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/api_handler.py +0 -0
  31. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/callbacks/__init__.py +0 -0
  32. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/callbacks/manager.py +0 -0
  33. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/loop.py +0 -0
  34. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/prompts.py +0 -0
  35. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/response_handler.py +0 -0
  36. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/tools/__init__.py +0 -0
  37. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/tools/base.py +0 -0
  38. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/tools/bash.py +0 -0
  39. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/tools/collection.py +0 -0
  40. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/tools/computer.py +0 -0
  41. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/tools/edit.py +0 -0
  42. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/tools/manager.py +0 -0
  43. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/tools/run.py +0 -0
  44. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/types.py +0 -0
  45. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/anthropic/utils.py +0 -0
  46. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/__init__.py +0 -0
  47. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/api_handler.py +0 -0
  48. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/clients/anthropic.py +0 -0
  49. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/clients/base.py +0 -0
  50. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/clients/oaicompat.py +0 -0
  51. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/clients/ollama.py +0 -0
  52. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/clients/openai.py +0 -0
  53. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/clients/utils.py +0 -0
  54. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/image_utils.py +0 -0
  55. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/loop.py +0 -0
  56. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/parser.py +0 -0
  57. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/prompts.py +0 -0
  58. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/tools/__init__.py +0 -0
  59. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/tools/base.py +0 -0
  60. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/tools/bash.py +0 -0
  61. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/tools/computer.py +0 -0
  62. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/tools/manager.py +0 -0
  63. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/omni/utils.py +0 -0
  64. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/openai/__init__.py +0 -0
  65. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/openai/api_handler.py +0 -0
  66. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/openai/response_handler.py +0 -0
  67. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/openai/tools/__init__.py +0 -0
  68. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/openai/tools/base.py +0 -0
  69. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/openai/tools/computer.py +0 -0
  70. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/openai/tools/manager.py +0 -0
  71. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/openai/types.py +0 -0
  72. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/openai/utils.py +0 -0
  73. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/uitars/__init__.py +0 -0
  74. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/uitars/clients/base.py +0 -0
  75. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/uitars/clients/oaicompat.py +0 -0
  76. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/uitars/loop.py +0 -0
  77. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/uitars/prompts.py +0 -0
  78. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/uitars/tools/__init__.py +0 -0
  79. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/uitars/tools/computer.py +0 -0
  80. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/uitars/tools/manager.py +0 -0
  81. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/providers/uitars/utils.py +0 -0
  82. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/telemetry.py +0 -0
  83. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/ui/__init__.py +0 -0
  84. {cua_agent-0.1.32 → cua_agent-0.1.34}/agent/ui/gradio/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cua-agent
3
- Version: 0.1.32
3
+ Version: 0.1.34
4
4
  Summary: CUA (Computer Use) Agent for AI-driven computer interaction
5
5
  Author-Email: TryCua <gh@trycua.com>
6
6
  Requires-Python: >=3.10
@@ -201,16 +201,7 @@ class OpenAILoop(BaseLoop):
201
201
 
202
202
  # Emit screenshot callbacks
203
203
  await self.handle_screenshot(screenshot_base64, action_type="initial_state")
204
-
205
- # Save screenshot if requested
206
- if self.save_trajectory:
207
- # Ensure screenshot_base64 is a string
208
- if not isinstance(screenshot_base64, str):
209
- logger.warning(
210
- "Converting non-string screenshot_base64 to string for _save_screenshot"
211
- )
212
- self._save_screenshot(screenshot_base64, action_type="state")
213
- logger.info("Screenshot saved to trajectory")
204
+ self._save_screenshot(screenshot_base64, action_type="state")
214
205
 
215
206
  # First add any existing user messages that were passed to run()
216
207
  user_query = None
@@ -351,6 +342,7 @@ class OpenAILoop(BaseLoop):
351
342
  # Process screenshot through hooks
352
343
  action_type = f"after_{action.get('type', 'action')}"
353
344
  await self.handle_screenshot(screenshot_base64, action_type=action_type)
345
+ self._save_screenshot(screenshot_base64, action_type=action_type)
354
346
 
355
347
  # Create computer_call_output
356
348
  computer_call_output = {
@@ -397,6 +389,7 @@ class OpenAILoop(BaseLoop):
397
389
 
398
390
  # Process the response
399
391
  # await self.response_handler.process_response(response, queue)
392
+ self._log_api_call("agent_response", request=None, response=response)
400
393
  await queue.put(response)
401
394
  except Exception as e:
402
395
  logger.error(f"Error executing computer action: {str(e)}")
@@ -480,6 +480,83 @@ def create_gradio_ui(
480
480
  "Open Safari, search for 'macOS automation tools', and save the first three results as bookmarks",
481
481
  "Configure SSH keys and set up a connection to a remote server",
482
482
  ]
483
+
484
+ # Function to generate Python code based on configuration and tasks
485
+ def generate_python_code(agent_loop_choice, provider, model_name, tasks, provider_url, recent_images=3, save_trajectory=True):
486
+ """Generate Python code for the current configuration and tasks.
487
+
488
+ Args:
489
+ agent_loop_choice: The agent loop type (e.g., UITARS, OPENAI, ANTHROPIC, OMNI)
490
+ provider: The provider type (e.g., OPENAI, ANTHROPIC, OLLAMA, OAICOMPAT)
491
+ model_name: The model name
492
+ tasks: List of tasks to execute
493
+ provider_url: The provider base URL for OAICOMPAT providers
494
+ recent_images: Number of recent images to keep in context
495
+ save_trajectory: Whether to save the agent trajectory
496
+
497
+ Returns:
498
+ Formatted Python code as a string
499
+ """
500
+ # Format the tasks as a Python list
501
+ tasks_str = ""
502
+ for task in tasks:
503
+ if task and task.strip():
504
+ tasks_str += f' "{task}",\n'
505
+
506
+ # Create the Python code template
507
+ code = f'''import asyncio
508
+ from computer import Computer
509
+ from agent import ComputerAgent, LLM, AgentLoop, LLMProvider
510
+
511
+ async def main():
512
+ async with Computer() as macos_computer:
513
+ agent = ComputerAgent(
514
+ computer=macos_computer,
515
+ loop=AgentLoop.{agent_loop_choice},
516
+ only_n_most_recent_images={recent_images},
517
+ save_trajectory={save_trajectory},'''
518
+
519
+ # Add the model configuration based on provider
520
+ if provider == LLMProvider.OAICOMPAT:
521
+ code += f'''
522
+ model=LLM(
523
+ provider=LLMProvider.OAICOMPAT,
524
+ name="{model_name}",
525
+ provider_base_url="{provider_url}"
526
+ )'''
527
+
528
+ code += """
529
+ )
530
+ """
531
+
532
+ # Add tasks section if there are tasks
533
+ if tasks_str:
534
+ code += f'''
535
+ # Prompts for the computer-use agent
536
+ tasks = [
537
+ {tasks_str.rstrip()}
538
+ ]
539
+
540
+ for task in tasks:
541
+ print(f"Executing task: {{task}}")
542
+ async for result in agent.run(task):
543
+ print(result)'''
544
+ else:
545
+ # If no tasks, just add a placeholder for a single task
546
+ code += f'''
547
+ # Execute a single task
548
+ task = "Search for information about CUA on GitHub"
549
+ print(f"Executing task: {{task}}")
550
+ async for result in agent.run(task):
551
+ print(result)'''
552
+
553
+ # Add the main block
554
+ code += '''
555
+
556
+ if __name__ == "__main__":
557
+ asyncio.run(main())'''
558
+
559
+ return code
483
560
 
484
561
  # Function to update model choices based on agent loop selection
485
562
  def update_model_choices(loop):
@@ -537,50 +614,20 @@ def create_gradio_ui(
537
614
  """
538
615
  )
539
616
 
540
- # Add installation prerequisites as a collapsible section
541
- with gr.Accordion("Prerequisites & Installation", open=False):
542
- gr.Markdown(
543
- """
544
- ## Prerequisites
545
-
546
- Before using the Computer-Use Agent, you need to set up the Lume daemon and pull the macOS VM image.
547
-
548
- ### 1. Install Lume daemon
549
-
550
- While a lume binary is included with Computer, we recommend installing the standalone version with brew, and starting the lume daemon service:
551
-
552
- ```bash
553
- sudo /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/lume/scripts/install.sh)"
554
- ```
555
-
556
- ### 2. Start the Lume daemon service
557
-
558
- In a separate terminal:
559
-
560
- ```bash
561
- lume serve
562
- ```
563
-
564
- ### 3. Pull the pre-built macOS image
565
-
566
- ```bash
567
- lume pull macos-sequoia-cua:latest
568
- ```
569
-
570
- Initial download requires 80GB storage, but reduces to ~30GB after first run due to macOS's sparse file system.
571
-
572
- VMs are stored in `~/.lume`, and locally cached images are stored in `~/.lume/cache`.
573
-
574
- ### 4. Test the sandbox
575
-
576
- ```bash
577
- lume run macos-sequoia-cua:latest
578
- ```
579
-
580
- For more detailed instructions, visit the [CUA GitHub repository](https://github.com/trycua/cua).
581
- """
617
+ # Add accordion for Python code
618
+ with gr.Accordion("Python Code", open=False):
619
+ code_display = gr.Code(
620
+ language="python",
621
+ value=generate_python_code(
622
+ initial_loop,
623
+ LLMProvider.OPENAI,
624
+ "gpt-4o",
625
+ [],
626
+ "https://openrouter.ai/api/v1"
627
+ ),
628
+ interactive=False,
582
629
  )
583
-
630
+
584
631
  with gr.Accordion("Configuration", open=True):
585
632
  # Configuration options
586
633
  agent_loop = gr.Dropdown(
@@ -643,6 +690,7 @@ def create_gradio_ui(
643
690
  info="Number of recent images to keep in context",
644
691
  interactive=True,
645
692
  )
693
+
646
694
 
647
695
  # Right column for chat interface
648
696
  with gr.Column(scale=2):
@@ -900,6 +948,62 @@ def create_gradio_ui(
900
948
  queue=False, # Process immediately without queueing
901
949
  )
902
950
 
951
+ # Function to update the code display based on configuration and chat history
952
+ def update_code_display(agent_loop, model_choice_val, custom_model_val, chat_history, provider_base_url, recent_images_val, save_trajectory_val):
953
+ # Extract messages from chat history
954
+ messages = []
955
+ if chat_history:
956
+ for msg in chat_history:
957
+ if msg.get("role") == "user":
958
+ messages.append(msg.get("content", ""))
959
+
960
+ # Determine provider and model name based on selection
961
+ model_string = custom_model_val if model_choice_val == "Custom model..." else model_choice_val
962
+ provider, model_name, _ = get_provider_and_model(model_string, agent_loop)
963
+
964
+ # Generate and return the code
965
+ return generate_python_code(
966
+ agent_loop,
967
+ provider,
968
+ model_name,
969
+ messages,
970
+ provider_base_url,
971
+ recent_images_val,
972
+ save_trajectory_val
973
+ )
974
+
975
+ # Update code display when configuration changes
976
+ agent_loop.change(
977
+ update_code_display,
978
+ inputs=[agent_loop, model_choice, custom_model, chatbot_history, provider_base_url, recent_images, save_trajectory],
979
+ outputs=[code_display]
980
+ )
981
+ model_choice.change(
982
+ update_code_display,
983
+ inputs=[agent_loop, model_choice, custom_model, chatbot_history, provider_base_url, recent_images, save_trajectory],
984
+ outputs=[code_display]
985
+ )
986
+ custom_model.change(
987
+ update_code_display,
988
+ inputs=[agent_loop, model_choice, custom_model, chatbot_history, provider_base_url, recent_images, save_trajectory],
989
+ outputs=[code_display]
990
+ )
991
+ chatbot_history.change(
992
+ update_code_display,
993
+ inputs=[agent_loop, model_choice, custom_model, chatbot_history, provider_base_url, recent_images, save_trajectory],
994
+ outputs=[code_display]
995
+ )
996
+ recent_images.change(
997
+ update_code_display,
998
+ inputs=[agent_loop, model_choice, custom_model, chatbot_history, provider_base_url, recent_images, save_trajectory],
999
+ outputs=[code_display]
1000
+ )
1001
+ save_trajectory.change(
1002
+ update_code_display,
1003
+ inputs=[agent_loop, model_choice, custom_model, chatbot_history, provider_base_url, recent_images, save_trajectory],
1004
+ outputs=[code_display]
1005
+ )
1006
+
903
1007
  return demo
904
1008
 
905
1009
 
@@ -6,7 +6,7 @@ build-backend = "pdm.backend"
6
6
 
7
7
  [project]
8
8
  name = "cua-agent"
9
- version = "0.1.32"
9
+ version = "0.1.34"
10
10
  description = "CUA (Computer Use) Agent for AI-driven computer interaction"
11
11
  readme = "README.md"
12
12
  authors = [
@@ -108,7 +108,7 @@ target-version = [
108
108
 
109
109
  [tool.ruff]
110
110
  line-length = 100
111
- target-version = "0.1.32"
111
+ target-version = "0.1.34"
112
112
  select = [
113
113
  "E",
114
114
  "F",
@@ -122,7 +122,7 @@ docstring-code-format = true
122
122
 
123
123
  [tool.mypy]
124
124
  strict = true
125
- python_version = "0.1.32"
125
+ python_version = "0.1.34"
126
126
  ignore_missing_imports = true
127
127
  disallow_untyped_defs = true
128
128
  check_untyped_defs = true
File without changes
File without changes