@@ -296,6 +296,35 @@ pub(crate) fn tool_impl_item(attr: TokenStream, mut input: ItemImpl) -> syn::Res
296296 } )
297297}
298298
299+ fn extract_doc_line ( attr : & syn:: Attribute ) -> Option < String > {
300+ if !attr. path ( ) . is_ident ( "doc" ) {
301+ return None ;
302+ }
303+
304+ let name_value = match & attr. meta {
305+ syn:: Meta :: NameValue ( nv) => nv,
306+ _ => return None ,
307+ } ;
308+
309+ let expr_lit = match & name_value. value {
310+ syn:: Expr :: Lit ( lit) => lit,
311+ _ => return None ,
312+ } ;
313+
314+ let lit_str = match & expr_lit. lit {
315+ syn:: Lit :: Str ( s) => s,
316+ _ => return None ,
317+ } ;
318+
319+ let content = lit_str. value ( ) . trim ( ) . to_string ( ) ;
320+
321+ if content. is_empty ( ) {
322+ None
323+ } else {
324+ Some ( content)
325+ }
326+ }
327+
299328pub ( crate ) fn tool_fn_item ( attr : TokenStream , mut input_fn : ItemFn ) -> syn:: Result < TokenStream > {
300329 let mut tool_macro_attrs = ToolAttrs :: default ( ) ;
301330 let args: ToolFnItemAttrs = syn:: parse2 ( attr) ?;
@@ -405,10 +434,19 @@ pub(crate) fn tool_fn_item(attr: TokenStream, mut input_fn: ItemFn) -> syn::Resu
405434 // generate get tool attr function
406435 let tool_attr_fn = {
407436 let description = if let Some ( expr) = tool_macro_attrs. fn_item . description {
437+ // Use explicitly provided description if available
408438 expr
409439 } else {
440+ // Try to extract documentation comments
441+ let doc_content = input_fn
442+ . attrs
443+ . iter ( )
444+ . filter_map ( extract_doc_line)
445+ . collect :: < Vec < _ > > ( )
446+ . join ( "\n " ) ;
447+
410448 parse_quote ! {
411- ""
449+ #doc_content . trim ( ) . to_string ( )
412450 }
413451 } ;
414452 let schema = match & tool_macro_attrs. params {
@@ -657,4 +695,41 @@ mod test {
657695 println ! ( "input: {:#}" , input) ;
658696 Ok ( ( ) )
659697 }
698+ #[ test]
699+ fn test_doc_comment_description ( ) -> syn:: Result < ( ) > {
700+ let attr = quote ! { } ; // No explicit description
701+ let input = quote ! {
702+ /// This is a test description from doc comments
703+ /// with multiple lines
704+ fn test_function( & self ) -> Result <( ) , Error > {
705+ Ok ( ( ) )
706+ }
707+ } ;
708+ let result = tool ( attr, input) ?;
709+
710+ // The output should contain the description from doc comments
711+ let result_str = result. to_string ( ) ;
712+ assert ! ( result_str. contains( "This is a test description from doc comments" ) ) ;
713+ assert ! ( result_str. contains( "with multiple lines" ) ) ;
714+
715+ Ok ( ( ) )
716+ }
717+ #[ test]
718+ fn test_explicit_description_priority ( ) -> syn:: Result < ( ) > {
719+ let attr = quote ! {
720+ description = "Explicit description has priority"
721+ } ;
722+ let input = quote ! {
723+ /// Doc comment description that should be ignored
724+ fn test_function( & self ) -> Result <( ) , Error > {
725+ Ok ( ( ) )
726+ }
727+ } ;
728+ let result = tool ( attr, input) ?;
729+
730+ // The output should contain the explicit description
731+ let result_str = result. to_string ( ) ;
732+ assert ! ( result_str. contains( "Explicit description has priority" ) ) ;
733+ Ok ( ( ) )
734+ }
660735}
0 commit comments