Fix Local Agent Execution And Auth Checks

- Gate server requests on available credentials
- Run local child agents directly without a parent run ID
- Include command IDs in Bedrock context and recognize transfer tools
This commit is contained in:
2026-07-28 10:43:59 -05:00
parent 87e0c83e9e
commit a078287f4b
35 changed files with 1078 additions and 237 deletions
+31 -29
View File
@@ -7,10 +7,10 @@ use galaxy_graphql::billing::AddonCreditsOption;
use galaxy_graphql::error::BudgetExceededError;
use galaxyui::elements::{
Align, Border, ChildAnchor, ChildView, ConstrainedBox, Container, CornerRadius,
CrossAxisAlignment, DropShadow, Empty, Expanded, Flex, FormattedTextElement, HighlightedHyperlink,
Hoverable, Icon as WarpUiIcon, MainAxisAlignment, MainAxisSize, MouseStateHandle,
OffsetPositioning, ParentAnchor, ParentElement as _, ParentOffsetBounds, Radius, Shrinkable,
SizeConstraintCondition, SizeConstraintSwitch, Stack, Text,
CrossAxisAlignment, DropShadow, Empty, Expanded, Flex, FormattedTextElement,
HighlightedHyperlink, Hoverable, Icon as WarpUiIcon, MainAxisAlignment, MainAxisSize,
MouseStateHandle, OffsetPositioning, ParentAnchor, ParentElement as _, ParentOffsetBounds,
Radius, Shrinkable, SizeConstraintCondition, SizeConstraintSwitch, Stack, Text,
};
use galaxyui::fonts::Weight;
use galaxyui::ui_components::button::ButtonVariant;
@@ -339,33 +339,35 @@ impl BuyCreditsBanner {
};
if discount_percent > 0 {
MenuItemFields::new_with_custom_label(
Arc::new(enclose!((primary_text) move |is_selected, is_hovered, appearance, _| {
let text_color = appearance.theme().main_text_color(
if is_selected || is_hovered {
appearance.theme().accent()
} else {
appearance.theme().surface_1()
}
);
let main_text = Text::new_inline(
primary_text.clone(),
appearance.ui_font_family(),
appearance.ui_font_size(),
)
.with_color(text_color.into())
.finish();
Arc::new(
enclose!((primary_text) move |is_selected, is_hovered, appearance, _| {
let text_color = appearance.theme().main_text_color(
if is_selected || is_hovered {
appearance.theme().accent()
} else {
appearance.theme().surface_1()
}
);
let main_text = Text::new_inline(
primary_text.clone(),
appearance.ui_font_family(),
appearance.ui_font_size(),
)
.with_color(text_color.into())
.finish();
let discount_badge = Empty::new().finish();
let discount_badge = Empty::new().finish();
Flex::row()
.with_cross_axis_alignment(CrossAxisAlignment::Center)
.with_main_axis_alignment(MainAxisAlignment::SpaceBetween)
.with_main_axis_size(MainAxisSize::Max)
.with_child(main_text)
.with_child(discount_badge)
.finish()
})),
Some(primary_text)
Flex::row()
.with_cross_axis_alignment(CrossAxisAlignment::Center)
.with_main_axis_alignment(MainAxisAlignment::SpaceBetween)
.with_main_axis_size(MainAxisSize::Max)
.with_child(main_text)
.with_child(discount_badge)
.finish()
}),
),
Some(primary_text),
)
.with_on_select_action(DropdownAction::select_action_and_close(
Action::SelectDenomination(index),
+26 -24
View File
@@ -165,32 +165,34 @@ impl EnableAutoReloadModalBody {
};
if discount_percent > 0 {
MenuItemFields::new_with_custom_label(
Arc::new(enclose!((primary_text) move |is_selected, is_hovered, appearance, _| {
let text_color = appearance.theme().main_text_color(
if is_selected || is_hovered {
appearance.theme().accent()
} else {
appearance.theme().surface_1()
}
);
let main_text = Text::new_inline(
primary_text.clone(),
appearance.ui_font_family(),
appearance.ui_font_size(),
)
.with_color(text_color.into())
.finish();
Arc::new(
enclose!((primary_text) move |is_selected, is_hovered, appearance, _| {
let text_color = appearance.theme().main_text_color(
if is_selected || is_hovered {
appearance.theme().accent()
} else {
appearance.theme().surface_1()
}
);
let main_text = Text::new_inline(
primary_text.clone(),
appearance.ui_font_family(),
appearance.ui_font_size(),
)
.with_color(text_color.into())
.finish();
let discount_badge = Empty::new().finish();
let discount_badge = Empty::new().finish();
Flex::row()
.with_cross_axis_alignment(CrossAxisAlignment::Center)
.with_main_axis_alignment(MainAxisAlignment::SpaceBetween)
.with_main_axis_size(MainAxisSize::Max)
.with_child(main_text)
.with_child(discount_badge)
.finish()
})),
Flex::row()
.with_cross_axis_alignment(CrossAxisAlignment::Center)
.with_main_axis_alignment(MainAxisAlignment::SpaceBetween)
.with_main_axis_size(MainAxisSize::Max)
.with_child(main_text)
.with_child(discount_badge)
.finish()
}),
),
Some(primary_text),
)
.with_on_select_action(DropdownAction::select_action_and_close(
+3 -8
View File
@@ -1217,9 +1217,7 @@ impl Input {
"ToolResult(id={tool_use_id}, err={is_error}): {truncated}"
)
}
crate::ai::bedrock::convert::MessageContent::MultiPart(
parts,
) => {
crate::ai::bedrock::convert::MessageContent::MultiPart(parts) => {
format!("MultiPart({} parts)", parts.len())
}
};
@@ -1270,16 +1268,13 @@ impl Input {
}
output.push('\n');
output.push_str(&format!(
"=== MESSAGE HISTORY ({msg_count} messages) ===\n"
));
output.push_str(&format!("=== MESSAGE HISTORY ({msg_count} messages) ===\n"));
for line in &messages {
output.push_str(line);
output.push('\n');
}
ctx.clipboard()
.write(ClipboardContent::plain_text(output));
ctx.clipboard().write(ClipboardContent::plain_text(output));
let window_id = ctx.window_id();
ToastStack::handle(ctx).update(ctx, |toast_stack, ctx| {
+7 -8
View File
@@ -219,14 +219,13 @@ impl PtySpawner {
>,
is_crash_reporting_enabled: bool,
) -> Result<(PtySpawnResult, Box<dyn PtyHandle>)> {
let pty_spawn_info =
invoke_without_crash_reporting(move || {
local_tty::spawn(
options,
#[cfg(windows)]
event_loop_tx,
)
})?;
let pty_spawn_info = invoke_without_crash_reporting(move || {
local_tty::spawn(
options,
#[cfg(windows)]
event_loop_tx,
)
})?;
let direct_pty_handle = Box::new(DirectPtyHandle {
child: pty_spawn_info.child,
});