v1.4.0: Auto-compact streaming, Bedrock summarization support, subagent orchestration, and Galaxy rebrand continuation
Major features: - Auto-compact: triggers conversation summarization when context window >= 85%, compacts Bedrock message history to a summary pair, and tracks live context tokens - Bedrock summarization: plumbs `is_summarization` flag through translator/client/response pipeline, handles SummarizeConversation input type, and marks `summarized` in metadata - Session restore: rebuilds bedrock_message_history from persisted task messages via newly-public `convert_proto_message`, preventing empty history on reconnect - Subagent orchestration: adds SubagentQuestion/Answer/CompletionSummary event types, parent-child question routing with depth limits, retry counting, and drain methods - Summarization UI: inline SummarizationView in AI blocks with progress/finished states Refactors: - Rename WarpTheme → GalaxyTheme across ~100 files (rebrand continuation) - Rename warp_home_config_dir → galaxy_home_config_dir and related path functions - Predefined rules: replace "System Defined Rule #N" with descriptive names (e.g. "Correctness Over Speed", "Never Guess") and add lookup helpers - Usage view: replace cumulative input/output token display with live context tokens, cache hit rate calculation, and separate cache read/write stats - Telemetry: remove verbose doc comments, simplify trait definitions - Facts view: simplify delete permission check (always allow local deletion) - Remove warp_managed_paths_watcher.rs (dead code) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
eaa2ddc75e
commit
6f54e2cb30
@@ -90,6 +90,7 @@ use crate::ai::blocklist::inline_action::aws_bedrock_credentials_error::{
|
||||
use crate::ai::blocklist::inline_action::search_codebase::{
|
||||
SearchCodebaseView, SearchCodebaseViewEvent,
|
||||
};
|
||||
use crate::ai::blocklist::inline_action::summarization::SummarizationView;
|
||||
use crate::ai::blocklist::inline_action::web_fetch::WebFetchView;
|
||||
use crate::ai::blocklist::inline_action::web_search::WebSearchView;
|
||||
use crate::ai::facts::{AIFact, AIMemory, CloudAIFactModel};
|
||||
@@ -830,6 +831,9 @@ pub struct AIBlock {
|
||||
/// Map from web fetch message IDs to their view handles.
|
||||
web_fetch_views: HashMap<MessageId, ViewHandle<WebFetchView>>,
|
||||
|
||||
/// Map from summarization message IDs to their view handles.
|
||||
summarization_views: HashMap<MessageId, ViewHandle<SummarizationView>>,
|
||||
|
||||
/// Map from todo list IDs to their states.
|
||||
todo_list_states: HashMap<MessageId, TodoListElementState>,
|
||||
|
||||
@@ -1340,6 +1344,7 @@ impl AIBlock {
|
||||
search_codebase_view: Default::default(),
|
||||
web_search_views: Default::default(),
|
||||
web_fetch_views: Default::default(),
|
||||
summarization_views: Default::default(),
|
||||
requested_commands_to_auto_collapse: Default::default(),
|
||||
review_changes_button,
|
||||
open_all_comments_button,
|
||||
@@ -1801,6 +1806,9 @@ impl AIBlock {
|
||||
self.handle_web_fetch_messages(&output.messages, ctx);
|
||||
}
|
||||
|
||||
self.handle_summarization_messages(&output.messages, ctx);
|
||||
self.maybe_create_summarization_view_from_input(ctx);
|
||||
|
||||
for action in output.actions() {
|
||||
let new_action_ids: HashSet<AIAgentActionId> =
|
||||
output.actions().map(|action| action.id.clone()).collect();
|
||||
@@ -3489,6 +3497,84 @@ impl AIBlock {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_summarization_messages(
|
||||
&mut self,
|
||||
messages: &[AIAgentOutputMessage],
|
||||
ctx: &mut ViewContext<Self>,
|
||||
) {
|
||||
use crate::ai::agent::SummarizationType;
|
||||
|
||||
for message in messages {
|
||||
let AIAgentOutputMessageType::Summarization {
|
||||
finished_duration,
|
||||
summarization_type,
|
||||
..
|
||||
} = &message.message
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if !matches!(summarization_type, SummarizationType::ConversationSummary) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(view) = self.summarization_views.get(&message.id) {
|
||||
if finished_duration.is_some() {
|
||||
view.update(ctx, |view, ctx| {
|
||||
view.mark_finished();
|
||||
ctx.notify();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
let is_finished = finished_duration.is_some();
|
||||
let view = ctx.add_view(|ctx| {
|
||||
let mut v = SummarizationView::new(ctx);
|
||||
if is_finished {
|
||||
v.mark_finished();
|
||||
}
|
||||
v
|
||||
});
|
||||
self.summarization_views.insert(message.id.clone(), view);
|
||||
ctx.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a SummarizationView when the exchange input is a SummarizeConversation.
|
||||
/// This handles the Bedrock path where no Summarization output message is emitted.
|
||||
fn maybe_create_summarization_view_from_input(&mut self, ctx: &mut ViewContext<Self>) {
|
||||
let is_summarize_input = self
|
||||
.model
|
||||
.inputs_to_render(ctx)
|
||||
.iter()
|
||||
.any(|i| matches!(i, AIAgentInput::SummarizeConversation { .. }));
|
||||
|
||||
if !is_summarize_input {
|
||||
return;
|
||||
}
|
||||
|
||||
let key = MessageId::new("__summarization_inline_view__".to_string());
|
||||
if self.summarization_views.contains_key(&key) {
|
||||
// Already created — check if we should mark it finished
|
||||
let is_complete = !self.model.status(ctx).is_streaming();
|
||||
if is_complete {
|
||||
if let Some(view) = self.summarization_views.get(&key) {
|
||||
view.update(ctx, |view, ctx| {
|
||||
if !view.is_finished {
|
||||
view.mark_finished();
|
||||
ctx.notify();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let view = ctx.add_view(|ctx| SummarizationView::new(ctx));
|
||||
self.summarization_views.insert(key, view);
|
||||
ctx.notify();
|
||||
}
|
||||
|
||||
/// Note this is called when the search codebase tool call definition finishes streaming, not when the search actually completes.
|
||||
fn handle_search_codebase_complete(
|
||||
&mut self,
|
||||
|
||||
Reference in New Issue
Block a user