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
setTextassigns string values directly to editable elements viacdpTypeForContextwithout generating keyboard events or requiring focus, making it optimal for high-speed data entry where intermediate state does not matter.keypresssynthesizes native keyboard events character-by-character throughcdpKeypressForContext, requiring a focused target but correctly triggering UI listeners for autocomplete, validation, and shortcuts.- Choose
setTextfor speed and reliability when you only need the final value; choosekeypresswhen 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →