rho-coding-agent 0.26.0

A lightweight agent harness inspired by Pi
Documentation
use async_trait::async_trait;
use serde::Deserialize;

use crate::{
    diagnostics::RuntimeDiagnostics,
    tool::{Tool, ToolContext, ToolError, ToolResult, ToolSpec},
};

pub struct Rho {
    diagnostics: RuntimeDiagnostics,
}

impl Rho {
    pub fn new(diagnostics: RuntimeDiagnostics) -> Self {
        Self { diagnostics }
    }
}

#[derive(Deserialize)]
struct Args {
    action: String,
}

#[async_trait]
impl Tool for Rho {
    fn spec(&self) -> ToolSpec {
        ToolSpec {
            name: "rho".into(),
            description: "Inspect the running Rho harness. Use info for basic runtime identity."
                .into(),
            input_schema: serde_json::json!({
                "type": "object",
                "properties": {
                    "action": {
                        "type": "string",
                        "description": "Read-only diagnostics action"
                    }
                },
                "required": ["action"],
                "additionalProperties": false
            }),
        }
    }

    fn display_content(&self, args: &serde_json::Value, _ctx: &ToolContext) -> Option<String> {
        args.get("action")
            .and_then(|action| action.as_str())
            .map(|action| format!("rho {action}"))
    }

    async fn call(
        &self,
        args: serde_json::Value,
        _ctx: ToolContext,
        id: String,
    ) -> Result<ToolResult, ToolError> {
        let args: Args = serde_json::from_value(args)?;
        let content = self
            .diagnostics
            .response(&args.action)
            .map_err(ToolError::Message)?;
        Ok(ToolResult {
            id,
            ok: true,
            content,
        })
    }
}

#[cfg(test)]
#[path = "rho_tests.rs"]
mod tests;