Skip to content

Commit 7083a7c

Browse files
Command actions & activation key recording (#116)
* first implementation of hotkey recording * refactor command actions * refactor record hotkey * refactor command execution * bugfixing * start refactor config template * convert rest of the config (untested, key names might be wrong) x * add commands and stubs * add response command * added mouse button push to talk support * add missing await * add record hotkey to command handler * fix function call * add timeout to record key function * monkeyfix MacOS thread generation --------- Co-authored-by: Timo Korinth <[email protected]>
1 parent 01eb54d commit 7083a7c

File tree

11 files changed

+529
-281
lines changed

11 files changed

+529
-281
lines changed

api/commands.py

+18
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from typing import Literal, Optional
22
from pydantic import BaseModel
33
from api.enums import CommandTag, LogSource, LogType, ToastType
4+
from api.interface import CommandActionConfig
45

56

67
# We use this Marker base class for reflection to "iterate all commands"
@@ -22,6 +23,18 @@ class SaveSecretCommand(WebSocketCommandModel):
2223
secret_value: str
2324

2425

26+
class RecordKeyboardActionsCommand(WebSocketCommandModel):
27+
command: Literal["record_keyboard_actions"] = "record_keyboard_actions"
28+
29+
30+
class RecordMouseActionsCommand(WebSocketCommandModel):
31+
command: Literal["record_mouse_actions"] = "record_mouse_actions"
32+
33+
34+
class StopRecordingCommand(WebSocketCommandModel):
35+
command: Literal["stop_recording"] = "stop_recording"
36+
37+
2538
# SENT TO CLIENT
2639

2740

@@ -44,3 +57,8 @@ class ToastCommand(WebSocketCommandModel):
4457
command: Literal["toast"] = "toast"
4558
text: str
4659
toast_type: ToastType
60+
61+
62+
class ActionsRecordedCommand(WebSocketCommandModel):
63+
command: Literal["actions_recorded"] = "actions_recorded"
64+
actions: list[CommandActionConfig]

api/interface.py

+33-17
Original file line numberDiff line numberDiff line change
@@ -273,27 +273,40 @@ class FeaturesConfig(BaseModel):
273273
remember_messages: Optional[int] = None
274274

275275

276-
class KeyPressConfig(BaseModel):
277-
key: str
278-
"""The key the wingman will press when executing the command. Use 'primary', 'secondary' or 'middle' for mouse buttons. Use 'scroll' to scroll."""
276+
class CommandKeyboardConfig(BaseModel):
277+
hotkey: str
278+
"""The hotkey. Can be a single key like 'a' or a combination like 'ctrl+shift+a'."""
279279

280-
modifier: Optional[str] = None
281-
"""This will press "modifier + key" instead of just "modifier". Optional."""
280+
hold: Optional[float] = None
281+
"""The duration the key will be pressed in seconds. Optional."""
282282

283-
wait: Optional[float] = None
284-
"""Wait time in seconds before pressing the next key. Optional."""
283+
284+
class CommandMouseConfig(BaseModel):
285+
button: Optional[str] = None
286+
"""The mouse button to press. Optional."""
285287

286288
hold: Optional[float] = None
287-
"""The duration the key will be pressed in seconds. Optional."""
289+
"""The duration the button will be pressed in seconds. Optional."""
290+
291+
scroll: Optional[int] = None
292+
"""The amount to scroll up (positive integer) or down (negative integer), example 10 or -10. Must have 'scroll' as key above to work."""
288293

289-
scroll_amount: Optional[int] = None
290-
"""The amount of clicks to scroll up (positive integer) or down (negative integer), example 10 or -10. Must have 'scroll' as key above to work."""
294+
move: Optional[list[int]] = None
295+
"""The x, y coordinates to move to relative to the current mouse position, expected [x,y] format in yaml. Must have associated button press to work."""
291296

292-
moveto: Optional[list[int]] = None
297+
move_to: Optional[list[int]] = None
293298
"""The x, y coordinates to move the mouse to on the screen, expected [x,y] format in yaml. Must have associated button press to work."""
294299

295-
moveto_relative: Optional[list[int]] = None
296-
"""The x, y coordinates to move to relative to the current mouse position, expected [x,y] format in yaml. Must have associated button press to work."""
300+
301+
class CommandActionConfig(BaseModel):
302+
keyboard: Optional[CommandKeyboardConfig] = None
303+
"""The keyboard configuration for this action. Optional."""
304+
305+
wait: Optional[float] = None
306+
"""Wait time in seconds before pressing the next key. Optional."""
307+
308+
mouse: Optional[CommandMouseConfig] = None
309+
"""The mouse configuration for this action. Optional."""
297310

298311
write: Optional[str] = None
299312
"""The word or phrase to type, for example, to type text in a login screen. Must have associated button press to work. May need special formatting for special characters."""
@@ -311,8 +324,8 @@ class CommandConfig(BaseModel):
311324
"""Optional: Faster - like Voice Attack! Provide phrases that will instantly activate the command (without AI roundtripping). You need to say the exact phrase to execute the command"""
312325
responses: Optional[list[str]] = None
313326
"""Optional: Provide responses that will be used when the command is executed. A random one will be chosen (if multiple)."""
314-
keys: Optional[list[KeyPressConfig]] = None
315-
"""The key or keys to press when the command is executed."""
327+
actions: Optional[list[CommandActionConfig]] = None
328+
"""The actions to execute when the command is called. You can use keyboard, mouse and wait actions here."""
316329

317330

318331
class CustomWingmanClassConfig(BaseModel):
@@ -334,7 +347,7 @@ class NestedConfig(BaseModel):
334347
elevenlabs: ElevenlabsConfig
335348
azure: AzureConfig
336349
xvasynth: XVASynthTtsConfig
337-
commands: list[CommandConfig] | None = None
350+
commands: Optional[list[CommandConfig]] = None
338351

339352

340353
class WingmanConfig(NestedConfig):
@@ -355,9 +368,12 @@ def __setitem__(self, key, value):
355368
"""The "friendly" name of this Wingman. Can be changed by the user."""
356369
description: str
357370
"""A short description of this Wingman."""
358-
record_key: str
371+
record_key: Optional[str] = None
359372
"""The "push-to-talk" key for this wingman. Keep it pressed while talking!
360373
Modifiers for this key are not supported yet. Don't use the same key for multiple wingmen!"""
374+
record_mouse_button: Optional[str] = None
375+
"""The "push-to-talk" mouse button for this wingman. Keep it pressed while talking!
376+
Don't use the same button for multiple wingmen!"""
361377

362378

363379
class Config(NestedConfig):

0 commit comments

Comments
 (0)