1111using Azure . Sdk . Tools . Cli . Helpers ;
1212using ModelContextProtocol . Server ;
1313using OpenAI . Chat ;
14+ using Azure . Sdk . Tools . Cli . Microagents ;
1415
1516namespace Azure . Sdk . Tools . Cli . Tools . Example ;
1617
@@ -26,6 +27,7 @@ public class ExampleTool : MCPTool
2627 private const string ErrorSubCommand = "error" ;
2728 private const string ProcessSubCommand = "process" ;
2829 private const string PowershellSubCommand = "powershell" ;
30+ private const string MicroagentSubCommand = "microagent" ;
2931
3032 // Dependencies injected via constructor
3133 private readonly ILogger < ExampleTool > logger ;
@@ -37,6 +39,7 @@ public class ExampleTool : MCPTool
3739 private readonly IProcessHelper processHelper ;
3840 private readonly IPowershellHelper powershellHelper ;
3941 private readonly TokenUsageHelper tokenUsageHelper ;
42+ private readonly IMicroagentHostService microagentHostService ;
4043
4144 // CLI Options and Arguments
4245 private readonly Argument < string > aiInputArg = new (
@@ -68,6 +71,11 @@ public class ExampleTool : MCPTool
6871 description : "Message to pass to the PowerShell script via parameter" )
6972 { Arity = ArgumentArity . ExactlyOne } ;
7073
74+ private readonly Option < int > fibonacciIndexOption = new (
75+ name : "--fibonacci" ,
76+ description : "Index (0-based) of Fibonacci number to compute using micro-agent" )
77+ { IsRequired = true } ;
78+
7179 private readonly Option < string > tenantOption = new ( [ "--tenant" , "-t" ] , "Tenant ID" ) ;
7280 private readonly Option < string > languageOption = new ( [ "--language" , "-l" ] , "Programming language of the repository" ) ;
7381 private readonly Option < string > promptOption = new ( [ "--prompt" , "-p" ] , "AI prompt text" ) ;
@@ -83,6 +91,7 @@ public ExampleTool(
8391 IProcessHelper processHelper ,
8492 IPowershellHelper powershellHelper ,
8593 TokenUsageHelper tokenUsageHelper ,
94+ IMicroagentHostService microagentHostService ,
8695 AzureOpenAIClient openAIClient
8796 ) : base ( )
8897 {
@@ -95,6 +104,7 @@ AzureOpenAIClient openAIClient
95104 this . processHelper = processHelper ;
96105 this . powershellHelper = powershellHelper ;
97106 this . tokenUsageHelper = tokenUsageHelper ;
107+ this . microagentHostService = microagentHostService ;
98108
99109 // Set command hierarchy - results in: azsdk example
100110 CommandHierarchy = [
@@ -142,13 +152,19 @@ public override Command GetCommand()
142152 powershellCmd . AddArgument ( powershellMessageArg ) ;
143153 powershellCmd . SetHandler ( async ctx => { await HandleCommand ( ctx , ctx . GetCancellationToken ( ) ) ; } ) ;
144154
155+ // Microagent Fibonacci demo sub-command
156+ var microagentCmd = new Command ( MicroagentSubCommand , "Demonstrate micro-agent looping tool calls to compute Fibonacci" ) ;
157+ microagentCmd . AddOption ( fibonacciIndexOption ) ;
158+ microagentCmd . SetHandler ( async ctx => { await HandleCommand ( ctx , ctx . GetCancellationToken ( ) ) ; } ) ;
159+
145160 parentCommand . Add ( azureCmd ) ;
146161 parentCommand . Add ( devopsCmd ) ;
147162 parentCommand . Add ( githubCmd ) ;
148163 parentCommand . Add ( aiCmd ) ;
149164 parentCommand . Add ( errorCmd ) ;
150165 parentCommand . Add ( processCmd ) ;
151166 parentCommand . Add ( powershellCmd ) ;
167+ parentCommand . Add ( microagentCmd ) ;
152168
153169 return parentCommand ;
154170 }
@@ -166,6 +182,7 @@ public override async Task HandleCommand(InvocationContext ctx, CancellationToke
166182 ErrorSubCommand => await DemonstrateErrorHandling ( ctx . ParseResult . GetValueForArgument ( errorInputArg ) , ctx . ParseResult . GetValueForOption ( forceFailureOption ) , ct ) ,
167183 ProcessSubCommand => await DemonstrateProcessExecution ( ctx . ParseResult . GetValueForArgument ( processSleepArg ) , ct ) ,
168184 PowershellSubCommand => await DemonstratePowershellExecution ( ctx . ParseResult . GetValueForArgument ( powershellMessageArg ) , ct ) ,
185+ MicroagentSubCommand => await DemonstrateMicroagentFibonacci ( ctx . ParseResult . GetValueForOption ( fibonacciIndexOption ) , ct ) ,
169186 _ => new ExampleServiceResponse { ResponseError = $ "Unknown command: { commandName } " }
170187 } ;
171188
@@ -486,5 +503,64 @@ public async Task<ExampleServiceResponse> DemonstratePowershellExecution(string
486503 }
487504 }
488505 }
506+
507+ public record Fibonacci
508+ {
509+ public int Index { get ; set ; }
510+ public int Previous { get ; set ; }
511+ public int Current { get ; set ; }
512+ }
513+
514+ [ McpServerTool ( Name = "azsdk_example_microagent_fibonacci" ) , Description ( "Demonstrates micro-agent computing Nth Fibonacci number via iterative tool calls" ) ]
515+ public async Task < DefaultCommandResponse > DemonstrateMicroagentFibonacci ( int n , CancellationToken ct = default )
516+ {
517+ try
518+ {
519+ if ( n < 2 )
520+ {
521+ SetFailure ( ) ;
522+ return new DefaultCommandResponse { ResponseError = "--fibonacci must be >= 2 to exercise the micro-agent (trivial cases are disallowed)" } ;
523+ }
524+
525+ var advanceTool = AgentTool < Fibonacci , Fibonacci > . FromFunc (
526+ name : "advance_state" ,
527+ description : "Advances state by one step" ,
528+ invokeHandler : ( input , ct ) =>
529+ {
530+ return Task . FromResult ( new Fibonacci
531+ {
532+ Index = input . Index + 1 ,
533+ Previous = input . Current ,
534+ Current = input . Previous + input . Current
535+ } ) ;
536+ } ) ;
537+
538+ // Avoid mentioning 'fibonacci' in the instructions so the LLM doesn't try to calculate it directly
539+ var instructions = $ """
540+ Call advance_state repeatedly until the returned index == { n } .
541+ Return the '{ nameof ( Fibonacci . Current ) } ' value when index == { n } .
542+ Initial state is { nameof ( Fibonacci . Index ) } =1, { nameof ( Fibonacci . Previous ) } =0, { nameof ( Fibonacci . Current ) } =1.
543+ """ ;
544+
545+ var agent = new Microagent < int >
546+ {
547+ Instructions = instructions ,
548+ MaxToolCalls = 7 ,
549+ Tools = [ advanceTool ] ,
550+ } ;
551+
552+ var resultValue = await microagentHostService . RunAgentToCompletion ( agent , ct ) ;
553+
554+ tokenUsageHelper . LogCost ( ) ;
555+ return new DefaultCommandResponse { Result = $ "Fibonacci({ n } ) = { resultValue } " } ;
556+ }
557+ catch ( Exception ex )
558+ {
559+ tokenUsageHelper . LogCost ( ) ;
560+ logger . LogError ( ex , "Error demonstrating micro-agent Fibonacci for n={n}" , n ) ;
561+ SetFailure ( ) ;
562+ return new DefaultCommandResponse { ResponseError = $ "Failed to compute Fibonacci({ n } ): { ex . Message } " } ;
563+ }
564+ }
489565}
490566#endif
0 commit comments