@@ -117,6 +117,7 @@ use tools::{
117
117
OutputKind ,
118
118
QueuedTool ,
119
119
Tool ,
120
+ ToolOrigin ,
120
121
ToolPermissions ,
121
122
ToolSpec ,
122
123
} ;
@@ -2399,24 +2400,43 @@ impl ChatContext {
2399
2400
style:: Print ( "▔" . repeat( terminal_width) ) ,
2400
2401
) ?;
2401
2402
2402
- self . conversation_state . tools . iter ( ) . for_each ( |( origin, tools) | {
2403
- let to_display = tools
2403
+ let mut origin_tools: Vec < _ > = self . conversation_state . tools . iter ( ) . collect ( ) ;
2404
+
2405
+ // Built in tools always appear first.
2406
+ origin_tools. sort_by ( |( origin_a, _) , ( origin_b, _) | match ( origin_a, origin_b) {
2407
+ ( ToolOrigin :: Native , _) => std:: cmp:: Ordering :: Less ,
2408
+ ( _, ToolOrigin :: Native ) => std:: cmp:: Ordering :: Greater ,
2409
+ ( ToolOrigin :: McpServer ( name_a) , ToolOrigin :: McpServer ( name_b) ) => name_a. cmp ( name_b) ,
2410
+ } ) ;
2411
+
2412
+ for ( origin, tools) in origin_tools. iter ( ) {
2413
+ let mut sorted_tools: Vec < _ > = tools
2404
2414
. iter ( )
2405
2415
. filter ( |FigTool :: ToolSpecification ( spec) | spec. name != DUMMY_TOOL_NAME )
2406
- . fold ( String :: new ( ) , |mut acc, FigTool :: ToolSpecification ( spec) | {
2407
- let width = longest - spec. name . len ( ) + 4 ;
2408
- acc. push_str (
2409
- format ! (
2410
- "- {}{:>width$}{}\n " ,
2411
- spec. name,
2412
- "" ,
2413
- self . tool_permissions. display_label( & spec. name) ,
2414
- width = width
2415
- )
2416
- . as_str ( ) ,
2417
- ) ;
2418
- acc
2419
- } ) ;
2416
+ . collect ( ) ;
2417
+
2418
+ sorted_tools. sort_by_key ( |t| match t {
2419
+ FigTool :: ToolSpecification ( spec) => & spec. name ,
2420
+ } ) ;
2421
+
2422
+ let to_display =
2423
+ sorted_tools
2424
+ . iter ( )
2425
+ . fold ( String :: new ( ) , |mut acc, FigTool :: ToolSpecification ( spec) | {
2426
+ let width = longest - spec. name . len ( ) + 4 ;
2427
+ acc. push_str (
2428
+ format ! (
2429
+ "- {}{:>width$}{}\n " ,
2430
+ spec. name,
2431
+ "" ,
2432
+ self . tool_permissions. display_label( & spec. name) ,
2433
+ width = width
2434
+ )
2435
+ . as_str ( ) ,
2436
+ ) ;
2437
+ acc
2438
+ } ) ;
2439
+
2420
2440
let _ = queue ! (
2421
2441
self . output,
2422
2442
style:: SetAttribute ( Attribute :: Bold ) ,
@@ -2425,7 +2445,7 @@ impl ChatContext {
2425
2445
style:: Print ( to_display) ,
2426
2446
style:: Print ( "\n " )
2427
2447
) ;
2428
- } ) ;
2448
+ }
2429
2449
2430
2450
let loading = self . conversation_state . tool_manager . pending_clients ( ) . await ;
2431
2451
if !loading. is_empty ( ) {
@@ -2444,15 +2464,15 @@ impl ChatContext {
2444
2464
2445
2465
queue ! (
2446
2466
self . output,
2447
- style:: Print ( "\n Trusted tools can be run without confirmation\n " ) ,
2467
+ style:: Print ( "\n Trusted tools will run without confirmation. " ) ,
2448
2468
style:: SetForegroundColor ( Color :: DarkGrey ) ,
2449
2469
style:: Print ( format!( "\n {}\n " , "* Default settings" ) ) ,
2450
2470
style:: Print ( "\n 💡 Use " ) ,
2451
2471
style:: SetForegroundColor ( Color :: Green ) ,
2452
2472
style:: Print ( "/tools help" ) ,
2453
2473
style:: SetForegroundColor ( Color :: Reset ) ,
2454
2474
style:: SetForegroundColor ( Color :: DarkGrey ) ,
2455
- style:: Print ( " to edit permissions." ) ,
2475
+ style:: Print ( " to edit permissions.\n \n " ) ,
2456
2476
style:: SetForegroundColor ( Color :: Reset ) ,
2457
2477
) ?;
2458
2478
} ,
@@ -2594,23 +2614,31 @@ impl ChatContext {
2594
2614
style:: Print ( "\n " ) ,
2595
2615
style:: Print ( format!( "{}\n " , "▔" . repeat( terminal_width) ) ) ,
2596
2616
) ?;
2597
- let prompts_by_server = prompts_wl. iter ( ) . fold (
2598
- HashMap :: < & String , Vec < & PromptBundle > > :: new ( ) ,
2599
- |mut acc, ( prompt_name, bundles) | {
2600
- if prompt_name. contains ( search_word. as_deref ( ) . unwrap_or ( "" ) ) {
2601
- if prompt_name. len ( ) > longest_name. len ( ) {
2602
- longest_name = prompt_name. as_str ( ) ;
2603
- }
2604
- for bundle in bundles {
2605
- acc. entry ( & bundle. server_name )
2606
- . and_modify ( |b| b. push ( bundle) )
2607
- . or_insert ( vec ! [ bundle] ) ;
2617
+ let mut prompts_by_server: Vec < _ > = prompts_wl
2618
+ . iter ( )
2619
+ . fold (
2620
+ HashMap :: < & String , Vec < & PromptBundle > > :: new ( ) ,
2621
+ |mut acc, ( prompt_name, bundles) | {
2622
+ if prompt_name. contains ( search_word. as_deref ( ) . unwrap_or ( "" ) ) {
2623
+ if prompt_name. len ( ) > longest_name. len ( ) {
2624
+ longest_name = prompt_name. as_str ( ) ;
2625
+ }
2626
+ for bundle in bundles {
2627
+ acc. entry ( & bundle. server_name )
2628
+ . and_modify ( |b| b. push ( bundle) )
2629
+ . or_insert ( vec ! [ bundle] ) ;
2630
+ }
2608
2631
}
2609
- }
2610
- acc
2611
- } ,
2612
- ) ;
2613
- for ( i, ( server_name, bundles) ) in prompts_by_server. iter ( ) . enumerate ( ) {
2632
+ acc
2633
+ } ,
2634
+ )
2635
+ . into_iter ( )
2636
+ . collect ( ) ;
2637
+ prompts_by_server. sort_by_key ( |( server_name, _) | server_name. as_str ( ) ) ;
2638
+
2639
+ for ( i, ( server_name, bundles) ) in prompts_by_server. iter_mut ( ) . enumerate ( ) {
2640
+ bundles. sort_by_key ( |bundle| & bundle. prompt_get . name ) ;
2641
+
2614
2642
if i > 0 {
2615
2643
queue ! ( self . output, style:: Print ( "\n " ) ) ?;
2616
2644
}
0 commit comments