Cua Computer-Use Interface (CUI) Framework
Cua-computer is a Python framework for building rich Computer-Use Interface (CUI) applications, providing programmatic control over terminal interactions, state management, and event processing. It leverages concepts like `Computer`, `Context`, `Task`, and `State` to enable complex, interactive command-line programs. Currently at version 0.5.17, it maintains an active development cadence, with a focus on Python 3.12+ environments.
Warnings
- breaking As a pre-1.0 library (currently 0.5.17), `cua-computer`'s API is subject to change without strict adherence to semantic versioning. Users should expect potential breaking changes in minor or even patch releases.
- gotcha CUI applications require careful management of the underlying asynchronous event loop. Improper handling of blocking operations or task concurrency can lead to frozen UIs or unexpected behavior.
- gotcha CUI applications can exhibit varying behavior across different terminal emulators (e.g., `xterm`, `gnome-terminal`, `iTerm2`, `tmux`) or operating systems, particularly concerning input handling, color support, and rendering of specific characters or escape codes.
- gotcha The `State` object is central to Cua applications. For complex applications, ensuring data consistency and managing state transitions across multiple concurrent `Task`s can become challenging without clear patterns.
- gotcha `cua-computer`'s `Task`s are designed to be asynchronous. Attempting to run long-duration CPU-bound or blocking I/O operations directly within a `Task` without offloading to a thread pool or separate process will block the entire CUI, freezing the user interface.
Install
-
pip install cua-computer
Imports
- Computer
from cua_computer import Computer
- Context
from cua_computer import Context
- State
from cua_computer import State
- Task
from cua_computer import Task
- TaskContext
from cua_computer import TaskContext
Quickstart
import asyncio
from cua_computer import Computer, Context, State, Task, TaskContext
from typing import Dict, Any
# Define a simple application state
class MyState(State):
count: int = 0
message: str = "Hello Cua!"
# Define a task that increments the count
class IncrementTask(Task):
async def run(self, context: TaskContext[MyState]):
await context.write("Incrementing count...")
context.state.count += 1
await context.sleep(1) # Simulate some work
await context.write(f"Count is now: {context.state.count}")
context.exit() # Task completes
# Define a task that displays the current state and offers an action
class DisplayTask(Task):
async def run(self, context: TaskContext[MyState]):
await context.write(f"Current State: {context.state.message} (Count: {context.state.count})")
await context.write("Press 'i' to increment, 'q' to quit.")
while True:
key = await context.read_key()
if key == 'i':
await context.spawn(IncrementTask())
elif key == 'q':
context.exit()
break
else:
await context.write("Unknown command. Press 'i' or 'q'.")
async def main():
initial_state = MyState()
computer = Computer(initial_state)
# Run the main display task
await computer.run(DisplayTask())
await computer.exit() # Ensure cleanup after tasks are done
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
print("\nExiting Cua application.")