/// Prompt base classes mirroring fastmcp/prompts/base.py.
///|
/// A wrapper for a prompt message with a role.
pub(all) struct Message {
role : @types.Role
content : @types.ContentBlock
} derive(Debug, Eq)
///|
/// Create a message from plain text, user role by default.
pub fn Message::text(
text : String,
role~ : @types.Role = @types.User,
) -> Message {
{ role, content: @types.text_block(text), }
}
///|
/// Create a message from an existing content block, user role by default.
pub fn Message::of_content(
content : @types.ContentBlock,
role~ : @types.Role = @types.User,
) -> Message {
{ role, content, }
}
///|
/// Convert to the wire prompt message.
pub fn Message::to_mcp_prompt_message(self : Message) -> @types.PromptMessage {
{ role: self.role, content: self.content, }
}
///|
/// The canonical result of rendering a prompt.
pub(all) struct PromptResult {
messages : Array[Message]
description : String?
meta : Map[String, Json]?
/// The client-input request when this leg resolved to an input ask
/// (SEP-2322); `messages` is always empty in that case.
input_required : @types.InputRequiredResult?
} derive(Debug, Eq)
///|
/// Create a prompt result from a list of messages.
pub fn PromptResult::new(
messages : Array[Message],
description? : String,
meta? : Map[String, Json],
) -> PromptResult {
{ messages, description, meta, input_required: None, }
}
///|
/// Wrap a client-input ask (SEP-2322) as an ordinary prompt result.
pub fn PromptResult::input_required(
input_required : @types.InputRequiredResult,
) -> PromptResult {
{
messages: [],
description: None,
meta: None,
input_required: Some(input_required),
}
}
///|
/// Whether this result carries a client-input ask (SEP-2322).
pub fn PromptResult::is_input_required(self : PromptResult) -> Bool {
self.input_required is Some(_)
}
///|
/// Convert to the wire get-prompt result.
pub fn PromptResult::to_mcp_prompt_result(
self : PromptResult,
) -> @types.GetPromptResult {
{
description: self.description,
messages: self.messages.map(Message::to_mcp_prompt_message),
cache_control: None,
meta: self.meta,
}
}
///|
/// What a prompt's render function may return: plain text, a message list,
/// or an already-assembled result.
pub(all) enum RenderedPrompt {
Text(String)
Messages(Array[Message])
Ready(PromptResult)
}
///|
/// A prompt template that can be rendered with arguments.
pub(all) struct Prompt {
component : @component.ComponentBase
/// Arguments that can be passed to the prompt.
arguments : Array[@types.PromptArgument]?
render_fn : async (Map[String, Json]) -> RenderedPrompt raise @exceptions.FastMCPError
}
///|
pub impl @component.Component for Prompt with fn base(self) {
self.component
}
///|
pub impl @component.Component for Prompt with fn identifier(self) {
self.component.name
}
///|
pub impl @component.Component for Prompt with fn key(self) {
self.component.key(self.component.name)
}
///|
pub impl @component.Component for Prompt with fn get_meta(self) {
self.component.get_meta()
}
///|
/// Register a prompt; `render_fn` renders it with the given arguments.
pub fn Prompt::new(
name : String,
render_fn~ : async (Map[String, Json]) -> RenderedPrompt raise @exceptions.FastMCPError,
version? : String,
title? : String,
description? : String,
icons? : Array[@types.Icon],
tags~ : @set.Set[String] = @set.Set::from_array([]),
meta? : Map[String, Json],
arguments? : Array[@types.PromptArgument],
) -> Prompt {
{
component: @component.ComponentBase::new(
"prompt",
name,
version?,
title?,
description?,
icons?,
tags~,
meta?,
),
arguments,
render_fn,
}
}
///|
/// Render the prompt with arguments.
pub async fn Prompt::render(
self : Prompt,
arguments : Map[String, Json],
) -> RenderedPrompt raise @exceptions.FastMCPError {
(self.render_fn)(arguments)
}
///|
/// Convert a rendered value to a canonical result.
pub fn Prompt::convert_result(
self : Prompt,
raw_value : RenderedPrompt,
) -> PromptResult {
match raw_value {
Ready(result) => result
Text(text) =>
PromptResult::new(
[Message::text(text)],
description?=self.component.description,
meta?=@component.public_result_meta(self.component.meta),
)
Messages(messages) =>
PromptResult::new(
messages,
description?=self.component.description,
meta?=@component.public_result_meta(self.component.meta),
)
}
}
///|
/// Server entry point for prompt rendering.
pub async fn Prompt::render_result(
self : Prompt,
arguments : Map[String, Json],
) -> PromptResult raise @exceptions.FastMCPError {
self.convert_result(self.render(arguments))
}
///|
/// Convert the prompt to its wire representation.
pub fn Prompt::to_mcp_prompt(self : Prompt) -> @types.Prompt {
{
name: self.component.name,
title: self.component.title,
description: self.component.description,
arguments: self.arguments,
meta: Some(Prompt::get_meta(self)),
}
}
///|
pub extend Message with Debug::{to_repr}
///|
pub extend Message with Eq::{not_equal, equal}
///|
pub extend Prompt with @component.Component::{base, identifier, key, get_meta}
///|
pub extend PromptResult with Debug::{to_repr}
///|
pub extend PromptResult with Eq::{not_equal, equal}