Skip to content

Commit ff8d0c1

Browse files
rgarciaclaude
andcommitted
Fix key translation bypass in batch actions and add type validation for batch args.
Route goto/back/forward/currentUrl batch helpers through normalizeKeypressPayload so CUA-style key names are translated to X11 keysyms. Validate that batch actions argument is a list/array before passing to batchActions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 0e81e18 commit ff8d0c1

File tree

4 files changed

+32
-54
lines changed

4 files changed

+32
-54
lines changed

pkg/templates/python/openai-computer-use/agent/agent.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,8 @@ def handle_item(self, item):
324324

325325
def _handle_batch_call(self, call_id, args):
326326
actions = args.get("actions", [])
327+
if not isinstance(actions, list):
328+
actions = []
327329
self.computer.batch_actions(actions)
328330
status_text = "Actions executed successfully."
329331
terminal_action = self._batch_terminal_read_action(actions if isinstance(actions, list) else [])

pkg/templates/python/openai-computer-use/computers/kernel_computer.py

Lines changed: 16 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -235,67 +235,43 @@ def _is_batch_computer_action_type(action_type: str) -> bool:
235235
}
236236

237237

238+
def _press_key_action(
239+
keys: List[str], hold_keys: List[str] | None = None
240+
) -> Dict[str, Any]:
241+
payload = _normalize_keypress_payload(keys=keys, hold_keys=hold_keys)
242+
return {"type": "press_key", "press_key": payload}
243+
244+
238245
def _goto_batch_actions(url: str) -> List[Dict[str, Any]]:
239246
return [
240-
{
241-
"type": "press_key",
242-
"press_key": {"hold_keys": ["Ctrl"], "keys": ["l"]},
243-
},
247+
_press_key_action(["l"], hold_keys=["Ctrl"]),
244248
{
245249
"type": "sleep",
246250
"sleep": {"duration_ms": GOTO_CHORD_DELAY_MS},
247251
},
248-
{
249-
"type": "press_key",
250-
"press_key": {"hold_keys": ["Ctrl"], "keys": ["a"]},
251-
},
252+
_press_key_action(["a"], hold_keys=["Ctrl"]),
252253
{
253254
"type": "type_text",
254255
"type_text": {"text": url},
255256
},
256-
{
257-
"type": "press_key",
258-
"press_key": {"keys": ["Return"]},
259-
},
257+
_press_key_action(["Return"]),
260258
]
261259

262260

263261
def _back_batch_actions() -> List[Dict[str, Any]]:
264-
return [
265-
{
266-
"type": "press_key",
267-
"press_key": {"hold_keys": ["Alt"], "keys": ["Left"]},
268-
}
269-
]
262+
return [_press_key_action(["Left"], hold_keys=["Alt"])]
270263

271264

272265
def _forward_batch_actions() -> List[Dict[str, Any]]:
273-
return [
274-
{
275-
"type": "press_key",
276-
"press_key": {"hold_keys": ["Alt"], "keys": ["Right"]},
277-
}
278-
]
266+
return [_press_key_action(["Right"], hold_keys=["Alt"])]
279267

280268

281269
def _current_url_batch_actions() -> List[Dict[str, Any]]:
282270
return [
283-
{
284-
"type": "press_key",
285-
"press_key": {"hold_keys": ["Ctrl"], "keys": ["l"]},
286-
},
287-
{
288-
"type": "press_key",
289-
"press_key": {"hold_keys": ["Ctrl"], "keys": ["a"]},
290-
},
291-
{
292-
"type": "press_key",
293-
"press_key": {"hold_keys": ["Ctrl"], "keys": ["c"]},
294-
},
295-
{
296-
"type": "press_key",
297-
"press_key": {"keys": ["Escape"]},
298-
},
271+
_press_key_action(["l"], hold_keys=["Ctrl"]),
272+
_press_key_action(["a"], hold_keys=["Ctrl"]),
273+
_press_key_action(["c"], hold_keys=["Ctrl"]),
274+
_press_key_action(["Escape"]),
299275
]
300276

301277

pkg/templates/typescript/openai-computer-use/lib/agent.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ export class Agent {
221221
callId: string,
222222
argsObj: Record<string, unknown>,
223223
): Promise<ResponseItem[]> {
224-
const actions = argsObj.actions as unknown as CuaAction[];
224+
const actions = Array.isArray(argsObj.actions) ? (argsObj.actions as CuaAction[]) : [];
225225
await this.computer.batchActions(actions);
226226

227227
let statusText = 'Actions executed successfully.';

pkg/templates/typescript/openai-computer-use/lib/kernel-computer.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -259,34 +259,34 @@ function isBatchComputerActionType(actionType: string): boolean {
259259
);
260260
}
261261

262+
function pressKeyAction(keys: string[], holdKeys?: string[]): BatchAction {
263+
return { type: 'press_key', press_key: normalizeKeypressPayload(keys, holdKeys) };
264+
}
265+
262266
function gotoBatchActions(url: string): BatchAction[] {
263267
return [
264-
{ type: 'press_key', press_key: { hold_keys: ['Ctrl'], keys: ['l'] } },
268+
pressKeyAction(['l'], ['Ctrl']),
265269
{ type: 'sleep', sleep: { duration_ms: GOTO_CHORD_DELAY_MS } },
266-
{ type: 'press_key', press_key: { hold_keys: ['Ctrl'], keys: ['a'] } },
270+
pressKeyAction(['a'], ['Ctrl']),
267271
{ type: 'type_text', type_text: { text: url } },
268-
{ type: 'press_key', press_key: { keys: ['Return'] } },
272+
pressKeyAction(['Return']),
269273
];
270274
}
271275

272276
function backBatchActions(): BatchAction[] {
273-
return [
274-
{ type: 'press_key', press_key: { hold_keys: ['Alt'], keys: ['Left'] } },
275-
];
277+
return [pressKeyAction(['Left'], ['Alt'])];
276278
}
277279

278280
function forwardBatchActions(): BatchAction[] {
279-
return [
280-
{ type: 'press_key', press_key: { hold_keys: ['Alt'], keys: ['Right'] } },
281-
];
281+
return [pressKeyAction(['Right'], ['Alt'])];
282282
}
283283

284284
function currentUrlBatchActions(): BatchAction[] {
285285
return [
286-
{ type: 'press_key', press_key: { hold_keys: ['Ctrl'], keys: ['l'] } },
287-
{ type: 'press_key', press_key: { hold_keys: ['Ctrl'], keys: ['a'] } },
288-
{ type: 'press_key', press_key: { hold_keys: ['Ctrl'], keys: ['c'] } },
289-
{ type: 'press_key', press_key: { keys: ['Escape'] } },
286+
pressKeyAction(['l'], ['Ctrl']),
287+
pressKeyAction(['a'], ['Ctrl']),
288+
pressKeyAction(['c'], ['Ctrl']),
289+
pressKeyAction(['Escape']),
290290
];
291291
}
292292

0 commit comments

Comments
 (0)