use std::sync::Arc;
use agent_client_protocol as acp;
use super::ZephAcpAgentState;
impl ZephAcpAgentState {
pub(crate) fn handle_lsp_publish_diagnostics(&self, params: &str) {
#[derive(serde::Deserialize)]
struct PublishDiagnosticsParams {
uri: String,
#[serde(default)]
diagnostics: Vec<crate::lsp::LspDiagnostic>,
}
match serde_json::from_str::<PublishDiagnosticsParams>(params) {
Ok(p) => {
let max = self.lsp_config.max_diagnostics_per_file;
let mut diags = p.diagnostics;
diags.truncate(max);
tracing::debug!(
uri = %p.uri,
count = diags.len(),
"lsp/publishDiagnostics: cached"
);
self.diagnostics_cache.write().update(p.uri, diags);
}
Err(e) => {
tracing::warn!(error = %e, "lsp/publishDiagnostics: failed to parse params");
}
}
}
#[allow(clippy::unused_async)]
pub(crate) async fn handle_lsp_did_save(
&self,
params: &str,
cx: &acp::ConnectionTo<acp::Client>,
) {
#[derive(serde::Deserialize)]
struct DidSaveParams {
uri: String,
}
if !self.lsp_config.auto_diagnostics_on_save {
return;
}
let uri = match serde_json::from_str::<DidSaveParams>(params) {
Ok(p) => p.uri,
Err(e) => {
tracing::warn!(error = %e, "lsp/didSave: failed to parse params");
return;
}
};
let params_json = serde_json::json!({ "uri": &uri });
let raw = match serde_json::value::to_raw_value(¶ms_json) {
Ok(r) => r,
Err(e) => {
tracing::warn!(error = %e, "lsp/didSave: failed to serialize params");
return;
}
};
let params_value =
serde_json::from_str::<serde_json::Value>(raw.get()).unwrap_or(serde_json::Value::Null);
let req = acp::UntypedMessage::new("lsp/diagnostics", params_value).unwrap_or_else(|_| {
acp::UntypedMessage {
method: "lsp/diagnostics".to_owned(),
params: serde_json::Value::Null,
}
});
let timeout = std::time::Duration::from_secs(self.lsp_config.request_timeout_secs);
let diagnostics_cache = Arc::clone(&self.diagnostics_cache);
let max = self.lsp_config.max_diagnostics_per_file;
let cx_inner = cx.clone();
let uri_clone = uri.clone();
cx.spawn(async move {
match tokio::time::timeout(timeout, cx_inner.send_request(req).block_task()).await {
Ok(Ok(resp)) => {
match serde_json::from_value::<Vec<crate::lsp::LspDiagnostic>>(resp) {
Ok(mut diags) => {
diags.truncate(max);
tracing::debug!(
uri = %uri_clone,
count = diags.len(),
"lsp/didSave: fetched diagnostics"
);
diagnostics_cache.write().update(uri_clone, diags);
}
Err(e) => {
tracing::warn!(error = %e, "lsp/didSave: failed to parse diagnostics response");
}
}
}
Ok(Err(e)) => {
tracing::warn!(error = %e, "lsp/didSave: diagnostics request failed");
}
Err(_) => {
tracing::warn!(uri = %uri_clone, "lsp/didSave: diagnostics request timed out");
}
}
Ok(())
}).ok();
}
}