fix(claude-code): defensive coding improvements for model switching (#7131)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
@@ -63,7 +63,9 @@ impl CliProcess {
|
|||||||
"request_id": request_id,
|
"request_id": request_id,
|
||||||
"request": {"subtype": "set_model", "model": model}
|
"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');
|
req_str.push('\n');
|
||||||
self.stdin
|
self.stdin
|
||||||
.write_all(req_str.as_bytes())
|
.write_all(req_str.as_bytes())
|
||||||
@@ -89,6 +91,14 @@ impl CliProcess {
|
|||||||
}
|
}
|
||||||
if let Ok(parsed) = serde_json::from_str::<Value>(trimmed) {
|
if let Ok(parsed) = serde_json::from_str::<Value>(trimmed) {
|
||||||
if parsed.get("type").and_then(|t| t.as_str()) == Some("control_response") {
|
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 =
|
let success =
|
||||||
parsed.pointer("/response/subtype").and_then(|s| s.as_str())
|
parsed.pointer("/response/subtype").and_then(|s| s.as_str())
|
||||||
== Some("success");
|
== Some("success");
|
||||||
@@ -639,7 +649,9 @@ impl Provider for ClaudeCodeProvider {
|
|||||||
"request_id": "model_list",
|
"request_id": "model_list",
|
||||||
"request": {"subtype": "initialize"}
|
"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');
|
request_str.push('\n');
|
||||||
stdin.write_all(request_str.as_bytes()).await.map_err(|e| {
|
stdin.write_all(request_str.as_bytes()).await.map_err(|e| {
|
||||||
ProviderError::RequestFailed(format!("Failed to write initialize request: {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))
|
Ok(parse_models_from_lines(&lines))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -275,8 +275,6 @@ impl ProviderTester {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn test_model_switch(&self, session_id: &str) -> Result<()> {
|
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 default = &self.provider.get_model_config().model_name;
|
||||||
let alt = self
|
let alt = self
|
||||||
.model_switch_name
|
.model_switch_name
|
||||||
@@ -297,7 +295,7 @@ impl ProviderTester {
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
matches!(response.content[0], MessageContent::Text(_)),
|
matches!(response.content.first(), Some(MessageContent::Text(_))),
|
||||||
"Expected text response after model switch"
|
"Expected text response after model switch"
|
||||||
);
|
);
|
||||||
println!(
|
println!(
|
||||||
|
|||||||
Reference in New Issue
Block a user