hip-0015

HIP-15: Computer Control Standard. Status Draft. Hanzo's own standard — read this before implementing against it.

HIP-0015: Computer Control Standard

Abstract

This proposal defines the Computer Control Standard for Hanzo Operative, a unified interface that enables AI agents to perceive, interpret, and interact with computer environments. The standard covers screen capture and recording, mouse and keyboard input, touch emulation, browser automation via Playwright, AI-driven visual interpretation of screen content, and device emulation across platforms. All computer control in the Hanzo ecosystem MUST conform to this interface.

Repository: github.com/hanzoai/operative MCP Package: hanzo-mcp (computer use tools) Platforms: macOS (Quartz), Linux (X11/Wayland), Windows (Win32)

Design Philosophy

Why Computer Use Matters for AI

LLMs are powerful reasoning engines constrained to text input and text output. They can write code but not run it in an IDE. They can describe a UI fix but not verify it visually. They can plan a workflow but not execute it across applications.

Computer use removes this constraint. When an AI agent can see the screen, move the mouse, type on the keyboard, and navigate between applications, it gains the ability to operate any software that a human can operate. This transforms AI from a conversational assistant into a productive worker that can:

Why Playwright for Browser Automation

For web-specific tasks, screen-based computer use is unnecessarily imprecise. Playwright (by Microsoft) provides a purpose-built browser automation layer with:

Operative uses both approaches: Playwright for web applications (faster, more reliable, semantically rich) and screen recording for native applications (universal, no API required). The agent chooses the appropriate backend based on the target application.

Specification

Core Interfaces

Screen Capture

interface ScreenCapture {
  // Single screenshot
  screenshot(options?: {
    region?: Region;          // Capture specific area
    optimize?: boolean;       // Compress for LLM (default: true)
    maxSize?: number;         // Max dimension in pixels (default: 768)
    quality?: number;         // JPEG quality 1-100 (default: 60)
  }): Promise<CaptureResult>;

  // Screen recording session
  session(options?: {
    duration?: number;        // Seconds (default: 30, max: 120)
    fps?: number;             // Frame rate (default: 30)
    quality?: "low" | "medium" | "high";
    region?: Region;          // Record specific area
    targetFrames?: number;    // Target keyframes to extract (default: 30)
    activityThreshold?: number; // Activity sensitivity (default: 0.02)
  }): Promise<SessionResult>;

  // Background recording (start/stop)
  record(options?: RecordOptions): Promise<RecordingHandle>;
  stop(handle: RecordingHandle): Promise<SessionResult>;

  // Get display information
  getScreens(): Promise<ScreenInfo[]>;
  screenSize(): Promise<Dimensions>;
  currentScreen(): Promise<ScreenInfo>;
}

interface CaptureResult {
  image: string;              // Base64-encoded image data
  width: number;
  height: number;
  timestamp: number;
  format: "jpeg" | "png";
}

interface SessionResult {
  frames: CaptureResult[];    // Extracted keyframes
  activities: Activity[];     // Detected activity events
  duration: number;           // Actual recording duration
  totalSize: number;          // Total payload size in bytes
}

interface Activity {
  timestamp: number;
  type: "movement" | "click" | "typing" | "window_change" | "scroll";
  position?: Point;
  details?: string;
}

Input Control

interface InputControl {
  // Mouse operations (< 5ms native latency)
  click(x: number, y: number, options?: ClickOptions): Promise<void>;
  doubleClick(x: number, y: number): Promise<void>;
  rightClick(x: number, y: number): Promise<void>;
  middleClick(x: number, y: number): Promise<void>;
  move(x: number, y: number): Promise<void>;
  moveRelative(dx: number, dy: number): Promise<void>;
  drag(startX: number, startY: number, endX: number, endY: number,
       options?: DragOptions): Promise<void>;
  scroll(amount: number, x?: number, y?: number): Promise<void>;

  // Keyboard operations (< 2ms native latency)
  type(text: string, options?: TypeOptions): Promise<void>;
  press(key: string): Promise<void>;
  keyDown(key: string): Promise<void>;
  keyUp(key: string): Promise<void>;
  hotkey(keys: string[]): Promise<void>;

  // Touch operations
  tap(x: number, y: number): Promise<void>;
  swipe(direction: Direction, distance?: number): Promise<void>;
  pinch(scale: number): Promise<void>;

