feat: clickable zoom reset, Pan tool (H), and batch command support
- Clicking the zoom percentage in the menu bar resets zoom to 100%
- New Pan tool (H key) for explicit left-click-drag panning mode
- Batch command support: agents can send multiple operations in a
single WebSocket message via {"type": "Batch", "requests": [...]}
with sequential execution and collected results
- New MCP tool 'batch' accepts a JSON array of request objects
- Nested batches rejected with clear error message
- Updated AGENTS.md with .app rebuild requirement
This commit is contained in:
@@ -187,6 +187,12 @@ pub struct BooleanOpParam {
|
||||
pub stroke_width: Option<f32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
|
||||
pub struct BatchParam {
|
||||
#[schemars(description = "JSON array of request objects. Each object must have a 'type' field and the same parameters as individual tool calls. Example: [{\"type\": \"CreateDrawingElement\", \"shape_type\": \"rectangle\", \"x\": 0, \"y\": 0, \"width\": 100, \"height\": 100}, {\"type\": \"CreateDrawingElement\", \"shape_type\": \"ellipse\", \"center_x\": 200, \"center_y\": 200, \"radius_x\": 50, \"radius_y\": 50}]")]
|
||||
pub requests_json: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AgCanvasServer {
|
||||
ws_url: String,
|
||||
@@ -521,6 +527,35 @@ impl AgCanvasServer {
|
||||
self.call_agcanvas(&request).await
|
||||
}
|
||||
|
||||
#[tool(
|
||||
description = "Send multiple Augmented Canvas operations in one request. Accepts a JSON array of request objects and returns one response per operation in a BatchResult."
|
||||
)]
|
||||
async fn batch(
|
||||
&self,
|
||||
Parameters(params): Parameters<BatchParam>,
|
||||
) -> Result<CallToolResult, McpError> {
|
||||
let requests = match serde_json::from_str::<serde_json::Value>(¶ms.requests_json) {
|
||||
Ok(serde_json::Value::Array(requests)) => requests,
|
||||
Ok(_) => {
|
||||
return Ok(CallToolResult::error(vec![Content::text(
|
||||
"Invalid requests_json: expected a JSON array of request objects",
|
||||
)]))
|
||||
}
|
||||
Err(e) => {
|
||||
return Ok(CallToolResult::error(vec![Content::text(format!(
|
||||
"Invalid requests_json: {}",
|
||||
e
|
||||
))]))
|
||||
}
|
||||
};
|
||||
|
||||
let request = serde_json::json!({
|
||||
"type": "Batch",
|
||||
"requests": requests,
|
||||
});
|
||||
self.call_agcanvas(&request).await
|
||||
}
|
||||
|
||||
#[tool(description = "Delete a drawing element by its ID.")]
|
||||
async fn delete_drawing_element(
|
||||
&self,
|
||||
|
||||
Reference in New Issue
Block a user