///|
pub(all) enum ElicitationAction {
Accept
Decline
Cancel
} derive(Debug, Eq)
///|
/// Elicitation form values. Numeric content keeps its wire literal through
/// `ExactNumber`, mirroring `ProgressToken`; `Number` remains a convenience
/// constructor for programmatic values.
pub(all) enum ElicitationValue {
String(String)
Number(Double)
ExactNumber(JsonNumber)
Boolean(Bool)
Strings(Array[String])
} derive(Debug)
///|
pub fn ElicitationAction::from_json(
value : Json,
) -> ElicitationAction raise MCPError {
match value {
String("accept") => Accept
String("decline") => Decline
String("cancel") => Cancel
_ => raise InvalidParams("Invalid elicitation action")
}
}
///|
pub impl ToJson for ElicitationAction with fn to_json(self) {
Json::string(
match self {
Accept => "accept"
Decline => "decline"
Cancel => "cancel"
},
)
}
///|
pub fn ElicitationValue::from_json(
value : Json,
) -> ElicitationValue raise MCPError {
match value {
String(value) => ElicitationValue::String(value)
Number(_, ..) => ElicitationValue::ExactNumber(JsonNumber::from_json(value))
True => ElicitationValue::Boolean(true)
False => ElicitationValue::Boolean(false)
Array(values) =>
ElicitationValue::Strings(
values.map(value => {
match value {
String(value) => value
_ => raise InvalidParams("Elicitation arrays must contain strings")
}
}),
)
_ =>
raise InvalidParams(
"Elicitation content values must be strings, finite numbers, booleans or string arrays",
)
}
}
///|
pub impl ToJson for ElicitationValue with fn to_json(self) {
match self {
String(value) => Json::string(value)
Number(value) => Json::number(value)
ExactNumber(value) => value.to_json()
Boolean(value) => Json::boolean(value)
Strings(values) => Json(values)
}
}
///|
pub impl Eq for ElicitationValue with fn equal(self, other) {
match (self, other) {
(String(left), String(right)) => left == right
(Boolean(left), Boolean(right)) => left == right
(Strings(left), Strings(right)) => left == right
(Number(_), _) | (_, Number(_)) => {
// Convenience doubles compare by exact numeric identity.
let left = JsonNumber::from_json(self.to_json()) catch {
_ => return false
}
let right = JsonNumber::from_json(other.to_json()) catch {
_ => return false
}
left == right
}
(ExactNumber(left), ExactNumber(right)) => left == right
_ => false
}
}
///|
pub fn ElicitationRequest::form(
message : String,
requested_schema : Json,
explicit_mode~ : Bool = false,
meta? : Map[String, Json],
) -> ElicitationRequest {
Form(message, requested_schema~, explicit_mode~, meta~, extensions=Map([]))
}
///|
pub fn ElicitationRequest::url(
message : String,
url : String,
elicitation_id? : String,
meta? : Map[String, Json],
) -> ElicitationRequest {
Url(message, url~, elicitation_id~, meta~, extensions=Map([]))
}
///|
pub fn ElicitationRequest::from_json(
value : Json,
) -> ElicitationRequest raise MCPError {
let fields = wire_object(value)
let message = wire_string(fields, "message")
let meta = wire_optional_object(fields, "_meta")
match fields.get("mode") {
None | Some(String("form")) => {
let requested_schema = match fields.get("requestedSchema") {
Some(Object(schema)) if schema.get("type") is Some(String("object")) =>
Json::object(schema.copy())
_ =>
raise InvalidParams(
"Elicitation form requestedSchema must have an object root",
)
}
check_elicitation_schema(requested_schema)
Form(
message,
requested_schema~,
explicit_mode=fields.contains("mode"),
meta~,
extensions=wire_extensions(fields, [
"message", "requestedSchema", "mode", "_meta",
]),
)
}
Some(String("url")) => {
let url = wire_string(fields, "url")
if !valid_elicitation_url(url) {
raise InvalidParams("Elicitation URL must be a valid absolute URL")
}
Url(
message,
url~,
elicitation_id=wire_optional_string(fields, "elicitationId"),
meta~,
extensions=wire_extensions(fields, [
"message", "mode", "url", "elicitationId", "_meta",
]),
)
}
_ => raise InvalidParams("Elicitation mode must be form or url")
}
}
///|
pub impl ToJson for ElicitationRequest with fn to_json(self) {
match self {
Form(message, requested_schema~, explicit_mode~, meta~, extensions~) => {
let fields = wire_extensions(extensions, [
"message", "requestedSchema", "mode", "_meta",
])
fields.set("message", Json::string(message))
fields.set("requestedSchema", requested_schema)
if explicit_mode {
fields.set("mode", Json::string("form"))
}
wire_put_meta(fields, meta)
Json::object(fields)
}
Url(message, url~, elicitation_id~, meta~, extensions~) => {
let fields = wire_extensions(extensions, [
"message", "mode", "url", "elicitationId", "_meta",
])
fields.set("message", Json::string(message))
fields.set("mode", Json::string("url"))
fields.set("url", Json::string(url))
wire_put_string(fields, "elicitationId", elicitation_id)
wire_put_meta(fields, meta)
Json::object(fields)
}
}
}
///|
pub fn ElicitationResult::new(
action : ElicitationAction,
content? : Map[String, ElicitationValue],
) -> ElicitationResult {
{ action, content, extensions: Map([]), }
}
///|
pub fn ElicitationResult::from_json(
value : Json,
) -> ElicitationResult raise MCPError {
let fields = wire_object(value)
let action = match fields.get("action") {
Some(value) => ElicitationAction::from_json(value)
None => raise InvalidParams("Missing elicitation action")
}
let content = match fields.get("content") {
None => None
Some(Object(values)) => {
let decoded : Map[String, ElicitationValue] = Map([])
for key, value in values {
decoded.set(key, ElicitationValue::from_json(value))
}
Some(decoded)
}
_ => raise InvalidParams("Elicitation content must be an object")
}
{
action,
content,
extensions: wire_extensions(fields, ["action", "content"]),
}
}
///|
pub impl ToJson for ElicitationResult with fn to_json(self) {
let fields = wire_extensions(self.extensions, ["action", "content"])
fields.set("action", self.action.to_json())
match self.content {
Some(content) => {
let values : Map[String, Json] = Map([])
for key, value in content {
values.set(key, value.to_json())
}
fields.set("content", Json::object(values))
}
None => ()
}
Json::object(fields)
}
///|
pub extend ElicitationAction with ToJson::{to_json}
///|
pub extend ElicitationAction with Eq::{equal, not_equal}
///|
pub extend ElicitationAction with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub extend ElicitationValue with ToJson::{to_json}
///|
pub extend ElicitationValue with Eq::{equal, not_equal}
///|
pub extend ElicitationValue with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub extend ElicitationRequest with ToJson::{to_json}
///|
pub extend ElicitationResult with ToJson::{to_json}