1use antigravity_sdk_rust::agent::{Agent, AgentConfig};
2use antigravity_sdk_rust::hooks::Hook;
3use antigravity_sdk_rust::policy;
4use antigravity_sdk_rust::types::{
5 BuiltinTools, CapabilitiesConfig, GeminiConfig, HookResult, ToolCall, ToolResult,
6};
7use std::sync::Arc;
8use std::sync::atomic::{AtomicBool, Ordering};
9use tracing_subscriber::EnvFilter;
10
11struct SubagentHook {
12 subagent_active: Arc<AtomicBool>,
13}
14
15impl Hook for SubagentHook {
16 async fn pre_tool_call(&self, tool_call: &ToolCall) -> Result<HookResult, anyhow::Error> {
17 if tool_call.name == "START_SUBAGENT" {
18 self.subagent_active.store(true, Ordering::SeqCst);
19 println!("\n --- 🤖 [Hook] Spawning Subagent ---");
20 println!(" Arguments: {}\n", tool_call.args);
21 } else {
22 let indent = if self.subagent_active.load(Ordering::SeqCst) {
23 " "
24 } else {
25 " "
26 };
27 println!(
28 "{}- [Start]: {} (ID: {})",
29 indent, tool_call.name, tool_call.id
30 );
31 }
32 Ok(HookResult {
33 allow: true,
34 message: String::new(),
35 })
36 }
37
38 async fn post_tool_call(&self, result: &ToolResult) -> Result<(), anyhow::Error> {
39 if result.name == "START_SUBAGENT" {
40 self.subagent_active.store(false, Ordering::SeqCst);
41 println!("\n --- 🤖 [Hook] Subagent Finished ---");
42 println!(" Result: {:?}\n", result.result);
43 } else {
44 let indent = if self.subagent_active.load(Ordering::SeqCst) {
45 " "
46 } else {
47 " "
48 };
49 println!(
50 "{}- [Done]: {} (ID: {}) ✅",
51 indent,
52 result.name,
53 result.id.as_deref().unwrap_or("")
54 );
55 }
56 Ok(())
57 }
58}
59
60#[tokio::main]
61async fn main() -> Result<(), anyhow::Error> {
62 tracing_subscriber::fmt()
64 .with_env_filter(EnvFilter::try_from_default_env().unwrap_or_else(|_| "info".into()))
65 .init();
66
67 dotenvy::dotenv().ok();
69
70 let mut config = AgentConfig::default();
71
72 if let Ok(harness_path) = std::env::var("ANTIGRAVITY_HARNESS_PATH") {
73 config.binary_path = Some(harness_path);
74 }
75
76 let mut gemini_config = GeminiConfig::default();
77 if let Ok(api_key) = std::env::var("GEMINI_API_KEY") {
78 gemini_config.api_key = Some(api_key);
79 }
80 gemini_config.models.default.name = "gemini-3.5-flash".to_string();
81 config.gemini_config = gemini_config;
82
83 let capabilities = CapabilitiesConfig {
85 enabled_tools: Some(vec![
86 BuiltinTools::StartSubagent,
87 BuiltinTools::ListDir,
88 BuiltinTools::ViewFile,
89 BuiltinTools::Finish,
90 ]),
91 ..Default::default()
92 };
93 config.capabilities = capabilities;
94
95 let subagent_active = Arc::new(AtomicBool::new(false));
97 config
98 .hooks
99 .push(Arc::new(SubagentHook { subagent_active }));
100
101 config.policies = Some(vec![policy::allow_all()]);
103
104 let mut agent = Agent::new(config);
105 println!("Starting agent...");
106 agent.start().await?;
107
108 let prompt = "Use a subagent to research the files in the current directory. \
109 Delegate the task of listing the directory to the subagent, and then \
110 tell me what files you found.";
111
112 println!(" User: {}", prompt);
113 let response = agent.chat(prompt).await?;
114 println!("\n Agent:\n{}", response.text);
115
116 agent.stop().await?;
117 Ok(())
118}