Skip to main content

crabtalk_runtime/
ask_user.rs

1//! Tool schema for the built-in `ask_user` tool.
2//!
3//! Schema types live here. Dispatch logic is server-specific and lives in
4//! the [`RuntimeBridge`](crate::bridge::RuntimeBridge) implementation.
5
6use serde::Deserialize;
7use wcore::{
8    agent::{AsTool, ToolDescription},
9    model::Tool,
10};
11
12/// A single option the user can choose from.
13#[derive(Deserialize, schemars::JsonSchema)]
14pub struct QuestionOption {
15    /// Concise option label (1-5 words).
16    pub label: String,
17    /// Explanation of the choice.
18    pub description: String,
19}
20
21/// A structured question with predefined options.
22#[derive(Deserialize, schemars::JsonSchema)]
23pub struct Question {
24    /// Full question text.
25    pub question: String,
26    /// Short UI title for the question (max 12 chars, e.g. "Database").
27    pub header: String,
28    /// Predefined choices for the user.
29    pub options: Vec<QuestionOption>,
30    /// Allow multiple selections.
31    #[serde(default)]
32    pub multi_select: bool,
33}
34
35/// Ask the user one or more structured questions and wait for their reply.
36#[derive(Deserialize, schemars::JsonSchema)]
37pub struct AskUser {
38    /// The questions to ask the user.
39    pub questions: Vec<Question>,
40}
41
42impl ToolDescription for AskUser {
43    const DESCRIPTION: &'static str = r#"Ask the user one or more structured questions with predefined options. Each question needs a short UI header, the full question text, and options with labels and descriptions. The user picks from the options or types a free-text "Other" answer. Returns JSON mapping question text to selected label. For multi_select, the answer is a comma-joined string like "Option A, Option B"."#;
44}
45
46pub fn tools() -> Vec<Tool> {
47    vec![AskUser::as_tool()]
48}