  // Batch execution
  batch(actions: Action[]): Promise<BatchResult>;
}

interface ClickOptions {
  button?: "left" | "right" | "middle";
  clickCount?: number;
  delay?: number;             // Delay between mousedown and mouseup
}

interface TypeOptions {
  interval?: number;          // Delay between keystrokes (default: 0.02s)
  clear?: boolean;            // Clear field before typing
}

interface DragOptions {
  duration?: number;          // Drag duration in seconds
  steps?: number;             // Intermediate points for smooth drag
}

Window Management

interface WindowManager {
  getActiveWindow(): Promise<WindowInfo>;
  listWindows(): Promise<WindowInfo[]>;
  focusWindow(title: string, options?: {
    useRegex?: boolean;
  }): Promise<void>;
}

interface WindowInfo {
  title: string;
  bounds: Region;
  pid: number;
  isActive: boolean;
  application: string;
}

Region Operations

interface RegionManager {
  // Define a named region for repeated operations
  defineRegion(name: string, x: number, y: number,
               width: number, height: number): Promise<void>;

  // Capture screenshot of named region
  regionScreenshot(name: string): Promise<CaptureResult>;

  // Find image within named region
  regionLocate(name: string, imagePath: string): Promise<Point | null>;
}

Image Location

interface ImageLocator {
  // Find image on screen, return center point
  locate(imagePath: string, options?: {
    confidence?: number;      // Match confidence (default: 0.9)
  }): Promise<Point | null>;

  // Find all instances of image
  locateAll(imagePath: string): Promise<Point[]>;

  // Wait for image to appear
  waitForImage(imagePath: string, timeout?: number): Promise<Point>;

  // Wait for image to disappear
  waitWhileImage(imagePath: string, timeout?: number): Promise<void>;

  // Get pixel color at point
  pixel(x: number, y: number): Promise<Color>;

  // Check if pixel matches color
  pixelMatches(x: number, y: number, color: Color,
               tolerance?: number): Promise<boolean>;
}

Browser Automation (Playwright Integration)

interface BrowserControl {
  // Navigation
  navigate(url: string): Promise<NavigateResult>;
  reload(): Promise<void>;
  goBack(): Promise<void>;
  goForward(): Promise<void>;
  url(): Promise<string>;
  title(): Promise<string>;
  content(): Promise<string>;

  // Element interaction
  click(selector: string, options?: BrowserClickOptions): Promise<void>;
  fill(selector: string, text: string): Promise<void>;
  type(selector: string, text: string): Promise<void>;
  press(selector: string, key: string): Promise<void>;
  selectOption(selector: string, value: string): Promise<void>;
  check(selector: string): Promise<void>;
  uncheck(selector: string): Promise<void>;
  upload(selector: string, files: string[]): Promise<void>;
  hover(selector: string): Promise<void>;

  // Element locators
  locator(selector: string): Locator;
  getByRole(role: string, options?: { name?: string }): Locator;
  getByText(text: string, options?: { exact?: boolean }): Locator;
  getByLabel(text: string): Locator;
  getByPlaceholder(text: string): Locator;
  getByTestId(testId: string): Locator;

  // Element state
  getText(selector: string): Promise<string>;
  getAttribute(selector: string, name: string): Promise<string | null>;
  getValue(selector: string): Promise<string>;
  isVisible(selector: string): Promise<boolean>;
  isEnabled(selector: string): Promise<boolean>;

  // Assertions
  expectVisible(selector: string): Promise<void>;
  expectText(selector: string, expected: string): Promise<void>;
  expectValue(selector: string, expected: string): Promise<void>;
  expectUrl(pattern: string): Promise<void>;
  expectTitle(expected: string): Promise<void>;

  // Waiting
  wait(timeout: number): Promise<void>;
  waitForLoad(state?: "load" | "domcontentloaded" | "networkidle"): Promise<void>;
  waitForUrl(pattern: string): Promise<void>;
  waitForSelector(selector: string, options?: WaitOptions): Promise<void>;

  // Screenshots and capture
  screenshot(options?: { fullPage?: boolean }): Promise<CaptureResult>;
  pdf(): Promise<Buffer>;
  snapshot(): Promise<string>;     // Accessibility tree snapshot

