Lots of changes -- package & platform metadata, work on agent & computer page, add more guides

This commit is contained in:
Morgan Dean
2025-07-09 14:38:12 -07:00
parent bbb1a2ccdc
commit 013ff2b24f
14 changed files with 872 additions and 624 deletions

View File

@@ -1,6 +1,6 @@
---
title: FAQ
description: C/ua's frequently asked questions. Find answers to the most common issues or questions when using C/ua tools.
description: Find answers to the most common issues or questions when using C/ua tools.
icon: CircleQuestionMark
---

View File

@@ -1,5 +1,5 @@
{
"title": "C/ua",
"description": "C/ua",
"icon": "House"
"title": "Guides",
"description": "Guides",
"icon": "BookCopy"
}

View File

@@ -11,20 +11,16 @@ C/ua is a collection of cross-platform libraries and tools for building Computer
<Cards>
<Card
href="https://docs.trycua.com/home/cua/computer-use-agent-quickstart"
href="./home/guides/computer-use-agent-quickstart"
title="Computer-Use Agent UI">
Read our guide on getting started with a Computer-Use Agent.
</Card>
<Card
href="https://docs.trycua.com/home/cua/cua-usage-guide"
title="C/ua Usage Guide">
<Card href="./home/guides/cua-usage-guide" title="C/ua Usage Guide">
Get started using C/ua services on your machine.
</Card>
<Card
href="https://docs.trycua.com/home/cua/dev-container-setup"
title="Dev Container Setup">
<Card href="./home/guides/dev-container-setup" title="Dev Container Setup">
Set up a development environment with the Dev Container.
</Card>

View File

