most basic example LLM calling

This commit is contained in:
CJ Pais 2025-02-16 19:17:44 -08:00
parent 0d4a69a620
commit 661c46eae8
4 changed files with 475 additions and 51 deletions

402
src-tauri/Cargo.lock generated
View file

@ -228,6 +228,28 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "async-stream"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476"
dependencies = [
"async-stream-impl",
"futures-core",
"pin-project-lite",
]
[[package]]
name = "async-stream-impl"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
]
[[package]]
name = "async-task"
version = "4.7.1"
@ -1176,6 +1198,15 @@ version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7"
[[package]]
name = "encoding_rs"
version = "0.8.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
dependencies = [
"cfg-if",
]
[[package]]
name = "endi"
version = "1.1.0"
@ -1394,6 +1425,21 @@ dependencies = [
"new_debug_unreachable",
]
[[package]]
name = "futures"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.31"
@ -1401,6 +1447,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
@ -1468,6 +1515,7 @@ version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
@ -1814,6 +1862,25 @@ dependencies = [
"syn 2.0.96",
]
[[package]]
name = "h2"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8"
dependencies = [
"bytes",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http 0.2.12",
"indexmap 2.7.1",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "handy-app"
version = "0.1.0"
@ -1821,6 +1888,7 @@ dependencies = [
"anyhow",
"cpal",
"rdev",
"rig-core",
"rubato",
"samplerate",
"serde",
@ -1895,6 +1963,17 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "http"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
dependencies = [
"bytes",
"fnv",
"itoa 1.0.14",
]
[[package]]
name = "http"
version = "1.2.0"
@ -1906,6 +1985,17 @@ dependencies = [
"itoa 1.0.14",
]
[[package]]
name = "http-body"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
dependencies = [
"bytes",
"http 0.2.12",
"pin-project-lite",
]
[[package]]
name = "http-body"
version = "1.0.1"
@ -1913,7 +2003,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
dependencies = [
"bytes",
"http",
"http 1.2.0",
]
[[package]]
@ -1924,8 +2014,8 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
dependencies = [
"bytes",
"futures-util",
"http",
"http-body",
"http 1.2.0",
"http-body 1.0.1",
"pin-project-lite",
]
@ -1935,6 +2025,36 @@ version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a"
[[package]]
name = "httpdate"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
version = "0.14.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"h2",
"http 0.2.12",
"http-body 0.4.6",
"httparse",
"httpdate",
"itoa 1.0.14",
"pin-project-lite",
"socket2",
"tokio",
"tower-service",
"tracing",
"want",
]
[[package]]
name = "hyper"
version = "1.6.0"
@ -1944,8 +2064,8 @@ dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http",
"http-body",
"http 1.2.0",
"http-body 1.0.1",
"httparse",
"itoa 1.0.14",
"pin-project-lite",
@ -1961,8 +2081,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2"
dependencies = [
"futures-util",
"http",
"hyper",
"http 1.2.0",
"hyper 1.6.0",
"hyper-util",
"rustls",
"rustls-pki-types",
@ -1972,6 +2092,19 @@ dependencies = [
"webpki-roots",
]
[[package]]
name = "hyper-tls"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [
"bytes",
"hyper 0.14.32",
"native-tls",
"tokio",
"tokio-native-tls",
]
[[package]]
name = "hyper-util"
version = "0.1.10"
@ -1981,9 +2114,9 @@ dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http",
"http-body",
"hyper",
"http 1.2.0",
"http-body 1.0.1",
"hyper 1.6.0",
"pin-project-lite",
"socket2",
"tokio",
@ -2647,6 +2780,23 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "native-tls"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dab59f8e050d5df8e4dd87d9206fb6f65a483e20ac9fda365ade4fab353196c"
dependencies = [
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[package]]
name = "ndk"
version = "0.8.0"
@ -3077,12 +3227,65 @@ dependencies = [
"pathdiff",
]
[[package]]
name = "openssl"
version = "0.10.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd"
dependencies = [
"bitflags 2.8.0",
"cfg-if",
"foreign-types 0.3.2",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
]
[[package]]
name = "openssl-probe"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "openssl-sys"
version = "0.9.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "option-ext"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "ordered-float"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951"
dependencies = [
"num-traits",
]
[[package]]
name = "ordered-stream"
version = "0.2.0"
@ -3720,6 +3923,48 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "reqwest"
version = "0.11.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
dependencies = [
"base64 0.21.7",
"bytes",
"encoding_rs",
"futures-core",
"futures-util",
"h2",
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.32",
"hyper-tls",
"ipnet",
"js-sys",
"log",
"mime",
"native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls-pemfile 1.0.4",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper 0.1.2",
"system-configuration",
"tokio",
"tokio-native-tls",
"tokio-util",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-streams",
"web-sys",
"winreg 0.50.0",
]
[[package]]
name = "reqwest"
version = "0.12.12"
@ -3730,10 +3975,10 @@ dependencies = [
"bytes",
"futures-core",
"futures-util",
"http",
"http-body",
"http 1.2.0",
"http-body 1.0.1",
"http-body-util",
"hyper",
"hyper 1.6.0",
"hyper-rustls",
"hyper-util",
"ipnet",
@ -3745,12 +3990,12 @@ dependencies = [
"pin-project-lite",
"quinn",
"rustls",
"rustls-pemfile",
"rustls-pemfile 2.2.0",
"rustls-pki-types",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"sync_wrapper 1.0.2",
"tokio",
"tokio-rustls",
"tokio-util",
@ -3765,6 +4010,25 @@ dependencies = [
"windows-registry",
]
[[package]]
name = "rig-core"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7aaf53f8631db9cc12287b5595b14964ae36a213f0d247055efcd26714f2da2b"
dependencies = [
"async-stream",
"bytes",
"futures",
"glob",
"ordered-float",
"reqwest 0.11.27",
"schemars",
"serde",
"serde_json",
"thiserror 1.0.69",
"tracing",
]
[[package]]
name = "ring"
version = "0.17.8"
@ -3861,6 +4125,15 @@ dependencies = [
"zeroize",
]
[[package]]
name = "rustls-pemfile"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
dependencies = [
"base64 0.21.7",
]
[[package]]
name = "rustls-pemfile"
version = "2.2.0"
@ -3920,6 +4193,15 @@ dependencies = [
"libsamplerate-sys",
]
[[package]]
name = "schannel"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "schemars"
version = "0.8.21"
@ -3953,6 +4235,29 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "security-framework"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags 2.8.0",
"core-foundation 0.9.4",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "selectors"
version = "0.22.0"
@ -4361,6 +4666,12 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "sync_wrapper"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]]
name = "sync_wrapper"
version = "1.0.2"
@ -4381,6 +4692,27 @@ dependencies = [
"syn 2.0.96",
]
[[package]]
name = "system-configuration"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
dependencies = [
"bitflags 1.3.2",
"core-foundation 0.9.4",
"system-configuration-sys",
]
[[package]]
name = "system-configuration-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "system-deps"
version = "6.2.2"
@ -4465,7 +4797,7 @@ dependencies = [
"glob",
"gtk",
"heck 0.5.0",
"http",
"http 1.2.0",
"jni",
"libc",
"log",
@ -4477,7 +4809,7 @@ dependencies = [
"percent-encoding",
"plist",
"raw-window-handle",
"reqwest",
"reqwest 0.12.12",
"serde",
"serde_json",
"serde_repr",
@ -4681,7 +5013,7 @@ checksum = "2274ef891ccc0a8d318deffa9d70053f947664d12d58b9c0d1ae5e89237e01f7"
dependencies = [
"dpi",
"gtk",
"http",
"http 1.2.0",
"jni",
"raw-window-handle",
"serde",
@ -4699,7 +5031,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3707b40711d3b9f6519150869e358ffbde7c57567fb9b5a8b51150606939b2a0"
dependencies = [
"gtk",
"http",
"http 1.2.0",
"jni",
"log",
"objc2",
@ -4730,7 +5062,7 @@ dependencies = [
"dunce",
"glob",
"html5ever",
"http",
"http 1.2.0",
"infer",
"json-patch",
"kuchikiki",
@ -4918,6 +5250,16 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.26.1"
@ -5020,7 +5362,7 @@ dependencies = [
"futures-core",
"futures-util",
"pin-project-lite",
"sync_wrapper",
"sync_wrapper 1.0.2",
"tokio",
"tower-layer",
"tower-service",
@ -5240,6 +5582,12 @@ dependencies = [
"serde",
]
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version-compare"
version = "0.2.0"
@ -6032,6 +6380,16 @@ dependencies = [
"winapi",
]
[[package]]
name = "winreg"
version = "0.50.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
dependencies = [
"cfg-if",
"windows-sys 0.48.0",
]
[[package]]
name = "winreg"
version = "0.52.0"
@ -6078,7 +6436,7 @@ dependencies = [
"gdkx11",
"gtk",
"html5ever",
"http",
"http 1.2.0",
"javascriptcore-rs",
"jni",
"kuchikiki",

View file

@ -30,6 +30,7 @@ whisper-rs = { version = "0.13.2", features = ["whisper-cpp-log"] }
anyhow = "1.0.95"
rubato = "0.16.1"
samplerate = "0.2.4"
rig-core = "0.8.0"
[target.'cfg(target_os = "macos")'.dependencies]
whisper-rs = { version = "0.13.2", features = ["metal"] }

View file

@ -4,6 +4,7 @@ use managers::keybinding::KeyBindingManager;
use managers::transcription::TranscriptionManager;
use managers::{audio::AudioRecordingManager, transcription};
use rdev::Key;
use rig::{completion::Prompt, providers::anthropic};
use std::sync::{Arc, Mutex};
use tauri_plugin_autostart::MacosLauncher;
@ -14,34 +15,96 @@ pub fn run() {
let transcription_manager =
Arc::new(TranscriptionManager::new().expect("Failed to initialize transcription manager"));
// let transcription_manager = Arc::new(TranscriptionManager::new());
let claude_client = anthropic::Client::from_env();
let sonnet: Arc<rig::agent::Agent<anthropic::completion::CompletionModel>> = Arc::new(
claude_client
.agent(anthropic::CLAUDE_3_5_SONNET)
.preamble("Be precise and concise.")
.temperature(0.5)
.build(),
);
let manager = Arc::new(Mutex::new(KeyBindingManager::new(
recording_manager.clone(),
transcription_manager.clone(),
sonnet.clone(),
)));
// Register your key bindings
{
let mut manager = manager.lock().unwrap();
// Example: Register Ctrl+Shift combination
// Register Basic Transcription
manager.register(
"ctrl-meta".to_string(),
vec![Key::ControlRight, Key::MetaRight],
|ctx| {
println!("Ctrl+Meta pressed!");
ctx.recording_manager.try_start_recording("ctrl-meta");
None
},
|ctx| {
println!("Ctrl+Meta released!");
if let Some(samples) = ctx.recording_manager.stop_recording("ctrl-meta") {
let samples: Vec<f32> = samples; // explicit type annotation
match ctx.transcription_manager.transcribe(samples) {
Ok(transcription) => println!("Transcription: {}", transcription),
Err(err) => println!("Transcription error: {}", err),
let ctx = ctx.clone();
Some(tauri::async_runtime::spawn(async move {
if let Some(samples) = ctx.recording_manager.stop_recording("ctrl-meta") {
match ctx.transcription_manager.transcribe(samples) {
Ok(transcription) => println!("Transcription: {}", transcription),
Err(err) => println!("Transcription error: {}", err),
}
}
} else {
println!("No samples recorded");
}
}))
},
);
// Register LLM Call after Transcription
manager.register(
"shift-alt".to_string(),
vec![Key::ShiftLeft, Key::Alt],
|ctx| {
println!("Shift+Alt pressed!");
ctx.recording_manager.try_start_recording("shift-alt");
None
},
|ctx| {
let ctx = ctx.clone();
Some(tauri::async_runtime::spawn(async move {
if let Some(samples) = ctx.recording_manager.stop_recording("shift-alt") {
if let Ok(transcription) = ctx.transcription_manager.transcribe(samples) {
println!("Transcription: {}", transcription);
match ctx.sonnet.prompt(transcription).await {
Ok(response) => println!("Sonnet response: {}", response),
Err(err) => println!("Sonnet error: {}", err),
}
}
}
}))
},
);
manager.register(
"ctrl-alt-meta".to_string(),
vec![Key::ControlLeft, Key::Alt, Key::MetaLeft],
|ctx| {
println!("Ctrl+Alt+Meta pressed!");
ctx.recording_manager.try_start_recording("ctrl-alt-meta");
None
},
|ctx| {
let ctx = ctx.clone();
Some(tauri::async_runtime::spawn(async move {
if let Some(samples) = ctx.recording_manager.stop_recording("ctrl-alt-meta") {
let samples: Vec<f32> = samples; // explicit type annotation
match ctx.transcription_manager.transcribe(samples) {
Ok(transcription) => {
println!("Transcription: {}", transcription);
// Call LLM for code
}
Err(err) => println!("Transcription error: {}", err),
}
} else {
println!("No samples recorded");
}
}))
},
);
}

View file

@ -1,35 +1,37 @@
// First, let's define some types for our audio recording functionality
use super::audio::AudioRecordingManager;
use super::transcription::TranscriptionManager;
use rdev::EventType;
use rig::agent::Agent;
use rig::providers::anthropic;
use std::collections::HashSet;
use std::sync::{Arc, Mutex};
type KeySet = HashSet<rdev::Key>;
// Now let's modify the KeyBinding structure to work with our new system
#[derive(Clone)]
pub struct BindingContext {
pub recording_manager: Arc<AudioRecordingManager>,
pub transcription_manager: Arc<TranscriptionManager>,
// Add other managers here as needed
// pub transcription_manager: Arc<TranscriptionManager>,
// pub llm_manager: Arc<LLMManager>,
pub sonnet: Arc<Agent<anthropic::completion::CompletionModel>>,
}
pub struct KeyBinding {
id: String,
keys: KeySet,
on_press: Box<dyn Fn(&BindingContext) + Send + 'static>,
on_release: Box<dyn Fn(&BindingContext) + Send + 'static>,
on_press: Box<
dyn Fn(&BindingContext) -> Option<tauri::async_runtime::JoinHandle<()>> + Send + 'static,
>,
on_release: Box<
dyn Fn(&BindingContext) -> Option<tauri::async_runtime::JoinHandle<()>> + Send + 'static,
>,
currently_pressed: Arc<Mutex<KeySet>>,
}
impl KeyBinding {
fn new<F, G>(id: String, keys: Vec<rdev::Key>, on_press: F, on_release: G) -> Self
where
F: Fn(&BindingContext) + Send + 'static,
G: Fn(&BindingContext) + Send + 'static,
F: Fn(&BindingContext) -> Option<tauri::async_runtime::JoinHandle<()>> + Send + 'static,
G: Fn(&BindingContext) -> Option<tauri::async_runtime::JoinHandle<()>> + Send + 'static,
{
Self {
id,
@ -41,21 +43,19 @@ impl KeyBinding {
}
fn handle_event(&self, key: rdev::Key, is_press: bool, context: &BindingContext) -> bool {
if !self.keys.contains(&key) {
return false;
}
let mut pressed = self.currently_pressed.lock().unwrap();
if is_press {
if pressed.contains(&key) {
return false;
}
pressed.insert(key);
if pressed.len() == self.keys.len() && pressed.is_subset(&self.keys) {
(self.on_press)(context);
let _ = (self.on_press)(context);
return true;
}
} else {
pressed.remove(&key);
if pressed.len() == self.keys.len() - 1 {
(self.on_release)(context);
if pressed.remove(&key) && pressed.len() == self.keys.len() - 1 {
let _ = (self.on_release)(context);
return true;
}
}
@ -72,20 +72,22 @@ impl KeyBindingManager {
pub fn new(
recording_manager: Arc<AudioRecordingManager>,
transcription_manager: Arc<TranscriptionManager>,
sonnet: Arc<Agent<anthropic::completion::CompletionModel>>,
) -> Self {
Self {
bindings: Vec::new(),
context: BindingContext {
recording_manager,
transcription_manager,
sonnet,
},
}
}
pub fn register<F, G>(&mut self, id: String, keys: Vec<rdev::Key>, on_press: F, on_release: G)
where
F: Fn(&BindingContext) + Send + 'static,
G: Fn(&BindingContext) + Send + 'static,
F: Fn(&BindingContext) -> Option<tauri::async_runtime::JoinHandle<()>> + Send + 'static,
G: Fn(&BindingContext) -> Option<tauri::async_runtime::JoinHandle<()>> + Send + 'static,
{
self.bindings
.push(KeyBinding::new(id, keys, on_press, on_release));