turbomcp_protocol/context/
elicitation.rs

1//! Elicitation context types for server-initiated user input requests.
2//!
3//! This module contains types for handling elicitation requests where the server
4//! needs to prompt the user for additional information during request processing.
5
6use std::collections::HashMap;
7
8use serde::{Deserialize, Serialize};
9use uuid::Uuid;
10
11use super::client::ClientSession;
12use crate::types::Timestamp;
13
14/// Context for server-initiated elicitation (user input) requests
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct ElicitationContext {
17    /// Unique elicitation request ID
18    pub elicitation_id: String,
19    /// Message presented to user
20    pub message: String,
21    /// Schema for user input validation (using protocol `ElicitationSchema` when available)
22    pub schema: serde_json::Value,
23    /// Input constraints and hints
24    pub constraints: Option<serde_json::Value>,
25    /// Default values for fields
26    pub defaults: Option<HashMap<String, serde_json::Value>>,
27    /// Whether input is required or optional
28    pub required: bool,
29    /// Timeout for user response in milliseconds
30    pub timeout_ms: Option<u64>,
31    /// Cancellation support
32    pub cancellable: bool,
33    /// Client session information
34    pub client_session: Option<ClientSession>,
35    /// Timestamp of elicitation request
36    pub requested_at: Timestamp,
37    /// Current elicitation state
38    pub state: ElicitationState,
39    /// Custom elicitation metadata
40    pub metadata: HashMap<String, serde_json::Value>,
41}
42
43/// State of an elicitation request
44#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
45pub enum ElicitationState {
46    /// Waiting for user response
47    Pending,
48    /// User provided input
49    Accepted,
50    /// User explicitly declined
51    Declined,
52    /// User cancelled/dismissed
53    Cancelled,
54    /// Response timeout exceeded
55    TimedOut,
56}
57
58impl ElicitationContext {
59    /// Create a new elicitation context
60    pub fn new(message: String, schema: serde_json::Value) -> Self {
61        Self {
62            elicitation_id: Uuid::new_v4().to_string(),
63            message,
64            schema,
65            constraints: None,
66            defaults: None,
67            required: true,
68            timeout_ms: Some(30000),
69            cancellable: true,
70            client_session: None,
71            requested_at: Timestamp::now(),
72            state: ElicitationState::Pending,
73            metadata: HashMap::new(),
74        }
75    }
76
77    /// Set the client session
78    pub fn with_client_session(mut self, session: ClientSession) -> Self {
79        self.client_session = Some(session);
80        self
81    }
82
83    /// Set the timeout
84    pub fn with_timeout(mut self, timeout_ms: u64) -> Self {
85        self.timeout_ms = Some(timeout_ms);
86        self
87    }
88
89    /// Update the state
90    pub fn set_state(&mut self, state: ElicitationState) {
91        self.state = state;
92    }
93
94    /// Check if elicitation is complete
95    pub fn is_complete(&self) -> bool {
96        !matches!(self.state, ElicitationState::Pending)
97    }
98}