feat(meta): add _meta field to prompts, resources and paginated result (#558)
This commit is contained in:
parent
eb5a7f7408
commit
81411fc12d
3 changed files with 195 additions and 8 deletions
|
|
@ -18,6 +18,8 @@ pub struct PromptAttribute {
|
|||
pub arguments: Option<Expr>,
|
||||
/// Optional icons for the prompt
|
||||
pub icons: Option<Expr>,
|
||||
/// Optional metadata for the prompt
|
||||
pub meta: Option<Expr>,
|
||||
}
|
||||
|
||||
pub struct ResolvedPromptAttribute {
|
||||
|
|
@ -26,6 +28,7 @@ pub struct ResolvedPromptAttribute {
|
|||
pub description: Option<Expr>,
|
||||
pub arguments: Expr,
|
||||
pub icons: Option<Expr>,
|
||||
pub meta: Option<Expr>,
|
||||
}
|
||||
|
||||
impl ResolvedPromptAttribute {
|
||||
|
|
@ -36,6 +39,7 @@ impl ResolvedPromptAttribute {
|
|||
arguments,
|
||||
title,
|
||||
icons,
|
||||
meta,
|
||||
} = self;
|
||||
let description = if let Some(description) = description {
|
||||
quote! { Some(#description.into()) }
|
||||
|
|
@ -52,6 +56,11 @@ impl ResolvedPromptAttribute {
|
|||
} else {
|
||||
quote! { None }
|
||||
};
|
||||
let meta = if let Some(meta) = meta {
|
||||
quote! { Some(#meta) }
|
||||
} else {
|
||||
quote! { None }
|
||||
};
|
||||
let tokens = quote! {
|
||||
pub fn #fn_ident() -> rmcp::model::Prompt {
|
||||
rmcp::model::Prompt {
|
||||
|
|
@ -60,6 +69,7 @@ impl ResolvedPromptAttribute {
|
|||
arguments: #arguments,
|
||||
title: #title,
|
||||
icons: #icons,
|
||||
meta: #meta,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -114,6 +124,7 @@ pub fn prompt(attr: TokenStream, input: TokenStream) -> syn::Result<TokenStream>
|
|||
arguments: arguments.clone(),
|
||||
title: attribute.title,
|
||||
icons: attribute.icons,
|
||||
meta: attribute.meta,
|
||||
};
|
||||
let prompt_attr_fn = resolved_prompt_attr.into_fn(prompt_attr_fn_ident.clone())?;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use syn::{Expr, ImplItem, ItemImpl, parse_quote};
|
|||
#[darling(default)]
|
||||
pub struct PromptHandlerAttribute {
|
||||
pub router: Option<Expr>,
|
||||
pub meta: Option<Expr>,
|
||||
}
|
||||
|
||||
pub fn prompt_handler(attr: TokenStream, input: TokenStream) -> syn::Result<TokenStream> {
|
||||
|
|
@ -40,6 +41,12 @@ pub fn prompt_handler(attr: TokenStream, input: TokenStream) -> syn::Result<Toke
|
|||
}
|
||||
};
|
||||
|
||||
let meta = if let Some(meta) = attribute.meta {
|
||||
quote! { Some(#meta) }
|
||||
} else {
|
||||
quote! { None }
|
||||
};
|
||||
|
||||
// Add list_prompts implementation
|
||||
let list_prompts_impl: ImplItem = parse_quote! {
|
||||
async fn list_prompts(
|
||||
|
|
@ -50,6 +57,7 @@ pub fn prompt_handler(attr: TokenStream, input: TokenStream) -> syn::Result<Toke
|
|||
let prompts = #router_expr.list_all();
|
||||
Ok(ListPromptsResult {
|
||||
prompts,
|
||||
meta: #meta,
|
||||
next_cursor: None,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use syn::{Expr, ImplItem, ItemImpl};
|
|||
#[darling(default)]
|
||||
pub struct ToolHandlerAttribute {
|
||||
pub router: Expr,
|
||||
pub meta: Option<Expr>,
|
||||
}
|
||||
|
||||
impl Default for ToolHandlerAttribute {
|
||||
|
|
@ -16,13 +17,14 @@ impl Default for ToolHandlerAttribute {
|
|||
self.tool_router
|
||||
})
|
||||
.unwrap(),
|
||||
meta: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tool_handler(attr: TokenStream, input: TokenStream) -> syn::Result<TokenStream> {
|
||||
let attr_args = NestedMeta::parse_meta_list(attr)?;
|
||||
let ToolHandlerAttribute { router } = ToolHandlerAttribute::from_list(&attr_args)?;
|
||||
let ToolHandlerAttribute { router, meta } = ToolHandlerAttribute::from_list(&attr_args)?;
|
||||
let mut item_impl = syn::parse2::<ItemImpl>(input.clone())?;
|
||||
let tool_call_fn = quote! {
|
||||
async fn call_tool(
|
||||
|
|
@ -34,13 +36,24 @@ pub fn tool_handler(attr: TokenStream, input: TokenStream) -> syn::Result<TokenS
|
|||
#router.call(tcc).await
|
||||
}
|
||||
};
|
||||
|
||||
let result_meta = if let Some(meta) = meta {
|
||||
quote! { Some(#meta) }
|
||||
} else {
|
||||
quote! { None }
|
||||
};
|
||||
|
||||
let tool_list_fn = quote! {
|
||||
async fn list_tools(
|
||||
&self,
|
||||
_request: Option<rmcp::model::PaginatedRequestParam>,
|
||||
_context: rmcp::service::RequestContext<rmcp::RoleServer>,
|
||||
) -> Result<rmcp::model::ListToolsResult, rmcp::ErrorData> {
|
||||
Ok(rmcp::model::ListToolsResult::with_all_items(#router.list_all()))
|
||||
Ok(rmcp::model::ListToolsResult{
|
||||
tools: #router.list_all(),
|
||||
meta: #result_meta,
|
||||
next_cursor: None,
|
||||
})
|
||||
}
|
||||
};
|
||||
let tool_call_fn = syn::parse2::<ImplItem>(tool_call_fn)?;
|
||||
|
|
|
|||
Loading…
Reference in a new issue