cua-agent 0.1.42__tar.gz → 0.1.43__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.42 → cua_agent-0.1.43}/PKG-INFO +1 -1
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/loop.py +42 -18
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/openai/loop.py +4 -4
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/uitars/loop.py +114 -87
- {cua_agent-0.1.42 → cua_agent-0.1.43}/pyproject.toml +3 -3
- {cua_agent-0.1.42 → cua_agent-0.1.43}/README.md +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/__init__.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/__init__.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/agent.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/base.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/callbacks.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/experiment.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/factory.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/messages.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/provider_config.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/telemetry.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/tools/__init__.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/tools/base.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/tools/bash.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/tools/collection.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/tools/computer.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/tools/edit.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/tools/manager.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/tools.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/types.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/core/visualization.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/__init__.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/__init__.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/api/client.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/api/logging.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/api_handler.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/callbacks/__init__.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/callbacks/manager.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/loop.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/prompts.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/response_handler.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/tools/__init__.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/tools/base.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/tools/bash.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/tools/collection.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/tools/computer.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/tools/edit.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/tools/manager.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/tools/run.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/types.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/anthropic/utils.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/__init__.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/api_handler.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/clients/anthropic.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/clients/base.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/clients/oaicompat.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/clients/ollama.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/clients/openai.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/clients/utils.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/image_utils.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/parser.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/prompts.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/tools/__init__.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/tools/base.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/tools/bash.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/tools/computer.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/tools/manager.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/omni/utils.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/openai/__init__.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/openai/api_handler.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/openai/response_handler.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/openai/tools/__init__.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/openai/tools/base.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/openai/tools/computer.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/openai/tools/manager.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/openai/types.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/openai/utils.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/uitars/__init__.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/uitars/clients/base.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/uitars/clients/mlxvlm.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/uitars/clients/oaicompat.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/uitars/prompts.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/uitars/tools/__init__.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/uitars/tools/computer.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/uitars/tools/manager.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/providers/uitars/utils.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/telemetry.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/ui/__init__.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/ui/gradio/__init__.py +0 -0
- {cua_agent-0.1.42 → cua_agent-0.1.43}/agent/ui/gradio/app.py +0 -0
|
@@ -581,17 +581,40 @@ class OmniLoop(BaseLoop):
|
|
|
581
581
|
Yields:
|
|
582
582
|
Agent response format
|
|
583
583
|
"""
|
|
584
|
-
# Initialize the message manager with the provided messages
|
|
585
|
-
self.message_manager.messages = messages.copy()
|
|
586
|
-
logger.info(f"Starting OmniLoop run with {len(self.message_manager.messages)} messages")
|
|
587
|
-
|
|
588
|
-
# Create a task to run the loop
|
|
589
|
-
self.loop_task = asyncio.create_task(self._run_loop(messages))
|
|
590
|
-
|
|
591
|
-
# Yield from the loop task
|
|
592
584
|
try:
|
|
593
|
-
|
|
594
|
-
|
|
585
|
+
logger.info(f"Starting OmniLoop run with {len(messages)} messages")
|
|
586
|
+
|
|
587
|
+
# Initialize the message manager with the provided messages
|
|
588
|
+
self.message_manager.messages = messages.copy()
|
|
589
|
+
|
|
590
|
+
# Create queue for response streaming
|
|
591
|
+
queue = asyncio.Queue()
|
|
592
|
+
|
|
593
|
+
# Start loop in background task
|
|
594
|
+
self.loop_task = asyncio.create_task(self._run_loop(queue, messages))
|
|
595
|
+
|
|
596
|
+
# Process and yield messages as they arrive
|
|
597
|
+
while True:
|
|
598
|
+
try:
|
|
599
|
+
item = await queue.get()
|
|
600
|
+
if item is None: # Stop signal
|
|
601
|
+
break
|
|
602
|
+
yield item
|
|
603
|
+
queue.task_done()
|
|
604
|
+
except Exception as e:
|
|
605
|
+
logger.error(f"Error processing queue item: {str(e)}")
|
|
606
|
+
continue
|
|
607
|
+
|
|
608
|
+
# Wait for loop to complete
|
|
609
|
+
await self.loop_task
|
|
610
|
+
|
|
611
|
+
# Send completion message
|
|
612
|
+
yield {
|
|
613
|
+
"role": "assistant",
|
|
614
|
+
"content": "Task completed successfully.",
|
|
615
|
+
"metadata": {"title": "✅ Complete"},
|
|
616
|
+
}
|
|
617
|
+
|
|
595
618
|
except Exception as e:
|
|
596
619
|
logger.error(f"Error in run method: {str(e)}")
|
|
597
620
|
yield {
|
|
@@ -600,14 +623,12 @@ class OmniLoop(BaseLoop):
|
|
|
600
623
|
"metadata": {"title": "❌ Error"},
|
|
601
624
|
}
|
|
602
625
|
|
|
603
|
-
async def _run_loop(self, messages: List[Dict[str, Any]]) ->
|
|
626
|
+
async def _run_loop(self, queue: asyncio.Queue, messages: List[Dict[str, Any]]) -> None:
|
|
604
627
|
"""Internal method to run the agent loop with provided messages.
|
|
605
628
|
|
|
606
629
|
Args:
|
|
630
|
+
queue: Queue to put responses into
|
|
607
631
|
messages: List of messages in standard OpenAI format
|
|
608
|
-
|
|
609
|
-
Yields:
|
|
610
|
-
Agent response format
|
|
611
632
|
"""
|
|
612
633
|
# Continue running until explicitly told to stop
|
|
613
634
|
running = True
|
|
@@ -698,8 +719,8 @@ class OmniLoop(BaseLoop):
|
|
|
698
719
|
# Log standardized response for ease of parsing
|
|
699
720
|
self._log_api_call("agent_response", request=None, response=openai_compatible_response)
|
|
700
721
|
|
|
701
|
-
#
|
|
702
|
-
|
|
722
|
+
# Put the response in the queue
|
|
723
|
+
await queue.put(openai_compatible_response)
|
|
703
724
|
|
|
704
725
|
# Check if we should continue this conversation
|
|
705
726
|
running = should_continue
|
|
@@ -720,14 +741,17 @@ class OmniLoop(BaseLoop):
|
|
|
720
741
|
if attempt >= max_attempts:
|
|
721
742
|
logger.error(f"Maximum retry attempts reached. Last error was: {str(e)}")
|
|
722
743
|
|
|
723
|
-
|
|
744
|
+
await queue.put({
|
|
724
745
|
"role": "assistant",
|
|
725
746
|
"content": f"Error: {str(e)}",
|
|
726
747
|
"metadata": {"title": "❌ Error"},
|
|
727
|
-
}
|
|
748
|
+
})
|
|
728
749
|
|
|
729
750
|
# Create a brief delay before retrying
|
|
730
751
|
await asyncio.sleep(1)
|
|
752
|
+
finally:
|
|
753
|
+
# Signal that we're done
|
|
754
|
+
await queue.put(None)
|
|
731
755
|
|
|
732
756
|
async def cancel(self) -> None:
|
|
733
757
|
"""Cancel the currently running agent loop task.
|
|
@@ -133,22 +133,22 @@ class OpenAILoop(BaseLoop):
|
|
|
133
133
|
logger.info("Starting OpenAI loop run")
|
|
134
134
|
|
|
135
135
|
# Create queue for response streaming
|
|
136
|
-
queue = asyncio.Queue()
|
|
136
|
+
self.queue = asyncio.Queue()
|
|
137
137
|
|
|
138
138
|
# Ensure tool manager is initialized
|
|
139
139
|
await self.tool_manager.initialize()
|
|
140
140
|
|
|
141
141
|
# Start loop in background task
|
|
142
|
-
self.loop_task = asyncio.create_task(self._run_loop(queue, messages))
|
|
142
|
+
self.loop_task = asyncio.create_task(self._run_loop(self.queue, messages))
|
|
143
143
|
|
|
144
144
|
# Process and yield messages as they arrive
|
|
145
145
|
while True:
|
|
146
146
|
try:
|
|
147
|
-
item = await queue.get()
|
|
147
|
+
item = await self.queue.get()
|
|
148
148
|
if item is None: # Stop signal
|
|
149
149
|
break
|
|
150
150
|
yield item
|
|
151
|
-
queue.task_done()
|
|
151
|
+
self.queue.task_done()
|
|
152
152
|
except Exception as e:
|
|
153
153
|
logger.error(f"Error processing queue item: {str(e)}")
|
|
154
154
|
continue
|
|
@@ -463,17 +463,40 @@ class UITARSLoop(BaseLoop):
|
|
|
463
463
|
Yields:
|
|
464
464
|
Agent response format
|
|
465
465
|
"""
|
|
466
|
-
# Initialize the message manager with the provided messages
|
|
467
|
-
self.message_manager.messages = messages.copy()
|
|
468
|
-
logger.info(f"Starting UITARSLoop run with {len(self.message_manager.messages)} messages")
|
|
469
|
-
|
|
470
|
-
# Create a task to run the loop
|
|
471
|
-
self.loop_task = asyncio.create_task(self._run_loop(messages))
|
|
472
|
-
|
|
473
|
-
# Yield from the loop task
|
|
474
466
|
try:
|
|
475
|
-
|
|
476
|
-
|
|
467
|
+
logger.info(f"Starting UITARSLoop run with {len(messages)} messages")
|
|
468
|
+
|
|
469
|
+
# Initialize the message manager with the provided messages
|
|
470
|
+
self.message_manager.messages = messages.copy()
|
|
471
|
+
|
|
472
|
+
# Create queue for response streaming
|
|
473
|
+
queue = asyncio.Queue()
|
|
474
|
+
|
|
475
|
+
# Start loop in background task
|
|
476
|
+
self.loop_task = asyncio.create_task(self._run_loop(queue, messages))
|
|
477
|
+
|
|
478
|
+
# Process and yield messages as they arrive
|
|
479
|
+
while True:
|
|
480
|
+
try:
|
|
481
|
+
item = await queue.get()
|
|
482
|
+
if item is None: # Stop signal
|
|
483
|
+
break
|
|
484
|
+
yield item
|
|
485
|
+
queue.task_done()
|
|
486
|
+
except Exception as e:
|
|
487
|
+
logger.error(f"Error processing queue item: {str(e)}")
|
|
488
|
+
continue
|
|
489
|
+
|
|
490
|
+
# Wait for loop to complete
|
|
491
|
+
await self.loop_task
|
|
492
|
+
|
|
493
|
+
# Send completion message
|
|
494
|
+
yield {
|
|
495
|
+
"role": "assistant",
|
|
496
|
+
"content": "Task completed successfully.",
|
|
497
|
+
"metadata": {"title": "✅ Complete"},
|
|
498
|
+
}
|
|
499
|
+
|
|
477
500
|
except Exception as e:
|
|
478
501
|
logger.error(f"Error in run method: {str(e)}")
|
|
479
502
|
yield {
|
|
@@ -482,14 +505,12 @@ class UITARSLoop(BaseLoop):
|
|
|
482
505
|
"metadata": {"title": "❌ Error"},
|
|
483
506
|
}
|
|
484
507
|
|
|
485
|
-
async def _run_loop(self, messages: List[Dict[str, Any]]) ->
|
|
508
|
+
async def _run_loop(self, queue: asyncio.Queue, messages: List[Dict[str, Any]]) -> None:
|
|
486
509
|
"""Internal method to run the agent loop with provided messages.
|
|
487
510
|
|
|
488
511
|
Args:
|
|
512
|
+
queue: Queue to put responses into
|
|
489
513
|
messages: List of messages in standard OpenAI format
|
|
490
|
-
|
|
491
|
-
Yields:
|
|
492
|
-
Agent response format
|
|
493
514
|
"""
|
|
494
515
|
# Continue running until explicitly told to stop
|
|
495
516
|
running = True
|
|
@@ -500,88 +521,94 @@ class UITARSLoop(BaseLoop):
|
|
|
500
521
|
attempt = 0
|
|
501
522
|
max_attempts = 3
|
|
502
523
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
524
|
+
try:
|
|
525
|
+
while running and attempt < max_attempts:
|
|
526
|
+
try:
|
|
527
|
+
# Create a new turn directory if it's not already created
|
|
528
|
+
if not turn_created:
|
|
529
|
+
self._create_turn_dir()
|
|
530
|
+
turn_created = True
|
|
509
531
|
|
|
510
|
-
|
|
511
|
-
if self.client is None:
|
|
512
|
-
logger.info("Initializing client...")
|
|
513
|
-
await self.initialize_client()
|
|
532
|
+
# Ensure client is initialized
|
|
514
533
|
if self.client is None:
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
+
logger.info("Initializing client...")
|
|
535
|
+
await self.initialize_client()
|
|
536
|
+
if self.client is None:
|
|
537
|
+
raise RuntimeError("Failed to initialize client")
|
|
538
|
+
logger.info("Client initialized successfully")
|
|
539
|
+
|
|
540
|
+
# Get current screen
|
|
541
|
+
base64_screenshot = await self._get_current_screen()
|
|
542
|
+
|
|
543
|
+
# Add screenshot to message history
|
|
544
|
+
self.message_manager.add_user_message(
|
|
545
|
+
[
|
|
546
|
+
{
|
|
547
|
+
"type": "image_url",
|
|
548
|
+
"image_url": {"url": f"data:image/png;base64,{base64_screenshot}"},
|
|
549
|
+
}
|
|
550
|
+
]
|
|
551
|
+
)
|
|
552
|
+
logger.info("Added screenshot to message history")
|
|
534
553
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
self.message_manager.messages, system_prompt
|
|
538
|
-
)
|
|
554
|
+
# Get system prompt
|
|
555
|
+
system_prompt = self._get_system_prompt()
|
|
539
556
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
)
|
|
557
|
+
# Make API call with retries
|
|
558
|
+
response = await self._make_api_call(
|
|
559
|
+
self.message_manager.messages, system_prompt
|
|
560
|
+
)
|
|
545
561
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
messages,
|
|
552
|
-
model=self.model,
|
|
553
|
-
)
|
|
554
|
-
# Log standardized response for ease of parsing
|
|
555
|
-
self._log_api_call("agent_response", request=None, response=agent_response)
|
|
556
|
-
yield agent_response
|
|
557
|
-
|
|
558
|
-
# Check if we should continue this conversation
|
|
559
|
-
running = should_continue
|
|
562
|
+
# Handle the response (may execute actions)
|
|
563
|
+
# Returns: (should_continue, action_screenshot_saved)
|
|
564
|
+
should_continue, new_screenshot_saved = await self._handle_response(
|
|
565
|
+
response, self.message_manager.messages
|
|
566
|
+
)
|
|
560
567
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
568
|
+
# Update whether an action screenshot was saved this turn
|
|
569
|
+
action_screenshot_saved = action_screenshot_saved or new_screenshot_saved
|
|
570
|
+
|
|
571
|
+
agent_response = await to_agent_response_format(
|
|
572
|
+
response,
|
|
573
|
+
messages,
|
|
574
|
+
model=self.model,
|
|
575
|
+
)
|
|
576
|
+
# Log standardized response for ease of parsing
|
|
577
|
+
self._log_api_call("agent_response", request=None, response=agent_response)
|
|
578
|
+
|
|
579
|
+
# Put the response in the queue
|
|
580
|
+
await queue.put(agent_response)
|
|
581
|
+
|
|
582
|
+
# Check if we should continue this conversation
|
|
583
|
+
running = should_continue
|
|
564
584
|
|
|
565
|
-
|
|
566
|
-
|
|
585
|
+
# Create a new turn directory if we're continuing
|
|
586
|
+
if running:
|
|
587
|
+
turn_created = False
|
|
567
588
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
error_msg = f"Error in run method (attempt {attempt}/{max_attempts}): {str(e)}"
|
|
571
|
-
logger.error(error_msg)
|
|
572
|
-
|
|
573
|
-
# If this is our last attempt, provide more info about the error
|
|
574
|
-
if attempt >= max_attempts:
|
|
575
|
-
logger.error(f"Maximum retry attempts reached. Last error was: {str(e)}")
|
|
576
|
-
|
|
577
|
-
yield {
|
|
578
|
-
"role": "assistant",
|
|
579
|
-
"content": f"Error: {str(e)}",
|
|
580
|
-
"metadata": {"title": "❌ Error"},
|
|
581
|
-
}
|
|
589
|
+
# Reset attempt counter on success
|
|
590
|
+
attempt = 0
|
|
582
591
|
|
|
583
|
-
|
|
584
|
-
|
|
592
|
+
except Exception as e:
|
|
593
|
+
attempt += 1
|
|
594
|
+
error_msg = f"Error in run method (attempt {attempt}/{max_attempts}): {str(e)}"
|
|
595
|
+
logger.error(error_msg)
|
|
596
|
+
|
|
597
|
+
# If this is our last attempt, provide more info about the error
|
|
598
|
+
if attempt >= max_attempts:
|
|
599
|
+
logger.error(f"Maximum retry attempts reached. Last error was: {str(e)}")
|
|
600
|
+
|
|
601
|
+
await queue.put({
|
|
602
|
+
"role": "assistant",
|
|
603
|
+
"content": f"Error: {str(e)}",
|
|
604
|
+
"metadata": {"title": "❌ Error"},
|
|
605
|
+
})
|
|
606
|
+
|
|
607
|
+
# Create a brief delay before retrying
|
|
608
|
+
await asyncio.sleep(1)
|
|
609
|
+
finally:
|
|
610
|
+
# Signal that we're done
|
|
611
|
+
await queue.put(None)
|
|
585
612
|
|
|
586
613
|
async def cancel(self) -> None:
|
|
587
614
|
"""Cancel the currently running agent loop task.
|
|
@@ -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.43"
|
|
10
10
|
description = "CUA (Computer Use) Agent for AI-driven computer interaction"
|
|
11
11
|
readme = "README.md"
|
|
12
12
|
authors = [
|
|
@@ -109,7 +109,7 @@ target-version = [
|
|
|
109
109
|
|
|
110
110
|
[tool.ruff]
|
|
111
111
|
line-length = 100
|
|
112
|
-
target-version = "0.1.
|
|
112
|
+
target-version = "0.1.43"
|
|
113
113
|
select = [
|
|
114
114
|
"E",
|
|
115
115
|
"F",
|
|
@@ -123,7 +123,7 @@ docstring-code-format = true
|
|
|
123
123
|
|
|
124
124
|
[tool.mypy]
|
|
125
125
|
strict = true
|
|
126
|
-
python_version = "0.1.
|
|
126
|
+
python_version = "0.1.43"
|
|
127
127
|
ignore_missing_imports = true
|
|
128
128
|
disallow_untyped_defs = true
|
|
129
129
|
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
|