chasm_cli/commands/
agency.rs

1// Copyright (c) 2024-2026 Nervosys LLC
2// SPDX-License-Identifier: Apache-2.0
3//! Agency (Agent Development Kit) command implementations
4
5use crate::agency::{AgentRole, OrchestrationType};
6use anyhow::Result;
7use colored::Colorize;
8
9/// List available agents and roles
10pub fn list_agents(verbose: bool) -> Result<()> {
11    println!(
12        "{}",
13        "+===================================================================+".cyan()
14    );
15    println!(
16        "{}",
17        "|              CSM Agent Development Kit (Agency)                   |".cyan()
18    );
19    println!(
20        "{}",
21        "+===================================================================+".cyan()
22    );
23    println!();
24
25    println!("{}", "[*] Available Agent Roles:".bold());
26    println!();
27
28    let roles = [
29        (
30            "coordinator",
31            "[C]",
32            "Manages and delegates tasks to other agents",
33        ),
34        ("researcher", "[R]", "Gathers information and analyzes data"),
35        ("coder", "[D]", "Writes and modifies code"),
36        ("reviewer", "[V]", "Reviews code and provides feedback"),
37        ("executor", "[E]", "Executes commands and tools"),
38        ("writer", "[W]", "Creates documentation and content"),
39        ("tester", "[T]", "Writes and runs tests"),
40        ("custom", "[X]", "User-defined agent with custom behavior"),
41    ];
42
43    for (role, icon, desc) in roles {
44        if verbose {
45            println!(
46                "  {} {} {}",
47                icon,
48                role.green().bold(),
49                format!("- {}", desc).dimmed()
50            );
51        } else {
52            println!("  {} {}", icon, role.green());
53        }
54    }
55
56    if verbose {
57        println!();
58        println!("{}", "[*] Default Agents:".bold());
59        println!();
60        println!(
61            "  {} {} - General-purpose assistant with planning",
62            "[A]".dimmed(),
63            "assistant".yellow()
64        );
65        println!(
66            "  {} {} - Research specialist with web search",
67            "[R]".dimmed(),
68            "researcher".yellow()
69        );
70        println!(
71            "  {} {} - Code generation and modification",
72            "[D]".dimmed(),
73            "coder".yellow()
74        );
75        println!(
76            "  {} {} - Code review and quality assurance",
77            "[V]".dimmed(),
78            "reviewer".yellow()
79        );
80    }
81
82    Ok(())
83}
84
85/// Show agent information
86pub fn show_agent_info(name: &str) -> Result<()> {
87    println!("{}", format!("Agent: {}", name).bold());
88    println!();
89
90    // Default agent configurations
91    match name.to_lowercase().as_str() {
92        "assistant" => {
93            println!("  {} {}", "Role:".dimmed(), "custom".green());
94            println!(
95                "  {} General-purpose AI assistant with planning and reflection",
96                "Description:".dimmed()
97            );
98            println!("  {} gemini-2.0-flash (default)", "Model:".dimmed());
99            println!("  {} 0.7", "Temperature:".dimmed());
100            println!(
101                "  {} planning, reflection, code_execution",
102                "Capabilities:".dimmed()
103            );
104        }
105        "researcher" => {
106            println!("  {} {}", "Role:".dimmed(), "researcher".green());
107            println!(
108                "  {} Research specialist with web search capabilities",
109                "Description:".dimmed()
110            );
111            println!("  {} gemini-2.0-flash (default)", "Model:".dimmed());
112            println!("  {} 0.5", "Temperature:".dimmed());
113            println!(
114                "  {} web_search, file_read, knowledge_base",
115                "Tools:".dimmed()
116            );
117        }
118        "coder" => {
119            println!("  {} {}", "Role:".dimmed(), "coder".green());
120            println!(
121                "  {} Code generation and modification specialist",
122                "Description:".dimmed()
123            );
124            println!("  {} gemini-2.0-flash (default)", "Model:".dimmed());
125            println!("  {} 0.3", "Temperature:".dimmed());
126            println!(
127                "  {} file_read, file_write, terminal, code_search",
128                "Tools:".dimmed()
129            );
130        }
131        "reviewer" => {
132            println!("  {} {}", "Role:".dimmed(), "reviewer".green());
133            println!(
134                "  {} Code review and quality assurance",
135                "Description:".dimmed()
136            );
137            println!("  {} gemini-2.0-flash (default)", "Model:".dimmed());
138            println!("  {} 0.2", "Temperature:".dimmed());
139            println!("  {} file_read, code_search, lint", "Tools:".dimmed());
140        }
141        _ => {
142            println!(
143                "  {} Agent '{}' not found in defaults",
144                "[!]".yellow(),
145                name
146            );
147            println!();
148            println!("  Use 'csm Agency create {}' to create a new agent", name);
149        }
150    }
151
152    Ok(())
153}
154
155/// List orchestration modes
156pub fn list_modes() -> Result<()> {
157    println!("{}", "[*] Orchestration Modes:".bold());
158    println!();
159
160    let modes = [
161        ("single", "[1]", "Traditional single-agent response"),
162        (
163            "sequential",
164            "[>]",
165            "Agents execute one after another, passing results forward",
166        ),
167        (
168            "parallel",
169            "[!]",
170            "Multiple agents work simultaneously on subtasks",
171        ),
172        ("loop", "[O]", "Agent repeats until a condition is met"),
173        (
174            "hierarchical",
175            "[H]",
176            "Lead agent delegates to specialized sub-agents",
177        ),
178        (
179            "swarm",
180            "[S]",
181            "Multiple agents collaborate with a coordinator",
182        ),
183        ("debate", "[D]", "Agents debate to reach the best solution"),
184    ];
185
186    for (mode, icon, desc) in modes {
187        println!("  {} {} - {}", icon, mode.cyan().bold(), desc.dimmed());
188    }
189
190    println!();
191    println!("{}", "Usage:".dimmed());
192    println!("  csm Agency run --orchestration swarm \"Build a web scraper\"");
193
194    Ok(())
195}
196
197/// Run an agent with a prompt
198pub fn run_agent(
199    agent_name: &str,
200    prompt: &str,
201    model: Option<&str>,
202    orchestration: &str,
203    verbose: bool,
204) -> Result<()> {
205    let model_name = model.unwrap_or("gemini-2.0-flash");
206
207    println!("{}", "[*] Starting agent execution...".bold());
208    println!();
209    println!("  {} {}", "Agent:".dimmed(), agent_name.green());
210    println!("  {} {}", "Model:".dimmed(), model_name.yellow());
211    println!("  {} {}", "Mode:".dimmed(), orchestration.cyan());
212    println!("  {} {}", "Prompt:".dimmed(), prompt);
213    println!();
214
215    // Parse orchestration type
216    let orch_type = match orchestration.to_lowercase().as_str() {
217        "single" => OrchestrationType::Sequential, // Single is just sequential with one agent
218        "sequential" => OrchestrationType::Sequential,
219        "parallel" => OrchestrationType::Parallel,
220        "loop" => OrchestrationType::Loop,
221        "hierarchical" => OrchestrationType::Hierarchical,
222        "swarm" => OrchestrationType::Hierarchical, // Swarm uses hierarchical orchestration
223        _ => {
224            println!(
225                "{} Unknown orchestration mode '{}', using single",
226                "[!]".yellow(),
227                orchestration
228            );
229            OrchestrationType::Sequential
230        }
231    };
232
233    if verbose {
234        println!("{}", "[*] Execution Details:".dimmed());
235        println!("  Orchestration Type: {:?}", orch_type);
236    }
237
238    // For now, show that the agent would be created and run
239    // Full implementation requires async runtime and API keys
240    println!(
241        "{}",
242        "[...] Agent execution requires API keys and async runtime.".dimmed()
243    );
244    println!(
245        "{}",
246        "   Use 'csm api serve' to start the backend API,".dimmed()
247    );
248    println!(
249        "{}",
250        "   then use csm-web or vscode-extension for full agent execution.".dimmed()
251    );
252    println!();
253
254    // Show what would happen
255    println!("{}", "[*] Execution Plan:".bold());
256    match orchestration.to_lowercase().as_str() {
257        "single" => {
258            println!("  1. {} agent receives prompt", agent_name);
259            println!("  2. Agent processes and responds");
260        }
261        "sequential" => {
262            println!("  1. First agent processes prompt");
263            println!("  2. Result passed to next agent");
264            println!("  3. Continue until all agents complete");
265        }
266        "parallel" => {
267            println!("  1. Task decomposed into subtasks");
268            println!("  2. Multiple agents work simultaneously");
269            println!("  3. Results merged");
270        }
271        "swarm" | "hierarchical" => {
272            println!("  1. Coordinator analyzes task");
273            println!("  2. Tasks delegated to specialists");
274            println!("  3. Results collected and synthesized");
275        }
276        "loop" => {
277            println!("  1. Agent processes prompt");
278            println!("  2. Check completion condition");
279            println!("  3. Repeat if needed (max iterations)");
280        }
281        _ => {}
282    }
283
284    Ok(())
285}
286
287/// Create a new agent configuration
288pub fn create_agent(
289    name: &str,
290    role: &str,
291    instruction: Option<&str>,
292    model: Option<&str>,
293) -> Result<()> {
294    let role_enum = match role.to_lowercase().as_str() {
295        "coordinator" => AgentRole::Coordinator,
296        "researcher" => AgentRole::Researcher,
297        "coder" => AgentRole::Coder,
298        "reviewer" => AgentRole::Reviewer,
299        "executor" => AgentRole::Executor,
300        "writer" => AgentRole::Writer,
301        "analyst" => AgentRole::Analyst,
302        "assistant" => AgentRole::Assistant,
303        "household" => AgentRole::Household,
304        "business" => AgentRole::Business,
305        "tester" => AgentRole::Tester,
306        _ => AgentRole::Custom,
307    };
308
309    let default_instruction = match role_enum {
310        AgentRole::Coordinator => "You are a coordinator agent that manages and delegates tasks.",
311        AgentRole::Researcher => "You are a research specialist that gathers and analyzes information.",
312        AgentRole::Coder => "You are a coding specialist that writes and modifies code.",
313        AgentRole::Reviewer => "You are a code reviewer that provides quality feedback.",
314        AgentRole::Executor => "You are an executor that runs commands and tools.",
315        AgentRole::Writer => "You are a writer that creates documentation and content.",
316        AgentRole::Analyst => "You are an analyst that examines data and provides insights.",
317        AgentRole::Assistant => "You are a helpful AI assistant.",
318        AgentRole::Household => "You are a proactive Household Agent that monitors and solves home problems with user permission. Track bills, maintenance, supplies, smart home devices, and daily household tasks.",
319        AgentRole::Business => "You are a proactive Business Agent that monitors and solves work problems with user permission. Optimize calendars, triage emails, prepare for meetings, track deadlines, and coordinate projects.",
320        AgentRole::Tester => "You are a testing specialist that creates and runs tests.",
321        AgentRole::Custom => "You are a helpful AI assistant.",
322    };
323
324    let instruction = instruction.unwrap_or(default_instruction);
325    let model = model.unwrap_or("gemini-2.0-flash");
326
327    println!("{}", "[+] Agent Configuration Created:".bold().green());
328    println!();
329    println!("  {} {}", "Name:".dimmed(), name.cyan().bold());
330    println!("  {} {:?}", "Role:".dimmed(), role_enum);
331    println!("  {} {}", "Model:".dimmed(), model.yellow());
332    println!("  {} {}", "Instruction:".dimmed(), instruction);
333    println!();
334    println!("{}", "[*] To use this agent:".dimmed());
335    println!("   csm Agency run --agent {} \"Your prompt here\"", name);
336
337    Ok(())
338}
339
340/// List available tools
341pub fn list_tools() -> Result<()> {
342    println!("{}", "[*] Available Tools:".bold());
343    println!();
344
345    let tools = [
346        ("file_read", "[F]", "Read file contents"),
347        ("file_write", "[W]", "Write or modify files"),
348        ("terminal", "[T]", "Execute shell commands"),
349        ("web_search", "[?]", "Search the web for information"),
350        ("code_search", "[?]", "Search codebase for symbols"),
351        ("knowledge_base", "[K]", "Query knowledge base"),
352        ("calculator", "[#]", "Perform calculations"),
353        ("http_request", "[H]", "Make HTTP requests"),
354    ];
355
356    for (tool, icon, desc) in tools {
357        println!("  {} {} - {}", icon, tool.green().bold(), desc.dimmed());
358    }
359
360    Ok(())
361}
362
363/// Show swarm templates
364pub fn list_templates() -> Result<()> {
365    println!("{}", "[S] Swarm Templates:".bold());
366    println!();
367
368    let templates = [
369        (
370            "code_review",
371            "Code Review Team",
372            vec!["coder", "reviewer", "tester"],
373        ),
374        (
375            "research",
376            "Research Team",
377            vec!["coordinator", "researcher", "writer"],
378        ),
379        (
380            "full_stack",
381            "Full Stack Team",
382            vec!["coordinator", "coder", "reviewer", "tester"],
383        ),
384        (
385            "content",
386            "Content Team",
387            vec!["researcher", "writer", "reviewer"],
388        ),
389    ];
390
391    for (id, name, agents) in templates {
392        println!("  {} {}", "[*]".dimmed(), name.cyan().bold());
393        println!("     {} {}", "ID:".dimmed(), id.yellow());
394        println!("     {} {}", "Agents:".dimmed(), agents.join(", ").green());
395        println!();
396    }
397
398    println!("{}", "Usage:".dimmed());
399    println!("  Select a template in csm-web or vscode-extension to create a swarm.");
400
401    Ok(())
402}