Rename agent/core packages to cua_agent/cua_core to avoid namespace collisions - #1319
Conversation
…ollisions - Rename libs/python/agent/agent/ to libs/python/agent/cua_agent/ - Rename libs/python/core/core/ to libs/python/core/cua_core/ - Update all imports from 'agent' to 'cua_agent' - Update all imports from 'core' to 'cua_core' - Pin cua-core dependency to >=0.3.0,<0.4.0 across all packages - Pin cua-agent dependency to >=0.8.0 across all packages - Update documentation and blog posts with new import paths Fixes CUA-445 https://claude.ai/code/session_013snU7pHE5ZNs6nEzjHmLXR
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThis PR performs a comprehensive namespace refactoring across the codebase, updating import paths from Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
📦 Publishable packages changed
Add |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 11
🧹 Nitpick comments (1)
libs/python/agent/cua_agent/loops/__init__.py (1)
1-3: Consider updating the docstring for consistency with the new namespace.The docstring still references "agent loops for agent" which could be updated to "Agent loops for cua_agent" or simplified to just "Agent loops" for better clarity after the namespace refactoring.
📝 Suggested docstring update
-""" -Agent loops for agent -""" +""" +Agent loops for cua_agent +"""🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@libs/python/agent/cua_agent/loops/__init__.py` around lines 1 - 3, Update the module docstring in __init__.py to reflect the new namespace by replacing the current text "Agent loops for agent" with a clearer description such as "Agent loops for cua_agent" or simply "Agent loops"; edit the top-of-file module docstring in the cua_agent.loops package to use the chosen wording so the docstring matches the refactored namespace.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@blog/build-your-own-operator-on-macos-2.md`:
- Line 484: Search the article for any occurrences of the stale import "from
agent import ComputerAgent" (e.g., in the snippets around the earlier blocks
that also import create_gradio_ui) and update each to import the renamed
package, replacing it with "from cua_agent.agent import ComputerAgent" so the
examples match the current layout and won't fail at runtime.
In `@libs/python/agent/cua_agent/loops/gelato.py`:
- Around line 122-124: Wrap the base64 decode and PIL image open steps (lines
handling image_b64, image_data, and image) in a try/except that catches (at
minimum) binascii.Error/ValueError for invalid base64 and
PIL.UnidentifiedImageError/OSError for invalid/corrupt image data; on exception,
log a clear error including the offending image identifier/context and return or
raise a controlled exception so callers can handle it (update the block that
assigns image_data = base64.b64decode(image_b64) and image =
Image.open(BytesIO(image_data)) to use this error handling).
- Around line 28-41: The extract_coordinates function currently uses a bare
except and returns (0, 0) on failure; change it to use specific exception logic:
use re.findall as before, convert matches to floats (tuple(map(float, match)))
and if no matches are found raise a ValueError with a clear message (do not
return (0, 0)), and only catch the narrow exceptions you expect
(TypeError/IndexError) if needed and re-raise them as ValueError with context;
reference extract_coordinates, re.findall, matches, and the tuple(map(...))
conversion when making the change.
- Around line 169-172: Wrap the await litellm.acompletion(**api_kwargs) call in
a try/except to catch network/API errors and log or re-raise a descriptive
error, then validate the response structure before accessing it: check that
response is not None, response.choices exists and is a non-empty list, and that
response.choices[0].message and response.choices[0].message.content are present;
if validation fails, handle gracefully (return an error value or raise a clear
exception). Update the code around litellm.acompletion and the output_text
extraction to use these checks and ensure any exceptions include context (e.g.,
API name and api_kwargs summary) so failures are informative.
In `@libs/python/agent/cua_agent/loops/uiins.py`:
- Around line 167-171: The function currently multiplies pred_x/pred_y from
parse_coordinates and always returns floored coordinates even when parse failed
(parse_coordinates returned an invalid sentinel like (-1, -1)); update the logic
in the function containing the parse_coordinates call to detect an invalid parse
result (e.g., check for None or the sentinel values returned by
parse_coordinates) before scaling, and return None immediately if parsing failed
so the method honors its "return None on prediction failure" contract; reference
the parse_coordinates call and the pred_x/pred_y handling (and scale_x/scale_y
usage) when applying this guard.
- Around line 42-56: The smart_resize logic can divide by zero when total_pixels
== 0; update the smart_resize function to guard against zero-sized inputs by
checking if height <= 0 or width <= 0 or total_pixels == 0 before the scaling
logic (where total_pixels = height * width is computed) and handle it by
returning a sensible default (e.g., nearest positive multiple of factor or
raising a clear ValueError) or clamping to min_pixels behavior; ensure
references to total_pixels, height, width, factor, min_pixels, max_pixels are
updated so the early-return or error prevents any subsequent division by
total_pixels.
- Around line 110-165: predict_click currently assumes successful base64 decode,
image processing, model call and response shape; wrap the whole
decoding/resizing/acompletion/response-extraction flow in a try/except to return
None on any failure and log the exception. Specifically, guard the
base64.b64decode/Image.open/BytesIO steps that use image_b64, the
smart_resize+resize logic (resized_image_b64), the litellm.acompletion call, and
the response parsing that reads response.choices[0].message.content; on
exception catch and log the exception (or use an existing logger) and return
None so the documented fallback is honored. Ensure you validate the response
structure (presence of choices, index 0, message, and content) before accessing
and return None if shape is unexpected.
In `@libs/python/agent/pyproject.toml`:
- Line 22: The package manifest currently pins the package version at version =
"0.7.39" which conflicts with downstream requirements; update the package
version string for cua-agent to at least "0.8.0" (e.g., change version =
"0.7.39" to version = "0.8.0") in pyproject.toml and ensure any related metadata
(package __version__ if present) is kept in sync so consumers requiring
cua-agent>=0.8.0 will resolve correctly.
In `@libs/python/computer-server/computer_server/main.py`:
- Line 44: This module still imports the old namespaces (core.http and
agent.computers) which breaks auth and the /responses routes; update the import
lines so they reference the migrated package paths used elsewhere (e.g., import
the HTTP utilities and types from the new cua_agent namespace and import
ComputerAgent from the new agent package) and adjust any local references if the
module path or symbol names changed; specifically replace usages/imports of
core.http and agent.computers with their new equivalents used by ComputerAgent
(ensure auth handlers and the /responses route reference the updated modules),
and run a quick grep for core.http and agent.computers to confirm all
imports/usages are migrated.
In `@libs/python/mcp-server/pyproject.toml`:
- Line 16: Import resolution breaks because code still uses the legacy module
export "from agent import ComputerAgent" while the package now exposes the class
as cua_agent.agent.ComputerAgent; update the import in mcp-server server module
to "from cua_agent.agent import ComputerAgent" (and similarly migrate any other
"from agent ..." imports) or else revert the pyproject bump (keep
"cua-agent[all]<0.8.0") until the migration is complete so the existing imports
remain valid.
In `@scripts/playground.sh`:
- Around line 259-260: The import line in the generated run_demo.py templates
incorrectly includes non-existent and unused symbols LLM, AgentLoop, and
LLMProvider from cua_agent; remove those three names so the import reads only
import ComputerAgent (leave the separate from cua_agent.ui.gradio.ui_components
import create_gradio_ui as-is), and apply this same change to both generated
run_demo.py templates (cloud and local branches) to prevent startup import
failures.
---
Nitpick comments:
In `@libs/python/agent/cua_agent/loops/__init__.py`:
- Around line 1-3: Update the module docstring in __init__.py to reflect the new
namespace by replacing the current text "Agent loops for agent" with a clearer
description such as "Agent loops for cua_agent" or simply "Agent loops"; edit
the top-of-file module docstring in the cua_agent.loops package to use the
chosen wording so the docstring matches the refactored namespace.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b0f7d60a-470b-4264-ae2e-9d988814bbb9
⛔ Files ignored due to path filters (1)
libs/python/agent/cua_agent/loops/model_types.csvis excluded by!**/*.csv
📒 Files selected for processing (115)
blog/build-your-own-operator-on-macos-2.mdblog/hud-agent-evals.mdblog/human-in-the-loop.mddocs/content/docs/cua/guide/advanced/custom-tools.mdxdocs/content/docs/cua/guide/fundamentals/agent-loops.mdxdocs/content/docs/cua/guide/fundamentals/callbacks.mdxdocs/content/docs/cua/guide/integrations/hud.mdxlibs/cua-bench/cua_bench/telemetry/events.pylibs/cua-bench/pyproject.tomllibs/python/agent/benchmarks/utils.pylibs/python/agent/cua_agent/__init__.pylibs/python/agent/cua_agent/__main__.pylibs/python/agent/cua_agent/adapters/__init__.pylibs/python/agent/cua_agent/adapters/azure_ml_adapter.pylibs/python/agent/cua_agent/adapters/cua_adapter.pylibs/python/agent/cua_agent/adapters/huggingfacelocal_adapter.pylibs/python/agent/cua_agent/adapters/human_adapter.pylibs/python/agent/cua_agent/adapters/mlxvlm_adapter.pylibs/python/agent/cua_agent/adapters/models/__init__.pylibs/python/agent/cua_agent/adapters/models/generic.pylibs/python/agent/cua_agent/adapters/models/internvl.pylibs/python/agent/cua_agent/adapters/models/opencua.pylibs/python/agent/cua_agent/adapters/models/qwen2_5_vl.pylibs/python/agent/cua_agent/adapters/yutori_adapter.pylibs/python/agent/cua_agent/agent.pylibs/python/agent/cua_agent/callbacks/__init__.pylibs/python/agent/cua_agent/callbacks/base.pylibs/python/agent/cua_agent/callbacks/budget_manager.pylibs/python/agent/cua_agent/callbacks/image_retention.pylibs/python/agent/cua_agent/callbacks/logging.pylibs/python/agent/cua_agent/callbacks/operator_validator.pylibs/python/agent/cua_agent/callbacks/otel.pylibs/python/agent/cua_agent/callbacks/pii_anonymization.pylibs/python/agent/cua_agent/callbacks/prompt_instructions.pylibs/python/agent/cua_agent/callbacks/telemetry.pylibs/python/agent/cua_agent/callbacks/trajectory_saver.pylibs/python/agent/cua_agent/cli.pylibs/python/agent/cua_agent/computers/__init__.pylibs/python/agent/cua_agent/computers/base.pylibs/python/agent/cua_agent/computers/cua.pylibs/python/agent/cua_agent/computers/custom.pylibs/python/agent/cua_agent/computers/sandbox.pylibs/python/agent/cua_agent/decorators.pylibs/python/agent/cua_agent/human_tool/__init__.pylibs/python/agent/cua_agent/human_tool/__main__.pylibs/python/agent/cua_agent/human_tool/server.pylibs/python/agent/cua_agent/human_tool/ui.pylibs/python/agent/cua_agent/integrations/hud/__init__.pylibs/python/agent/cua_agent/integrations/hud/agent.pylibs/python/agent/cua_agent/integrations/hud/proxy.pylibs/python/agent/cua_agent/loops/__init__.pylibs/python/agent/cua_agent/loops/anthropic.pylibs/python/agent/cua_agent/loops/base.pylibs/python/agent/cua_agent/loops/composed_grounded.pylibs/python/agent/cua_agent/loops/fara/__init__.pylibs/python/agent/cua_agent/loops/fara/config.pylibs/python/agent/cua_agent/loops/fara/helpers.pylibs/python/agent/cua_agent/loops/fara/schema.pylibs/python/agent/cua_agent/loops/gelato.pylibs/python/agent/cua_agent/loops/gemini.pylibs/python/agent/cua_agent/loops/generic_vlm.pylibs/python/agent/cua_agent/loops/glm45v.pylibs/python/agent/cua_agent/loops/gta1.pylibs/python/agent/cua_agent/loops/holo.pylibs/python/agent/cua_agent/loops/internvl.pylibs/python/agent/cua_agent/loops/moondream3.pylibs/python/agent/cua_agent/loops/omniparser.pylibs/python/agent/cua_agent/loops/openai.pylibs/python/agent/cua_agent/loops/opencua.pylibs/python/agent/cua_agent/loops/qwen35.pylibs/python/agent/cua_agent/loops/qwen3vl.pylibs/python/agent/cua_agent/loops/uiins.pylibs/python/agent/cua_agent/loops/uitars.pylibs/python/agent/cua_agent/loops/uitars2.pylibs/python/agent/cua_agent/loops/yutori.pylibs/python/agent/cua_agent/playground/__init__.pylibs/python/agent/cua_agent/playground/server.pylibs/python/agent/cua_agent/proxy/examples.pylibs/python/agent/cua_agent/proxy/handlers.pylibs/python/agent/cua_agent/responses.pylibs/python/agent/cua_agent/tools/__init__.pylibs/python/agent/cua_agent/tools/base.pylibs/python/agent/cua_agent/tools/browser_tool.pylibs/python/agent/cua_agent/types.pylibs/python/agent/cua_agent/ui/__init__.pylibs/python/agent/cua_agent/ui/__main__.pylibs/python/agent/cua_agent/ui/gradio/__init__.pylibs/python/agent/cua_agent/ui/gradio/app.pylibs/python/agent/cua_agent/ui/gradio/ui_components.pylibs/python/agent/pyproject.tomllibs/python/agent/tests/test_tool_resolution.pylibs/python/computer-server/computer_server/main.pylibs/python/computer-server/pyproject.tomllibs/python/computer/computer/computer.pylibs/python/computer/computer/interface/generic.pylibs/python/computer/computer/providers/cloud/provider.pylibs/python/computer/computer/providers/cloud/providerv2.pylibs/python/computer/pyproject.tomllibs/python/core/cua_core/__init__.pylibs/python/core/cua_core/http.pylibs/python/core/cua_core/telemetry/__init__.pylibs/python/core/cua_core/telemetry/otel.pylibs/python/core/cua_core/telemetry/posthog.pylibs/python/core/pyproject.tomllibs/python/cua-cli/cua_cli/api/client.pylibs/python/cua-cli/cua_cli/commands/auth.pylibs/python/cua-cli/cua_cli/commands/workspace.pylibs/python/cua-cli/pyproject.tomllibs/python/cua-sandbox/pyproject.tomllibs/python/cua/cua/callbacks.pylibs/python/cua/cua/tools.pylibs/python/cua/pyproject.tomllibs/python/mcp-server/pyproject.tomlscripts/playground.shtests/test_telemetry.py
|
|
||
| ```python | ||
| from agent.ui.gradio.app import create_gradio_ui | ||
| from cua_agent.ui.gradio.app import create_gradio_ui |
There was a problem hiding this comment.
This article still contains stale agent imports in earlier code blocks.
After this rename, examples at Line 214, Line 266, Line 358, and Line 578 still use from agent import ComputerAgent, which will mislead users and fail with the new package layout.
📝 Suggested updates
- from agent import ComputerAgent
+ from cua_agent import ComputerAgentApply this replacement to each outdated snippet in the post.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@blog/build-your-own-operator-on-macos-2.md` at line 484, Search the article
for any occurrences of the stale import "from agent import ComputerAgent" (e.g.,
in the snippets around the earlier blocks that also import create_gradio_ui) and
update each to import the renamed package, replacing it with "from
cua_agent.agent import ComputerAgent" so the examples match the current layout
and won't fail at runtime.
| def extract_coordinates(raw_string): | ||
| """ | ||
| Extract the coordinates from the raw string. | ||
| Args: | ||
| raw_string: str (e.g. "(100, 200)") | ||
| Returns: | ||
| x: float (e.g. 100.0) | ||
| y: float (e.g. 200.0) | ||
| """ | ||
| try: | ||
| matches = re.findall(r"\((-?\d*\.?\d+),\s*(-?\d*\.?\d+)\)", raw_string) | ||
| return [tuple(map(int, match)) for match in matches][0] | ||
| except: | ||
| return 0, 0 |
There was a problem hiding this comment.
Replace bare except: with specific exception handling and improve error signaling.
The bare except: clause catches all exceptions including system-level ones (KeyboardInterrupt, SystemExit). Additionally, returning (0, 0) on parsing failure is misleading since (0, 0) is a valid coordinate—this could cause silent failures where clicks are incorrectly placed at the top-left corner instead of failing explicitly.
🛡️ Proposed fix
def extract_coordinates(raw_string):
"""
Extract the coordinates from the raw string.
Args:
raw_string: str (e.g. "(100, 200)")
Returns:
x: float (e.g. 100.0)
y: float (e.g. 200.0)
"""
try:
matches = re.findall(r"\((-?\d*\.?\d+),\s*(-?\d*\.?\d+)\)", raw_string)
+ if not matches:
+ raise ValueError(f"No coordinate pattern found in: {raw_string}")
return [tuple(map(int, match)) for match in matches][0]
- except:
- return 0, 0
+ except (ValueError, IndexError) as e:
+ raise ValueError(f"Failed to extract coordinates from '{raw_string}': {e}")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@libs/python/agent/cua_agent/loops/gelato.py` around lines 28 - 41, The
extract_coordinates function currently uses a bare except and returns (0, 0) on
failure; change it to use specific exception logic: use re.findall as before,
convert matches to floats (tuple(map(float, match))) and if no matches are found
raise a ValueError with a clear message (do not return (0, 0)), and only catch
the narrow exceptions you expect (TypeError/IndexError) if needed and re-raise
them as ValueError with context; reference extract_coordinates, re.findall,
matches, and the tuple(map(...)) conversion when making the change.
| image_data = base64.b64decode(image_b64) | ||
| image = Image.open(BytesIO(image_data)) | ||
| width, height = image.width, image.height |
There was a problem hiding this comment.
Add error handling for image decoding operations.
The base64 decoding and image opening operations can fail (invalid base64, corrupted image data) but lack error handling. This could cause the method to raise unexpected exceptions.
🛡️ Proposed fix
+ try:
- # Decode base64 image
- image_data = base64.b64decode(image_b64)
- image = Image.open(BytesIO(image_data))
+ # Decode base64 image
+ image_data = base64.b64decode(image_b64)
+ image = Image.open(BytesIO(image_data))
+ except (base64.binascii.Error, Exception) as e:
+ raise ValueError(f"Failed to decode or open image: {e}")
width, height = image.width, image.height📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| image_data = base64.b64decode(image_b64) | |
| image = Image.open(BytesIO(image_data)) | |
| width, height = image.width, image.height | |
| try: | |
| # Decode base64 image | |
| image_data = base64.b64decode(image_b64) | |
| image = Image.open(BytesIO(image_data)) | |
| except (base64.binascii.Error, Exception) as e: | |
| raise ValueError(f"Failed to decode or open image: {e}") | |
| width, height = image.width, image.height |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@libs/python/agent/cua_agent/loops/gelato.py` around lines 122 - 124, Wrap the
base64 decode and PIL image open steps (lines handling image_b64, image_data,
and image) in a try/except that catches (at minimum) binascii.Error/ValueError
for invalid base64 and PIL.UnidentifiedImageError/OSError for invalid/corrupt
image data; on exception, log a clear error including the offending image
identifier/context and return or raise a controlled exception so callers can
handle it (update the block that assigns image_data =
base64.b64decode(image_b64) and image = Image.open(BytesIO(image_data)) to use
this error handling).
| response = await litellm.acompletion(**api_kwargs) | ||
|
|
||
| # Extract response text | ||
| output_text = response.choices[0].message.content # type: ignore |
There was a problem hiding this comment.
Add error handling for API call and response validation.
The liteLLM API call and response access lack error handling. Network failures, API errors, or unexpected response structures could cause uncaught exceptions.
🛡️ Proposed fix
- # Use liteLLM acompletion
- response = await litellm.acompletion(**api_kwargs)
-
- # Extract response text
- output_text = response.choices[0].message.content # type: ignore
+ # Use liteLLM acompletion
+ try:
+ response = await litellm.acompletion(**api_kwargs)
+ except Exception as e:
+ raise RuntimeError(f"API call failed: {e}")
+
+ # Extract response text
+ if not response.choices or not response.choices[0].message.content:
+ raise ValueError("API response missing expected content")
+ output_text = response.choices[0].message.content🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@libs/python/agent/cua_agent/loops/gelato.py` around lines 169 - 172, Wrap the
await litellm.acompletion(**api_kwargs) call in a try/except to catch
network/API errors and log or re-raise a descriptive error, then validate the
response structure before accessing it: check that response is not None,
response.choices exists and is a non-empty list, and that
response.choices[0].message and response.choices[0].message.content are present;
if validation fails, handle gracefully (return an error value or raise a clear
exception). Update the code around litellm.acompletion and the output_text
extraction to use these checks and ensure any exceptions include context (e.g.,
API name and api_kwargs summary) so failures are informative.
| total_pixels = height * width | ||
|
|
||
| # If already within bounds, return original dimensions | ||
| if min_pixels <= total_pixels <= max_pixels: | ||
| # Round to nearest factor | ||
| new_height = (height // factor) * factor | ||
| new_width = (width // factor) * factor | ||
| return new_height, new_width | ||
|
|
||
| # Calculate scaling factor | ||
| if total_pixels > max_pixels: | ||
| scale = (max_pixels / total_pixels) ** 0.5 | ||
| else: | ||
| scale = (min_pixels / total_pixels) ** 0.5 | ||
|
|
There was a problem hiding this comment.
Guard against zero-sized inputs in smart_resize.
At Line 55, total_pixels can be zero for invalid/empty dimensions, causing a division-by-zero path.
Proposed fix
def smart_resize(
@@
) -> Tuple[int, int]:
"""Smart resize function similar to qwen_vl_utils."""
# Calculate the total pixels
total_pixels = height * width
+ if height <= 0 or width <= 0:
+ return factor, factor🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@libs/python/agent/cua_agent/loops/uiins.py` around lines 42 - 56, The
smart_resize logic can divide by zero when total_pixels == 0; update the
smart_resize function to guard against zero-sized inputs by checking if height
<= 0 or width <= 0 or total_pixels == 0 before the scaling logic (where
total_pixels = height * width is computed) and handle it by returning a sensible
default (e.g., nearest positive multiple of factor or raising a clear
ValueError) or clamping to min_pixels behavior; ensure references to
total_pixels, height, width, factor, min_pixels, max_pixels are updated so the
early-return or error prevents any subsequent division by total_pixels.
| pred_x, pred_y = parse_coordinates(output_text) # type: ignore | ||
| pred_x *= scale_x | ||
| pred_y *= scale_y | ||
|
|
||
| return (math.floor(pred_x), math.floor(pred_y)) |
There was a problem hiding this comment.
Return None on invalid coordinate parse to match the method contract.
At Line 167, failed parsing yields (-1, -1), but the method still returns coordinates at Line 171. That violates the “None if prediction fails” contract and can propagate invalid clicks.
Proposed fix
- pred_x, pred_y = parse_coordinates(output_text) # type: ignore
- pred_x *= scale_x
- pred_y *= scale_y
-
- return (math.floor(pred_x), math.floor(pred_y))
+ pred_x, pred_y = parse_coordinates(output_text) # type: ignore
+ if pred_x < 0 or pred_y < 0:
+ return None
+
+ pred_x *= scale_x
+ pred_y *= scale_y
+ return (math.floor(pred_x), math.floor(pred_y))🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@libs/python/agent/cua_agent/loops/uiins.py` around lines 167 - 171, The
function currently multiplies pred_x/pred_y from parse_coordinates and always
returns floored coordinates even when parse failed (parse_coordinates returned
an invalid sentinel like (-1, -1)); update the logic in the function containing
the parse_coordinates call to detect an invalid parse result (e.g., check for
None or the sentinel values returned by parse_coordinates) before scaling, and
return None immediately if parsing failed so the method honors its "return None
on prediction failure" contract; reference the parse_coordinates call and the
pred_x/pred_y handling (and scale_x/scale_y usage) when applying this guard.
| "rich>=13.7.1", | ||
| "python-dotenv>=1.0.1", | ||
| "cua-core>=0.1.18,<0.2.0", | ||
| "cua-core>=0.3.0,<0.4.0", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Check declared cua-agent package version:"
fd -i pyproject.toml | xargs rg -n '^name = "cua-agent"$|^version = "'
echo
echo "Check where cua-agent>=0.8.0 is required:"
fd -i pyproject.toml | xargs rg -n 'cua-agent>=0\.8\.0'Repository: trycua/cua
Length of output: 2756
cua-agent version must be bumped to 0.8.0 or higher.
The package declares version = "0.7.39" but downstream packages (cua-sandbox and cua-bench) require cua-agent>=0.8.0. Publishing at 0.7.39 will cause dependency resolution failures.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@libs/python/agent/pyproject.toml` at line 22, The package manifest currently
pins the package version at version = "0.7.39" which conflicts with downstream
requirements; update the package version string for cua-agent to at least
"0.8.0" (e.g., change version = "0.7.39" to version = "0.8.0") in pyproject.toml
and ensure any related metadata (package __version__ if present) is kept in sync
so consumers requiring cua-agent>=0.8.0 will resolve correctly.
|
|
||
| try: | ||
| from agent import ComputerAgent | ||
| from cua_agent import ComputerAgent |
There was a problem hiding this comment.
Complete the namespace migration in this module.
The file still imports old package paths at Line 282 (core.http) and Line 985 (agent.computers). Once old namespaces are removed, this will break auth and /responses at runtime.
🔧 Proposed fix
- from core.http import cua_version_headers
+ from cua_core.http import cua_version_headers
...
- from agent.computers import AsyncComputerHandler # runtime-checkable Protocol
+ from cua_agent.computers import AsyncComputerHandler # runtime-checkable Protocol🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@libs/python/computer-server/computer_server/main.py` at line 44, This module
still imports the old namespaces (core.http and agent.computers) which breaks
auth and the /responses routes; update the import lines so they reference the
migrated package paths used elsewhere (e.g., import the HTTP utilities and types
from the new cua_agent namespace and import ComputerAgent from the new agent
package) and adjust any local references if the module path or symbol names
changed; specifically replace usages/imports of core.http and agent.computers
with their new equivalents used by ComputerAgent (ensure auth handlers and the
/responses route reference the updated modules), and run a quick grep for
core.http and agent.computers to confirm all imports/usages are migrated.
| dependencies = [ | ||
| "mcp>=1.6.0,<2.0.0", | ||
| "cua-agent[all]>=0.4.0,<0.5.0", | ||
| "cua-agent[all]>=0.8.0", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "1) Find legacy mcp-server import usage"
rg -n --type=py -C2 '\bfrom\s+agent\s+import\s+ComputerAgent\b' libs/python/mcp-server
echo "2) Confirm canonical ComputerAgent export under renamed package"
rg -n --type=py -C2 'from \.agent import ComputerAgent|__all__' libs/python/agent/cua_agent/__init__.py
echo "3) Check whether legacy top-level package shim still exists in this repo"
fd -HI '^agent$' libs/python/agentRepository: trycua/cua
Length of output: 832
Migrate mcp-server imports before bumping cua-agent to >=0.8.0.
libs/python/mcp-server/mcp_server/server.py line 38 imports from agent import ComputerAgent, which no longer exists under the legacy namespace. The canonical export is now at cua_agent.agent.ComputerAgent. Either update the mcp-server imports to use cua_agent or keep the version constraint until the migration completes in this PR.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@libs/python/mcp-server/pyproject.toml` at line 16, Import resolution breaks
because code still uses the legacy module export "from agent import
ComputerAgent" while the package now exposes the class as
cua_agent.agent.ComputerAgent; update the import in mcp-server server module to
"from cua_agent.agent import ComputerAgent" (and similarly migrate any other
"from agent ..." imports) or else revert the pyproject bump (keep
"cua-agent[all]<0.8.0") until the migration is complete so the existing imports
remain valid.
| from cua_agent import ComputerAgent, LLM, AgentLoop, LLMProvider | ||
| from cua_agent.ui.gradio.ui_components import create_gradio_ui |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Checking generated imports in scripts/playground.sh..."
rg -n 'from cua_agent import ComputerAgent, LLM, AgentLoop, LLMProvider' scripts/playground.sh || true
echo
echo "Inspecting cua_agent package namespace definition..."
sed -n '1,120p' libs/python/agent/cua_agent/__init__.py
echo
echo "Searching for direct top-level bindings for LLM/AgentLoop/LLMProvider in __init__.py..."
rg -n '\b(LLM|AgentLoop|LLMProvider|__getattr__)\b' libs/python/agent/cua_agent/__init__.py || true
echo
echo "Expected: import line exists in playground.sh, but no LLM/AgentLoop/LLMProvider binding in cua_agent/__init__.py."Repository: trycua/cua
Length of output: 1754
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Full size of cua_agent/__init__.py ==="
wc -l libs/python/agent/cua_agent/__init__.py
echo
echo "=== Full content of cua_agent/__init__.py ==="
cat -n libs/python/agent/cua_agent/__init__.py
echo
echo "=== Search for LLM definition in cua_agent package ==="
rg -r 'class LLM|def LLM' libs/python/agent/cua_agent/ || echo "No matches found"
echo
echo "=== Search for AgentLoop definition in cua_agent package ==="
rg -r 'class AgentLoop|def AgentLoop' libs/python/agent/cua_agent/ || echo "No matches found"
echo
echo "=== Search for LLMProvider definition in cua_agent package ==="
rg -r 'class LLMProvider|def LLMProvider' libs/python/agent/cua_agent/ || echo "No matches found"Repository: trycua/cua
Length of output: 2012
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Check what symbols are used from the problematic import in run_demo.py ==="
# Extract the generated run_demo.py content around the imports and uses
rg -A 50 'from cua_agent import ComputerAgent, LLM, AgentLoop, LLMProvider' scripts/playground.sh | head -100
echo
echo "=== Search for actual usage of LLM, AgentLoop, LLMProvider in playground.sh ==="
rg '\b(LLM|AgentLoop|LLMProvider)\b' scripts/playground.sh || echo "No usage found"
echo
echo "=== Check if liteLLM or similar packages are available ==="
fd -t f '.*requirements.*\.txt' libs/python/agent/ | head -5 | xargs cat || echo "No requirements files found"Repository: trycua/cua
Length of output: 3313
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Search for LLM/AgentLoop/LLMProvider definitions anywhere in repo ==="
rg -l '\bLLM\b|\bAgentLoop\b|\bLLMProvider\b' --type python . | head -20 || echo "No matches"
echo
echo "=== Check what's actually imported and used in generated run_demo.py code ==="
# Extract just the relevant sections more carefully
rg -B 5 -A 100 'from cua_agent import ComputerAgent, LLM, AgentLoop, LLMProvider' scripts/playground.sh | grep -E '(^[0-9]+-import|^[0-9]+-from|^[0-9]+-[A-Z]|EOF|LLM|AgentLoop|LLMProvider)' | head -50 || true
echo
echo "=== Confirm: These imports are NOT used in the generated code ==="
echo "The only symbols used in run_demo.py are:"
echo " - ComputerAgent (imported from cua_agent)"
echo " - create_gradio_ui (imported from cua_agent.ui.gradio.ui_components)"
echo " - Standard library modules"Repository: trycua/cua
Length of output: 697
Remove unused imports that will cause startup failure.
Lines 259 and 294 in the generated run_demo.py import LLM, AgentLoop, and LLMProvider from cua_agent, but these symbols do not exist in the package and are never used in the generated code. The import statement will fail at runtime and block playground startup.
Proposed fix
-from cua_agent import ComputerAgent, LLM, AgentLoop, LLMProvider
+from cua_agent import ComputerAgent
from cua_agent.ui.gradio.ui_components import create_gradio_uiApply the same change in both generated run_demo.py templates (cloud and local branches).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@scripts/playground.sh` around lines 259 - 260, The import line in the
generated run_demo.py templates incorrectly includes non-existent and unused
symbols LLM, AgentLoop, and LLMProvider from cua_agent; remove those three names
so the import reads only import ComputerAgent (leave the separate from
cua_agent.ui.gradio.ui_components import create_gradio_ui as-is), and apply this
same change to both generated run_demo.py templates (cloud and local branches)
to prevent startup import failures.
Fix 24 files that still imported from the old 'agent' and 'core' namespaces after the initial rename commit, including two runtime-critical missed imports in computer_server/main.py (core.http at line 282 and agent.computers at line 985), blog examples, tests, cua-cli, cua-sandbox, mcp-server, computer library, and cua-bench agent files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
📦 Publishable packages changed
Add |
Ensures the metapackage requires cua-sandbox with the cua_core namespace migration (0.1.11+). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
📦 Publishable packages changed
Add |
Fixes CUA-445
https://claude.ai/code/session_013snU7pHE5ZNs6nEzjHmLXR
Summary by CodeRabbit
Documentation
Chores