  // JavaScript execution
  evaluate(code: string): Promise<unknown>;

  // Device emulation
  emulate(device: DevicePreset): Promise<void>;
  viewport(width: number, height: number): Promise<void>;

  // Network interception
  route(pattern: string, options: RouteOptions): Promise<void>;
  unroute(pattern: string): Promise<void>;

  // Multi-tab / multi-context
  newPage(): Promise<PageHandle>;
  newContext(options?: ContextOptions): Promise<ContextHandle>;
  newTab(): Promise<TabHandle>;
  tabs(): Promise<TabInfo[]>;

  // Storage and cookies
  cookies(): Promise<Cookie[]>;
  clearCookies(): Promise<void>;
  storage(type: "local" | "session"): Promise<Record<string, string>>;

  // Debugging
  highlight(selector: string): Promise<void>;
  traceStart(): Promise<void>;
  traceStop(path: string): Promise<void>;
  console(): Promise<ConsoleMessage[]>;
  errors(): Promise<Error[]>;
}

type DevicePreset =
  | "mobile" | "tablet" | "laptop"
  | "iphone_14" | "pixel_7" | "ipad_pro";

interface ContextOptions {
  device?: DevicePreset;
  locale?: string;
  geolocation?: { latitude: number; longitude: number };
  permissions?: string[];
  storageState?: string;      // Path to saved auth state
}

AI Interpretation Pipeline

The AI interpretation pipeline is the core innovation that distinguishes Operative from traditional automation frameworks. Rather than requiring explicit selectors or coordinates, the agent observes the screen and reasons about what to do next.

┌──────────────────────────────────────────────────────────────────┐
│                    AI Interpretation Pipeline                     │
├──────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Screen Recording ──> Activity Detection ──> Keyframe Extraction │
│                                                    │             │
│                                                    v             │
│                                           Frame Compression      │
│                                           (~768px, 60% JPEG)     │
│                                                    │             │
│                                                    v             │
│                                        LLM Visual Analysis       │
│                                        (multimodal reasoning)    │
│                                                    │             │
│                                                    v             │
│                                          Action Planning         │
│                                          (click, type, scroll)   │
│                                                    │             │
│                                                    v             │
│                                         Action Execution         │
│                                         (native or Playwright)   │
│                                                    │             │
│                                                    v             │
│                                        Verification Capture      │
│                                        (screenshot after action) │
│                                                    │             │
│                                                    v             │
│                                            Loop / Complete       │
│                                                                  │
└──────────────────────────────────────────────────────────────────┘

Activity Detection

Activity detection identifies moments of significance in a screen recording. The system monitors for:

| Activity Type | Detection Method | Threshold | |---------------|-----------------|-----------| | Mouse movement | Frame-to-frame cursor position delta | > 10px displacement | | Click events | OS-level input event hooks | Any click | | Typing | Keyboard event hooks + screen text change | Any keystroke | | Window change | Active window title change | Title differs | | Scroll | Viewport content shift without cursor movement | > 5% content shift | | Animation | Pixel-level frame difference | > 2% of frame area |

Keyframe Selection

From a 30-second recording at 30fps (900 raw frames), the system selects approximately 30 keyframes using the following algorithm:

  1. Score each frame by the sum of activity intensities at that timestamp
  2. Apply non-maximum suppression with a 500ms window to avoid duplicates
  3. Always include the first frame, last frame, and frames immediately after click events
  4. Fill remaining slots with the highest-scoring frames distributed evenly across the timeline

Frame Compression

Each keyframe is compressed for efficient LLM consumption:

Control Flow: Agent Observe-Act Loop

The standard defines a control flow for agents interacting with computers:

class ComputerUseAgent:
    """
    Agent that controls a computer through the Operative interface.
    Integrates with HIP-9 Agent SDK and HIP-10 MCP tools.
    """

    def __init__(self, operative: OperativeClient, model: LLMClient):
        self.operative = operative
        self.model = model
        self.history = []

    async def execute_task(self, task: str) -> TaskResult:
        """
        Execute a task on the computer by observing and acting in a loop.
        """
        # Initial observation
        screen = await self.operative.screenshot()
        self.history.append({"role": "observation", "image": screen})

        while not self.is_complete():
            # Ask the LLM what to do given the screen and task
            action = await self.model.reason(
                task=task,
                current_screen=screen,
                history=self.history,
                available_actions=self.operative.capabilities()
            )

            if action.type == "done":
                return TaskResult(success=True, output=action.summary)

            # Execute the action
            await self.operative.execute(action)
            self.history.append({"role": "action", "action": action})

            # Observe the result
            await asyncio.sleep(action.wait_after or 0.5)
            screen = await self.operative.screenshot()
            self.history.append({"role": "observation", "image": screen})

        return TaskResult(success=False, output="Max iterations reached")

