cua-agent 0.1.33__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.
- {cua_agent-0.1.33 → cua_agent-0.1.34}/PKG-INFO +1 -1
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/ui/gradio/app.py +147 -43
- {cua_agent-0.1.33 → cua_agent-0.1.34}/pyproject.toml +3 -3
- {cua_agent-0.1.33 → cua_agent-0.1.34}/README.md +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/__init__.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/__init__.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/agent.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/base.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/callbacks.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/experiment.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/factory.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/messages.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/provider_config.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/telemetry.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/tools/__init__.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/tools/base.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/tools/bash.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/tools/collection.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/tools/computer.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/tools/edit.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/tools/manager.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/tools.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/types.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/core/visualization.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/__init__.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/__init__.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/api/client.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/api/logging.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/api_handler.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/callbacks/__init__.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/callbacks/manager.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/loop.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/prompts.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/response_handler.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/tools/__init__.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/tools/base.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/tools/bash.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/tools/collection.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/tools/computer.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/tools/edit.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/tools/manager.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/tools/run.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/types.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/anthropic/utils.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/__init__.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/api_handler.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/clients/anthropic.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/clients/base.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/clients/oaicompat.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/clients/ollama.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/clients/openai.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/clients/utils.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/image_utils.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/loop.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/parser.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/prompts.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/tools/__init__.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/tools/base.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/tools/bash.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/tools/computer.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/tools/manager.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/omni/utils.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/openai/__init__.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/openai/api_handler.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/openai/loop.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/openai/response_handler.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/openai/tools/__init__.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/openai/tools/base.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/openai/tools/computer.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/openai/tools/manager.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/openai/types.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/openai/utils.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/uitars/__init__.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/uitars/clients/base.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/uitars/clients/oaicompat.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/uitars/loop.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/uitars/prompts.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/uitars/tools/__init__.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/uitars/tools/computer.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/uitars/tools/manager.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/providers/uitars/utils.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/telemetry.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/ui/__init__.py +0 -0
- {cua_agent-0.1.33 → cua_agent-0.1.34}/agent/ui/gradio/__init__.py +0 -0
|
@@ -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
|
|
541
|
-
with gr.Accordion("
|
|
542
|
-
gr.
|
|
543
|
-
""
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|