Compaction overhaul (#5186)

Co-authored-by: Douwe Osinga <douwe@squareup.com>
Co-authored-by: David Katz <dkatz@squareup.com>
Co-authored-by: Alex Hancock <alexhancock@block.xyz>
This commit is contained in:
Douwe Osinga
2025-10-15 18:39:12 -04:00
committed by GitHub
parent ef9e68f2c6
commit 7c1f5dcb2f
56 changed files with 3069 additions and 4465 deletions
@@ -90,10 +90,7 @@ pub fn format_messages(messages: &[Message]) -> Vec<Value> {
MessageContent::ToolConfirmationRequest(_tool_confirmation_request) => {
// Skip tool confirmation requests
}
MessageContent::ContextLengthExceeded(_) => {
// Skip
}
MessageContent::SummarizationRequested(_) => {
MessageContent::ConversationCompacted(_) => {
// Skip
}
MessageContent::Thinking(thinking) => {
@@ -48,10 +48,7 @@ pub fn to_bedrock_message_content(content: &MessageContent) -> Result<bedrock::C
// Redacted thinking blocks are not supported in Bedrock - skip
bedrock::ContentBlock::Text("".to_string())
}
MessageContent::ContextLengthExceeded(_) => {
bail!("ContextLengthExceeded should not get passed to the provider")
}
MessageContent::SummarizationRequested(_) => {
MessageContent::ConversationCompacted(_) => {
bail!("SummarizationRequested should not get passed to the provider")
}
MessageContent::ToolRequest(tool_req) => {
@@ -127,10 +127,7 @@ fn format_messages(messages: &[Message], image_format: &ImageFormat) -> Vec<Data
}
}
}
MessageContent::ContextLengthExceeded(_) => {
continue;
}
MessageContent::SummarizationRequested(_) => {
MessageContent::ConversationCompacted(_) => {
continue;
}
MessageContent::ToolResponse(response) => {
+1 -4
View File
@@ -95,10 +95,7 @@ pub fn format_messages(messages: &[Message], image_format: &ImageFormat) -> Vec<
// Redacted thinking blocks are not directly used in OpenAI format
continue;
}
MessageContent::ContextLengthExceeded(_) => {
continue;
}
MessageContent::SummarizationRequested(_) => {
MessageContent::ConversationCompacted(_) => {
continue;
}
MessageContent::ToolRequest(request) => match &request.tool_call {
@@ -53,10 +53,7 @@ pub fn format_messages(messages: &[Message]) -> Vec<Value> {
MessageContent::ToolConfirmationRequest(_) => {
// Skip tool confirmation requests
}
MessageContent::ContextLengthExceeded(_) => {
// Skip
}
MessageContent::SummarizationRequested(_) => {
MessageContent::ConversationCompacted(_) => {
// Skip
}
MessageContent::Thinking(_thinking) => {
@@ -1,6 +1,6 @@
use crate::conversation::message::Message;
use crate::providers::base::ProviderUsage;
use crate::token_counter::create_async_token_counter;
use crate::token_counter::create_token_counter;
use anyhow::Result;
use rmcp::model::Tool;
@@ -17,7 +17,7 @@ pub async fn ensure_usage_tokens(
return Ok(());
}
let token_counter = create_async_token_counter()
let token_counter = create_token_counter()
.await
.map_err(|e| anyhow::anyhow!("Failed to create token counter: {}", e))?;
+28 -10
View File
@@ -1,6 +1,8 @@
use super::base::Usage;
use super::errors::GoogleErrorCode;
use crate::config::paths::Paths;
use crate::model::ModelConfig;
use crate::providers::errors::{OpenAIError, ProviderError};
use anyhow::Result;
use base64::Engine;
use regex::Regex;
@@ -12,8 +14,6 @@ use std::io::Read;
use std::path::Path;
use std::time::Duration;
use crate::providers::errors::{OpenAIError, ProviderError};
#[derive(serde::Deserialize)]
struct OpenAIErrorResponse {
error: OpenAIError,
@@ -461,14 +461,32 @@ pub fn emit_debug_trace<T1, T2>(
T1: ?Sized + Serialize,
T2: ?Sized + Serialize,
{
tracing::debug!(
model_config = %serde_json::to_string_pretty(model_config).unwrap_or_default(),
input = %serde_json::to_string_pretty(payload).unwrap_or_default(),
output = %serde_json::to_string_pretty(response).unwrap_or_default(),
input_tokens = ?usage.input_tokens.unwrap_or_default(),
output_tokens = ?usage.output_tokens.unwrap_or_default(),
total_tokens = ?usage.total_tokens.unwrap_or_default(),
);
let logs_dir = Paths::in_state_dir("logs");
if let Err(e) = std::fs::create_dir_all(&logs_dir) {
tracing::warn!("Failed to create logs directory: {}", e);
return;
}
let log_path = |i| logs_dir.join(format!("llm_request.{}.json", i));
for i in (0..4).rev() {
let _ = std::fs::rename(log_path(i), log_path(i + 1));
}
let data = serde_json::json!({
"model_config": model_config,
"input": payload,
"output": response,
"usage": usage,
});
if let Err(e) = std::fs::write(
log_path(0),
serde_json::to_string_pretty(&data).unwrap_or_default(),
) {
tracing::warn!("Failed to write log file: {}", e);
}
}
/// Safely parse a JSON string that may contain doubly-encoded or malformed JSON.