Skip to content

Commit 846669f

Browse files
feat: warn when duplicate agents are found during load (#3335)
1 parent 8ff6db8 commit 846669f

File tree

1 file changed

+68
-3
lines changed
  • crates/chat-cli/src/cli/agent

1 file changed

+68
-3
lines changed

crates/chat-cli/src/cli/agent/mod.rs

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ impl Agents {
563563
};
564564

565565
let mut agents = Vec::<Agent>::new();
566-
let results = load_agents_from_entries(files, os, &mut global_mcp_config, mcp_enabled, output).await;
566+
let results = load_agents_from_entries(files, os, &mut global_mcp_config, mcp_enabled, false, output).await;
567567
for result in results {
568568
match result {
569569
Ok(agent) => agents.push(agent),
@@ -601,7 +601,7 @@ impl Agents {
601601
};
602602

603603
let mut agents = Vec::<Agent>::new();
604-
let results = load_agents_from_entries(files, os, &mut global_mcp_config, mcp_enabled, output).await;
604+
let results = load_agents_from_entries(files, os, &mut global_mcp_config, mcp_enabled, true, output).await;
605605
for result in results {
606606
match result {
607607
Ok(agent) => agents.push(agent),
@@ -886,6 +886,7 @@ async fn load_agents_from_entries(
886886
os: &Os,
887887
global_mcp_config: &mut Option<McpServerConfig>,
888888
mcp_enabled: bool,
889+
is_from_global_dir: bool,
889890
output: &mut impl Write,
890891
) -> Vec<Result<Agent, AgentConfigError>> {
891892
let mut res = Vec::<Result<Agent, AgentConfigError>>::new();
@@ -897,7 +898,30 @@ async fn load_agents_from_entries(
897898
.and_then(OsStr::to_str)
898899
.is_some_and(|s| s == "json")
899900
{
900-
res.push(Agent::load(os, file_path, global_mcp_config, mcp_enabled, output).await);
901+
let agent_res = Agent::load(os, file_path, global_mcp_config, mcp_enabled, output).await;
902+
if let Ok(agent) = &agent_res {
903+
if res.iter().any(|res| match res {
904+
Ok(a) => a.name == agent.name,
905+
Err(_) => false,
906+
}) {
907+
let _ = queue!(
908+
output,
909+
StyledText::warning_fg(),
910+
style::Print("WARNING: "),
911+
StyledText::reset(),
912+
style::Print("Duplicate agent with name "),
913+
StyledText::success_fg(),
914+
style::Print(&agent.name),
915+
StyledText::reset(),
916+
style::Print(" was found in the "),
917+
style::Print(if is_from_global_dir { "global" } else { "workspace" }),
918+
style::Print(" directory.\n"),
919+
StyledText::reset(),
920+
);
921+
continue;
922+
}
923+
}
924+
res.push(agent_res);
901925
}
902926
}
903927

@@ -996,6 +1020,7 @@ fn validate_agent_name(name: &str) -> eyre::Result<()> {
9961020
mod tests {
9971021
use std::fs;
9981022

1023+
use bstr::ByteSlice;
9991024
use serde_json::json;
10001025
use tempfile::TempDir;
10011026

@@ -1581,4 +1606,44 @@ mod tests {
15811606
let result = agent.resolve_prompt();
15821607
assert!(result.is_err());
15831608
}
1609+
1610+
#[tokio::test]
1611+
async fn test_load_agents_from_entries_warns_duplicate() {
1612+
// Given two agents with the same name
1613+
let os = Os::new().await.unwrap();
1614+
let agents = [
1615+
Agent {
1616+
name: "test-agent".to_string(),
1617+
..Default::default()
1618+
},
1619+
Agent {
1620+
name: "test-agent".to_string(),
1621+
..Default::default()
1622+
},
1623+
];
1624+
for (i, agent) in agents.iter().enumerate() {
1625+
os.fs
1626+
.write(format!("{}_{}.json", agent.name, i), agent.to_str_pretty().unwrap())
1627+
.await
1628+
.unwrap();
1629+
}
1630+
1631+
// When we load them
1632+
let mut output = Vec::new();
1633+
let results = load_agents_from_entries(
1634+
os.fs.read_dir(".").await.unwrap(),
1635+
&os,
1636+
&mut None,
1637+
false,
1638+
false,
1639+
&mut output,
1640+
)
1641+
.await;
1642+
1643+
// We should see a warning
1644+
assert!(output.contains_str("WARNING"));
1645+
assert!(output.contains_str("test-agent"));
1646+
assert!(output.contains_str("workspace"));
1647+
assert_eq!(results.len(), 1);
1648+
}
15841649
}

0 commit comments

Comments
 (0)