diff --git a/crates/goose/src/providers/claude_code.rs b/crates/goose/src/providers/claude_code.rs index 73e5205ad8..72a1de7b6d 100644 --- a/crates/goose/src/providers/claude_code.rs +++ b/crates/goose/src/providers/claude_code.rs @@ -63,7 +63,9 @@ impl CliProcess { "request_id": request_id, "request": {"subtype": "set_model", "model": model} }); - let mut req_str = serde_json::to_string(&req).unwrap(); + let mut req_str = serde_json::to_string(&req).map_err(|e| { + ProviderError::RequestFailed(format!("Failed to serialize set_model request: {e}")) + })?; req_str.push('\n'); self.stdin .write_all(req_str.as_bytes()) @@ -89,6 +91,14 @@ impl CliProcess { } if let Ok(parsed) = serde_json::from_str::(trimmed) { if parsed.get("type").and_then(|t| t.as_str()) == Some("control_response") { + // Skip responses that don't match our request_id + if parsed + .pointer("/response/request_id") + .and_then(|id| id.as_str()) + != Some(request_id.as_str()) + { + continue; + } let success = parsed.pointer("/response/subtype").and_then(|s| s.as_str()) == Some("success"); @@ -639,7 +649,9 @@ impl Provider for ClaudeCodeProvider { "request_id": "model_list", "request": {"subtype": "initialize"} }); - let mut request_str = serde_json::to_string(&request).unwrap(); + let mut request_str = serde_json::to_string(&request).map_err(|e| { + ProviderError::RequestFailed(format!("Failed to serialize initialize request: {e}")) + })?; request_str.push('\n'); stdin.write_all(request_str.as_bytes()).await.map_err(|e| { ProviderError::RequestFailed(format!("Failed to write initialize request: {e}")) @@ -670,7 +682,7 @@ impl Provider for ClaudeCodeProvider { } } - let _ = child.start_kill(); + let _ = child.kill().await; Ok(parse_models_from_lines(&lines)) } diff --git a/crates/goose/tests/providers.rs b/crates/goose/tests/providers.rs index 9feea377fb..9eb65818f5 100644 --- a/crates/goose/tests/providers.rs +++ b/crates/goose/tests/providers.rs @@ -275,8 +275,6 @@ impl ProviderTester { } async fn test_model_switch(&self, session_id: &str) -> Result<()> { - // The process is already running with the default model from test_basic_response. - // Switch to model_switch_name and call complete_with_model to exercise send_set_model. let default = &self.provider.get_model_config().model_name; let alt = self .model_switch_name @@ -297,7 +295,7 @@ impl ProviderTester { .await?; assert!( - matches!(response.content[0], MessageContent::Text(_)), + matches!(response.content.first(), Some(MessageContent::Text(_))), "Expected text response after model switch" ); println!(