Batch Operations

Batch operations execute multiple actions atomically with guaranteed ordering:

interface BatchOperation {
  actions: Action[];
  options?: {
    stopOnError?: boolean;    // Halt on first failure (default: true)
    delayBetween?: number;    // Milliseconds between actions (default: 50)
  };
}

// Example: login form automation
const loginBatch: BatchOperation = {
  actions: [
    { action: "click", x: 400, y: 300 },
    { action: "type", text: "user@example.com" },
    { action: "press", key: "Tab" },
    { action: "type", text: "password123" },
    { action: "press", key: "Enter" }
  ],
  options: { delayBetween: 100 }
};

Platform Backends

| Platform | Backend | Mouse Latency | Keyboard Latency | Screen Capture | |----------|---------|---------------|-------------------|----------------| | macOS | Quartz (native) | < 5ms | < 2ms | < 50ms | | Linux | X11 | < 5ms | < 2ms | < 50ms | | Linux | Wayland | < 10ms | < 5ms | < 100ms | | Windows | Win32 | < 5ms | < 2ms | < 50ms | | Docker | Virtual Display (Xvfb) | < 10ms | < 5ms | < 100ms |

MCP Tool Interface

Computer control is exposed as MCP tools (HIP-10) so any MCP-compatible agent can invoke computer use without custom integration.

MCP Tool: computer
  Description: Control local computer with native API acceleration
  Actions:
    # Mouse
    - click(x, y)
    - double_click(x, y)
    - right_click(x, y)
    - move(x, y)
    - drag(start_x, start_y, end_x, end_y)
    - scroll(amount, x, y)

    # Keyboard
    - type(text, interval)
    - press(key)
    - hotkey(keys[])
    - key_down(key) / key_up(key)

    # Screen
    - screenshot()
    - screenshot_region(region)
    - get_screens()
    - screen_size()

    # Image location
    - locate(image_path)
    - locate_all(image_path)
    - wait_for_image(image_path, timeout)

    # Pixel
    - pixel(x, y)
    - pixel_matches(x, y, color, tolerance)

    # Windows
    - get_active_window()
    - list_windows()
    - focus_window(title)

    # Regions
    - define_region(name, x, y, w, h)
    - region_screenshot(name)
    - region_locate(name, image)

    # Batch
    - batch(actions[])

    # Timing
    - sleep(seconds)
    - set_pause(seconds)

MCP Tool: screen
  Description: Screen recording and AI interpretation
  Actions:
    - session(duration)        # Record + analyze + compress + return
    - capture()                # Single optimized screenshot
    - record(duration, fps)    # Start background recording
    - stop()                   # Stop and process recording
    - analyze(path)            # Process existing video file
    - status()                 # Check recording state
    - info()                   # System capabilities

MCP Tool: browser
  Description: Full Playwright browser automation
  Actions:
    # Navigation: navigate, reload, go_back, go_forward, url, title
    # Input: click, fill, type, press, select_option, check, upload
    # Locators: locator, get_by_role, get_by_text, get_by_label
    # State: is_visible, is_enabled, is_checked, get_text, get_attribute
    # Assertions: expect_visible, expect_text, expect_value, expect_url
    # Wait: wait, wait_for_load, wait_for_url, wait_for_selector
    # Capture: screenshot, pdf, snapshot, evaluate
    # Device: viewport, emulate, geolocation, permissions
    # Network: route, unroute
    # Multi-tab: new_page, new_context, tabs, close_tab
    # Debug: trace_start, trace_stop, highlight, console, errors

Configuration

Configuration via environment variables:

