Skip to main content

adk_ui/tools/
render_chart.rs

1use crate::schema::*;
2use crate::tools::{LegacyProtocolOptions, render_ui_response_with_protocol};
3use adk_core::{Result, Tool, ToolContext};
4use async_trait::async_trait;
5use schemars::JsonSchema;
6use serde::{Deserialize, Serialize};
7use serde_json::Value;
8use std::collections::HashMap;
9use std::sync::Arc;
10
11/// Parameters for the render_chart tool
12#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
13pub struct RenderChartParams {
14    /// Chart title
15    #[serde(default)]
16    pub title: Option<String>,
17    /// Chart type: bar, line, area, or pie
18    #[serde(rename = "type", default = "default_chart_type")]
19    pub chart_type: String,
20    /// Data points - array of objects with x_key and y_key values
21    pub data: Vec<HashMap<String, Value>>,
22    /// Key for x-axis values
23    pub x_key: String,
24    /// Keys for y-axis values (can be multiple for multi-series)
25    pub y_keys: Vec<String>,
26    /// Optional protocol output configuration.
27    #[serde(flatten)]
28    pub protocol: LegacyProtocolOptions,
29}
30
31fn default_chart_type() -> String {
32    "bar".to_string()
33}
34
35/// Tool for rendering charts and data visualizations.
36///
37/// Creates interactive charts to display data trends, comparisons, and distributions.
38/// Supports multiple chart types and customizable axis labels, legends, and colors.
39///
40/// # Chart Types
41///
42/// - `bar`: Vertical bar chart (default)
43/// - `line`: Line chart for trends
44/// - `area`: Filled area chart
45/// - `pie`: Pie chart for distributions
46///
47/// # Example JSON Parameters
48///
49/// ```json
50/// {
51///   "title": "Monthly Sales",
52///   "type": "line",
53///   "data": [
54///     { "month": "Jan", "sales": 100 },
55///     { "month": "Feb", "sales": 150 },
56///     { "month": "Mar", "sales": 120 }
57///   ],
58///   "x_key": "month",
59///   "y_keys": ["sales"]
60/// }
61/// ```
62pub struct RenderChartTool;
63
64impl RenderChartTool {
65    pub fn new() -> Self {
66        Self
67    }
68}
69
70impl Default for RenderChartTool {
71    fn default() -> Self {
72        Self::new()
73    }
74}
75
76#[async_trait]
77impl Tool for RenderChartTool {
78    fn name(&self) -> &str {
79        "render_chart"
80    }
81
82    fn description(&self) -> &str {
83        "Render a chart to visualize data. Supports bar, line, area, and pie charts. Use this for showing trends, comparisons, or distributions."
84    }
85
86    fn parameters_schema(&self) -> Option<Value> {
87        Some(super::generate_gemini_schema::<RenderChartParams>())
88    }
89
90    async fn execute(&self, _ctx: Arc<dyn ToolContext>, args: Value) -> Result<Value> {
91        let params: RenderChartParams = serde_json::from_value(args)
92            .map_err(|e| adk_core::AdkError::Tool(format!("Invalid parameters: {}", e)))?;
93        let protocol_options = params.protocol.clone();
94
95        let kind = match params.chart_type.as_str() {
96            "line" => ChartKind::Line,
97            "area" => ChartKind::Area,
98            "pie" => ChartKind::Pie,
99            _ => ChartKind::Bar,
100        };
101
102        let ui = UiResponse::new(vec![Component::Chart(Chart {
103            id: None,
104            title: params.title,
105            kind,
106            data: params.data,
107            x_key: params.x_key,
108            y_keys: params.y_keys,
109            x_label: None,
110            y_label: None,
111            show_legend: true,
112            colors: None,
113        })]);
114
115        render_ui_response_with_protocol(ui, &protocol_options, "chart")
116    }
117}