make admin compact requests cancellable as well

This commit is contained in:
Chris Beck
2025-12-14 12:11:43 -07:00
parent e9daba0d7c
commit 4a1b1ecafb
3 changed files with 34 additions and 9 deletions
+20 -7
View File
@@ -175,7 +175,7 @@ impl ClaudeAssistant {
}; };
if can_compact { if can_compact {
self.do_compact(true).await; self.do_compact(true, None).await;
} else { } else {
self.drop_oldest_messages(); self.drop_oldest_messages();
} }
@@ -216,7 +216,9 @@ impl ClaudeAssistant {
} }
/// Perform compaction by summarizing messages and storing the result. /// Perform compaction by summarizing messages and storing the result.
async fn do_compact(&mut self, is_automatic: bool) { ///
/// If `cancel` is provided, the operation can be interrupted.
async fn do_compact(&mut self, is_automatic: bool, cancel: Option<&CancellationToken>) {
if self.messages.is_empty() { if self.messages.is_empty() {
return; return;
} }
@@ -257,15 +259,26 @@ impl ClaudeAssistant {
tools: Vec::new(), tools: Vec::new(),
}; };
let result = self let http_fut = self
.client .client
.post(&self.config.claude_api_url) .post(&self.config.claude_api_url)
.header("x-api-key", &self.api_key) .header("x-api-key", &self.api_key)
.header("anthropic-version", ANTHROPIC_API_VERSION) .header("anthropic-version", ANTHROPIC_API_VERSION)
.header("content-type", "application/json") .header("content-type", "application/json")
.json(&request_body) .json(&request_body)
.send() .send();
.await;
let result = if let Some(cancel) = cancel {
tokio::select! {
result = http_fut => result,
_ = cancel.cancelled() => {
info!("Compaction cancelled");
return;
}
}
} else {
http_fut.await
};
match result { match result {
Ok(response) if response.status().is_success() => { Ok(response) if response.status().is_success() => {
@@ -469,9 +482,9 @@ impl Assistant for ClaudeAssistant {
Ok(self.handle_request(&cancel).await?) Ok(self.handle_request(&cancel).await?)
} }
async fn compact(&mut self) { async fn compact(&mut self, cancel: CancellationToken) {
// Manual compaction always runs (is_automatic = false) // Manual compaction always runs (is_automatic = false)
self.do_compact(false).await; self.do_compact(false, Some(&cancel)).await;
} }
fn debug_log(&mut self) { fn debug_log(&mut self) {
+3 -1
View File
@@ -25,7 +25,9 @@ pub trait Assistant: Send {
/// ///
/// This is called when the user explicitly requests compaction. /// This is called when the user explicitly requests compaction.
/// Automatic compaction is an internal implementation detail. /// Automatic compaction is an internal implementation detail.
async fn compact(&mut self); ///
/// The cancellation token can be used to interrupt the operation.
async fn compact(&mut self, cancel: CancellationToken);
/// Log the assistant's current state for debugging. /// Log the assistant's current state for debugging.
fn debug_log(&mut self); fn debug_log(&mut self);
+11 -1
View File
@@ -117,7 +117,17 @@ impl AssistantWorker {
false false
} }
Input::Compact => { Input::Compact => {
self.assistant.compact().await; let cancel_token = self.cancellation_token.child_token();
let mut compact_fut = self.assistant.compact(cancel_token.clone());
tokio::select! {
_ = &mut compact_fut => {},
_ = self.stop_rx.recv() => {
cancel_token.cancel();
compact_fut.await;
return true;
}
};
false false
} }
Input::Debug => { Input::Debug => {