# Screen recording defaults
HANZO_SCREEN_DURATION=30           # Default session duration (seconds)
HANZO_SCREEN_TARGET_FRAMES=30     # Target keyframes per session
HANZO_SCREEN_MAX_SIZE=768          # Max frame dimension (pixels)
HANZO_SCREEN_QUALITY=60            # JPEG compression quality (1-100)
HANZO_SCREEN_ACTIVITY_THRESHOLD=0.02  # Activity detection sensitivity

# Browser automation
HANZO_BROWSER_HEADLESS=true        # Run browser in headless mode
HANZO_BROWSER_TIMEOUT=30000        # Default action timeout (ms)
HANZO_BROWSER_SLOW_MO=0            # Slow down actions for debugging (ms)

# Platform
HANZO_OPERATIVE_BACKEND=auto       # auto, quartz, x11, wayland, win32
HANZO_OPERATIVE_DISPLAY=:0         # X11 display (Linux)

Implementation

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                         Agent (HIP-9)                           │
│                    (reasoning + planning)                        │
├─────────────────────────────────────────────────────────────────┤
│                       MCP Protocol (HIP-10)                     │
│              (tool invocation + context management)              │
├──────────────────┬──────────────────┬───────────────────────────┤
│  computer tool   │   screen tool    │      browser tool         │
│  (input control) │   (recording)    │      (Playwright)         │
├──────────────────┴──────────────────┴───────────────────────────┤
│                    Operative Core Library                        │
│              (platform abstraction + dispatch)                   │
├──────────────┬──────────────┬──────────────┬────────────────────┤
│    Quartz    │     X11      │   Wayland    │      Win32         │
│   (macOS)    │   (Linux)    │   (Linux)    │    (Windows)       │
├──────────────┴──────────────┴──────────────┴────────────────────┤
│                    Operating System                              │
│              (display server + input subsystem)                  │
└─────────────────────────────────────────────────────────────────┘

Repository Structure

operative/
├── src/
│   ├── core/                    # Platform abstraction layer
│   │   ├── backend.py           # Backend interface
│   │   ├── quartz.py            # macOS Quartz backend
│   │   ├── x11.py               # Linux X11 backend
│   │   ├── wayland.py           # Linux Wayland backend
│   │   └── win32.py             # Windows Win32 backend
│   ├── screen/                  # Screen capture and recording
│   │   ├── capture.py           # Screenshot operations
│   │   ├── recorder.py          # Screen recording
│   │   ├── activity.py          # Activity detection
│   │   ├── keyframe.py          # Keyframe extraction
│   │   └── compress.py          # Frame compression
│   ├── input/                   # Input control
│   │   ├── mouse.py             # Mouse operations
│   │   ├── keyboard.py          # Keyboard operations
│   │   ├── touch.py             # Touch emulation
│   │   └── batch.py             # Batch action execution
│   ├── browser/                 # Playwright integration
│   │   ├── engine.py            # Browser engine management
│   │   ├── page.py              # Page interaction
│   │   ├── locators.py          # Element location strategies
│   │   ├── network.py           # Network interception
│   │   └── devices.py           # Device emulation presets
│   ├── window/                  # Window management
│   │   ├── manager.py           # Window operations
│   │   └── regions.py           # Named region management
│   ├── image/                   # Image location
│   │   ├── locator.py           # Template matching
│   │   └── pixel.py             # Pixel operations
│   ├── mcp/                     # MCP tool definitions
│   │   ├── computer_tool.py     # computer() MCP tool
│   │   ├── screen_tool.py       # screen() MCP tool
│   │   └── browser_tool.py      # browser() MCP tool
│   └── security/                # Security and audit
│       ├── permissions.py       # Permission system
│       ├── audit.py             # Action audit trail
│       ├── sandbox.py           # Execution sandbox
│       └── pii.py               # PII detection and blurring
├── tests/
│   ├── test_capture.py
│   ├── test_input.py
│   ├── test_browser.py
│   ├── test_activity.py
│   ├── test_batch.py
│   └── test_security.py
├── pyproject.toml
├── Makefile
└── README.md

Platform Support Matrix