@@ -1,266 +0,0 @@
---
title: Agent
---
<div
align="center"
style={{
display: 'flex',
gap: '10px',
margin: '0 auto',
width: '100%',
justifyContent: 'center',
}}>
<a href="#">
<img
src="https://img.shields.io/badge/Python-333333?logo=python&logoColor=white&labelColor=blue"
alt="Python"
/>
</a>
<a href="#">
<img
src="https://img.shields.io/badge/macOS-000000?logo=apple&logoColor=F0F0F0"
alt="macOS"
/>
</a>
<a href="https://discord.com/invite/mVnXXpdE85">
<img
src="https://img.shields.io/badge/Discord-%235865F2.svg?&logo=discord&logoColor=white"
alt="Discord"
/>
</a>
<a href="https://pypi.org/project/cua-computer/">
<img
src="https://img.shields.io/pypi/v/cua-computer?color=blue"
alt="PyPI"
/>
</a>
</div>
<div
align="center"
style={{
display: 'flex',
margin: '0 0',
width: '100%',
justifyContent: 'center',
}}
>
<a href="/api/computer">
Reference
</a>
</div>
**cua-agent** is a general Computer-Use framework for running multi-app agentic workflows targeting macOS and Linux sandbox created with C/ua, supporting local (Ollama) and cloud model providers (OpenAI, Anthropic, Groq, DeepSeek, Qwen).
### Get started with Agent
<div align="center">
<img src="/img/agent.png" />
</div>
## Install
```bash
pip install "cua-agent[all]"
# or install specific loop providers
pip install "cua-agent[openai]" # OpenAI Cua Loop
pip install "cua-agent[anthropic]" # Anthropic Cua Loop
pip install "cua-agent[uitars]" # UI-Tars support
pip install "cua-agent[omni]" # Cua Loop based on OmniParser (includes Ollama for local models)
pip install "cua-agent[ui]" # Gradio UI for the agent
# For local UI-TARS with MLX support, you need to manually install mlx-vlm:
pip install "cua-agent[uitars-mlx]"
pip install git+https://github.com/ddupont808/mlx-vlm.git@stable/fix/qwen2-position-id # PR: https://github.com/Blaizzy/mlx-vlm/pull/349
```
## Run
```bash
async with Computer() as macos_computer:
# Create agent with loop and provider
agent = ComputerAgent(
computer=macos_computer,
loop=AgentLoop.OPENAI,
model=LLM(provider=LLMProvider.OPENAI)
# or
# loop=AgentLoop.ANTHROPIC,
# model=LLM(provider=LLMProvider.ANTHROPIC)
# or
# loop=AgentLoop.OMNI,
# model=LLM(provider=LLMProvider.OLLAMA, name="gemma3")
# or
# loop=AgentLoop.UITARS,
# model=LLM(provider=LLMProvider.OAICOMPAT, name="ByteDance-Seed/UI-TARS-1.5-7B", provider_base_url="https://**************.us-east-1.aws.endpoints.huggingface.cloud/v1")
)
tasks = [
"Look for a repository named trycua/cua on GitHub.",
"Check the open issues, open the most recent one and read it.",
"Clone the repository in users/lume/projects if it doesn't exist yet.",
"Open the repository with an app named Cursor (on the dock, black background and white cube icon).",
"From Cursor, open Composer if not already open.",
"Focus on the Composer text area, then write and submit a task to help resolve the GitHub issue.",
]
for i, task in enumerate(tasks):
print(f"\nExecuting task {i}/{len(tasks)}: {task}")
async for result in agent.run(task):
print(result)
print(f"\n✅ Task {i+1}/{len(tasks)} completed: {task}")
```
Refer to these notebooks for step-by-step guides on how to use the Computer-Use Agent (CUA):
- [Agent Notebook](https://github.com/trycua/cua/tree/main/notebooks/agent_nb.ipynb) - Complete examples and workflows
## Using the Gradio UI
The agent includes a Gradio-based user interface for easier interaction.
<div align="center">
<img src="/img/agent_gradio_ui.png" />
</div>
To use it:
```bash
# Install with Gradio support
pip install "cua-agent[ui]"
```
### Create a simple launcher script
```python
# launch_ui.py
from agent.ui.gradio.app import create_gradio_ui
app = create_gradio_ui()
app.launch(share=False)
```
### Setting up API Keys
For the Gradio UI to show available models, you need to set API keys as environment variables:
```bash
# For OpenAI models
export OPENAI_API_KEY=your_openai_key_here
# For Anthropic models
export ANTHROPIC_API_KEY=your_anthropic_key_here
# Launch with both keys set
OPENAI_API_KEY=your_key ANTHROPIC_API_KEY=your_key python launch_ui.py
```
Without these environment variables, the UI will show "No models available" for the corresponding providers, but you can still use local models with the OMNI loop provider.
### Using Local Models
You can use local models with the OMNI loop provider by selecting "Custom model..." from the dropdown. The default provider URL is set to `http://localhost:1234/v1` which works with LM Studio.
If you're using a different local model server:
- vLLM: `http://localhost:8000/v1`
- LocalAI: `http://localhost:8080/v1`
- Ollama with OpenAI compat API: `http://localhost:11434/v1`
The Gradio UI provides:
- Selection of different agent loops (OpenAI, Anthropic, OMNI)
- Model selection for each provider
- Configuration of agent parameters
- Chat interface for interacting with the agent
### Using UI-TARS
The UI-TARS models are available in two forms:
1. **MLX UI-TARS models** (Default): These models run locally using MLXVLM provider
- `mlx-community/UI-TARS-1.5-7B-4bit` (default) - 4-bit quantized version
- `mlx-community/UI-TARS-1.5-7B-6bit` - 6-bit quantized version for higher quality
```python
agent = ComputerAgent(
computer=macos_computer,
loop=AgentLoop.UITARS,
model=LLM(provider=LLMProvider.MLXVLM, name="mlx-community/UI-TARS-1.5-7B-4bit")
)
```
2. **OpenAI-compatible UI-TARS**: For using the original ByteDance model
- If you want to use the original ByteDance UI-TARS model via an OpenAI-compatible API, follow the [deployment guide](https://github.com/bytedance/UI-TARS/blob/main/README_deploy.md)
- This will give you a provider URL like `https://**************.us-east-1.aws.endpoints.huggingface.cloud/v1` which you can use in the code or Gradio UI:
```python
agent = ComputerAgent(
computer=macos_computer,
loop=AgentLoop.UITARS,
model=LLM(provider=LLMProvider.OAICOMPAT, name="tgi",
provider_base_url="https://**************.us-east-1.aws.endpoints.huggingface.cloud/v1")
)
```
## Agent Loops
The `cua-agent` package provides three agent loops variations, based on different CUA models providers and techniques:
| Agent Loop | Supported Models | Description | Set-Of-Marks |
| :-------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------- | :----------- |
| `AgentLoop.OPENAI` | • `computer_use_preview` | Use OpenAI Operator CUA model | Not Required |
| `AgentLoop.ANTHROPIC` | • `claude-3-5-sonnet-20240620`<br/>• `claude-3-7-sonnet-20250219` | Use Anthropic Computer-Use | Not Required |
| `AgentLoop.UITARS` | • `mlx-community/UI-TARS-1.5-7B-4bit` (default)<br/>• `mlx-community/UI-TARS-1.5-7B-6bit`<br/>• `ByteDance-Seed/UI-TARS-1.5-7B` (via openAI-compatible endpoint) | Uses UI-TARS models with MLXVLM (default) or OAICOMPAT providers | Not Required |
| `AgentLoop.OMNI` | • `claude-3-5-sonnet-20240620`<br/>• `claude-3-7-sonnet-20250219`<br/>• `gpt-4.5-preview`<br/>• `gpt-4o`<br/>• `gpt-4`<br/>• `phi4`<br/>• `phi4-mini`<br/>• `gemma3`<br/>• `...`<br/>• `Any Ollama or OpenAI-compatible model` | Use OmniParser for element pixel-detection (SoM) and any VLMs for UI Grounding and Reasoning | OmniParser |
## AgentResponse
The `AgentResponse` class represents the structured output returned after each agent turn. It contains the agent's response, reasoning, tool usage, and other metadata. The response format aligns with the new [OpenAI Agent SDK specification](https://platform.openai.com/docs/api-reference/responses) for better consistency across different agent loops.
```python
async for result in agent.run(task):
print("Response ID: ", result.get("id"))
# Print detailed usage information
usage = result.get("usage")
if usage:
print("\nUsage Details:")
print(f" Input Tokens: {usage.get('input_tokens')}")
if "input_tokens_details" in usage:
print(f" Input Tokens Details: {usage.get('input_tokens_details')}")
print(f" Output Tokens: {usage.get('output_tokens')}")
if "output_tokens_details" in usage:
print(f" Output Tokens Details: {usage.get('output_tokens_details')}")
print(f" Total Tokens: {usage.get('total_tokens')}")
print("Response Text: ", result.get("text"))
# Print tools information
tools = result.get("tools")
if tools:
print("\nTools:")
print(tools)
# Print reasoning and tool call outputs
outputs = result.get("output", [])
for output in outputs:
output_type = output.get("type")
if output_type == "reasoning":
print("\nReasoning Output:")
print(output)
elif output_type == "computer_call":
print("\nTool Call Output:")
print(output)
```
**Note on Settings Persistence:**
- The Gradio UI automatically saves your configuration (Agent Loop, Model Choice, Custom Base URL, Save Trajectory state, Recent Images count) to a file named `.gradio_settings.json` in the project's root directory when you successfully run a task.
- This allows your preferences to persist between sessions.
- API keys entered into the custom provider field are **not** saved in this file for security reasons. Manage API keys using environment variables (e.g., `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`) or a `.env` file.
- It's recommended to add `.gradio_settings.json` to your `.gitignore` file.

View File

@@ -0,0 +1,158 @@
---
title: Gradio UI with the Python Agent
description: The agent module includes a Gradio-based user interface for easier interaction with Computer-Use Agent workflows.
---
The agent includes a Gradio-based user interface for easier interaction.
<div align="center">
<img src="/img/agent_gradio_ui.png" />
</div>
## Install
```bash
# Install with Gradio support
pip install "cua-agent[ui]"
```
## Create a simple launcher script
```python
# launch_ui.py
from agent.ui.gradio.app import create_gradio_ui
app = create_gradio_ui()
app.launch(share=False)
```
### Run the launcher
```bash
python launch_ui.py
```
This will start the Gradio interface on `http://localhost:7860`.
## Features
The Gradio UI provides:
- **Model Selection**: Choose between different AI models and providers
- **Task Input**: Enter tasks for the agent to execute
- **Real-time Output**: View the agent's actions and results as they happen
- **Screenshot Display**: See visual feedback from the computer screen
- **Settings Management**: Configure and save your preferred settings
## Supported Providers
1. **OpenAI**: GPT-4 and GPT-4 Vision models
2. **Anthropic**: Claude models
3. **Ollama**: Local models like Gemma3
4. **UI-TARS**: Specialized UI understanding models
### Using UI-TARS
UI-TARS is a specialized model for UI understanding tasks. You have two options:
1. **Local MLX UI-TARS**: For running the model locally on Apple Silicon
```bash
# Install MLX support
pip install "cua-agent[uitars-mlx]"
pip install git+https://github.com/ddupont808/mlx-vlm.git@stable/fix/qwen2-position-id
```
Then select "UI-TARS (MLX)" in the Gradio interface.
2. **OpenAI-compatible UI-TARS**: For using the original ByteDance model
- If you want to use the original ByteDance UI-TARS model via an OpenAI-compatible API, follow the [deployment guide](https://github.com/bytedance/UI-TARS/blob/main/README_deploy.md)
- This will give you a provider URL like `https://**************.us-east-1.aws.endpoints.huggingface.cloud/v1` which you can use in the code or Gradio UI:
```python
agent = ComputerAgent(
computer=macos_computer,
loop=AgentLoop.UITARS,
model=LLM(
provider=LLMProvider.OAICOMPAT,
name="ByteDance-Seed/UI-TARS-1.5-7B",
provider_base_url="https://**************.us-east-1.aws.endpoints.huggingface.cloud/v1"
)
)
```
Or in the Gradio UI, select "OpenAI Compatible" and enter:
- Model Name: `ByteDance-Seed/UI-TARS-1.5-7B`
- Base URL: Your deployment URL
- API Key: Your API key (if required)
## Advanced Configuration
### Custom Provider Settings
You can configure custom providers in the UI:
1. Select "OpenAI Compatible" from the provider dropdown
2. Enter your custom model name, base URL, and API key
3. The settings will be saved for future sessions
## Environment Variables
Set API keys as environment variables for security:
```bash
export OPENAI_API_KEY="your-openai-key"
export ANTHROPIC_API_KEY="your-anthropic-key"
export GROQ_API_KEY="your-groq-key"
export DEEPSEEK_API_KEY="your-deepseek-key"
export QWEN_API_KEY="your-qwen-key"
```
Or use a `.env` file:
```bash
# .env
OPENAI_API_KEY=your-openai-key
ANTHROPIC_API_KEY=your-anthropic-key
# ... other keys
```
## Settings Persistence
The Gradio UI automatically saves your settings to `.gradio_settings.json` in your working directory. This includes:
- Selected provider and model
- Custom provider configurations (URLs and model names)
- Other UI preferences
**Note**: API keys entered into the custom provider field are **not** saved in this file for security reasons. Manage API keys using environment variables (e.g., `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`) or a `.env` file.
It's recommended to add `.gradio_settings.json` to your `.gitignore` file.
## Example Usage
Here's a complete example of using the Gradio UI with different providers:
```python
# launch_ui_with_env.py
from agent.ui.gradio.app import create_gradio_ui
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Create and launch the UI
app = create_gradio_ui()
app.launch(share=False, server_port=7860)
```
Once launched, you can:
1. Select your preferred AI provider and model
2. Enter a task like "Open a web browser and search for Python tutorials"
3. Click "Run" to execute the task
4. Watch the agent perform the actions in real-time
5. View screenshots and logs of the execution
The UI makes it easy to experiment with different models and tasks without writing code for each interaction.

View File

@@ -0,0 +1,257 @@
---
title: Agent
description: The Computer-Use framework for running multi-app agentic workflows targeting macOS, Linux, and Windows sandboxes.
pypi: cua-computer
macos: true
windows: true
linux: true
---
import { buttonVariants } from 'fumadocs-ui/components/ui/button';
import { cn } from 'fumadocs-ui/utils/cn';
import { ChevronRight } from 'lucide-react';
**Agent** is a powerful Computer-Use framework that enables AI agents to interact with desktop applications and perform complex multi-step workflows across macOS, Linux, and Windows environments. Built on the C/ua platform, it supports both local models (via Ollama) and cloud providers (OpenAI, Anthropic, Groq, DeepSeek, Qwen).
## Installation
Install CUA Agent with pip. Choose the installation that matches your needs:
### All Providers (Recommended)
```bash
# Install everything you need
pip install "cua-agent[all]"
```
### Selective Installation
```bash
# OpenAI models (GPT-4, Computer Use Preview)
pip install "cua-agent[openai]"
# Anthropic models (Claude 3.5 Sonnet)
pip install "cua-agent[anthropic]"
# Local UI-TARS models
pip install "cua-agent[uitars]"
# OmniParser + Ollama for local models
pip install "cua-agent[omni]"
# Gradio web interface
pip install "cua-agent[ui]"
```
### Advanced: Local UI-TARS with MLX
```bash
pip install "cua-agent[uitars-mlx]"
pip install git+https://github.com/ddupont808/mlx-vlm.git@stable/fix/qwen2-position-id
```
### Requirements
- Python 3.8+
- macOS, Linux, or Windows
- For cloud providers: API keys (OpenAI, Anthropic, etc.)
- For local models: Sufficient RAM and compute resources
## Getting Started
### Basic Usage
Here's a simple example to get you started with CUA Agent:
```python
from cua_agent import ComputerAgent, AgentLoop, LLM, LLMProvider
from cua_computer import Computer
# Set your API key
import os
os.environ["OPENAI_API_KEY"] = "your-api-key-here"
async with Computer() as computer:
# Create agent with OpenAI
agent = ComputerAgent(
computer=computer,
loop=AgentLoop.OPENAI,
model=LLM(provider=LLMProvider.OPENAI)
)
# Run a simple task
async for result in agent.run("Open a text editor and write 'Hello, World!'"):
print(result.get("text"))
```
### Multi-Step Workflow
```python
async with Computer() as computer:
# Create agent with your preferred provider
agent = ComputerAgent(
computer=computer,
loop=AgentLoop.OPENAI, # or ANTHROPIC, OMNI, UITARS
model=LLM(provider=LLMProvider.OPENAI)
)
# Define complex workflow
tasks = [
"Look for a repository named trycua/cua on GitHub.",
"Check the open issues, open the most recent one and read it.",
"Clone the repository in users/lume/projects if it doesn't exist yet.",
"Open the repository with an app named Cursor.",
"From Cursor, open Composer and write a task to help resolve the GitHub issue.",
]
# Execute tasks sequentially
for i, task in enumerate(tasks):
print(f"\nExecuting task {i+1}/{len(tasks)}: {task}")
async for result in agent.run(task):
print(result.get("text"))
print(f"✅ Task {i+1} completed")
```
### Alternative Model Providers
```python
# Anthropic Claude
agent = ComputerAgent(
computer=computer,
loop=AgentLoop.ANTHROPIC,
model=LLM(provider=LLMProvider.ANTHROPIC)
)
# Local Ollama model
agent = ComputerAgent(
computer=computer,
loop=AgentLoop.OMNI,
model=LLM(provider=LLMProvider.OLLAMA, name="gemma3")
)
# UI-TARS model
agent = ComputerAgent(
computer=computer,
loop=AgentLoop.UITARS,
model=LLM(
provider=LLMProvider.OAICOMPAT,
name="ByteDance-Seed/UI-TARS-1.5-7B",
provider_base_url="https://your-endpoint.com/v1"
)
)
```
## Agent Loops
The `cua-agent` package provides three agent loops variations, based on different CUA models providers and techniques:
| Agent Loop | Supported Models | Description | Set-Of-Marks |
| :-------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------- | :----------- |
| `AgentLoop.OPENAI` | • `computer_use_preview` | Use OpenAI Operator CUA model | Not Required |
| `AgentLoop.ANTHROPIC` | • `claude-3-5-sonnet-20240620`<br/>• `claude-3-7-sonnet-20250219` | Use Anthropic Computer-Use | Not Required |
| `AgentLoop.UITARS` | • `mlx-community/UI-TARS-1.5-7B-4bit` (default)<br/>• `mlx-community/UI-TARS-1.5-7B-6bit`<br/>• `ByteDance-Seed/UI-TARS-1.5-7B` (via openAI-compatible endpoint) | Uses UI-TARS models with MLXVLM (default) or OAICOMPAT providers | Not Required |
| `AgentLoop.OMNI` | • `claude-3-5-sonnet-20240620`<br/>• `claude-3-7-sonnet-20250219`<br/>• `gpt-4.5-preview`<br/>• `gpt-4o`<br/>• `gpt-4`<br/>• `phi4`<br/>• `phi4-mini`<br/>• `gemma3`<br/>• `...`<br/>• `Any Ollama or OpenAI-compatible model` | Use OmniParser for element pixel-detection (SoM) and any VLMs for UI Grounding and Reasoning | OmniParser |
## Agent Response
The `AgentResponse` class represents the structured output returned after each agent turn. It contains the agent's response, reasoning, tool usage, and other metadata. The response format aligns with the new [OpenAI Agent SDK specification](https://platform.openai.com/docs/api-reference/responses) for better consistency across different agent loops.
```typescript
interface AgentResponse {
id: string;
text: string;
usage?: {
input_tokens: number;
input_tokens_details?: {
text_tokens: number;
image_tokens: number;
};
output_tokens: number;
output_tokens_details?: {
text_tokens: number;
reasoning_tokens: number;
};
total_tokens: number;
};
tools?: Array<{
name: string;
description: string;
}>;
output?: Array<{
type: 'reasoning' | 'computer_call';
content?: string; // for reasoning type
tool_name?: string; // for computer_call type
parameters?: Record<string, any>; // for computer_call type
result?: string; // for computer_call type
}>;
}
```
### Example Usage
```python
async for result in agent.run(task):
print("Response ID: ", result.get("id"))
# Print detailed usage information
usage = result.get("usage")
if usage:
print("\nUsage Details:")
print(f" Input Tokens: {usage.get('input_tokens')}")
if "input_tokens_details" in usage:
print(f" Input Tokens Details: {usage.get('input_tokens_details')}")
print(f" Output Tokens: {usage.get('output_tokens')}")
if "output_tokens_details" in usage:
print(f" Output Tokens Details: {usage.get('output_tokens_details')}")
print(f" Total Tokens: {usage.get('total_tokens')}")
print("Response Text: ", result.get("text"))
# Print tools information
tools = result.get("tools")
if tools:
print("\nTools:")
print(tools)
# Print reasoning and tool call outputs
outputs = result.get("output", [])
for output in outputs:
output_type = output.get("type")
if output_type == "reasoning":
print("\nReasoning Output:")
print(output)
elif output_type == "computer_call":
print("\nTool Call Output:")
print(output)
```
## Examples & Guides
<Cards>
<Card
href="https://github.com/trycua/cua/tree/main/notebooks/agent_nb.ipynb"
title="Agent Notebook">
Step-by-step instructions on using the Computer-Use Agent (CUA)
</Card>
<Card href="../libraries/agent/agent-gradio-ui" title="Agent Gradio Guide">
Use the Agent library with a Python Gradio UI
</Card>
</Cards>
---
<Callout type="info">
**Need detailed API documentation?** Explore the complete API reference with
detailed class documentation, and method signatures.
<a
href="/api/agent"
className={cn(
buttonVariants({
color: 'secondary',
}),
'no-underline h-10'
)}>
View API Reference
<ChevronRight />
</a>
</Callout>

View File

@@ -1,275 +0,0 @@
---
title: Computer
---
import { Tabs, Tab } from 'fumadocs-ui/components/tabs';
<div
align="center"
style={{
display: 'flex',
gap: '10px',
margin: '0 auto',
width: '100%',
justifyContent: 'center',
}}
>
<a href="#">
<img
src="https://img.shields.io/badge/Python-333333?logo=python&logoColor=white&labelColor=blue"
alt="Python"
/>
</a>
<a href="https://pypi.org/project/cua-computer/">
<img
src="https://img.shields.io/pypi/v/cua-computer?color=blue"
alt="PyPI"
/>
</a>
<a href="#">
<img
src="https://img.shields.io/badge/TypeScript-333333?logo=typescript&logoColor=white&labelColor=3178C6"
alt="TypeScript"
/>
</a>
<a href="https://www.npmjs.com/package/@cua/computer">
<img
alt="NPM Version"
src="https://img.shields.io/npm/v/react?color=CB3837"
/>
</a>
</div>
<div
align="center"
style={{
display: 'flex',
margin: '0 0',
width: '100%',
justifyContent: 'center',
}}
>
<a href="/api/computer">
Reference
</a>
</div>
**cua-computer** is a Computer-Use Interface (CUI) framework powering Cua for interacting with local macOS and Linux sandboxes. It's PyAutoGUI-compatible and pluggable with any AI agent systems (Cua, Langchain, CrewAI, AutoGen). Computer relies on [Lume](./lume.mdx) for creating and managing sandbox environments.
<div align="center">
<img src="/img/computer.png" />
</div>
## Key Features
- Create and manage virtual machine sandboxes
- Take screenshots of the virtual machine
- Control mouse movements and clicks
- Simulate keyboard input
- Manage clipboard content
- Interact with the operating system interface
- Support for macOS and Linux environments
## Installation
<Tabs groupId='language' persist items={['Python', 'TypeScript']}>
<Tab value="Python">
To install the Computer-Use Interface (CUI) for Python:
```bash
pip install "cua-computer[all]"
```
The `cua-computer` PyPi package pulls automatically the latest executable version of Lume through [pylume](https://github.com/trycua/pylume).
</Tab>
<Tab value="TypeScript">
To install the Computer-Use Interface (CUI) for TypeScript:
```bash
npm install @cua/computer
```
</Tab>
</Tabs>
## Quick Start
<Tabs groupId='language' persist items={['Python', 'TypeScript']}>
<Tab value="Python">
```python
from computer import Computer
computer = Computer(os_type="macos", display="1024x768", memory="8GB", cpu="4")
try:
await computer.run()
screenshot = await computer.interface.screenshot()
with open("screenshot.png", "wb") as f:
f.write(screenshot)
await computer.interface.move_cursor(100, 100)
await computer.interface.left_click()
await computer.interface.right_click(300, 300)
await computer.interface.double_click(400, 400)
await computer.interface.type("Hello, World!")
await computer.interface.press_key("enter")
await computer.interface.set_clipboard("Test clipboard")
content = await computer.interface.copy_to_clipboard()
print(f"Clipboard content: {content}")
finally:
await computer.stop()
```
</Tab>
<Tab value="TypeScript">
```typescript
import { Computer, OSType } from '@cua/computer';
const main = async () => {
// Create a cloud-based computer
const computer = new Computer({
name: 'cloud-vm',
osType: OSType.Linux,
apiKey: 'your-api-key',
});
// Access the interface
const interface = computer.interface;
// Screenshot operations
const screenshot = await interface.screenshot();
// Mouse operations
await interface.moveCursor(100, 100);
await interface.leftClick();
await interface.rightClick(300, 300);
await interface.doubleClick(400, 400);
await interface.dragTo(500, 500, 'left', 1000); // Drag with left button for 1 second
// Keyboard operations
await interface.typeText('Hello from TypeScript!');
await interface.pressKey('enter');
await interface.hotkey('command', 'a'); // Select all
// Clipboard operations
await interface.setClipboard('Clipboard content');
const content = await interface.copyToClipboard();
// File operations
await interface.writeText('/tmp/test.txt', 'Hello world');
const fileContent = await interface.readText('/tmp/test.txt');
// Run a command in the VM
const [stdout, stderr] = await interface.runCommand('ls -la');
// Disconnect from the cloud VM
await computer.disconnect();
};
main().catch(console.error);
```
</Tab>
</Tabs>
## Getting Started
<Tabs groupId='language' persist items={['Python', 'TypeScript']}>
<Tab value="Python">
Refer to this notebook for a step-by-step guide on how to use the Computer-Use Interface (CUI):
- [Computer-Use Interface (CUI)](https://github.com/trycua/cua/tree/main/notebooks/samples/computer_nb.ipynb)
</Tab>
<Tab value="TypeScript">
Check out the examples in the repository for more detailed usage patterns and advanced scenarios.
</Tab>
</Tabs>
## Using the Gradio Computer UI (Python Only)
The computer module includes a Gradio UI for creating and sharing demonstration data. We make it easy for people to build community datasets for better computer use models with an upload to Huggingface feature.
```bash
# Install with UI support
pip install "cua/computer[ui]"
```
> **Note:** For precise control of the computer, we recommend using VNC or Screen Sharing instead of the Computer Gradio UI.
### Building and Sharing Demonstrations with Huggingface
Follow these steps to contribute your own demonstrations:
#### 1. Set up Huggingface Access
Set your HF_TOKEN in a .env file or in your environment variables:
```bash
# In .env file
HF_TOKEN=your_huggingface_token
```
#### 2. Launch the Computer UI
```python
# launch_ui.py
from computer.ui.gradio.app import create_gradio_ui
from dotenv import load_dotenv
load_dotenv('.env')
app = create_gradio_ui()
app.launch(share=False)
```
For examples, see [Computer UI Examples](https://github.com/trycua/cua/tree/main/examples/computer_ui_examples.py)
#### 3. Record Your Tasks
<details open>
<summary>View demonstration video</summary>
<video
src="https://github.com/user-attachments/assets/de3c3477-62fe-413c-998d-4063e48de176"
controls
width="600"></video>
</details>
Record yourself performing various computer tasks using the UI.
#### 4. Save Your Demonstrations
<details open>
<summary>View demonstration video</summary>
<video
src="https://github.com/user-attachments/assets/5ad1df37-026a-457f-8b49-922ae805faef"
controls
width="600"></video>
</details>
Save each task by picking a descriptive name and adding relevant tags (e.g., "office", "web-browsing", "coding").
#### 5. Record Additional Demonstrations
Repeat steps 3 and 4 until you have a good amount of demonstrations covering different tasks and scenarios.
#### 6. Upload to Huggingface
<details open>
<summary>View demonstration video</summary>
<video
src="https://github.com/user-attachments/assets/c586d460-3877-4b5f-a736-3248886d2134"
controls
width="600"></video>
</details>
Upload your dataset to Huggingface by:
- Naming it as `{your_username}/{dataset_name}`
- Choosing public or private visibility
- Optionally selecting specific tags to upload only tasks with certain tags
#### Examples and Resources
- Example Dataset: [ddupont/test-dataset](https://huggingface.co/datasets/ddupont/test-dataset)
- Find Community Datasets: 🔍 [Browse CUA Datasets on Huggingface](https://huggingface.co/datasets?other=cua)

View File

@@ -0,0 +1,90 @@
---
title: Gradio UI with the Python Computer Interface
description: The computer module includes a Gradio UI for creating and sharing demonstration data. This guide makes it easy for people to build community datasets for better computer use models with an upload to Huggingface feature.
---
<Callout title="Note">
For precise control of the computer, we recommend using VNC or Screen Sharing
instead of Gradio UI.
</Callout>
```bash
# Install with UI support
pip install "cua/computer[ui]"
```
## Building and Sharing Demonstrations with Huggingface
Follow these steps to contribute your own demonstrations:
### 1. Set up Huggingface Access
Set your HF_TOKEN in a .env file or in your environment variables:
```bash
# In .env file
HF_TOKEN=your_huggingface_token
```
### 2. Launch the Computer UI
```python
# launch_ui.py
from computer.ui.gradio.app import create_gradio_ui
from dotenv import load_dotenv
load_dotenv('.env')
app = create_gradio_ui()
app.launch(share=False)
```
For examples, see [Computer UI Examples](https://github.com/trycua/cua/tree/main/examples/computer_ui_examples.py)
### 3. Record Your Tasks
<details open>
<summary>View demonstration video</summary>
<video
src="https://github.com/user-attachments/assets/de3c3477-62fe-413c-998d-4063e48de176"
controls
width="600"></video>
</details>
Record yourself performing various computer tasks using the UI.
### 4. Save Your Demonstrations
<details open>
<summary>View demonstration video</summary>
<video
src="https://github.com/user-attachments/assets/5ad1df37-026a-457f-8b49-922ae805faef"
controls
width="600"></video>
</details>
Save each task by picking a descriptive name and adding relevant tags (e.g., "office", "web-browsing", "coding").
### 5. Record Additional Demonstrations
Repeat steps 3 and 4 until you have a good amount of demonstrations covering different tasks and scenarios.
### 6. Upload to Huggingface
<details open>
<summary>View demonstration video</summary>
<video
src="https://github.com/user-attachments/assets/c586d460-3877-4b5f-a736-3248886d2134"
controls
width="600"></video>
</details>
Upload your dataset to Huggingface by:
- Naming it as `{your_username}/{dataset_name}`
- Choosing public or private visibility
- Optionally selecting specific tags to upload only tasks with certain tags
### Examples and Resources
- Example Dataset: [ddupont/test-dataset](https://huggingface.co/datasets/ddupont/test-dataset)
- Find Community Datasets: 🔍 [Browse CUA Datasets on Huggingface](https://huggingface.co/datasets?other=cua)

View File

@@ -0,0 +1,177 @@
---
title: Computer
description: The Computer-Use Interface (CUI) framework for interacting with local macOS, Linux, and Windows sandboxes.
macos: true
windows: true
linux: true
pypi: cua-computer
npm: '@trycua/computer'
---
import { Tabs, Tab } from 'fumadocs-ui/components/tabs';
import { buttonVariants } from 'fumadocs-ui/components/ui/button';
import { cn } from 'fumadocs-ui/utils/cn';
import { ChevronRight } from 'lucide-react';
Computer powers Cua systems and is PyAutoGUI-compatible and pluggable with any AI agent system (Cua, Langchain, CrewAI, AutoGen). It relies on [Lume](./lume.mdx) for creating and managing sandbox environments.
## Installation
<Tabs groupId='language' persist items={['Python', 'TypeScript']}>
<Tab value="Python">
```bash
pip install "cua-computer[all]"
```
The `cua-computer` PyPi package automatically pulls the latest executable version of Lume through [pylume](https://github.com/trycua/pylume).
</Tab>
<Tab value="TypeScript">
```bash
npm install @trycua/computer
```
</Tab>
</Tabs>
## Key Features
- Create and manage virtual machine sandboxes
- Take screenshots of the virtual machine
- Control mouse movements and clicks
- Simulate keyboard input
- Manage clipboard content
- Interact with the operating system interface
- Support for macOS and Linux environments
## Simple Example
<Tabs groupId='language' persist items={['Python', 'TypeScript']}>
<Tab value="Python">
```python
from computer import Computer
computer = Computer(os_type="macos", display="1024x768", memory="8GB", cpu="4")
try:
# Start a new local vm instance using Lume
await computer.run()
# Interface with the instance
screenshot = await computer.interface.screenshot()
with open("screenshot.png", "wb") as f:
f.write(screenshot)
await computer.interface.move_cursor(100, 100)
await computer.interface.left_click()
await computer.interface.right_click(300, 300)
await computer.interface.double_click(400, 400)
await computer.interface.type("Hello, World!")
await computer.interface.press_key("enter")
await computer.interface.set_clipboard("Test clipboard")
content = await computer.interface.copy_to_clipboard()
print(f"Clipboard content: {content}")
finally:
# Stop the vm instance
await computer.stop()
```
</Tab>
<Tab value="TypeScript">
```typescript
import { Computer, OSType } from '@trycua/computer';
// This creates and interfaces with a cloud-based c/ua container.
const main = async () => {
// Create a cloud-based computer
const computer = new Computer({
name: 'cloud-vm',
osType: OSType.Linux,
apiKey: 'your-api-key',
});
// Access the interface
const interface = computer.interface;
// Screenshot operations
const screenshot = await interface.screenshot();
// Mouse operations
await interface.moveCursor(100, 100);
await interface.leftClick();
await interface.rightClick(300, 300);
await interface.doubleClick(400, 400);
await interface.dragTo(500, 500, 'left', 1000); // Drag with left button for 1 second
// Keyboard operations
await interface.typeText('Hello from TypeScript!');
await interface.pressKey('enter');
await interface.hotkey('command', 'a'); // Select all
// Clipboard operations
await interface.setClipboard('Clipboard content');
const content = await interface.copyToClipboard();
// File operations
await interface.writeText('/tmp/test.txt', 'Hello world');
const fileContent = await interface.readText('/tmp/test.txt');
// Run a command in the VM
const [stdout, stderr] = await interface.runCommand('ls -la');
// Disconnect from the cloud VM
await computer.disconnect();
};
main().catch(console.error);
```
</Tab>
</Tabs>
## Examples & Guides
<Tabs groupId="language" persist items={['Python', 'TypeScript']}>
<Tab value="Python">
<Cards>
<Card
href="https://github.com/trycua/cua/tree/main/notebooks/samples/computer_nb.ipynb"
title="Computer-Use Interface (CUI)">
Step-by-step guide on using the Computer-Use Interface (CUI)
</Card>
<Card
href="../libraries/computer/computer-use-gradio-ui"
title="Computer-Use Gradio UI">
Use the Computer library with a Python Gradio UI
</Card>
</Cards>
</Tab>
<Tab value="TypeScript">
<Cards>
<Card
href="https://github.com/trycua/cua/tree/main/examples/computer-example-ts"
title="Computer Cloud OpenAI">
Use C/ua Cloud Containers with OpenAI's API to execute tasks in a sandbox
</Card>
</Cards>
</Tab>
</Tabs>
---
<Callout type="info">
**Need detailed API documentation?** Explore the complete API reference with
detailed class documentation, and method signatures.
<a
href="/api/computer"
className={cn(
buttonVariants({
color: 'secondary',
}),
'no-underline h-10'
)}>
View API Reference
<ChevronRight />
</a>
</Callout>

View File

@@ -9,7 +9,12 @@
"faq",
"telemetry",
"---[BookCopy]Guides---",
"...guides",
"guides/cua-usage-guide",
"guides/developer-guide",
"guides/dev-container-setup",
"guides/computer-use-agent-quickstart",
"guides/agent-gradio-ui",
"guides/computer-use-gradio-ui",
"---[Library]Libraries---",
"...libraries"
]

View File

@@ -15,7 +15,9 @@
"lucide-react": "^0.525.0",
"next": "15.3.3",
"react": "^19.1.0",
"react-dom": "^19.1.0"
"react-dom": "^19.1.0",
"tailwind-merge": "^3.3.1",
"zod": "^3.25.76"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",

14
docs/pnpm-lock.yaml generated
View File

@@ -29,6 +29,12 @@ importers:
react-dom:
specifier: ^19.1.0
version: 19.1.0(react@19.1.0)
tailwind-merge:
specifier: ^3.3.1
version: 3.3.1
zod:
specifier: ^3.25.76
version: 3.25.76
devDependencies:
'@biomejs/biome':
specifier: 1.9.4
@@ -1894,8 +1900,8 @@ packages:
resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
engines: {node: '>=18'}
zod@3.25.67:
resolution: {integrity: sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==}
zod@3.25.76:
resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
@@ -2959,7 +2965,7 @@ snapshots:
tinyexec: 1.0.1
tinyglobby: 0.2.14
unist-util-visit: 5.0.0
zod: 3.25.67
zod: 3.25.76
transitivePeerDependencies:
- acorn
- supports-color
@@ -4010,6 +4016,6 @@ snapshots:
yallist@5.0.0: {}
zod@3.25.67: {}
zod@3.25.76: {}
zwitch@2.0.4: {}

View File

@@ -4,12 +4,19 @@ import {
frontmatterSchema,
metaSchema,
} from 'fumadocs-mdx/config';
import { z } from 'zod';
// You can customise Zod schemas for frontmatter and `meta.json` here
// see https://fumadocs.vercel.app/docs/mdx/collections#define-docs
export const docs = defineDocs({
docs: {
schema: frontmatterSchema,
schema: frontmatterSchema.extend({
pypi: z.string().optional(),
npm: z.string().optional(),
macos: z.boolean().default(false),
windows: z.boolean().default(false),
linux: z.boolean().default(false),
}),
},
meta: {
schema: metaSchema,

View File

@@ -16,7 +16,7 @@ import {
import { cn } from 'fumadocs-ui/utils/cn';
import { ChevronDown } from 'lucide-react';
import Link from 'next/link';
import { notFound } from 'next/navigation';
import { notFound, redirect } from 'next/navigation';
export default async function Page(props: {
params: Promise<{ slug?: string[] }>;
@@ -24,9 +24,9 @@ export default async function Page(props: {
const params = await props.params;
const slug = params.slug || [];
const page = source.getPage(slug);
if (!page) notFound();
if (!page) redirect('/home');
// Detect if this is an API reference page: /docs/api/[section] or /docs/api/[section]/[version]
// Detect if this is an API reference page: /api/[section] or /api/[section]/[version]
let apiSection: string | null = null;
let apiVersionSlug: string[] = [];
if (slug[0] === 'api' && slug.length >= 2) {
@@ -41,72 +41,161 @@ export default async function Page(props: {
versionItems = await getApiVersions(apiSection);
}
const macos = page.data.macos;
const windows = page.data.windows;
const linux = page.data.linux;
const pypi = page.data.pypi;
const npm = page.data.npm;
const MDXContent = page.data.body;
// Platform icons component
const PlatformIcons = () => {
const hasAnyPlatform = macos || windows || linux;
if (!hasAnyPlatform && !pypi) return null;
return (
<div className="flex flex-col gap-2 mx-4">
{hasAnyPlatform && (
<div className="flex flex-row gap-2 items-center mx-2 h-5 dark:text-neutral-400">
{windows && (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 448 512">
<title>Windows</title>
<path d="M0 93.7l183.6-25.3v177.4H0V93.7zm0 324.6l183.6 25.3V268.4H0v149.9zm203.8 28L448 480V268.4H203.8v177.9zm0-380.6v180.1H448V32L203.8 65.7z" />
</svg>
)}
{macos && (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 384 512">
<title>macOS</title>
<path d="M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184.8 4 273.5q0 39.3 14.4 81.2c12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z" />
</svg>
)}
{linux && (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 448 512">
<title>Linux</title>
<path d="M220.8 123.3c1 .5 1.8 1.7 3 1.7 1.1 0 2.8-.4 2.9-1.5 .2-1.4-1.9-2.3-3.2-2.9-1.7-.7-3.9-1-5.5-.1-.4 .2-.8 .7-.6 1.1 .3 1.3 2.3 1.1 3.4 1.7zm-21.9 1.7c1.2 0 2-1.2 3-1.7 1.1-.6 3.1-.4 3.5-1.6 .2-.4-.2-.9-.6-1.1-1.6-.9-3.8-.6-5.5 .1-1.3 .6-3.4 1.5-3.2 2.9 .1 1 1.8 1.5 2.8 1.4zM420 403.8c-3.6-4-5.3-11.6-7.2-19.7-1.8-8.1-3.9-16.8-10.5-22.4-1.3-1.1-2.6-2.1-4-2.9-1.3-.8-2.7-1.5-4.1-2 9.2-27.3 5.6-54.5-3.7-79.1-11.4-30.1-31.3-56.4-46.5-74.4-17.1-21.5-33.7-41.9-33.4-72C311.1 85.4 315.7 .1 234.8 0 132.4-.2 158 103.4 156.9 135.2c-1.7 23.4-6.4 41.8-22.5 64.7-18.9 22.5-45.5 58.8-58.1 96.7-6 17.9-8.8 36.1-6.2 53.3-6.5 5.8-11.4 14.7-16.6 20.2-4.2 4.3-10.3 5.9-17 8.3s-14 6-18.5 14.5c-2.1 3.9-2.8 8.1-2.8 12.4 0 3.9 .6 7.9 1.2 11.8 1.2 8.1 2.5 15.7 .8 20.8-5.2 14.4-5.9 24.4-2.2 31.7 3.8 7.3 11.4 10.5 20.1 12.3 17.3 3.6 40.8 2.7 59.3 12.5 19.8 10.4 39.9 14.1 55.9 10.4 11.6-2.6 21.1-9.6 25.9-20.2 12.5-.1 26.3-5.4 48.3-6.6 14.9-1.2 33.6 5.3 55.1 4.1 .6 2.3 1.4 4.6 2.5 6.7v.1c8.3 16.7 23.8 24.3 40.3 23 16.6-1.3 34.1-11 48.3-27.9 13.6-16.4 36-23.2 50.9-32.2 7.4-4.5 13.4-10.1 13.9-18.3 .4-8.2-4.4-17.3-15.5-29.7zM223.7 87.3c9.8-22.2 34.2-21.8 44-.4 6.5 14.2 3.6 30.9-4.3 40.4-1.6-.8-5.9-2.6-12.6-4.9 1.1-1.2 3.1-2.7 3.9-4.6 4.8-11.8-.2-27-9.1-27.3-7.3-.5-13.9 10.8-11.8 23-4.1-2-9.4-3.5-13-4.4-1-6.9-.3-14.6 2.9-21.8zM183 75.8c10.1 0 20.8 14.2 19.1 33.5-3.5 1-7.1 2.5-10.2 4.6 1.2-8.9-3.3-20.1-9.6-19.6-8.4 .7-9.8 21.2-1.8 28.1 1 .8 1.9-.2-5.9 5.5-15.6-14.6-10.5-52.1 8.4-52.1zm-13.6 60.7c6.2-4.6 13.6-10 14.1-10.5 4.7-4.4 13.5-14.2 27.9-14.2 7.1 0 15.6 2.3 25.9 8.9 6.3 4.1 11.3 4.4 22.6 9.3 8.4 3.5 13.7 9.7 10.5 18.2-2.6 7.1-11 14.4-22.7 18.1-11.1 3.6-19.8 16-38.2 14.9-3.9-.2-7-1-9.6-2.1-8-3.5-12.2-10.4-20-15-8.6-4.8-13.2-10.4-14.7-15.3-1.4-4.9 0-9 4.2-12.3zm3.3 334c-2.7 35.1-43.9 34.4-75.3 18-29.9-15.8-68.6-6.5-76.5-21.9-2.4-4.7-2.4-12.7 2.6-26.4v-.2c2.4-7.6 .6-16-.6-23.9-1.2-7.8-1.8-15 .9-20 3.5-6.7 8.5-9.1 14.8-11.3 10.3-3.7 11.8-3.4 19.6-9.9 5.5-5.7 9.5-12.9 14.3-18 5.1-5.5 10-8.1 17.7-6.9 8.1 1.2 15.1 6.8 21.9 16l19.6 35.6c9.5 19.9 43.1 48.4 41 68.9zm-1.4-25.9c-4.1-6.6-9.6-13.6-14.4-19.6 7.1 0 14.2-2.2 16.7-8.9 2.3-6.2 0-14.9-7.4-24.9-13.5-18.2-38.3-32.5-38.3-32.5-13.5-8.4-21.1-18.7-24.6-29.9s-3-23.3-.3-35.2c5.2-22.9 18.6-45.2 27.2-59.2 2.3-1.7 .8 3.2-8.7 20.8-8.5 16.1-24.4 53.3-2.6 82.4 .6-20.7 5.5-41.8 13.8-61.5 12-27.4 37.3-74.9 39.3-112.7 1.1 .8 4.6 3.2 6.2 4.1 4.6 2.7 8.1 6.7 12.6 10.3 12.4 10 28.5 9.2 42.4 1.2 6.2-3.5 11.2-7.5 15.9-9 9.9-3.1 17.8-8.6 22.3-15 7.7 30.4 25.7 74.3 37.2 95.7 6.1 11.4 18.3 35.5 23.6 64.6 3.3-.1 7 .4 10.9 1.4 13.8-35.7-11.7-74.2-23.3-84.9-4.7-4.6-4.9-6.6-2.6-6.5 12.6 11.2 29.2 33.7 35.2 59 2.8 11.6 3.3 23.7 .4 35.7 16.4 6.8 35.9 17.9 30.7 34.8-2.2-.1-3.2 0-4.2 0 3.2-10.1-3.9-17.6-22.8-26.1-19.6-8.6-36-8.6-38.3 12.5-12.1 4.2-18.3 14.7-21.4 27.3-2.8 11.2-3.6 24.7-4.4 39.9-.5 7.7-3.6 18-6.8 29-32.1 22.9-76.7 32.9-114.3 7.2zm257.4-11.5c-.9 16.8-41.2 19.9-63.2 46.5-13.2 15.7-29.4 24.4-43.6 25.5s-26.5-4.8-33.7-19.3c-4.7-11.1-2.4-23.1 1.1-36.3 3.7-14.2 9.2-28.8 9.9-40.6 .8-15.2 1.7-28.5 4.2-38.7 2.6-10.3 6.6-17.2 13.7-21.1 .3-.2 .7-.3 1-.5 .8 13.2 7.3 26.6 18.8 29.5 12.6 3.3 30.7-7.5 38.4-16.3 9-.3 15.7-.9 22.6 5.1 9.9 8.5 7.1 30.3 17.1 41.6 10.6 11.6 14 19.5 13.7 24.6zM173.3 148.7c2 1.9 4.7 4.5 8 7.1 6.6 5.2 15.8 10.6 27.3 10.6 11.6 0 22.5-5.9 31.8-10.8 4.9-2.6 10.9-7 14.8-10.4s5.9-6.3 3.1-6.6-2.6 2.6-6 5.1c-4.4 3.2-9.7 7.4-13.9 9.8-7.4 4.2-19.5 10.2-29.9 10.2s-18.7-4.8-24.9-9.7c-3.1-2.5-5.7-5-7.7-6.9-1.5-1.4-1.9-4.6-4.3-4.9-1.4-.1-1.8 3.7 1.7 6.5z" />
</svg>
)}
</div>
)}
{pypi && (
<a target="_blank" href={`https://pypi.org/project/${pypi}/`}>
<img
src={`https://img.shields.io/pypi/v/${pypi}?color=blue`}
className="h-5"
alt="PyPI"
/>
</a>
)}
{npm && (
<a target="_blank" href={`https://www.npmjs.com/package/${npm}`}>
<img
src={`https://img.shields.io/npm/v/${npm}?color=bf4c4b`}
className="h-5"
alt="NPM"
/>
</a>
)}
{slug.includes('libraries') && (
<a
className={cn(
buttonVariants({
color: 'secondary',
size: 'sm',
className:
'gap-2 [&_svg]:size-3.5 [&_svg]:text-fd-muted-foreground',
}),
''
)}
href={`/api/${page.data.title.toLowerCase()}`}>
Reference
</a>
)}
</div>
);
};
return (
<DocsPage toc={page.data.toc} full={page.data.full}>
<div className="flex flex-row w-full">
<DocsTitle>{page.data.title}</DocsTitle>
<div className="ml-auto">
{apiSection && versionItems.length > 1 && (
<Popover>
<PopoverTrigger
className={cn(
buttonVariants({
color: 'secondary',
size: 'sm',
className: 'gap-2',
})
)}>
{(() => {
// Find the current version label
let currentLabel = 'Current';
if (apiVersionSlug.length > 0) {
const found = versionItems.find(
(item) =>
item.label !== 'Current' &&
apiVersionSlug[0] === item.label
);
if (found) currentLabel = found.label;
}
return (
<>
API Version: {currentLabel}
<ChevronDown className="size-3.5 text-fd-muted-foreground" />
</>
);
})()}
</PopoverTrigger>
<PopoverContent className="flex flex-col overflow-auto">
{versionItems.map((item) => {
// Build the href for each version
const href =
item.label === 'Current'
? `/api/${apiSection}`
: `/api/${apiSection}/${item.label}`;
// Highlight current version
const isCurrent =
(item.label === 'Current' && apiVersionSlug.length === 0) ||
(item.label !== 'Current' &&
apiVersionSlug[0] === item.label);
return (
<Link
key={item.label}
href={href}
className={cn(
'px-3 py-1 rounded hover:bg-fd-muted',
isCurrent && 'font-bold bg-fd-muted'
)}>
API version: {item.label}
</Link>
);
})}
</PopoverContent>
</Popover>
)}
<div className="flex flex-row w-full items-start">
<div className="flex-1">
<div className="flex flex-row w-full">
<DocsTitle>{page.data.title}</DocsTitle>
<div className="ml-auto">
{apiSection && versionItems.length > 1 && (
<Popover>
<PopoverTrigger
className={cn(
buttonVariants({
color: 'secondary',
size: 'sm',
className: 'gap-2',
})
)}>
{(() => {
// Find the current version label
let currentLabel = 'Current';
if (apiVersionSlug.length > 0) {
const found = versionItems.find(
(item) =>
item.label !== 'Current' &&
apiVersionSlug[0] === item.label
);
if (found) currentLabel = found.label;
}
return (
<>
API Version: {currentLabel}
<ChevronDown className="size-3.5 text-fd-muted-foreground" />
</>
);
})()}
</PopoverTrigger>
<PopoverContent className="flex flex-col overflow-auto">
{versionItems.map((item) => {
// Build the href for each version
const href =
item.label === 'Current'
? `/api/${apiSection}`
: `/api/${apiSection}/${item.label}`;
// Highlight current version
const isCurrent =
(item.label === 'Current' &&
apiVersionSlug.length === 0) ||
(item.label !== 'Current' &&
apiVersionSlug[0] === item.label);
return (
<Link
key={item.label}
href={href}
className={cn(
'px-3 py-1 rounded hover:bg-fd-muted',
isCurrent && 'font-bold bg-fd-muted'
)}>
API version: {item.label}
</Link>
);
})}
</PopoverContent>
</Popover>
)}
</div>
</div>
<DocsDescription className=" text-md mt-1">
{page.data.description}
</DocsDescription>
</div>
<PlatformIcons />
</div>
<DocsDescription>{page.data.description}</DocsDescription>
<DocsBody>
<MDXContent
components={getMDXComponents({
@@ -130,8 +219,10 @@ export async function generateMetadata(props: {
const page = source.getPage(params.slug);
if (!page) notFound();
let title = `c/ua Docs: ${page.data.title}`;
if (page.url.includes('api')) title = `c/ua API: ${page.data.title}`;
let title = `${page.data.title} | C/ua Docs`;
if (page.url.includes('api')) title = `${page.data.title} | C/ua API Docs`;
if (page.url.includes('guide'))
title = ` Guide: ${page.data.title} | C/ua Docs`;
return {
title,