diff --git a/crates/openfang-api/src/ws.rs b/crates/openfang-api/src/ws.rs index 9f776ba8..193c689f 100644 --- a/crates/openfang-api/src/ws.rs +++ b/crates/openfang-api/src/ws.rs @@ -169,7 +169,7 @@ pub async fn agent_ws( let query_auth = uri .query() .and_then(|q| q.split('&').find_map(|pair| pair.strip_prefix("token="))) - .map(|raw| crate::percent_decode(raw)) + .map(crate::percent_decode) .map(|token| ct_eq(&token, api_key)) .unwrap_or(false); diff --git a/crates/openfang-cli/src/tui/screens/init_wizard.rs b/crates/openfang-cli/src/tui/screens/init_wizard.rs index 4d708f49..a2947128 100644 --- a/crates/openfang-cli/src/tui/screens/init_wizard.rs +++ b/crates/openfang-cli/src/tui/screens/init_wizard.rs @@ -970,13 +970,11 @@ pub fn run() -> InitResult { if matches!( state.copilot_auth_status, CopilotAuthStatus::WaitingForUser - ) { - if !state.copilot_verification_uri.is_empty() { - let _ = - openfang_runtime::drivers::copilot::open_verification_url( - &state.copilot_verification_uri, - ); - } + ) && !state.copilot_verification_uri.is_empty() { + let _ = + openfang_runtime::drivers::copilot::open_verification_url( + &state.copilot_verification_uri, + ); } } _ => {} diff --git a/crates/openfang-kernel/src/kernel.rs b/crates/openfang-kernel/src/kernel.rs index 7f67fbc2..e1261040 100644 --- a/crates/openfang-kernel/src/kernel.rs +++ b/crates/openfang-kernel/src/kernel.rs @@ -514,7 +514,7 @@ impl OpenFangKernel { fn fetch_copilot_models(openfang_dir: &Path) -> Result, String> { use openfang_runtime::drivers::copilot; - let tokens = copilot::PersistedTokens::load(&openfang_dir.to_path_buf()) + let tokens = copilot::PersistedTokens::load(openfang_dir) .ok_or("No persisted Copilot tokens found")?; let fetch = async { diff --git a/crates/openfang-runtime/src/drivers/copilot.rs b/crates/openfang-runtime/src/drivers/copilot.rs index 5ddf5912..9c1f15f3 100644 --- a/crates/openfang-runtime/src/drivers/copilot.rs +++ b/crates/openfang-runtime/src/drivers/copilot.rs @@ -10,7 +10,7 @@ //! `config.toml`. The driver handles the rest — device flow, token persistence, //! refresh, and Copilot API token exchange — automatically. -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::sync::Mutex; use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; @@ -55,6 +55,7 @@ const OAUTH_SCOPES: &str = "copilot"; const TOKEN_FILE_NAME: &str = ".copilot-tokens.json"; /// Device flow polling interval (seconds) — GitHub default is 5. +#[allow(dead_code)] const DEVICE_FLOW_POLL_INTERVAL: Duration = Duration::from_secs(5); /// Maximum time to wait for user to authorize the device flow. @@ -83,14 +84,14 @@ impl PersistedTokens { } /// Load from the OpenFang data directory. - pub fn load(openfang_dir: &PathBuf) -> Option { + pub fn load(openfang_dir: &Path) -> Option { let path = openfang_dir.join(TOKEN_FILE_NAME); let data = std::fs::read_to_string(&path).ok()?; serde_json::from_str(&data).ok() } /// Persist to the OpenFang data directory with restricted permissions. - pub fn save(&self, openfang_dir: &PathBuf) -> Result<(), String> { + pub fn save(&self, openfang_dir: &Path) -> Result<(), String> { let path = openfang_dir.join(TOKEN_FILE_NAME); let json = serde_json::to_string_pretty(self) .map_err(|e| format!("Failed to serialize tokens: {e}"))?; @@ -138,6 +139,7 @@ impl CachedCopilotToken { #[derive(Clone)] struct CachedModels { models: Vec, + #[allow(dead_code)] fetched_at: Instant, } @@ -358,7 +360,7 @@ pub async fn exchange_copilot_token( .ok_or("Missing 'token' field in Copilot response")?; let expires_at_unix = body.get("expires_at").and_then(|v| v.as_i64()).unwrap_or(0); - let ttl_secs = (expires_at_unix - unix_now() as i64).max(60) as u64; + let ttl_secs = (expires_at_unix - unix_now()).max(60) as u64; // Extract base URL from endpoints.api or proxy-ep in the token. let base_url = body @@ -732,7 +734,7 @@ impl crate::llm_driver::LlmDriver for CopilotDriver { /// /// Called from `openfang config set-key github-copilot`, `openfang init`, /// `openfang onboard`, and `openfang configure`. -pub async fn run_interactive_setup(openfang_dir: &PathBuf) -> Result { +pub async fn run_interactive_setup(openfang_dir: &Path) -> Result { run_device_flow(openfang_dir).await } @@ -740,7 +742,7 @@ pub async fn run_interactive_setup(openfang_dir: &PathBuf) -> Result Result { +pub async fn run_device_flow(openfang_dir: &Path) -> Result { let client = reqwest::Client::builder() .timeout(Duration::from_secs(30)) .build() @@ -817,7 +819,7 @@ pub fn open_verification_url(url: &str) -> bool { } /// Check if Copilot OAuth tokens exist on disk. -pub fn copilot_auth_available(openfang_dir: &PathBuf) -> bool { +pub fn copilot_auth_available(openfang_dir: &Path) -> bool { openfang_dir.join(TOKEN_FILE_NAME).exists() } diff --git a/crates/openfang-runtime/src/drivers/openai.rs b/crates/openfang-runtime/src/drivers/openai.rs index 2d9f63a2..2c3edc8c 100644 --- a/crates/openfang-runtime/src/drivers/openai.rs +++ b/crates/openfang-runtime/src/drivers/openai.rs @@ -276,7 +276,7 @@ struct OaiUsage { /// Strip trailing empty assistant messages without tool calls. /// Some API proxies reject empty assistant messages as "prefill". fn strip_trailing_empty_assistant(messages: &mut Vec) { - while messages.last().map_or(false, |m| { + while messages.last().is_some_and(|m| { m.role == "assistant" && m.tool_calls.is_none() && match &m.content {