use crate::{ElicitCommunicator, ElicitResult, Elicitation, Prompt, Select};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum StringStyle {
#[default]
Human,
Agent,
}
impl Prompt for StringStyle {
fn prompt() -> Option<&'static str> {
Some("Select elicitation style:")
}
}
impl Select for StringStyle {
fn options() -> Vec<Self> {
vec![Self::Human, Self::Agent]
}
fn labels() -> Vec<String> {
vec!["human".to_string(), "agent".to_string()]
}
fn from_label(label: &str) -> Option<Self> {
match label {
"human" => Some(Self::Human),
"agent" => Some(Self::Agent),
_ => None,
}
}
}
impl Elicitation for StringStyle {
type Style = ();
async fn elicit<C: ElicitCommunicator>(communicator: &C) -> ElicitResult<Self> {
let prompt = <Self as Prompt>::prompt().unwrap();
let labels = <Self as Select>::labels();
let formatted_prompt = format!("{}\nOptions: {}", prompt, labels.join(", "));
let response = communicator.send_prompt(&formatted_prompt).await?;
<Self as Select>::from_label(response.trim()).ok_or_else(|| {
crate::ElicitError::from(crate::ElicitErrorKind::ParseError(format!(
"Invalid style selection: {}",
response.trim()
)))
})
}
}
impl Prompt for String {
fn prompt() -> Option<&'static str> {
Some("Please enter text:")
}
}
impl Elicitation for String {
type Style = StringStyle;
#[tracing::instrument(skip(communicator))]
async fn elicit<C: ElicitCommunicator>(communicator: &C) -> ElicitResult<Self> {
let style = communicator.style_or_elicit::<Self>().await?;
tracing::debug!(?style, "Eliciting String with style");
let prompt = match style {
StringStyle::Human => "Please provide a text value:",
StringStyle::Agent => "Value?",
};
communicator.send_prompt(prompt).await
}
}