omlins / JustSayIt.jl

Software and high-level API for offline, low latency and secure translation of human speech to computer commands or text on Linux, MacOS and Windows
BSD 3-Clause "New" or "Revised" License
84 stars 10 forks source link

Usage example fails due to incorrect type checks #87

Closed pfitzseb closed 1 year ago

pfitzseb commented 1 year ago

The example at https://omlins.github.io/JustSayIt.jl/stable/usage/ fails due to the types specified at https://github.com/omlins/JustSayIt.jl/blob/7ec7f1bdfe90975e3de485a7cd406889ecbd73a9/src/init_jsi.jl#L29 not including typeof(Key.ctrl) == PyObject.

Ref https://github.com/JuliaCon/proceedings-review/issues/121.

omlins commented 1 year ago

@pfitzseb : Thanks for noting that. Could you please point to the exact location of the example that fails? The link you posted goes to the beginning of the section...

pfitzseb commented 1 year ago

This is super weird -- I can't repro this with the example on that page, but the following REPL session does consistently fail for me:

julia> using JustSayIt

julia> # time: 2023-01-30 12:12:50 CET
       # mode: julia
       using JustSayIt.API       # Import JustSayIt API to write @voicearg functions

julia> # time: 2023-01-30 12:12:52 CET
       # mode: julia
       using DefaultApplication  # To install type: `]` and then `add DefaultApplication`

julia> # time: 2023-01-30 12:12:52 CET
       # mode: julia
       # 1) Define a custom weather forecast search function.
       @doc """
           weather `today` | `tomorrow`

       Find out how the weather is `today` or `tomorrow`.
       """
       weather
weather

julia> # time: 2023-01-30 12:12:53 CET
       # mode: julia
       @enum Day today tomorrow

julia> # time: 2023-01-30 12:12:53 CET
       # mode: julia
       @voiceargs day=>(valid_input_auto=true) function weather(day::Day)
           DefaultApplication.open("https://www.google.com/search?q=weather+$day")
       end
weather (generic function with 2 methods)

julia> # time: 2023-01-30 12:12:55 CET
       # mode: julia
       # 2) Define command name to function mapping, calling custom function
       commands = Dict("help"      => Help.help,
                       "weather"   => weather,
                       );

julia> # time: 2023-01-30 12:12:59 CET
       # mode: julia
       # 3) Start JustSayIt with the custom commands.
       start(commands=commands)
