#![allow(deprecated)]
use adk_code::{
CodeExecutor, ExecutionLanguage, ExecutionPayload, ExecutionRequest, ExecutionResult,
RustSandboxExecutor, SandboxPolicy,
};
use adk_core::{Result, Tool, ToolContext};
use async_trait::async_trait;
use serde_json::{Value, json};
use std::sync::Arc;
#[deprecated(since = "0.5.0", note = "Use adk_code::CodeTool instead")]
pub struct RustCodeTool {
executor: RustSandboxExecutor,
}
impl RustCodeTool {
pub fn new() -> Self {
Self { executor: RustSandboxExecutor::default() }
}
pub fn backend() -> Self {
Self::new()
}
pub fn with_executor(executor: RustSandboxExecutor) -> Self {
Self { executor }
}
}
impl Default for RustCodeTool {
fn default() -> Self {
Self::new()
}
}
fn result_to_json(result: &ExecutionResult) -> Value {
json!({
"status": result.status,
"stdout": result.stdout,
"stderr": result.stderr,
"output": result.output,
"exitCode": result.exit_code,
"durationMs": result.duration_ms,
})
}
#[async_trait]
impl Tool for RustCodeTool {
fn name(&self) -> &str {
"rust_code"
}
fn description(&self) -> &str {
"Execute Rust code in a sandbox. The code must define a \
`fn run(input: serde_json::Value) -> serde_json::Value` entry point. \
Returns structured output, stdout, stderr, and execution status."
}
fn required_scopes(&self) -> &[&str] {
&["code:execute", "code:execute:rust"]
}
fn parameters_schema(&self) -> Option<Value> {
Some(json!({
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "Rust source code to execute. Must define a `fn run(input: serde_json::Value) -> serde_json::Value` entry point."
},
"input": {
"description": "Optional JSON value passed as the `input` argument to the `run` function."
}
},
"required": ["code"]
}))
}
async fn execute(&self, _ctx: Arc<dyn ToolContext>, args: Value) -> Result<Value> {
let code = match args.get("code").and_then(Value::as_str) {
Some(c) => c.to_string(),
None => {
return Ok(json!({
"status": "rejected",
"stdout": "",
"stderr": "missing required field: code",
"output": null,
"exitCode": null,
"durationMs": 0,
}));
}
};
let code = code.replace("\\n", "\n").replace("\\t", "\t");
let input = args.get("input").cloned();
let request = ExecutionRequest {
language: ExecutionLanguage::Rust,
payload: ExecutionPayload::Source { code },
argv: vec![],
stdin: None,
input,
sandbox: SandboxPolicy::host_local(),
identity: None,
};
match self.executor.execute(request).await {
Ok(result) => Ok(result_to_json(&result)),
Err(e) => Ok(json!({
"status": "failed",
"stdout": "",
"stderr": e.to_string(),
"output": null,
"exitCode": null,
"durationMs": 0,
})),
}
}
}