| Feature | macOS (Quartz) | Linux (X11) | Linux (Wayland) | Windows (Win32) | Docker (Xvfb) | |---------|---------------|-------------|-----------------|-----------------|----------------| | Screenshot | Yes | Yes | Yes | Yes | Yes | | Screen recording | Yes | Yes | Yes | Yes | Yes | | Mouse control | Yes | Yes | Yes | Yes | Yes | | Keyboard control | Yes | Yes | Yes | Yes | Yes | | Touch emulation | Yes | No | Yes | Yes | No | | Window management | Yes | Yes | Partial | Yes | Yes | | Image location | Yes | Yes | Yes | Yes | Yes | | Browser (Playwright) | Yes | Yes | Yes | Yes | Yes | | HiDPI support | Yes | Yes | Yes | Yes | N/A |

Agent SDK Integration

Agents built with the Agent SDK (HIP-9) can invoke computer use as a first-class capability:

from hanzoai.agent import Agent
from hanzoai.operative import ComputerTool, ScreenTool, BrowserTool

agent = Agent(
    name="desktop-worker",
    model="claude-sonnet-4-20250514",
    tools=[
        ComputerTool(),       # Native mouse/keyboard/screen
        ScreenTool(),         # Screen recording + AI interpretation
        BrowserTool(),        # Playwright browser automation
    ],
    instructions="""You can control this computer. Use the browser tool
    for web tasks and the computer tool for native applications. Take
    screenshots to verify your actions succeeded before moving on."""
)

result = await agent.run("Open the settings app and enable dark mode")

Deployment Modes

Local Development

The agent runs directly on the developer machine. Screen capture and input control target the local display.

pip install hanzo-operative
# or
pip install hanzo-mcp  # includes operative tools

Docker Container

For CI/CD and headless environments, Operative runs in a Docker container with a virtual display:

FROM hanzoai/operative:latest

# Virtual display is pre-configured
# Playwright browsers are pre-installed
# MCP tools are registered automatically

ENV DISPLAY=:99
ENV HANZO_OPERATIVE_BACKEND=x11
# compose.yml
services:
  operative:
    image: hanzoai/operative:latest
    environment:
      - DISPLAY=:99
    ports:
      - "6080:6080"    # noVNC for visual debugging
    volumes:
      - /tmp/.X11-unix:/tmp/.X11-unix

Cloud Deployment

For production agents running on Hanzo infrastructure, Operative instances are provisioned per-agent with isolated virtual displays:

Agent Request → Hanzo Cloud → Provision VM with Operative →
  → Agent connects via MCP → Executes task → Returns result →
  → VM destroyed

Security

Permission System

All computer use actions require explicit permission grants. Permissions are scoped to specific capabilities and can be restricted to specific applications or screen regions.

permissions:
  # Screen capture permissions
  screen.capture:
    allowed: true
    restricted_regions:         # Never capture these areas
      - name: "password_field"
        bounds: { x: 100, y: 200, w: 300, h: 50 }

  # Input control permissions
  input.mouse:
    allowed: true
    restricted_windows:         # Cannot interact with these windows
      - "1Password"
      - "Keychain Access"

  input.keyboard:
    allowed: true
    block_hotkeys:              # Cannot execute these key combinations
      - ["Command", "Q"]       # Prevent quitting applications
      - ["Command", "Shift", "Delete"]  # Prevent emptying trash

  # Browser permissions
  browser.navigate:
    allowed: true
    blocked_domains:
      - "*.bank.com"
      - "mail.google.com"

  browser.network:
    allowed: false              # Cannot intercept network traffic

Sandboxed Execution

Computer use actions run in a restricted context:

  1. Process isolation: Operative runs as a separate process with minimal OS privileges
  2. Application allowlisting: Only designated applications can be targeted
  3. Input rate limiting: Maximum actions per second to prevent runaway automation
  4. Timeout enforcement: All operations have hard timeouts to prevent hangs
  5. Resource limits: CPU, memory, and disk usage are capped

Audit Trail

Every action is logged with full context for forensic analysis:

{
  "id": "act_01HQ3X7...",
  "timestamp": "2025-01-15T10:30:45.123Z",
  "agent_id": "agent_desktop-worker",
  "session_id": "sess_01HQ3X...",
  "action": {
    "type": "click",
    "x": 450,
    "y": 300,
    "button": "left"
  },
  "context": {
    "active_window": "Google Chrome - Settings",
    "screen_resolution": "2560x1440",
    "before_screenshot": "scr_01HQ3X7_before.jpg",
    "after_screenshot": "scr_01HQ3X7_after.jpg"
  },
  "permission": {
    "granted": true,
    "policy": "default_allow_chrome"
  },
  "duration_ms": 3
}

