mirror of
https://github.com/hanzoai/dev.git
synced 2026-10-25 03:32:32 +00:00
fix(tui/agents): show built-ins as available and skip install prompts
- mark built-in agents that resolve to the current binary as "available" and remove install hints in Agents UI - thread self-resolved status through overview rendering for consistent labeling in overlay and bottom pane - add regression test for available status copy Refs #429
This commit is contained in:
@@ -13,7 +13,7 @@ use super::BottomPane;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct AgentsOverviewView {
|
||||
agents: Vec<(String, bool /*enabled*/ , bool /*installed*/ , String /*command*/ )>,
|
||||
agents: Vec<(String, bool /*enabled*/ , bool /*installed*/ , bool /*self_resolved*/ , String /*command*/ )>,
|
||||
commands: Vec<String>,
|
||||
selected: usize,
|
||||
is_complete: bool,
|
||||
@@ -22,7 +22,7 @@ pub(crate) struct AgentsOverviewView {
|
||||
|
||||
impl AgentsOverviewView {
|
||||
pub fn new(
|
||||
agents: Vec<(String, bool, bool, String)>,
|
||||
agents: Vec<(String, bool, bool, bool, String)>,
|
||||
commands: Vec<String>,
|
||||
selected_index: usize,
|
||||
app_event_tx: AppEventSender,
|
||||
@@ -50,10 +50,12 @@ impl AgentsOverviewView {
|
||||
.map(|(name, _, _, _)| name.len())
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
for (i, (name, enabled, installed, _cmd)) in self.agents.iter().enumerate() {
|
||||
for (i, (name, enabled, installed, self_resolved, _cmd)) in self.agents.iter().enumerate() {
|
||||
let sel = i == self.selected;
|
||||
let (status_text, status_color) = if !*enabled {
|
||||
("disabled", crate::colors::error())
|
||||
} else if *self_resolved {
|
||||
("available", crate::colors::success())
|
||||
} else if !*installed {
|
||||
("not installed", crate::colors::warning())
|
||||
} else {
|
||||
@@ -74,7 +76,9 @@ impl AgentsOverviewView {
|
||||
];
|
||||
if sel {
|
||||
spans.push(Span::raw(" "));
|
||||
let hint = if !*installed {
|
||||
let hint = if *self_resolved {
|
||||
"(press Enter to configure)"
|
||||
} else if !*installed {
|
||||
"(press Enter to install)"
|
||||
} else {
|
||||
"(press Enter to configure)"
|
||||
@@ -201,3 +205,29 @@ impl<'a> BottomPaneView<'a> for AgentsOverviewView {
|
||||
.render(Rect { x: inner.x.saturating_add(1), y: inner.y, width: inner.width.saturating_sub(2), height: inner.height }, buf);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn builtin_agent_shows_available_status() {
|
||||
let app_event_tx = AppEventSender::new(|_| {});
|
||||
let mut view = AgentsOverviewView::new(
|
||||
vec![("code".to_string(), true, true, true, "coder".to_string())],
|
||||
Vec::new(),
|
||||
0,
|
||||
app_event_tx,
|
||||
);
|
||||
|
||||
let lines = view.build_lines();
|
||||
let combined = lines
|
||||
.iter()
|
||||
.map(|l| l.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
assert!(combined.contains("available"), "expected status text to show 'available', got: {combined}");
|
||||
assert!(!combined.contains("not installed"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20027,6 +20027,7 @@ Have we met every part of this goal and is there no further work to do?"#
|
||||
name: cfg.name.clone(),
|
||||
enabled: cfg.enabled,
|
||||
installed,
|
||||
self_resolved: builtin,
|
||||
description: Self::agent_description_for(
|
||||
&cfg.name,
|
||||
Some(&cfg.command),
|
||||
@@ -20052,6 +20053,7 @@ Have we met every part of this goal and is there no further work to do?"#
|
||||
name: cfg.name.clone(),
|
||||
enabled: cfg.enabled,
|
||||
installed,
|
||||
self_resolved: builtin,
|
||||
description: Self::agent_description_for(
|
||||
&cfg.name,
|
||||
Some(&cfg.command),
|
||||
@@ -20073,6 +20075,7 @@ Have we met every part of this goal and is there no further work to do?"#
|
||||
name: name.clone(),
|
||||
enabled: true,
|
||||
installed,
|
||||
self_resolved: builtin,
|
||||
description: Self::agent_description_for(name, Some(&cmd), None),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -434,6 +434,7 @@ pub(crate) struct AgentOverviewRow {
|
||||
pub(crate) name: String,
|
||||
pub(crate) enabled: bool,
|
||||
pub(crate) installed: bool,
|
||||
pub(crate) self_resolved: bool,
|
||||
pub(crate) description: Option<String>,
|
||||
}
|
||||
|
||||
@@ -546,6 +547,8 @@ impl AgentsSettingsContent {
|
||||
let selected = idx == state.selected;
|
||||
let status = if !row.enabled {
|
||||
("disabled", crate::colors::error())
|
||||
} else if row.self_resolved {
|
||||
("available", crate::colors::success())
|
||||
} else if !row.installed {
|
||||
("not installed", crate::colors::warning())
|
||||
} else {
|
||||
@@ -605,7 +608,9 @@ impl AgentsSettingsContent {
|
||||
|
||||
if selected && !showed_desc {
|
||||
spans.push(Span::raw(" "));
|
||||
let hint = if !row.installed {
|
||||
let hint = if row.self_resolved {
|
||||
"Enter to configure"
|
||||
} else if !row.installed {
|
||||
"Enter to install"
|
||||
} else {
|
||||
"Enter to configure"
|
||||
|
||||
Reference in New Issue
Block a user