[ Info: JustSayIt: I am initializing...
[ Info: Listening for commands in English (United States) (say "sleep JustSayIt" to put me to sleep; press CTRL+c to terminate)...
[ Info: Starting command: help
┌ Info: Command weather
│    =
│      weather `today` | `tomorrow`
│
└      Find out how the weather is today or tomorrow.
^C[ Info: Terminating JustSayIt...
[ Info: Stopped listening for commands.

julia> # time: 2023-01-30 12:18:55 CET
       # mode: julia
       commands = Dict(
         "ma" => Mouse.click_left
       )
Dict{String, typeof(JustSayIt.Mouse.click_left)} with 1 entry:
  "ma" => click_left

julia> # time: 2023-01-30 12:19:08 CET
       # mode: julia
       # 3) Start JustSayIt with the custom commands.
       start(commands=commands)
[ Info: JustSayIt: I am initializing...
[ Info: Listening for commands in English (United States) (say "sleep JustSayIt" to put me to sleep; press CTRL+c to terminate)...
[ Info: Starting command: click_left
^C[ Info: Terminating JustSayIt...
[ Info: Stopped listening for commands.

julia> # time: 2023-01-30 12:20:05 CET
       # mode: julia
       # 3) Start JustSayIt with the custom commands.
       start(;commands=commands, max_speed_subset=["ma"])
[ Info: JustSayIt: I am initializing...
[ Info: Listening for commands in English (United States) (say "sleep JustSayIt" to put me to sleep; press CTRL+c to terminate)...
[ Info: Starting command: click_left (latency: 18 ms)
^C[ Info: Terminating JustSayIt...
[ Info: Stopped listening for commands.

julia> # time: 2023-01-30 12:23:06 CET
       # mode: julia
       commands = Dict("help"      => Help.help,
                       "type"      => Keyboard.type,
                       "ma"        => Mouse.click_left,
                       "select"    => Mouse.press_left,
                       "okay"      => Mouse.release_left,
                       "middle"    => Mouse.click_middle,
                       "right"     => Mouse.click_right,
                       "double"    => Mouse.click_double,
                       "triple"    => Mouse.click_triple,
                       "copy"      => (Key.ctrl, 'c'),
                       "cut"       => (Key.ctrl, 'x'),
                       "paste"     => (Key.ctrl, 'v'),
                       "undo"      => (Key.ctrl, 'z'),
                       "redo"      => (Key.ctrl, Key.shift, 'z'),
                       "upwards"   => Key.page_up,
                       "downwards" => Key.page_down,
                       "take"      => [Mouse.click_double, (Key.ctrl, 'c')],
                       "replace"   => [Mouse.click_double, (Key.ctrl, 'v')],
                       );

julia> # time: 2023-01-30 12:23:07 CET
       # mode: julia
       start(commands=commands, max_speed_subset=["ma", "select", "okay", "middle", "right", "double", "triple", "copy", "upwards", "downwards", "take"])
[ Info: JustSayIt: I am initializing...
ERROR: ArgumentError: the command belonging to commmand name upwards is of an invalid type. Valid are functions (e.g., Keyboard.type), keys (e.g., Key.ctrl or 'f'), tuples of keys (e.g., (Key.ctrl, 'c') ) and arrays containing any combination of the afore noted.
Stacktrace:
 [1] init_jsi(commands::Dict{String, Any}, modeldirs::Dict{String, String}, noises::Dict{String, Vector{String}}; default_language::String, type_languages::Vector{String}, vosk_log_level::Int64)
   @ JustSayIt ~/.julia/packages/JustSayIt/IefnA/src/init_jsi.jl:64
 [2] start(; default_language::String, type_languages::String, commands::Dict{String, Any}, subset::Nothing, max_speed_subset::Vector{String}, modeldirs::Nothing, noises::Dict{String, Vector{String}}, audio_input_cmd::Nothing)
   @ JustSayIt ~/.julia/packages/JustSayIt/IefnA/src/start.jl:158
 [3] top-level scope
   @ REPL[15]:3

julia> commands["upwards"]
PyObject <Key.page_up: <65365>>

julia> Key.ctrl
PyObject <Key.ctrl: <65507>>

julia> Key.page_up
PyObject <Key.page_up: <65365>>

I can't repro the failure in a fresh session:

julia> using JustSayIt

julia> # time: 2023-01-30 12:23:06 CET
       # mode: julia
       commands = Dict("help"      => Help.help,
                       "type"      => Keyboard.type,
                       "ma"        => Mouse.click_left,
                       "select"    => Mouse.press_left,
                       "okay"      => Mouse.release_left,
                       "middle"    => Mouse.click_middle,
                       "right"     => Mouse.click_right,
                       "double"    => Mouse.click_double,
                       "triple"    => Mouse.click_triple,
                       "copy"      => (Key.ctrl, 'c'),
                       "cut"       => (Key.ctrl, 'x'),
                       "paste"     => (Key.ctrl, 'v'),
                       "undo"      => (Key.ctrl, 'z'),
                       "redo"      => (Key.ctrl, Key.shift, 'z'),
                       "upwards"   => Key.page_up,
                       "downwards" => Key.page_down,
                       "take"      => [Mouse.click_double, (Key.ctrl, 'c')],
                       "replace"   => [Mouse.click_double, (Key.ctrl, 'v')],
                       );

julia> # time: 2023-01-30 12:23:07 CET
       # mode: julia
       start(commands=commands, max_speed_subset=["ma", "select", "okay", "middle", "right", "double", "triple", "copy", "upwards", "downwards", "take"])
[ Info: JustSayIt: I am initializing...
[ Info: Listening for commands in English (United States) (say "sleep JustSayIt" to put me to sleep; press CTRL+c to terminate)...
[ Info: Starting command: page_up (latency: 79 ms)
[ Info: Starting command: page_down (latency: 19 ms)

Don't currently have time to debug this further though, sorry.