Skip to content

Commit 173ae21

Browse files
committed
Updated
1 parent c822511 commit 173ae21

File tree

3 files changed

+102
-16
lines changed

3 files changed

+102
-16
lines changed

dotnet/samples/GettingStartedWithAgents/AzureAIAgent/Step02_AzureAIAgent_Plugins.cs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,36 @@ public async Task UseAzureAgentWithPluginEnumParameter()
6262
}
6363
}
6464

65+
[Fact]
66+
public async Task UseAzureAgentWithPromptFunction()
67+
{
68+
// Define prompt function
69+
KernelFunction promptFunction =
70+
KernelFunctionFactory.CreateFromPrompt(
71+
promptTemplate:
72+
"""
73+
Count the number of vowels in INPUT and report as a markdown table.
74+
75+
INPUT:
76+
{{$input}}
77+
""",
78+
description: "Counts the number of vowels");
79+
80+
// Define the agent
81+
AzureAIAgent agent =
82+
await CreateAzureAgentAsync(
83+
KernelPluginFactory.CreateFromFunctions("AgentPlugin", [promptFunction]),
84+
instructions: "You job is to only and always analyze the vowels in the user input without confirmation.");
85+
86+
agent.Kernel.FunctionInvocationFilters.Add(new PromptFunctionFilter());
87+
88+
// Create the chat history thread to capture the agent interaction.
89+
AzureAIAgentThread thread = new(agent.Client);
90+
91+
// Respond to user input, invoking functions where appropriate.
92+
await InvokeAgentAsync(agent, thread, "Who would know naught of art must learn, act, and then take his ease.");
93+
}
94+
6595
private async Task<AzureAIAgent> CreateAzureAgentAsync(KernelPlugin plugin, string? instructions = null, string? name = null)
6696
{
6797
// Define the agent
@@ -71,7 +101,11 @@ private async Task<AzureAIAgent> CreateAzureAgentAsync(KernelPlugin plugin, stri
71101
null,
72102
instructions);
73103

74-
AzureAIAgent agent = new(definition, this.Client);
104+
AzureAIAgent agent =
105+
new(definition, this.Client)
106+
{
107+
Kernel = this.CreateKernelWithChatCompletion(),
108+
};
75109

76110
// Add to the agent's Kernel
77111
if (plugin != null)
@@ -93,4 +127,14 @@ private async Task InvokeAgentAsync(AzureAIAgent agent, AgentThread thread, stri
93127
this.WriteAgentChatMessage(response);
94128
}
95129
}
130+
131+
private sealed class PromptFunctionFilter : IFunctionInvocationFilter
132+
{
133+
public async Task OnFunctionInvocationAsync(FunctionInvocationContext context, Func<FunctionInvocationContext, Task> next)
134+
{
135+
System.Console.WriteLine($"INVOKING: {context.Function.Name}");
136+
await next.Invoke(context);
137+
System.Console.WriteLine($"RESULT: {context.Result}");
138+
}
139+
}
96140
}

dotnet/samples/GettingStartedWithAgents/Step02_Plugins.cs

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ public async Task UseChatCompletionWithPlugin(bool useChatClient)
2525
name: "Host",
2626
useChatClient: useChatClient);
2727

28-
/// Create the chat history thread to capture the agent interaction.
29-
AgentThread thread = new ChatHistoryAgentThread();
28+
// Create the chat history thread to capture the agent interaction.
29+
ChatHistoryAgentThread thread = new();
3030

3131
// Respond to user input, invoking functions where appropriate.
3232
await InvokeAgentAsync(agent, thread, "Hello");
@@ -45,13 +45,45 @@ public async Task UseChatCompletionWithPluginEnumParameter(bool useChatClient)
4545
KernelPluginFactory.CreateFromType<WidgetFactory>(),
4646
useChatClient: useChatClient);
4747

48-
/// Create the chat history thread to capture the agent interaction.
49-
AgentThread thread = new ChatHistoryAgentThread();
48+
// Create the chat history thread to capture the agent interaction.
49+
ChatHistoryAgentThread thread = new();
5050

5151
// Respond to user input, invoking functions where appropriate.
5252
await InvokeAgentAsync(agent, thread, "Create a beautiful red colored widget for me.");
5353
}
5454

