44using System ;
55using System . Collections . Generic ;
66using System . Diagnostics . CodeAnalysis ;
7+ using System . Threading ;
8+ using System . Threading . Tasks ;
79using Microsoft . Shared . Diagnostics ;
810
911namespace Microsoft . Extensions . AI ;
@@ -12,30 +14,77 @@ namespace Microsoft.Extensions.AI;
1214/// Represents a logical grouping of tools that can be dynamically expanded.
1315/// </summary>
1416/// <remarks>
15- /// A <see cref="AIToolGroup"/> supplies a stable ordered list of <see cref="AITool"/> instances.
16- /// Group membership is determined by reference equality of the tool instances.
17+ /// <para>
18+ /// A <see cref="AIToolGroup"/> is an <see cref="AITool"/> that supplies an ordered list of <see cref="AITool"/> instances
19+ /// via the <see cref="GetToolsAsync"/> method. This enables grouping tools together for organizational purposes
20+ /// and allows for dynamic tool selection based on context.
21+ /// </para>
22+ /// <para>
23+ /// Tool groups can be used independently or in conjunction with <see cref="ToolGroupingChatClient"/> to implement
24+ /// hierarchical tool selection, where groups are initially collapsed and can be expanded on demand.
25+ /// </para>
1726/// </remarks>
1827[ Experimental ( "MEAI001" ) ]
19- public sealed class AIToolGroup
28+ public abstract class AIToolGroup : AITool
2029{
30+ private readonly string _name ;
31+ private readonly string _description ;
32+
2133 /// <summary>Initializes a new instance of the <see cref="AIToolGroup"/> class.</summary>
2234 /// <param name="name">Group name (identifier used by the expansion function).</param>
2335 /// <param name="description">Human readable description of the group.</param>
24- /// <param name="tools">Ordered tools contained in the group.</param>
25- /// <exception cref="ArgumentNullException">If any argument is null.</exception>
26- public AIToolGroup ( string name , string description , IReadOnlyList < AITool > tools )
36+ /// <exception cref="ArgumentNullException"><paramref name="name"/> is <see langword="null"/>.</exception>
37+ protected AIToolGroup ( string name , string description )
2738 {
28- Name = Throw . IfNull ( name ) ;
29- Description = description ?? string . Empty ;
30- Tools = Throw . IfNull ( tools ) ;
39+ _name = Throw . IfNull ( name ) ;
40+ _description = Throw . IfNull ( description ) ;
3141 }
3242
3343 /// <summary>Gets the group name.</summary>
34- public string Name { get ; }
44+ public override string Name => _name ;
3545
3646 /// <summary>Gets the group description.</summary>
37- public string Description { get ; }
47+ public override string Description => _description ;
3848
39- /// <summary>Gets the ordered tools belonging to the group.</summary>
40- public IReadOnlyList < AITool > Tools { get ; }
49+ /// <summary>Creates a tool group with a static list of tools.</summary>
50+ /// <param name="name">Group name (identifier used by the expansion function).</param>
51+ /// <param name="description">Human readable description of the group.</param>
52+ /// <param name="tools">Ordered tools contained in the group.</param>
53+ /// <returns>An <see cref="AIToolGroup"/> instance containing the specified tools.</returns>
54+ /// <exception cref="ArgumentNullException"><paramref name="name"/> or <paramref name="tools"/> is <see langword="null"/>.</exception>
55+ public static AIToolGroup Create ( string name , string description , IReadOnlyList < AITool > tools )
56+ {
57+ _ = Throw . IfNull ( name ) ;
58+ _ = Throw . IfNull ( tools ) ;
59+ return new StaticAIToolGroup ( name , description , tools ) ;
60+ }
61+
62+ /// <summary>
63+ /// Asynchronously retrieves the ordered list of tools belonging to this group.
64+ /// </summary>
65+ /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests.</param>
66+ /// <returns>A <see cref="ValueTask{TResult}"/> representing the asynchronous operation, containing the ordered list of tools in the group.</returns>
67+ /// <remarks>
68+ /// The returned list may contain other <see cref="AIToolGroup"/> instances, enabling hierarchical tool organization.
69+ /// Implementations should ensure the returned list is stable and deterministic for a given group instance.
70+ /// </remarks>
71+ public abstract ValueTask < IReadOnlyList < AITool > > GetToolsAsync ( CancellationToken cancellationToken = default ) ;
72+
73+ /// <summary>A tool group implementation that returns a static list of tools.</summary>
74+ private sealed class StaticAIToolGroup : AIToolGroup
75+ {
76+ private readonly IReadOnlyList < AITool > _tools ;
77+
78+ public StaticAIToolGroup ( string name , string description , IReadOnlyList < AITool > tools )
79+ : base ( name , description )
80+ {
81+ _tools = tools ;
82+ }
83+
84+ public override ValueTask < IReadOnlyList < AITool > > GetToolsAsync ( CancellationToken cancellationToken = default )
85+ {
86+ cancellationToken . ThrowIfCancellationRequested ( ) ;
87+ return new ValueTask < IReadOnlyList < AITool > > ( _tools ) ;
88+ }
89+ }
4190}
0 commit comments