diff --git a/crates/goose-llm/examples/simple.rs b/crates/goose-llm/examples/simple.rs index 99ecea31..e7d36a78 100644 --- a/crates/goose-llm/examples/simple.rs +++ b/crates/goose-llm/examples/simple.rs @@ -116,7 +116,7 @@ async fn main() -> Result<()> { println!("\nCompletion Response:"); println!("{}", serde_json::to_string_pretty(&completion_response)?); - let tooltip = generate_tooltip(provider, provider_config.clone().into(), &messages).await?; + let tooltip = generate_tooltip(provider, provider_config.clone(), &messages).await?; println!("\nTooltip: {}", tooltip); } diff --git a/crates/goose-llm/src/message/mod.rs b/crates/goose-llm/src/message/mod.rs index 0212fbc3..ac2aaf27 100644 --- a/crates/goose-llm/src/message/mod.rs +++ b/crates/goose-llm/src/message/mod.rs @@ -151,7 +151,7 @@ mod tests { .with_text("Hello, I'll help you with that.") .with_tool_request( "tool123", - Ok(ToolCall::new("test_tool", json!({"param": "value"})).into()), + Ok(ToolCall::new("test_tool", json!({"param": "value"}))), ); let json_str = serde_json::to_string_pretty(&message).unwrap(); diff --git a/crates/goose-llm/src/providers/formats/databricks.rs b/crates/goose-llm/src/providers/formats/databricks.rs index 649d2f67..d69c31bb 100644 --- a/crates/goose-llm/src/providers/formats/databricks.rs +++ b/crates/goose-llm/src/providers/formats/databricks.rs @@ -681,7 +681,7 @@ mod tests { Message::user().with_text("How are you?"), Message::assistant().with_tool_request( "tool1", - Ok(ToolCall::new("example", json!({"param1": "value1"})).into()), + Ok(ToolCall::new("example", json!({"param1": "value1"}))), ), ]; @@ -801,7 +801,7 @@ mod tests { 0x0D, 0x0A, 0x1A, 0x0A, // PNG header 0x00, 0x00, 0x00, 0x0D, // Rest of fake PNG data ]; - std::fs::write(&png_path, &png_data)?; + std::fs::write(&png_path, png_data)?; let png_path_str = png_path.to_str().unwrap(); // Create message with image path diff --git a/crates/goose-llm/src/providers/formats/openai.rs b/crates/goose-llm/src/providers/formats/openai.rs index 06fd527e..afc48745 100644 --- a/crates/goose-llm/src/providers/formats/openai.rs +++ b/crates/goose-llm/src/providers/formats/openai.rs @@ -674,7 +674,7 @@ mod tests { 0x0D, 0x0A, 0x1A, 0x0A, // PNG header 0x00, 0x00, 0x00, 0x0D, // Rest of fake PNG data ]; - std::fs::write(&png_path, &png_data)?; + std::fs::write(&png_path, png_data)?; let png_path_str = png_path.to_str().unwrap(); // Create message with image path diff --git a/crates/goose-llm/src/providers/utils.rs b/crates/goose-llm/src/providers/utils.rs index caca0a00..1a3945dc 100644 --- a/crates/goose-llm/src/providers/utils.rs +++ b/crates/goose-llm/src/providers/utils.rs @@ -277,7 +277,7 @@ mod tests { 0x0D, 0x0A, 0x1A, 0x0A, // PNG header 0x00, 0x00, 0x00, 0x0D, // Rest of fake PNG data ]; - std::fs::write(&png_path, &png_data).unwrap(); + std::fs::write(&png_path, png_data).unwrap(); let png_path_str = png_path.to_str().unwrap(); // Create a fake PNG (wrong magic numbers) @@ -315,7 +315,7 @@ mod tests { 0x0D, 0x0A, 0x1A, 0x0A, // PNG header 0x00, 0x00, 0x00, 0x0D, // Rest of fake PNG data ]; - std::fs::write(&png_path, &png_data).unwrap(); + std::fs::write(&png_path, png_data).unwrap(); let png_path_str = png_path.to_str().unwrap(); // Create a fake PNG (wrong magic numbers) diff --git a/crates/goose-mcp/src/developer/mod.rs b/crates/goose-mcp/src/developer/mod.rs index 9eea65ce..2c15f302 100644 --- a/crates/goose-mcp/src/developer/mod.rs +++ b/crates/goose-mcp/src/developer/mod.rs @@ -1695,7 +1695,7 @@ mod tests { std::env::set_current_dir(&temp_dir).unwrap(); // Create a DeveloperRouter with custom ignore patterns - let mut builder = GitignoreBuilder::new(temp_dir.path().to_path_buf()); + let mut builder = GitignoreBuilder::new(temp_dir.path()); builder.add_line(None, "secret.txt").unwrap(); builder.add_line(None, "*.env").unwrap(); let ignore_patterns = builder.build().unwrap(); @@ -1747,7 +1747,7 @@ mod tests { std::env::set_current_dir(&temp_dir).unwrap(); // Create a DeveloperRouter with custom ignore patterns - let mut builder = GitignoreBuilder::new(temp_dir.path().to_path_buf()); + let mut builder = GitignoreBuilder::new(temp_dir.path()); builder.add_line(None, "secret.txt").unwrap(); let ignore_patterns = builder.build().unwrap(); @@ -1807,7 +1807,7 @@ mod tests { std::env::set_current_dir(&temp_dir).unwrap(); // Create a DeveloperRouter with custom ignore patterns - let mut builder = GitignoreBuilder::new(temp_dir.path().to_path_buf()); + let mut builder = GitignoreBuilder::new(temp_dir.path()); builder.add_line(None, "secret.txt").unwrap(); let ignore_patterns = builder.build().unwrap(); diff --git a/crates/goose-server/src/routes/audio.rs b/crates/goose-server/src/routes/audio.rs index 17818c5a..d9eb718d 100644 --- a/crates/goose-server/src/routes/audio.rs +++ b/crates/goose-server/src/routes/audio.rs @@ -66,23 +66,7 @@ async fn transcribe_handler( ) -> Result, StatusCode> { verify_secret_key(&headers, &state)?; - // Get the OpenAI API key from config - let config = goose::config::Config::global(); - let api_key: String = config - .get_secret("OPENAI_API_KEY") - .map_err(|_| StatusCode::PRECONDITION_FAILED)?; - - // Get the OpenAI host from config (with default) - let openai_host = match config.get("OPENAI_HOST", false) { - Ok(value) => value - .as_str() - .map(|s| s.to_string()) - .unwrap_or_else(|| "https://api.openai.com".to_string()), - Err(_) => "https://api.openai.com".to_string(), - }; - - tracing::debug!("Using OpenAI host: {}", openai_host); - + // Validate input first before checking API key configuration // Decode the base64 audio data let audio_bytes = BASE64 .decode(&request.audio) @@ -110,6 +94,23 @@ async fn transcribe_handler( _ => return Err(StatusCode::UNSUPPORTED_MEDIA_TYPE), }; + // Get the OpenAI API key from config (after input validation) + let config = goose::config::Config::global(); + let api_key: String = config + .get_secret("OPENAI_API_KEY") + .map_err(|_| StatusCode::PRECONDITION_FAILED)?; + + // Get the OpenAI host from config (with default) + let openai_host = match config.get("OPENAI_HOST", false) { + Ok(value) => value + .as_str() + .map(|s| s.to_string()) + .unwrap_or_else(|| "https://api.openai.com".to_string()), + Err(_) => "https://api.openai.com".to_string(), + }; + + tracing::debug!("Using OpenAI host: {}", openai_host); + // Create a multipart form with the audio file let part = reqwest::multipart::Part::bytes(audio_bytes) .file_name(format!("audio.{}", file_extension)) @@ -176,7 +177,35 @@ async fn transcribe_elevenlabs_handler( ) -> Result, StatusCode> { verify_secret_key(&headers, &state)?; - // Get the ElevenLabs API key from config + // Validate input first before checking API key configuration + // Decode the base64 audio data + let audio_bytes = BASE64 + .decode(&request.audio) + .map_err(|_| StatusCode::BAD_REQUEST)?; + + // Check file size + if audio_bytes.len() > MAX_AUDIO_SIZE_BYTES { + tracing::warn!( + "Audio file too large: {} bytes (max: {} bytes)", + audio_bytes.len(), + MAX_AUDIO_SIZE_BYTES + ); + return Err(StatusCode::PAYLOAD_TOO_LARGE); + } + + // Determine file extension and content type based on MIME type + let (file_extension, content_type) = match request.mime_type.as_str() { + "audio/webm" => ("webm", "audio/webm"), + "audio/mp4" => ("mp4", "audio/mp4"), + "audio/mpeg" => ("mp3", "audio/mpeg"), + "audio/mpga" => ("mp3", "audio/mpeg"), + "audio/m4a" => ("m4a", "audio/m4a"), + "audio/wav" => ("wav", "audio/wav"), + "audio/x-wav" => ("wav", "audio/wav"), + _ => return Err(StatusCode::UNSUPPORTED_MEDIA_TYPE), + }; + + // Get the ElevenLabs API key from config (after input validation) let config = goose::config::Config::global(); // First try to get it as a secret @@ -216,33 +245,6 @@ async fn transcribe_elevenlabs_handler( } }; - // Decode the base64 audio data - let audio_bytes = BASE64 - .decode(&request.audio) - .map_err(|_| StatusCode::BAD_REQUEST)?; - - // Check file size - if audio_bytes.len() > MAX_AUDIO_SIZE_BYTES { - tracing::warn!( - "Audio file too large: {} bytes (max: {} bytes)", - audio_bytes.len(), - MAX_AUDIO_SIZE_BYTES - ); - return Err(StatusCode::PAYLOAD_TOO_LARGE); - } - - // Determine file extension and content type based on MIME type - let (file_extension, content_type) = match request.mime_type.as_str() { - "audio/webm" => ("webm", "audio/webm"), - "audio/mp4" => ("mp4", "audio/mp4"), - "audio/mpeg" => ("mp3", "audio/mpeg"), - "audio/mpga" => ("mp3", "audio/mpeg"), - "audio/m4a" => ("m4a", "audio/m4a"), - "audio/wav" => ("wav", "audio/wav"), - "audio/x-wav" => ("wav", "audio/wav"), - _ => return Err(StatusCode::UNSUPPORTED_MEDIA_TYPE), - }; - // Create multipart form for ElevenLabs API let part = reqwest::multipart::Part::bytes(audio_bytes) .file_name(format!("audio.{}", file_extension)) diff --git a/crates/goose/src/providers/formats/databricks.rs b/crates/goose/src/providers/formats/databricks.rs index fad832a8..eb0db413 100644 --- a/crates/goose/src/providers/formats/databricks.rs +++ b/crates/goose/src/providers/formats/databricks.rs @@ -838,7 +838,7 @@ mod tests { 0x0D, 0x0A, 0x1A, 0x0A, // PNG header 0x00, 0x00, 0x00, 0x0D, // Rest of fake PNG data ]; - std::fs::write(&png_path, &png_data)?; + std::fs::write(&png_path, png_data)?; let png_path_str = png_path.to_str().unwrap(); // Create message with image path diff --git a/crates/goose/src/providers/formats/openai.rs b/crates/goose/src/providers/formats/openai.rs index 662456a5..fc7de71c 100644 --- a/crates/goose/src/providers/formats/openai.rs +++ b/crates/goose/src/providers/formats/openai.rs @@ -716,7 +716,7 @@ mod tests { 0x0D, 0x0A, 0x1A, 0x0A, // PNG header 0x00, 0x00, 0x00, 0x0D, // Rest of fake PNG data ]; - std::fs::write(&png_path, &png_data)?; + std::fs::write(&png_path, png_data)?; let png_path_str = png_path.to_str().unwrap(); // Create message with image path diff --git a/crates/mcp-client/examples/integration_test.rs b/crates/mcp-client/examples/integration_test.rs index 1cc0dc12..9d8909ea 100644 --- a/crates/mcp-client/examples/integration_test.rs +++ b/crates/mcp-client/examples/integration_test.rs @@ -24,7 +24,7 @@ async fn main() -> Result<()> { // Test broken transport match test_transport(broken_stdio_transport().await?).await { - Ok(_) => assert!(false, "Expected an error but got success"), + Ok(_) => panic!("Expected an error but got success"), Err(e) => { assert!(e .to_string()