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                "  {} {}",
96                "Description:".dimmed(),
97                "General-purpose AI assistant with planning and reflection"
98            );
99            println!("  {} {}", "Model:".dimmed(), "gemini-2.0-flash (default)");
100            println!("  {} {}", "Temperature:".dimmed(), "0.7");
101            println!(
102                "  {} {}",
103                "Capabilities:".dimmed(),
104                "planning, reflection, code_execution"
105            );
106        }
107        "researcher" => {
108            println!("  {} {}", "Role:".dimmed(), "researcher".green());
109            println!(
110                "  {} {}",
111                "Description:".dimmed(),
112                "Research specialist with web search capabilities"
113            );
114            println!("  {} {}", "Model:".dimmed(), "gemini-2.0-flash (default)");
115            println!("  {} {}", "Temperature:".dimmed(), "0.5");
116            println!(
117                "  {} {}",
118                "Tools:".dimmed(),
119                "web_search, file_read, knowledge_base"
120            );
121        }
122        "coder" => {
123            println!("  {} {}", "Role:".dimmed(), "coder".green());
124            println!(
125                "  {} {}",
126                "Description:".dimmed(),
127                "Code generation and modification specialist"
128            );
129            println!("  {} {}", "Model:".dimmed(), "gemini-2.0-flash (default)");
130            println!("  {} {}", "Temperature:".dimmed(), "0.3");
131            println!(
132                "  {} {}",
133                "Tools:".dimmed(),
134                "file_read, file_write, terminal, code_search"
135            );
136        }
137        "reviewer" => {
138            println!("  {} {}", "Role:".dimmed(), "reviewer".green());
139            println!(
140                "  {} {}",
141                "Description:".dimmed(),
142                "Code review and quality assurance"
143            );
144            println!("  {} {}", "Model:".dimmed(), "gemini-2.0-flash (default)");
145            println!("  {} {}", "Temperature:".dimmed(), "0.2");
146            println!("  {} {}", "Tools:".dimmed(), "file_read, code_search, lint");
147        }
148        _ => {
149            println!(
150                "  {} Agent '{}' not found in defaults",
151                "[!]".yellow(),
152                name
153            );
154            println!();
155            println!("  Use 'csm Agency create {}' to create a new agent", name);
156        }
157    }
158
159    Ok(())
160}
161
162/// List orchestration modes
163pub fn list_modes() -> Result<()> {
164    println!("{}", "[*] Orchestration Modes:".bold());
165    println!();
166
167    let modes = [
168        ("single", "[1]", "Traditional single-agent response"),
169        (
170            "sequential",
171            "[>]",
172            "Agents execute one after another, passing results forward",
173        ),
174        (
175            "parallel",
176            "[!]",
177            "Multiple agents work simultaneously on subtasks",
178        ),
179        ("loop", "[O]", "Agent repeats until a condition is met"),
180        (
181            "hierarchical",
182            "[H]",
183            "Lead agent delegates to specialized sub-agents",
184        ),
185        (
186            "swarm",
187            "[S]",
188            "Multiple agents collaborate with a coordinator",
189        ),
190        ("debate", "[D]", "Agents debate to reach the best solution"),
191    ];
192
193    for (mode, icon, desc) in modes {
194        println!("  {} {} - {}", icon, mode.cyan().bold(), desc.dimmed());
195    }
196
197    println!();
198    println!("{}", "Usage:".dimmed());
199    println!("  csm Agency run --orchestration swarm \"Build a web scraper\"");
200
201    Ok(())
202}
203
204/// Run an agent with a prompt
205pub fn run_agent(
206    agent_name: &str,
207    prompt: &str,
208    model: Option<&str>,
209    orchestration: &str,
210    verbose: bool,
211) -> Result<()> {
212    let model_name = model.unwrap_or("gemini-2.0-flash");
213
214    println!("{}", "[*] Starting agent execution...".bold());
215    println!();
216    println!("  {} {}", "Agent:".dimmed(), agent_name.green());
217    println!("  {} {}", "Model:".dimmed(), model_name.yellow());
218    println!("  {} {}", "Mode:".dimmed(), orchestration.cyan());
219    println!("  {} {}", "Prompt:".dimmed(), prompt);
220    println!();
221
222    // Parse orchestration type
223    let orch_type = match orchestration.to_lowercase().as_str() {
224        "single" => OrchestrationType::Sequential, // Single is just sequential with one agent
225        "sequential" => OrchestrationType::Sequential,
226        "parallel" => OrchestrationType::Parallel,
227        "loop" => OrchestrationType::Loop,
228        "hierarchical" => OrchestrationType::Hierarchical,
229        "swarm" => OrchestrationType::Hierarchical, // Swarm uses hierarchical orchestration
230        _ => {
231            println!(
232                "{} Unknown orchestration mode '{}', using single",
233                "[!]".yellow(),
234                orchestration
235            );
236            OrchestrationType::Sequential
237        }
238    };
239
240    if verbose {
241        println!("{}", "[*] Execution Details:".dimmed());
242        println!("  Orchestration Type: {:?}", orch_type);
243    }
244
245    // For now, show that the agent would be created and run
246    // Full implementation requires async runtime and API keys
247    println!(
248        "{}",
249        "[...] Agent execution requires API keys and async runtime.".dimmed()
250    );
251    println!(
252        "{}",
253        "   Use 'csm api serve' to start the backend API,".dimmed()
254    );
255    println!(
256        "{}",
257        "   then use csm-web or vscode-extension for full agent execution.".dimmed()
258    );
259    println!();
260
261    // Show what would happen
262    println!("{}", "[*] Execution Plan:".bold());
263    match orchestration.to_lowercase().as_str() {
264        "single" => {
265            println!("  1. {} agent receives prompt", agent_name);
266            println!("  2. Agent processes and responds");
267        }
268        "sequential" => {
269            println!("  1. First agent processes prompt");
270            println!("  2. Result passed to next agent");
271            println!("  3. Continue until all agents complete");
272        }
273        "parallel" => {
274            println!("  1. Task decomposed into subtasks");
275            println!("  2. Multiple agents work simultaneously");
276            println!("  3. Results merged");
277        }
278        "swarm" | "hierarchical" => {
279            println!("  1. Coordinator analyzes task");
280            println!("  2. Tasks delegated to specialists");
281            println!("  3. Results collected and synthesized");
282        }
283        "loop" => {
284            println!("  1. Agent processes prompt");
285            println!("  2. Check completion condition");
286            println!("  3. Repeat if needed (max iterations)");
287        }
288        _ => {}
289    }
290
291    Ok(())
292}
293
294/// Create a new agent configuration
295pub fn create_agent(
296    name: &str,
297    role: &str,
298    instruction: Option<&str>,
299    model: Option<&str>,
300) -> Result<()> {
301    let role_enum = match role.to_lowercase().as_str() {
302        "coordinator" => AgentRole::Coordinator,
303        "researcher" => AgentRole::Researcher,
304        "coder" => AgentRole::Coder,
305        "reviewer" => AgentRole::Reviewer,
306        "executor" => AgentRole::Executor,
307        "writer" => AgentRole::Writer,
308        "analyst" => AgentRole::Analyst,
309        "assistant" => AgentRole::Assistant,
310        "household" => AgentRole::Household,
311        "business" => AgentRole::Business,
312        "tester" => AgentRole::Tester,
313        _ => AgentRole::Custom,
314    };
315
316    let default_instruction = match role_enum {
317        AgentRole::Coordinator => "You are a coordinator agent that manages and delegates tasks.",
318        AgentRole::Researcher => "You are a research specialist that gathers and analyzes information.",
319        AgentRole::Coder => "You are a coding specialist that writes and modifies code.",
320        AgentRole::Reviewer => "You are a code reviewer that provides quality feedback.",
321        AgentRole::Executor => "You are an executor that runs commands and tools.",
322        AgentRole::Writer => "You are a writer that creates documentation and content.",
323        AgentRole::Analyst => "You are an analyst that examines data and provides insights.",
324        AgentRole::Assistant => "You are a helpful AI assistant.",
325        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.",
326        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.",
327        AgentRole::Tester => "You are a testing specialist that creates and runs tests.",
328        AgentRole::Custom => "You are a helpful AI assistant.",
329    };
330
331    let instruction = instruction.unwrap_or(default_instruction);
332    let model = model.unwrap_or("gemini-2.0-flash");
333
334    println!("{}", "[+] Agent Configuration Created:".bold().green());
335    println!();
336    println!("  {} {}", "Name:".dimmed(), name.cyan().bold());
337    println!("  {} {:?}", "Role:".dimmed(), role_enum);
338    println!("  {} {}", "Model:".dimmed(), model.yellow());
339    println!("  {} {}", "Instruction:".dimmed(), instruction);
340    println!();
341    println!("{}", "[*] To use this agent:".dimmed());
342    println!("   csm Agency run --agent {} \"Your prompt here\"", name);
343
344    Ok(())
345}
346
347/// List available tools
348pub fn list_tools() -> Result<()> {
349    println!("{}", "[*] Available Tools:".bold());
350    println!();
351
352    let tools = [
353        ("file_read", "[F]", "Read file contents"),
354        ("file_write", "[W]", "Write or modify files"),
355        ("terminal", "[T]", "Execute shell commands"),
356        ("web_search", "[?]", "Search the web for information"),
357        ("code_search", "[?]", "Search codebase for symbols"),
358        ("knowledge_base", "[K]", "Query knowledge base"),
359        ("calculator", "[#]", "Perform calculations"),
360        ("http_request", "[H]", "Make HTTP requests"),
361    ];
362
363    for (tool, icon, desc) in tools {
364        println!("  {} {} - {}", icon, tool.green().bold(), desc.dimmed());
365    }
366
367    Ok(())
368}
369
370/// Show swarm templates
371pub fn list_templates() -> Result<()> {
372    println!("{}", "[S] Swarm Templates:".bold());
373    println!();
374
375    let templates = [
376        (
377            "code_review",
378            "Code Review Team",
379            vec!["coder", "reviewer", "tester"],
380        ),
381        (
382            "research",
383            "Research Team",
384            vec!["coordinator", "researcher", "writer"],
385        ),
386        (
387            "full_stack",
388            "Full Stack Team",
389            vec!["coordinator", "coder", "reviewer", "tester"],
390        ),
391        (
392            "content",
393            "Content Team",
394            vec!["researcher", "writer", "reviewer"],
395        ),
396    ];
397
398    for (id, name, agents) in templates {
399        println!("  {} {}", "[*]".dimmed(), name.cyan().bold());
400        println!("     {} {}", "ID:".dimmed(), id.yellow());
401        println!("     {} {}", "Agents:".dimmed(), agents.join(", ").green());
402        println!();
403    }
404
405    println!("{}", "Usage:".dimmed());
406    println!("  Select a template in csm-web or vscode-extension to create a swarm.");
407
408    Ok(())
409}