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:
Ryan Ward
2026-05-21 11:59:37 -05:00
co-authored by Claude Opus 4.6
parent eaa2ddc75e
commit 6f54e2cb30
229 changed files with 2506 additions and 2634 deletions
+2 -2
View File
@@ -6,7 +6,7 @@ use galaxy_editor::{
search::{SearchEvent, Searcher},
};
use galaxyui::{
accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole},
accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole},
elements::{
Border, ChildAnchor, Clipped, ConstrainedBox, Container, CornerRadius, CrossAxisAlignment,
Empty, Flex, MouseStateHandle, OffsetPositioning, ParentElement, PositionedElementAnchor,
@@ -565,7 +565,7 @@ impl TypedActionView for FindBar {
};
Some(AccessibilityContent::new_without_help(
text,
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
.into()
}
+3 -3
View File
@@ -2,7 +2,7 @@ use base64::{prelude::BASE64_STANDARD, Engine as _};
use std::{any::Any, borrow::Cow, collections::HashMap, ops::Range, time::Duration};
use galaxyui::{
accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole},
accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole},
clipboard::ClipboardContent,
AppContext, Entity, ModelAsRef, ModelContext, ModelHandle, SingletonEntity, WindowId,
};
@@ -1289,7 +1289,7 @@ impl NotebooksEditorModel {
if let Some(command) = child_model.executable_command(ctx) {
ctx.emit_a11y_content(AccessibilityContent::new_without_help(
format!("Selected workflow: {command}"),
WarpA11yRole::TextareaRole,
GalaxyA11yRole::TextareaRole,
));
}
@@ -1650,7 +1650,7 @@ impl NotebooksEditorModel {
let text = format!("{style:?} {action}");
ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
text,
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
+3 -3
View File
@@ -10,7 +10,7 @@ use galaxy_editor::{
render::model::RenderState,
};
use galaxyui::{
accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole},
accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole},
elements::{
AnchorPair, Border, ConstrainedBox, Container, CornerRadius, DropShadow, Flex,
MainAxisSize, MouseStateHandle, OffsetPositioning, OffsetType, ParentElement, Point,
@@ -447,12 +447,12 @@ impl TypedActionView for Omnibar {
OmnibarAction::ConvertBlock(style) => {
ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
format!("Convert to {}", BlockType::from(style).label()),
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
OmnibarAction::OpenLinkEditor => ActionAccessibilityContent::from_debug(),
OmnibarAction::UnstyleLink => ActionAccessibilityContent::Custom(
AccessibilityContent::new_without_help("Remove link", WarpA11yRole::UserAction),
AccessibilityContent::new_without_help("Remove link", GalaxyA11yRole::UserAction),
),
}
}
+26 -26
View File
@@ -28,7 +28,7 @@ use string_offset::CharOffset;
use galaxy_util::{path::LineAndColumnArg, user_input::UserInput};
use galaxyui::{
accessibility::{AccessibilityContent, ActionAccessibilityContent, WarpA11yRole},
accessibility::{AccessibilityContent, ActionAccessibilityContent, GalaxyA11yRole},
assets::asset_cache::{AssetCache, AssetHandle, AssetState},
clipboard::ClipboardContent,
elements::{
@@ -2440,7 +2440,7 @@ impl RichTextEditorView {
if show_open_in_warp {
let path_for_warp = path.clone();
links.push(TooltipLink {
text: "Open in Warp".to_string(),
text: "Open in Galaxy".to_string(),
on_click: Box::new(move |ctx: &mut EventContext| {
ctx.dispatch_typed_action(EditorViewAction::OpenFile {
path: path_for_warp.clone(),
@@ -3015,13 +3015,13 @@ impl TypedActionView for RichTextEditorView {
EditorViewAction::UserTyped(text) => {
ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
text.clone().into_inner(),
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
EditorViewAction::Paste | EditorViewAction::MiddleClickPaste => {
ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
format!("Pasting: {}", ctx.clipboard().read().plain_text),
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
EditorViewAction::Enter
@@ -3034,21 +3034,21 @@ impl TypedActionView for RichTextEditorView {
| EditorViewAction::Unindent
| EditorViewAction::Tab => ActionAccessibilityContent::from_debug(),
EditorViewAction::ShiftTab => ActionAccessibilityContent::Custom(
AccessibilityContent::new_without_help("Shift-tab", WarpA11yRole::UserAction),
AccessibilityContent::new_without_help("Shift-tab", GalaxyA11yRole::UserAction),
),
EditorViewAction::EditLink | EditorViewAction::CreateOrEditLink => {
ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
"Edit Link",
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
EditorViewAction::CopyLink => ActionAccessibilityContent::Custom(
AccessibilityContent::new_without_help("Copy Link", WarpA11yRole::UserAction),
AccessibilityContent::new_without_help("Copy Link", GalaxyA11yRole::UserAction),
),
EditorViewAction::OpenTooltipLink(link) => {
ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
format!("Open link: {}", **link),
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
EditorViewAction::SecondaryLinkAction(link) => {
@@ -3058,72 +3058,72 @@ impl TypedActionView for RichTextEditorView {
);
ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
content,
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
EditorViewAction::DeleteLineLeft => {
ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
"Delete line left",
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
EditorViewAction::DeleteLineRight => {
ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
"Delete line right",
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
EditorViewAction::DeleteWordLeft => {
ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
"Delete word left",
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
EditorViewAction::DeleteWordRight => {
ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
"Delete word right",
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
EditorViewAction::CutLineLeft => ActionAccessibilityContent::Custom(
AccessibilityContent::new_without_help("Cut line left", WarpA11yRole::UserAction),
AccessibilityContent::new_without_help("Cut line left", GalaxyA11yRole::UserAction),
),
EditorViewAction::CutLineRight => ActionAccessibilityContent::Custom(
AccessibilityContent::new_without_help("Cut line right", WarpA11yRole::UserAction),
AccessibilityContent::new_without_help("Cut line right", GalaxyA11yRole::UserAction),
),
EditorViewAction::CutWordLeft => ActionAccessibilityContent::Custom(
AccessibilityContent::new_without_help("Cut word left", WarpA11yRole::UserAction),
AccessibilityContent::new_without_help("Cut word left", GalaxyA11yRole::UserAction),
),
EditorViewAction::CutWordRight => ActionAccessibilityContent::Custom(
AccessibilityContent::new_without_help("Cut word right", WarpA11yRole::UserAction),
AccessibilityContent::new_without_help("Cut word right", GalaxyA11yRole::UserAction),
),
EditorViewAction::ShowCharacterPalette => {
ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
"Show character palette",
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
EditorViewAction::ShowFindBar => ActionAccessibilityContent::Custom(
AccessibilityContent::new_without_help("Show find bar", WarpA11yRole::UserAction),
AccessibilityContent::new_without_help("Show find bar", GalaxyA11yRole::UserAction),
),
EditorViewAction::OpenBlockInsertionMenu => {
ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
"Open block-insertion menu",
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
EditorViewAction::OpenEmbeddedObjectSearch => {
ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
"Open embedded object search menu",
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
EditorViewAction::InsertBlock(block_type) => {
ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
format!("Insert {} block", BlockType::from(block_type).label()),
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
EditorViewAction::Bold => self
@@ -3150,23 +3150,23 @@ impl TypedActionView for RichTextEditorView {
ActionAccessibilityContent::Custom(AccessibilityContent::new(
"De-select command",
"Switch from selecting commands to selecting text",
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
EditorViewAction::CodeBlockTypeSelectedAtOffset {
code_block_type, ..
} => ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
format!("Change code block language to {code_block_type}"),
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
)),
EditorViewAction::CopyTextToClipboard { .. } => ActionAccessibilityContent::Custom(
AccessibilityContent::new_without_help("Copy code block", WarpA11yRole::UserAction),
AccessibilityContent::new_without_help("Copy code block", GalaxyA11yRole::UserAction),
),
EditorViewAction::ToggleTaskList(_) => {
// TODO(ben): Is it useful to include the text and/or on/off state here?
ActionAccessibilityContent::Custom(AccessibilityContent::new_without_help(
"Toggle task list",
WarpA11yRole::UserAction,
GalaxyA11yRole::UserAction,
))
}
EditorViewAction::Delete
+2 -2
View File
@@ -8,7 +8,7 @@ use galaxy_util::path::user_friendly_path;
#[cfg(feature = "local_fs")]
use galaxyui::clipboard::ClipboardContent;
use galaxyui::{
accessibility::{AccessibilityContent, WarpA11yRole},
accessibility::{AccessibilityContent, GalaxyA11yRole},
elements::{
Align, Container, CrossAxisAlignment, DispatchEventResult, Empty, EventHandler, Flex,
MainAxisAlignment, MainAxisSize, MouseStateHandle, ParentElement, SavePosition, Shrinkable,
@@ -810,7 +810,7 @@ impl View for FileNotebookView {
fn accessibility_contents(&self, _ctx: &AppContext) -> Option<AccessibilityContent> {
Some(AccessibilityContent::new_without_help(
format!("{} notebook", self.title()),
WarpA11yRole::TextRole,
GalaxyA11yRole::TextRole,
))
}
+4 -4
View File
@@ -21,7 +21,7 @@ use crate::util::file::external_editor::EditorSettings;
#[cfg(feature = "local_fs")]
use crate::util::openable_file_type::{is_supported_image_file, resolve_file_target, FileTarget};
use crate::{
drive::OpenWarpDriveObjectArgs,
drive::OpenGalaxyDriveObjectArgs,
terminal::model::session::Session,
uri::parse_url_paths::{get_item_data_from_warp_link, WarpWebLink},
workspace::ActiveSession,
@@ -266,7 +266,7 @@ impl NotebookLinks {
match link {
LinkTarget::Url(url) => {
if let Some(WarpWebLink::DriveObject(args)) = get_item_data_from_warp_link(&url) {
return ctx.emit(LinkEvent::OpenWarpDriveLink {
return ctx.emit(LinkEvent::OpenGalaxyDriveLink {
open_warp_drive_args: *args,
});
}
@@ -409,8 +409,8 @@ pub enum LinkEvent {
path: PathBuf,
session: Arc<Session>,
},
OpenWarpDriveLink {
open_warp_drive_args: OpenWarpDriveObjectArgs,
OpenGalaxyDriveLink {
open_warp_drive_args: OpenGalaxyDriveObjectArgs,
},
/// This event tells the parent pane group to open a new terminal session in the given
/// directory.
+2 -2
View File
@@ -13,7 +13,7 @@ use crate::{
model::persistence::{CloudModel, CloudModelEvent},
Owner,
},
drive::OpenWarpDriveObjectSettings,
drive::OpenGalaxyDriveObjectSettings,
pane_group::{NotebookPane, PaneContent},
safe_debug, safe_warn,
server::{
@@ -182,7 +182,7 @@ impl NotebookManager {
pub fn create_pane(
&mut self,
source: &NotebookSource,
settings: &OpenWarpDriveObjectSettings,
settings: &OpenGalaxyDriveObjectSettings,
window_id: WindowId,
ctx: &mut ModelContext<Self>,
) -> NotebookPane {
+7 -7
View File
@@ -16,7 +16,7 @@ use galaxy_editor::{
model::{CoreEditorModel, RichTextEditorModel},
};
use galaxyui::{
accessibility::{AccessibilityContent, WarpA11yRole},
accessibility::{AccessibilityContent, GalaxyA11yRole},
clipboard::ClipboardContent,
elements::{
Align, Clipped, ConstrainedBox, Container, CrossAxisAlignment, DispatchEventResult, Empty,
@@ -52,7 +52,7 @@ use crate::{
drive::{
drive_helpers::has_feature_gated_anonymous_user_reached_notebook_limit,
export::ExportManager, items::WarpDriveItemId, sharing::ShareableObject,
CloudObjectTypeAndId, OpenWarpDriveObjectSettings,
CloudObjectTypeAndId, OpenGalaxyDriveObjectSettings,
},
editor::{
EditOrigin, EditorView, Event as EditorEvent, InteractionState,
@@ -1522,7 +1522,7 @@ impl NotebookView {
pub fn wait_for_initial_load_then_load(
&mut self,
notebook_id: SyncId,
settings: &OpenWarpDriveObjectSettings,
settings: &OpenGalaxyDriveObjectSettings,
window_id: WindowId,
ctx: &mut ViewContext<Self>,
) {
@@ -1561,7 +1561,7 @@ impl NotebookView {
fn fetch_and_load_notebook(
&mut self,
notebook_id: ServerId,
settings: &OpenWarpDriveObjectSettings,
settings: &OpenGalaxyDriveObjectSettings,
window_id: WindowId,
ctx: &mut ViewContext<Self>,
) {
@@ -1605,7 +1605,7 @@ impl NotebookView {
pub fn load(
&mut self,
notebook: CloudNotebook,
settings: &OpenWarpDriveObjectSettings,
settings: &OpenGalaxyDriveObjectSettings,
ctx: &mut ViewContext<Self>,
) -> SpawnedFutureHandle {
self.set_title(&notebook.model().title, ctx);
@@ -1868,7 +1868,7 @@ impl NotebookView {
if let Some(notebook) = CloudModel::as_ref(ctx).get_notebook(&id) {
self.load(
notebook.clone(),
&OpenWarpDriveObjectSettings::default(),
&OpenGalaxyDriveObjectSettings::default(),
ctx,
);
}
@@ -2185,7 +2185,7 @@ impl View for NotebookView {
fn accessibility_contents(&self, ctx: &AppContext) -> Option<AccessibilityContent> {
Some(AccessibilityContent::new_without_help(
format!("{} notebook", self.title(ctx)),
WarpA11yRole::TextRole,
GalaxyA11yRole::TextRole,
))
}
+2 -2
View File
@@ -25,7 +25,7 @@ use crate::{
},
Owner, Revision, ServerCloudObject, ServerMetadata, ServerNotebook, ServerPermissions,
},
drive::OpenWarpDriveObjectSettings,
drive::OpenGalaxyDriveObjectSettings,
editor::{DisplayPoint, EditorAction, InteractionState, SelectAction},
network::NetworkStatus,
notebooks::{
@@ -140,7 +140,7 @@ fn open_notebook(
notebook: CloudNotebook,
) -> BoxFuture<'static, ()> {
let load_future = handle.update(app, |view, ctx| {
view.load(notebook, &OpenWarpDriveObjectSettings::default(), ctx)
view.load(notebook, &OpenGalaxyDriveObjectSettings::default(), ctx)
});
app.update(|ctx| ctx.await_spawned_future(load_future.future_id()))
}