use elicitation::elicit_tool;
use rmcp::ErrorData;
use rmcp::model::{CallToolResult, Content};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use tracing::instrument;
use crate::serde_types::{RectJson, Vec2Json};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "type")]
pub enum ResponseQueryJson {
Clicked,
DoubleClicked,
SecondaryClicked,
Hovered,
HasFocus,
GainedFocus,
LostFocus,
Dragged,
DragReleased,
Changed,
Rect,
DragDelta,
HoverPos,
RequestFocus,
SurrenderFocus,
ShowTooltip {
text: String,
},
SetEnabled {
enabled: bool,
},
Highlight,
ScrollToMe,
ClickedN {
count: usize,
},
ContextMenu,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "type")]
pub enum ResponseInfoJson {
Bool {
value: bool,
},
Rect {
rect: RectJson,
},
Vec2 {
value: Vec2Json,
},
OptionalPos {
pos: Option<Vec2Json>,
},
Action,
}
fn query_result(query: &ResponseQueryJson) -> CallToolResult {
match serde_json::to_string(query) {
Ok(s) => CallToolResult::success(vec![Content::text(s)]),
Err(e) => CallToolResult::error(vec![Content::text(format!("serialize error: {e}"))]),
}
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct EmptyResponseParams {}
#[elicit_tool(
plugin = "egui_response",
name = "response_clicked",
description = "Check if the widget was clicked. Returns ResponseQueryJson::Clicked."
)]
#[instrument(skip_all)]
async fn response_clicked(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::Clicked))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_double_clicked",
description = "Check if the widget was double-clicked. Returns ResponseQueryJson::DoubleClicked.",
emit = None
)]
#[instrument(skip_all)]
async fn response_double_clicked(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::DoubleClicked))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_secondary_clicked",
description = "Check if the widget was right-clicked. Returns ResponseQueryJson::SecondaryClicked.",
emit = None
)]
#[instrument(skip_all)]
async fn response_secondary_clicked(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::SecondaryClicked))
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct ClickedNParams {
pub count: usize,
}
#[elicit_tool(
plugin = "egui_response",
name = "response_clicked_n",
description = "Check if the widget was clicked N times. Returns ResponseQueryJson::ClickedN."
)]
#[instrument(skip_all)]
async fn response_clicked_n(p: ClickedNParams) -> Result<CallToolResult, ErrorData> {
let q = ResponseQueryJson::ClickedN { count: p.count };
Ok(query_result(&q))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_hovered",
description = "Check if the widget is being hovered. Returns ResponseQueryJson::Hovered.",
emit = None
)]
#[instrument(skip_all)]
async fn response_hovered(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::Hovered))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_has_focus",
description = "Check if the widget has keyboard focus. Returns ResponseQueryJson::HasFocus.",
emit = None
)]
#[instrument(skip_all)]
async fn response_has_focus(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::HasFocus))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_gained_focus",
description = "Check if the widget just gained focus. Returns ResponseQueryJson::GainedFocus.",
emit = None
)]
#[instrument(skip_all)]
async fn response_gained_focus(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::GainedFocus))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_lost_focus",
description = "Check if the widget just lost focus. Returns ResponseQueryJson::LostFocus.",
emit = None
)]
#[instrument(skip_all)]
async fn response_lost_focus(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::LostFocus))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_request_focus",
description = "Request keyboard focus for the widget. Returns ResponseQueryJson::RequestFocus.",
emit = None
)]
#[instrument(skip_all)]
async fn response_request_focus(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::RequestFocus))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_surrender_focus",
description = "Surrender keyboard focus from the widget. Returns ResponseQueryJson::SurrenderFocus.",
emit = None
)]
#[instrument(skip_all)]
async fn response_surrender_focus(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::SurrenderFocus))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_dragged",
description = "Check if the widget is being dragged. Returns ResponseQueryJson::Dragged.",
emit = None
)]
#[instrument(skip_all)]
async fn response_dragged(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::Dragged))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_drag_released",
description = "Check if drag was released. Returns ResponseQueryJson::DragReleased.",
emit = None
)]
#[instrument(skip_all)]
async fn response_drag_released(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::DragReleased))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_drag_delta",
description = "Get the drag delta (pointer movement while dragging). Returns ResponseQueryJson::DragDelta.",
emit = None
)]
#[instrument(skip_all)]
async fn response_drag_delta(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::DragDelta))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_changed",
description = "Check if the widget value changed. Returns ResponseQueryJson::Changed.",
emit = None
)]
#[instrument(skip_all)]
async fn response_changed(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::Changed))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_rect",
description = "Get the widget bounding rectangle. Returns ResponseQueryJson::Rect.",
emit = None
)]
#[instrument(skip_all)]
async fn response_rect(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::Rect))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_hover_pos",
description = "Get the pointer position while hovering. Returns ResponseQueryJson::HoverPos.",
emit = None
)]
#[instrument(skip_all)]
async fn response_hover_pos(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::HoverPos))
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct ShowTooltipParams {
pub text: String,
}
#[elicit_tool(
plugin = "egui_response",
name = "response_show_tooltip",
description = "Show a tooltip when the widget is hovered. Returns ResponseQueryJson::ShowTooltip."
)]
#[instrument(skip_all)]
async fn response_show_tooltip(p: ShowTooltipParams) -> Result<CallToolResult, ErrorData> {
let q = ResponseQueryJson::ShowTooltip { text: p.text };
Ok(query_result(&q))
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct SetEnabledParams {
pub enabled: bool,
}
#[elicit_tool(
plugin = "egui_response",
name = "response_set_enabled",
description = "Set the widget enabled/disabled state. Returns ResponseQueryJson::SetEnabled."
)]
#[instrument(skip_all)]
async fn response_set_enabled(p: SetEnabledParams) -> Result<CallToolResult, ErrorData> {
let q = ResponseQueryJson::SetEnabled { enabled: p.enabled };
Ok(query_result(&q))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_highlight",
description = "Highlight the widget for emphasis. Returns ResponseQueryJson::Highlight.",
emit = None
)]
#[instrument(skip_all)]
async fn response_highlight(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::Highlight))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_scroll_to_me",
description = "Scroll to make the widget visible. Returns ResponseQueryJson::ScrollToMe.",
emit = None
)]
#[instrument(skip_all)]
async fn response_scroll_to_me(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::ScrollToMe))
}
#[elicit_tool(
plugin = "egui_response",
name = "response_context_menu",
description = "Show a context menu for the widget. Returns ResponseQueryJson::ContextMenu.",
emit = None
)]
#[instrument(skip_all)]
async fn response_context_menu(p: EmptyResponseParams) -> Result<CallToolResult, ErrorData> {
let _ = p;
Ok(query_result(&ResponseQueryJson::ContextMenu))
}