55+
[Theory]
56+
[InlineData(true)]
57+
[InlineData(false)]
58+
public async Task UseChatCompletionWithPromptFunction(bool useChatClient)
59+
{
60+
// Define prompt function
61+
KernelFunction promptFunction =
62+
KernelFunctionFactory.CreateFromPrompt(
63+
promptTemplate:
64+
"""
65+
Count the number of vowels in INPUT and report as a markdown table.
66+
67+
INPUT:
68+
{{$input}}
69+
""",
70+
description: "Counts the number of vowels");
71+
72+
// Define the agent
73+
ChatCompletionAgent agent = CreateAgentWithPlugin(
74+
KernelPluginFactory.CreateFromFunctions("AgentPlugin", [promptFunction]),
75+
instructions: "You job is to only and always analyze the vowels in the user input without confirmation.",
76+
useChatClient: useChatClient);
77+
78+
agent.Kernel.FunctionInvocationFilters.Add(new PromptFunctionFilter());
79+
80+
// Create the chat history thread to capture the agent interaction.
81+
ChatHistoryAgentThread thread = new();
82+
83+
// Respond to user input, invoking functions where appropriate.
84+
await InvokeAgentAsync(agent, thread, "Who would know naught of art must learn, act, and then take his ease.");
85+
}
86+
5587
[Theory]
5688
[InlineData(true)]
5789
[InlineData(false)]
@@ -72,8 +104,8 @@ public async Task UseChatCompletionWithTemplateExecutionSettings(bool useChatCli
72104

73105
agent.Kernel.Plugins.AddFromType<WidgetFactory>();
74106

75-
/// Create the chat history thread to capture the agent interaction.
76-
AgentThread thread = new ChatHistoryAgentThread();
107+
// Create the chat history thread to capture the agent interaction.
108+
ChatHistoryAgentThread thread = new();
77109

78110
// Respond to user input, invoking functions where appropriate.
79111
await InvokeAgentAsync(agent, thread, "Create a beautiful red colored widget for me.");
@@ -88,13 +120,13 @@ private ChatCompletionAgent CreateAgentWithPlugin(
88120
bool useChatClient = false)
89121
{
90122
ChatCompletionAgent agent =
91-
new()
92-
{
93-
Instructions = instructions,
94-
Name = name,
95-
Kernel = this.CreateKernelWithChatCompletion(useChatClient, out _),
96-
Arguments = new KernelArguments(new PromptExecutionSettings() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() }),
97-
};
123+
new()
124+
{
125+
Instructions = instructions,
126+
Name = name,
127+
Kernel = this.CreateKernelWithChatCompletion(useChatClient, out _),
128+
Arguments = new KernelArguments(new PromptExecutionSettings() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() }),
129+
};
98130

99131
// Initialize plugin and add to the agent's Kernel (same as direct Kernel usage).
100132
agent.Kernel.Plugins.Add(plugin);
@@ -113,4 +145,14 @@ private async Task InvokeAgentAsync(ChatCompletionAgent agent, AgentThread threa
113145
this.WriteAgentChatMessage(response);
114146
}
115147
}
148+
149+
private sealed class PromptFunctionFilter : IFunctionInvocationFilter
150+
{
151+
public async Task OnFunctionInvocationAsync(FunctionInvocationContext context, Func<FunctionInvocationContext, Task> next)
152+
{
153+
System.Console.WriteLine($"INVOKING: {context.Function.Name}");
154+
await next.Invoke(context);
155+
System.Console.WriteLine($"RESULT: {context.Result}");
156+
}
157+
}
116158
}

dotnet/src/InternalUtilities/samples/InternalUtilities/BaseTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ protected IChatClient AddChatClientToKernel(IKernelBuilder builder)
120120
.AsIChatClient();
121121
}
122122

123-
var functionCallingChatClient = chatClient!.AsBuilder().UseKernelFunctionInvocation().Build();
124-
builder.Services.AddTransient<IChatClient>((sp) => functionCallingChatClient);
123+
IChatClient functionCallingChatClient = chatClient.AsBuilder().UseKernelFunctionInvocation().Build();
124+
builder.Services.AddSingleton(functionCallingChatClient);
125125
return functionCallingChatClient;
126126
#pragma warning restore CA2000 // Dispose objects before losing scope
127127
}

0 commit comments

Comments
 (0)