Skip to content

Commit 60ef649

Browse files
Merge pull request #50 from askui/feat/repeat-keyboard
feat(agent): add repeat parameter to VisionAgent.keyboard()
2 parents 2481658 + 5bae16c commit 60ef649

File tree

3 files changed

+35
-13
lines changed

3 files changed

+35
-13
lines changed

src/askui/agent.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -476,13 +476,15 @@ def keyboard(
476476
self,
477477
key: PcKey | ModifierKey,
478478
modifier_keys: Optional[list[ModifierKey]] = None,
479+
repeat: Annotated[int, Field(gt=0)] = 1,
479480
) -> None:
480481
"""
481-
Simulates pressing a key or key combination on the keyboard.
482+
Simulates pressing (and releasing) a key or key combination on the keyboard.
482483
483484
Args:
484485
key (PcKey | ModifierKey): The main key to press. This can be a letter, number, special character, or function key.
485486
modifier_keys (list[ModifierKey] | None, optional): List of modifier keys to press along with the main key. Common modifier keys include `'ctrl'`, `'alt'`, `'shift'`.
487+
repeat (int, optional): The number of times to press (and release) the key. Must be greater than `0`. Defaults to `1`.
486488
487489
Example:
488490
```python
@@ -493,10 +495,18 @@ def keyboard(
493495
agent.keyboard('enter') # Press 'Enter' key
494496
agent.keyboard('v', ['control']) # Press Ctrl+V (paste)
495497
agent.keyboard('s', ['control', 'shift']) # Press Ctrl+Shift+S
498+
agent.keyboard('a', repeat=2) # Press 'a' key twice
496499
```
497500
"""
501+
msg = f"press and release key '{key}'"
502+
if modifier_keys is not None:
503+
modifier_keys_str = ' + '.join(f"'{key}'" for key in modifier_keys)
504+
msg += f" with modifiers key{'s' if len(modifier_keys) > 1 else ''} {modifier_keys_str}"
505+
if repeat > 1:
506+
msg += f" {repeat}x times"
507+
self._reporter.add_message("User", msg)
498508
logger.debug("VisionAgent received instruction to press '%s'", key)
499-
self.tools.agent_os.keyboard_tap(key, modifier_keys)
509+
self.tools.agent_os.keyboard_tap(key, modifier_keys, count=repeat)
500510

501511
@telemetry.record_call(exclude={"command"})
502512
@validate_call

src/askui/tools/agent_os.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,10 @@ def keyboard_release(
276276

277277
@abstractmethod
278278
def keyboard_tap(
279-
self, key: PcKey | ModifierKey, modifier_keys: list[ModifierKey] | None = None
279+
self,
280+
key: PcKey | ModifierKey,
281+
modifier_keys: list[ModifierKey] | None = None,
282+
count: int = 1,
280283
) -> None:
281284
"""
282285
Simulates pressing and immediately releasing a keyboard key.
@@ -285,6 +288,7 @@ def keyboard_tap(
285288
key (PcKey | ModifierKey): The key to tap.
286289
modifier_keys (list[ModifierKey] | None, optional): List of modifier keys to
287290
press along with the main key. Defaults to `None`.
291+
count (int, optional): The number of times to tap the key. Defaults to `1`.
288292
"""
289293
raise NotImplementedError
290294

src/askui/tools/askui/askui_controller.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,10 @@ def keyboard_release(
648648
@telemetry.record_call()
649649
@override
650650
def keyboard_tap(
651-
self, key: PcKey | ModifierKey, modifier_keys: list[ModifierKey] | None = None
651+
self,
652+
key: PcKey | ModifierKey,
653+
modifier_keys: list[ModifierKey] | None = None,
654+
count: int = 1,
652655
) -> None:
653656
"""
654657
Press and immediately release a keyboard key.
@@ -657,18 +660,23 @@ def keyboard_tap(
657660
key (PcKey | ModifierKey): The key to tap.
658661
modifier_keys (list[ModifierKey] | None, optional): List of modifier keys to
659662
press along with the main key. Defaults to `None`.
663+
count (int, optional): The number of times to tap the key. Defaults to `1`.
660664
"""
661-
self._reporter.add_message("AgentOS", f'keyboard_tap("{key}", {modifier_keys})')
665+
self._reporter.add_message(
666+
"AgentOS",
667+
f'keyboard_tap("{key}", {modifier_keys}, {count})',
668+
)
662669
if modifier_keys is None:
663670
modifier_keys = []
664-
self._run_recorder_action(
665-
acion_class_id=controller_v1_pbs.ActionClassID_KeyboardKey_PressAndRelease,
666-
action_parameters=controller_v1_pbs.ActionParameters(
667-
keyboardKeyPressAndRelease=controller_v1_pbs.ActionParameters_KeyboardKey_PressAndRelease(
668-
keyName=key, modifierKeyNames=modifier_keys
669-
)
670-
),
671-
)
671+
for _ in range(count):
672+
self._run_recorder_action(
673+
acion_class_id=controller_v1_pbs.ActionClassID_KeyboardKey_PressAndRelease,
674+
action_parameters=controller_v1_pbs.ActionParameters(
675+
keyboardKeyPressAndRelease=controller_v1_pbs.ActionParameters_KeyboardKey_PressAndRelease(
676+
keyName=key, modifierKeyNames=modifier_keys
677+
)
678+
),
679+
)
672680

673681
@telemetry.record_call()
674682
@override

0 commit comments

Comments
 (0)