feat: long-running session improvements

- Hang fix: 120s timeout on compression LLM call + raw_stream
  channel-close handling (None => break instead of spinning)
- Supervisor effective active count: stop counting finished
  JoinHandles as occupying capacity slots
- Universal tool result size cap: truncate_if_needed() on
  ToolResult, applied in eval_tool_calls() after escalation block;
  configurable via max_tool_result_chars in AppConfig/AgentConfig
- Windowed compression: compression_keep_last config param keeps
  the N most recent messages visible after compression
- Fix pre-existing flaky test: add #[serial] to
  handle_list_available_unrestricted_when_no_whitelist so it does
  not race with TestConfigDirGuard-based tests that temporarily
  populate the agents data dir
This commit is contained in:
2026-07-23 12:25:54 -06:00
parent d51bdd3086
commit 54c5079cb7
9 changed files with 118 additions and 19 deletions
+12 -2
View File
@@ -3941,7 +3941,12 @@ impl RequestContext {
.clone()
.unwrap_or_else(|| SUMMARIZATION_PROMPT.into());
let input = Input::from_str(self, &prompt, None)?;
let summary = input.fetch_chat_text().await?;
let summary = tokio::time::timeout(
std::time::Duration::from_secs(120),
input.fetch_chat_text(),
)
.await
.map_err(|_| anyhow::anyhow!("Compression LLM call timed out after 120 s"))??;
let summary_context_prompt = self
.app
.config
@@ -3958,8 +3963,13 @@ impl RequestContext {
String::new()
};
let keep_last = self
.agent
.as_ref()
.and_then(|a| a.compression_keep_last())
.unwrap_or(self.app.config.compression_keep_last);
if let Some(session) = self.session.as_mut() {
session.compress(format!("{todo_prefix}{summary_context_prompt}{summary}"));
session.compress(format!("{todo_prefix}{summary_context_prompt}{summary}"), keep_last);
}
self.discontinuous_last_message();
Ok(())