PII Detection and Protection

When screen captures contain sensitive information, the system detects and protects it:

  1. Detection: On-device ML model identifies common PII patterns (credit card numbers, SSNs, email addresses, passwords) in captured frames
  2. Blurring: Detected PII regions are blurred before frames are sent to the LLM
  3. Redaction in logs: Audit trail screenshots have PII regions redacted
  4. Opt-out: Specific screen regions can be marked as "never capture" in the permission configuration
class PIIDetector:
    """
    Detects and protects personally identifiable information
    in screen captures before they are sent to the LLM.
    """

    PATTERNS = [
        "credit_card",       # 16-digit card numbers
        "ssn",               # Social security numbers
        "email",             # Email addresses in input fields
        "password_field",    # Active password input fields
        "api_key",           # API keys and tokens
    ]

    async def protect(self, frame: CaptureResult) -> CaptureResult:
        """Detect and blur PII regions in a captured frame."""
        detections = await self.detect(frame)
        if detections:
            frame = self.blur_regions(frame, detections)
        return frame

Network Security

When Operative is deployed remotely (Docker, cloud), the connection between agent and Operative instance is secured:

Compatibility

Relationship to Other HIPs

| HIP | Relationship | |-----|-------------| | HIP-9 (Agent SDK) | Agents invoke computer use through the Agent SDK's tool interface | | HIP-10 (MCP) | Computer use exposed as MCP tools (computer, screen, browser) | | HIP-4 (LLM Gateway) | Visual reasoning requests routed through the LLM Gateway | | HIP-11 (Chat Interface) | Chat UI can display computer use sessions inline | | HIP-14 (App Deployment) | Operative containers deployed via the application platform |

Migration from Existing Tools

| Existing Tool | Migration Path | |---------------|---------------| | Selenium | Replace with browser tool (Playwright-based, same concepts) | | Puppeteer | Replace with browser tool (Playwright is Puppeteer's successor) | | PyAutoGUI | Replace with computer tool (same API concepts, native performance) | | SikuliX | Replace with computer tool + image location (locate, waitForImage) | | Anthropic Computer Use | Replace with computer + screen tools (self-hosted, MCP-integrated) |

Test Plan

Unit Tests

# Run full test suite
pytest tests/ -v

# Platform-specific tests
pytest tests/test_capture.py -v -k "quartz"   # macOS
pytest tests/test_capture.py -v -k "x11"       # Linux

Integration Tests

async def test_observe_act_loop():
    """Test the full observe-act cycle."""
    operative = OperativeClient()

    # Take screenshot
    screen = await operative.screenshot()
    assert screen.width > 0
    assert screen.height > 0
    assert len(screen.image) > 0

    # Click at a position
    await operative.click(100, 100)

    # Verify screen changed
    screen_after = await operative.screenshot()
    assert screen_after.timestamp > screen.timestamp


async def test_screen_recording_session():
    """Test screen recording with activity detection."""
    operative = OperativeClient()

    result = await operative.session(duration=5)

    assert len(result.frames) > 0
    assert len(result.frames) <= 30
    assert result.duration >= 4.5
    assert result.totalSize < 1_000_000  # Under 1MB


async def test_browser_navigation():
    """Test Playwright browser automation."""
    browser = BrowserClient()

    await browser.navigate("https://example.com")

    title = await browser.title()
    assert "Example" in title

    text = await browser.getText("h1")
    assert "Example Domain" in text

Performance Benchmarks

| Operation | Target Latency | Platform | |-----------|---------------|----------| | Screenshot | < 50ms | All | | Mouse click | < 5ms | Native | | Keyboard type (per char) | < 2ms | Native | | Screen recording start | < 100ms | All | | Session processing (30s) | < 5s | All | | Browser navigate | < 3s | All | | Image locate | < 200ms | All |

References

  1. HIP-9: Agent SDK
  2. HIP-10: MCP Integration Standards
  3. HIP-4: LLM Gateway
  4. Operative Repository
  5. Playwright Documentation
  6. Model Context Protocol Specification
  7. Apple Quartz Event Services
  8. X11 Protocol Reference

Copyright

Copyright and related rights waived via CC0.