diff --git a/.github/workflows/ci-lume.yml b/.github/workflows/ci-lume.yml index d33191cc..abf678e0 100644 --- a/.github/workflows/ci-lume.yml +++ b/.github/workflows/ci-lume.yml @@ -3,7 +3,13 @@ on: push: branches: - "main" - pull_request: {} + paths: + - "libs/lume/**" + - ".github/workflows/ci-lume.yml" + pull_request: + paths: + - "libs/lume/**" + - ".github/workflows/ci-lume.yml" concurrency: group: lume-${{ github.workflow }}-${{ github.ref }} diff --git a/libs/python/agent/.bumpversion.cfg b/libs/python/agent/.bumpversion.cfg index ef4bfda4..8bf284e0 100644 --- a/libs/python/agent/.bumpversion.cfg +++ b/libs/python/agent/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.4.38 +current_version = 0.4.39 commit = True tag = True tag_name = agent-v{new_version} diff --git a/libs/python/agent/agent/adapters/__init__.py b/libs/python/agent/agent/adapters/__init__.py index 1f07a9fc..cded1d34 100644 --- a/libs/python/agent/agent/adapters/__init__.py +++ b/libs/python/agent/agent/adapters/__init__.py @@ -2,6 +2,7 @@ Adapters package for agent - Custom LLM adapters for LiteLLM """ +from .cua_adapter import CUAAdapter from .huggingfacelocal_adapter import HuggingFaceLocalAdapter from .human_adapter import HumanAdapter from .mlxvlm_adapter import MLXVLMAdapter @@ -10,4 +11,5 @@ __all__ = [ "HuggingFaceLocalAdapter", "HumanAdapter", "MLXVLMAdapter", + "CUAAdapter", ] diff --git a/libs/python/agent/agent/adapters/cua_adapter.py b/libs/python/agent/agent/adapters/cua_adapter.py new file mode 100644 index 00000000..76e13977 --- /dev/null +++ b/libs/python/agent/agent/adapters/cua_adapter.py @@ -0,0 +1,73 @@ +import os +from typing import Any, AsyncIterator, Iterator + +from litellm import acompletion, completion +from litellm.llms.custom_llm import CustomLLM +from litellm.types.utils import GenericStreamingChunk, ModelResponse + + +class CUAAdapter(CustomLLM): + def __init__(self, base_url: str | None = None, api_key: str | None = None, **_: Any): + super().__init__() + self.base_url = base_url or os.environ.get("CUA_BASE_URL") or "https://inference.cua.ai/v1" + self.api_key = api_key or os.environ.get("CUA_INFERENCE_API_KEY") or os.environ.get("CUA_API_KEY") + + def _normalize_model(self, model: str) -> str: + # Accept either "cua/" or raw "" + return model.split("/", 1)[1] if model and model.startswith("cua/") else model + + def completion(self, *args, **kwargs) -> ModelResponse: + params = dict(kwargs) + inner_model = self._normalize_model(params.get("model", "")) + params.update( + { + "model": f"openai/{inner_model}", + "api_base": self.base_url, + "api_key": self.api_key, + "stream": False, + } + ) + return completion(**params) # type: ignore + + async def acompletion(self, *args, **kwargs) -> ModelResponse: + params = dict(kwargs) + inner_model = self._normalize_model(params.get("model", "")) + params.update( + { + "model": f"openai/{inner_model}", + "api_base": self.base_url, + "api_key": self.api_key, + "stream": False, + } + ) + return await acompletion(**params) # type: ignore + + def streaming(self, *args, **kwargs) -> Iterator[GenericStreamingChunk]: + params = dict(kwargs) + inner_model = self._normalize_model(params.get("model", "")) + params.update( + { + "model": f"openai/{inner_model}", + "api_base": self.base_url, + "api_key": self.api_key, + "stream": True, + } + ) + # Yield chunks directly from LiteLLM's streaming generator + for chunk in completion(**params): # type: ignore + yield chunk # type: ignore + + async def astreaming(self, *args, **kwargs) -> AsyncIterator[GenericStreamingChunk]: + params = dict(kwargs) + inner_model = self._normalize_model(params.get("model", "")) + params.update( + { + "model": f"openai/{inner_model}", + "api_base": self.base_url, + "api_key": self.api_key, + "stream": True, + } + ) + stream = await acompletion(**params) # type: ignore + async for chunk in stream: # type: ignore + yield chunk # type: ignore diff --git a/libs/python/agent/agent/agent.py b/libs/python/agent/agent/agent.py index f85c513c..42f04a00 100644 --- a/libs/python/agent/agent/agent.py +++ b/libs/python/agent/agent/agent.py @@ -23,11 +23,7 @@ import litellm import litellm.utils from litellm.responses.utils import Usage -from .adapters import ( - HuggingFaceLocalAdapter, - HumanAdapter, - MLXVLMAdapter, -) +from .adapters import CUAAdapter, HuggingFaceLocalAdapter, HumanAdapter, MLXVLMAdapter from .callbacks import ( BudgetManagerCallback, ImageRetentionCallback, @@ -278,10 +274,12 @@ class ComputerAgent: ) human_adapter = HumanAdapter() mlx_adapter = MLXVLMAdapter() + cua_adapter = CUAAdapter() litellm.custom_provider_map = [ {"provider": "huggingface-local", "custom_handler": hf_adapter}, {"provider": "human", "custom_handler": human_adapter}, {"provider": "mlx", "custom_handler": mlx_adapter}, + {"provider": "cua", "custom_handler": cua_adapter}, ] litellm.suppress_debug_info = True diff --git a/libs/python/agent/pyproject.toml b/libs/python/agent/pyproject.toml index e240e4ff..6a3b522f 100644 --- a/libs/python/agent/pyproject.toml +++ b/libs/python/agent/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "pdm.backend" [project] name = "cua-agent" -version = "0.4.38" +version = "0.4.39" description = "CUA (Computer Use) Agent for AI-driven computer interaction" readme = "README.md" authors = [ diff --git a/libs/python/computer-server/.bumpversion.cfg b/libs/python/computer-server/.bumpversion.cfg index baba7c21..b668353e 100644 --- a/libs/python/computer-server/.bumpversion.cfg +++ b/libs/python/computer-server/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.1.29 +current_version = 0.1.30 commit = True tag = True tag_name = computer-server-v{new_version} diff --git a/libs/python/computer-server/pyproject.toml b/libs/python/computer-server/pyproject.toml index c8fc81a8..7bae1e06 100644 --- a/libs/python/computer-server/pyproject.toml +++ b/libs/python/computer-server/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "pdm.backend" [project] name = "cua-computer-server" -version = "0.1.29" +version = "0.1.30" description = "Server component for the Computer-Use Interface (CUI) framework powering Cua" authors = [