diff --git a/assistant_v2/Cargo.lock b/assistant_v2/Cargo.lock index cd5b06a..d5b6e0f 100644 --- a/assistant_v2/Cargo.lock +++ b/assistant_v2/Cargo.lock @@ -120,7 +120,9 @@ dependencies = [ "clipboard", "colored", "cpal", + "dirs", "dotenvy", + "enigo", "flume", "futures", "hound", @@ -534,7 +536,7 @@ dependencies = [ "block", "core-foundation 0.9.4", "core-graphics 0.21.0", - "foreign-types", + "foreign-types 0.3.2", "libc", "objc", ] @@ -624,7 +626,7 @@ checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" dependencies = [ "bitflags 1.3.2", "core-foundation 0.7.0", - "foreign-types", + "foreign-types 0.3.2", "libc", ] @@ -636,7 +638,31 @@ checksum = "52a67c4378cf203eace8fb6567847eb641fd6ff933c1145a115c6ee820ebb978" dependencies = [ "bitflags 1.3.2", "core-foundation 0.9.4", - "foreign-types", + "foreign-types 0.3.2", + "libc", +] + +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "core-graphics-types", + "foreign-types 0.5.0", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", "libc", ] @@ -680,7 +706,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "windows", + "windows 0.54.0", ] [[package]] @@ -801,6 +827,27 @@ dependencies = [ "syn", ] +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -833,6 +880,19 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enigo" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "802e4b2ae123615659085369b453cba87c5562e46ed8050a909fee18a9bc3157" +dependencies = [ + "core-graphics 0.23.2", + "libc", + "objc", + "pkg-config", + "windows 0.51.1", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -917,7 +977,28 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "foreign-types-shared", + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -926,6 +1007,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1490,6 +1577,16 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "libredox" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4488594b9328dee448adb906d8b126d9b7deb7cf5c22161ee591610bb1be83c0" +dependencies = [ + "bitflags 2.9.1", + "libc", +] + [[package]] name = "linux-raw-sys" version = "0.9.4" @@ -1822,6 +1919,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "overload" version = "0.1.1" @@ -2091,6 +2194,17 @@ dependencies = [ "x11", ] +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.16", + "libredox", + "thiserror 1.0.69", +] + [[package]] name = "regex" version = "1.11.1" @@ -2462,7 +2576,7 @@ dependencies = [ "tempfile", "tokio", "tracing", - "windows", + "windows 0.54.0", ] [[package]] @@ -2583,7 +2697,7 @@ dependencies = [ "memchr", "ntapi", "rayon", - "windows", + "windows 0.54.0", ] [[package]] @@ -3096,16 +3210,35 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" +dependencies = [ + "windows-core 0.51.1", + "windows-targets 0.48.5", +] + [[package]] name = "windows" version = "0.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" dependencies = [ - "windows-core", + "windows-core 0.54.0", "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-core" version = "0.54.0" @@ -3134,6 +3267,15 @@ dependencies = [ "windows-targets 0.42.2", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -3167,6 +3309,21 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -3189,6 +3346,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -3201,6 +3364,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -3213,6 +3382,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -3231,6 +3406,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -3243,6 +3424,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -3255,6 +3442,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -3267,6 +3460,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" diff --git a/assistant_v2/Cargo.toml b/assistant_v2/Cargo.toml index 9f31854..3da0dbf 100644 --- a/assistant_v2/Cargo.toml +++ b/assistant_v2/Cargo.toml @@ -25,3 +25,4 @@ clipboard = "0.5.0" open = "5.3.1" sysinfo = "0.32.1" enigo = "0.1.3" +dirs = "5.0.1" diff --git a/assistant_v2/FEATURE_PROGRESS.md b/assistant_v2/FEATURE_PROGRESS.md index ce12f13..8800889 100644 --- a/assistant_v2/FEATURE_PROGRESS.md +++ b/assistant_v2/FEATURE_PROGRESS.md @@ -8,7 +8,7 @@ This document tracks which features from the original assistant have been implem | System volume adjustment (Windows only) | Pending | | Media playback commands | Done | | Launch applications from voice | Pending | -| Display log files | Pending | +| Display log files | Done | | Get system info | Done | | List and kill processes | Pending | | Run internet speed tests | Done (async) | diff --git a/assistant_v2/src/main.rs b/assistant_v2/src/main.rs index 4b280bf..a59427c 100644 --- a/assistant_v2/src/main.rs +++ b/assistant_v2/src/main.rs @@ -19,6 +19,7 @@ use std::error::Error; use std::path::PathBuf; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; +use std::sync::LazyLock; use std::time::Instant; use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; use tracing::info; @@ -33,6 +34,13 @@ use tempfile::tempdir; use uuid::Uuid; use sysinfo::{Components, Disks, Networks, System}; +static LOGS_DIR: LazyLock = LazyLock::new(|| { + dirs::cache_dir() + .unwrap() + .join("quick-assistant") + .join("logs") +}); + #[derive(Parser, Debug)] struct Opt { /// How fast the AI speaks. 1.0 is normal speed. @@ -224,6 +232,19 @@ async fn main() -> Result<(), Box> { strict: None, } .into(), + FunctionObject { + name: "open_logs_folder".into(), + description: Some( + "Opens the logs folder in the default file browser.".into(), + ), + parameters: Some(serde_json::json!({ + "type": "object", + "properties": {}, + "required": [], + })), + strict: None, + } + .into(), FunctionObject { name: "get_system_info".into(), description: Some("Returns system information like CPU and memory usage.".into()), @@ -709,6 +730,19 @@ async fn handle_requires_action( }); } + if tool.function.name == "open_logs_folder" { + let _ = std::fs::create_dir_all(&*LOGS_DIR); + let result = open::that(&*LOGS_DIR); + let msg = match result { + Ok(_) => format!("Opened logs folder: {}", LOGS_DIR.display()), + Err(e) => format!("Failed to open logs folder: {}", e), + }; + tool_outputs.push(ToolsOutputs { + tool_call_id: Some(tool.id.clone()), + output: Some(msg.into()), + }); + } + if tool.function.name == "speedtest" { tool_outputs.push(ToolsOutputs { tool_call_id: Some(tool.id.clone()), @@ -952,6 +986,35 @@ mod tests { })); } + #[test] + fn includes_open_logs_folder_function() { + let req = CreateAssistantRequestArgs::default() + .instructions("test") + .model("gpt-4o") + .tools(vec![FunctionObject { + name: "open_logs_folder".into(), + description: Some( + "Opens the logs folder in the default file browser.".into(), + ), + parameters: Some(serde_json::json!({ + "type": "object", + "properties": {}, + "required": [], + })), + strict: None, + } + .into()]) + .build() + .unwrap(); + + let tools = req.tools.unwrap(); + assert!(tools.iter().any(|t| match t { + async_openai::types::AssistantTools::Function(f) => + f.function.name == "open_logs_folder", + _ => false, + })); + } + #[test] fn includes_speedtest_function() { let req = CreateAssistantRequestArgs::default()