use async_trait::async_trait;
use serde_json::{json, Value};
use crate::traits::{Tool, ToolCapabilities, ToolRole};
pub struct SystemInfoTool;
#[async_trait]
impl Tool for SystemInfoTool {
fn name(&self) -> &str {
"system_info"
}
fn description(&self) -> &str {
"Get system information including CPU and memory usage"
}
fn schema(&self) -> Value {
json!({
"name": "system_info",
"description": "Get system information including CPU and memory usage",
"parameters": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
}
})
}
fn tool_role(&self) -> ToolRole {
ToolRole::Universal
}
fn capabilities(&self) -> ToolCapabilities {
ToolCapabilities {
read_only: true,
external_side_effect: false,
needs_approval: false,
idempotent: true,
high_impact_write: false,
}
}
async fn call(&self, _arguments: &str) -> anyhow::Result<String> {
let mut info = String::new();
if let Ok(output) = tokio::process::Command::new("date").output().await {
let date = String::from_utf8_lossy(&output.stdout).trim().to_string();
info.push_str(&format!("Date: {}\n", date));
}
if let Ok(output) = tokio::process::Command::new("hostname").output().await {
let hostname = String::from_utf8_lossy(&output.stdout).trim().to_string();
info.push_str(&format!("Hostname: {}\n", hostname));
}
if let Ok(output) = tokio::process::Command::new("uname")
.arg("-a")
.output()
.await
{
let uname = String::from_utf8_lossy(&output.stdout).trim().to_string();
info.push_str(&format!("OS: {}\n", uname));
}
if let Ok(output) = tokio::process::Command::new("uptime").output().await {
let uptime = String::from_utf8_lossy(&output.stdout).trim().to_string();
info.push_str(&format!("Uptime: {}\n", uptime));
}
#[cfg(target_os = "linux")]
{
if let Ok(output) = tokio::process::Command::new("free")
.arg("-h")
.output()
.await
{
let mem = String::from_utf8_lossy(&output.stdout).trim().to_string();
info.push_str(&format!("Memory:\n{}\n", mem));
}
}
#[cfg(target_os = "macos")]
{
if let Ok(output) = tokio::process::Command::new("vm_stat").output().await {
let mem = String::from_utf8_lossy(&output.stdout).trim().to_string();
info.push_str(&format!("Memory:\n{}\n", mem));
}
}
if info.is_empty() {
info.push_str("Could not retrieve system information.");
}
Ok(info)
}
}