setText vs keypress in pi-computer-use: Action Types Explained

setText directly assigns a string to an editable element without simulating keystrokes, while keypress synthesizes native keyboard events to replicate human typing character-by-character.

The injaneity/pi-computer-use repository defines a minimal set of UI automation primitives for controlling computer interfaces programmatically. When automating text input, choosing between setText and keypress determines whether your automation performs atomic value assignment or realistic keystroke simulation. Understanding these architectural differences ensures your scripts interact correctly with form validation, autocomplete, and other event-driven UI components.

The setText Action

setText performs direct value assignment to an editable element. When invoked, the backend writes the entire string to the target in a single operation without generating intermediate keyboard events, bypassing the browser or platform's input event queue.

In src/platform/types.ts, the request shape is defined as:

{ action: "setText"; params: { text: string } }

The bridge implementation in src/bridge.ts routes this to cdpTypeForContext, which immediately sets the element's value. Because this approach does not simulate hardware input, it executes faster than keystroke simulation but does not trigger listeners monitoring for keydown, keyup, or keypress events.

Focus and Foreground Handling

According to prepareAction in src/actions.ts (lines 100-106), setText operates with establishesFocus: false and needsForeground: false. This means the action does not require the target element to have focus before execution and does not bring the application to the foreground, making it ideal for batch form population behind the scenes.

The keypress Action

keypress simulates realistic keyboard input by synthesizing native key-down and key-up events for each character in the sequence. This action replicates human typing behavior exactly, triggering any UI listeners that react to individual keystrokes, including autocomplete suggestions, inline validation, and keyboard shortcuts.

The type definition in src/platform/types.ts specifies:

{ action: "keypress"; params: { keys: string[] } }

The backend delegates this to cdpKeypressForContext in src/bridge.ts, which iterates through the keys array and fires separate hardware events for each entry.

Focus Requirements

Unlike setText, keypress depends on focus state. As implemented in src/actions.ts (lines 95-96), this action sets usesCurrentFocus: true, meaning keystrokes are sent to whichever element currently has focus unless you explicitly provide a ref parameter. The action does not establish focus automatically, so the target must be focused beforehand for input to register correctly.

Key Differences

The fundamental distinction lies in how each action interacts with the platform event system:

Aspect setText keypress
Event Generation No intermediate events; value changes atomically Generates key-down/up events for each character
Performance Faster; single operation Slower; scales with string length
UI Reactivity Bypasses autocomplete, validation, and keystroke listeners Triggers all keyboard event handlers
Focus Handling Works without focus (needsForeground: false) Requires focused element (usesCurrentFocus: true)
Use Case Setting final values, bulk data entry Realistic typing, keyboard shortcuts, incremental validation

Implementation Details

The public API surface is defined in src/contract.ts, which exports the UiAction type exposing both "setText" and "keypress" as valid action strings. The JSON schema in extensions/computer-use.ts surfaces these actions to the extension UI, allowing the computer-use extension to serialize requests for the platform backend.

When the platform receives a setText request, src/bridge.ts routes it through cdpTypeForContext with an immediate write flag. For keypress, the same file routes to cdpKeypressForContext, managing the event synthesis loop for the provided key array.

Code Examples

Setting Text Directly

Use setText when you need to populate a field instantly and do not require intermediate events:

await actUi({
  actions: [
    {
      action: "setText",
      ref: "emailField",
      text: "alice@example.com"
    }
  ]
});

Simulating Keystrokes

Use keypress when you need to trigger per-character event handlers or simulate human typing patterns:

await actUi({
  actions: [
    {
      action: "keypress",
      keys: ["a", "l", "i", "c", "e", "@", "e", "x", "a", "m", "p", "l", "e", ".", "c", "o", "m"]
    }
  ]
});

Note that omitting the ref property causes the keystrokes to target the currently focused element.

Summary

  • setText assigns string values directly to editable elements via cdpTypeForContext without generating keyboard events or requiring focus, making it optimal for high-speed data entry where intermediate state does not matter.
  • keypress synthesizes native keyboard events character-by-character through cdpKeypressForContext, requiring a focused target but correctly triggering UI listeners for autocomplete, validation, and shortcuts.
  • Choose setText for speed and reliability when you only need the final value; choose keypress when the application logic depends on per-keystroke event handling.

Frequently Asked Questions

Does setText trigger input or change events?

Typically, setText writes the value directly to the DOM element via cdpTypeForContext, which may or may not dispatch semantic events depending on the backend implementation. Unlike keypress, it does not generate discrete key events, so handlers listening specifically for keydown or keyup will not fire. However, some backends may emit a single change or input event after the atomic assignment.

Can I send special keys like Enter or ArrowUp with setText?

No. setText accepts only plain strings and writes them literally to the element's value property. To send special keys or keyboard shortcuts like Enter, ArrowUp, or Control+c, you must use keypress with the appropriate key identifiers in the keys array.

Why would keypress fail to input text?

keypress requires the target element to maintain focus throughout the operation. If the ref is omitted and no element currently has focus, or if the window loses focus during execution, the synthesized keystrokes will not register in the intended field. Ensure the element is focused before dispatching the action, or explicitly provide a ref to a focusable element as shown in the setText example.

Is there a performance difference between setText and keypress?

Yes. setText executes in constant time regardless of string length because it performs a single atomic write via the CDP backend. keypress scales linearly with the number of characters in the keys array because it synthesizes separate hardware events for each entry. For large text blocks, setText is significantly more efficient.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →