feat: Added loaded indicators to .list tools/mcp-servers/skills
CI / All (ubuntu-latest) (push) Failing after 27s
CI / All (macos-latest) (push) Has been cancelled
CI / All (windows-latest) (push) Has been cancelled

This commit is contained in:
2026-08-05 13:11:24 -06:00
parent 70b6d51b55
commit 9540345ec7
+69 -8
View File
@@ -38,6 +38,7 @@ use super::memory::{
}; };
use crate::graph; use crate::graph;
use anyhow::{Context, Error, Result, bail}; use anyhow::{Context, Error, Result, bail};
use colored::Colorize;
use gman::providers::SupportedProvider; use gman::providers::SupportedProvider;
#[cfg(test)] #[cfg(test)]
use indexmap::IndexMap; use indexmap::IndexMap;
@@ -1111,10 +1112,17 @@ impl RequestContext {
} }
fn concrete_tool_names(&self) -> Vec<String> { fn concrete_tool_names(&self) -> Vec<String> {
let declarations = match &self.agent { let declarations: Vec<&FunctionDeclaration> = self
Some(agent) => agent.functions().declarations(), .tool_scope
None => self.tool_scope.functions.declarations(), .functions
}; .declarations()
.iter()
.chain(
self.agent
.iter()
.flat_map(|agent| agent.functions().declarations()),
)
.collect();
declarations declarations
.iter() .iter()
.filter(|v| { .filter(|v| {
@@ -2425,8 +2433,12 @@ impl RequestContext {
println!("Skills:"); println!("Skills:");
for (name, description, loaded) in entries { for (name, description, loaded) in entries {
let marker = if loaded { " (loaded)" } else { "" }; let marker = if loaded {
println!("{name}{marker}{description}"); "".green().bold().to_string()
} else {
"".red().bold().to_string()
};
println!(" {marker} {name}{description}");
} }
Ok(()) Ok(())
@@ -2450,7 +2462,31 @@ impl RequestContext {
names.sort_unstable(); names.sort_unstable();
names.dedup(); names.dedup();
print_asset_names("tools", &names) let active: HashSet<String> = if self.app.config.function_calling_support {
let role = self.extract_role(&self.app.config)?;
match self.select_functions(&role) {
None => HashSet::new(),
Some(functions) => functions.iter().map(|f| f.name.clone()).collect(),
}
} else {
HashSet::new()
};
if names.is_empty() {
println!("No tools found.");
return Ok(());
}
println!("Tools:");
for name in &names {
let marker = if active.contains(name.as_str()) {
"".green().bold().to_string()
} else {
"".red().bold().to_string()
};
println!(" {marker} {name}");
}
Ok(())
} }
"mcp-servers" => { "mcp-servers" => {
let mut names: Vec<String> = vec![]; let mut names: Vec<String> = vec![];
@@ -2467,7 +2503,32 @@ impl RequestContext {
names.sort_unstable(); names.sort_unstable();
names.dedup(); names.dedup();
print_asset_names("MCP servers", &names) if names.is_empty() {
println!("No MCP servers found.");
return Ok(());
}
let enabled: Option<Vec<String>> = if let Some(session) = &self.session {
session.enabled_mcp_servers()
} else if let Some(role) = &self.role {
role.enabled_mcp_servers()
} else {
self.app.config.enabled_mcp_servers.clone()
};
let skill_mcps = self.skill_registry.loaded_mcp_servers();
println!("MCP servers:");
for name in &names {
let active = skill_mcps.contains(name.as_str())
|| matches!(&enabled, Some(list) if list.iter().any(|s| s.trim() == "all") || self.mcp_list_covers(list, name));
let marker = if active {
"".green().bold().to_string()
} else {
"".red().bold().to_string()
};
println!(" {marker} {name}");
}
Ok(())
} }
_ => bail!( _ => bail!(
"Unknown kind '{kind}'. Valid kinds: roles, sessions, agents, rags, macros, skills, tools, mcp-servers" "Unknown kind '{kind}'. Valid kinds: roles, sessions, agents, rags, macros, skills, tools, mcp-servers"