Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
246 commits
Select commit Hold shift + click to select a range
ed2bd33
Agent framework
crickman Mar 30, 2024
33f1c0e
Project structure
crickman Mar 31, 2024
ca4c1a6
Readme cleanup
crickman Mar 31, 2024
d58e416
Build
crickman Mar 31, 2024
74d8deb
Tests and examples
crickman Mar 31, 2024
de71d83
Test coverage
crickman Mar 31, 2024
5236c28
Update tests
crickman Mar 31, 2024
308d4b8
Spelling
crickman Mar 31, 2024
905e438
Namespace
crickman Mar 31, 2024
d86380d
Coverage
crickman Mar 31, 2024
4273aae
PlugIn Example
crickman Apr 1, 2024
2a1aba2
Merge branch 'main' into feature_agent_framework
crickman Apr 1, 2024
bd98124
Test comments & clean-up
crickman Apr 1, 2024
070f82d
Merge branch 'feature_agent_framework' of https://github.com/microsof…
crickman Apr 1, 2024
ca53ecd
MVP
crickman Apr 1, 2024
fbdf862
Format Fix
crickman Apr 1, 2024
72b720e
Remove System.Linq.Async
crickman Apr 1, 2024
425af3c
Build GD
crickman Apr 1, 2024
000f079
Rollback
crickman Apr 1, 2024
e7d365a
Merge branch 'main' into feature_agent_framework
crickman Apr 1, 2024
6a4fb99
Build plz
crickman Apr 1, 2024
4e880e3
Format
crickman Apr 1, 2024
1e01292
Project form
crickman Apr 1, 2024
264cc82
Extra instructions
crickman Apr 1, 2024
f3c54c4
ChatCompletionAgent UT
crickman Apr 1, 2024
0e44caf
Coverage
crickman Apr 1, 2024
7225767
Coverage
crickman Apr 1, 2024
22fc872
TODO - Render Filters
crickman Apr 1, 2024
6416ea6
Experiment def
crickman Apr 1, 2024
7dbe37a
Bootstrap AgentChat
crickman Apr 1, 2024
ba16b05
Fix experiments
crickman Apr 2, 2024
2ac41f0
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman Apr 2, 2024
8ba1c91
Introducing AgentChat
crickman Apr 2, 2024
42e0bcd
Comment
crickman Apr 2, 2024
56bc185
Tuning
crickman Apr 2, 2024
2cc1686
Merge branch 'main' into feature_agent_framework
crickman Apr 2, 2024
aa7231c
Spelling
crickman Apr 2, 2024
01c7d85
Merge branch 'feature_agent_framework' of https://github.com/microsof…
crickman Apr 2, 2024
8f99aa6
TODO Comments
crickman Apr 2, 2024
9048a69
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman Apr 2, 2024
cd5ed82
Example
crickman Apr 2, 2024
7977d0a
Spelling
crickman Apr 2, 2024
b931c48
More tests
crickman Apr 2, 2024
f334ccc
Merge branch 'main' into feature_agent_framework
crickman Apr 2, 2024
f57d1ca
Refine
crickman Apr 2, 2024
75fc135
Merge branch 'main' into feature_agent_framework
crickman Apr 2, 2024
ac090fd
Merge branch 'main' into feature_agent_framework
crickman Apr 2, 2024
dec0de2
Checkpoint
crickman Apr 2, 2024
0984733
Less experiment ids
crickman Apr 2, 2024
f8a8365
Identity
crickman Apr 2, 2024
4f436a3
Merge from main
crickman Apr 2, 2024
0438231
Update test
crickman Apr 2, 2024
737cd2f
Test checkpoint
crickman Apr 3, 2024
acc0d2a
Encoder fix
crickman Apr 3, 2024
180d37d
Encoder2
crickman Apr 3, 2024
713d20c
Test cleanup
crickman Apr 3, 2024
7fe0af3
Needs unit test
crickman Apr 3, 2024
afde6b3
Yeah
crickman Apr 3, 2024
ab1383c
BroadcastQueue Failure Propagation
crickman Apr 3, 2024
fdedc20
Merge branch 'main' into feature_agent_framework
crickman Apr 3, 2024
7144324
Update from PR Comments
crickman Apr 3, 2024
cc5c211
Merge branch 'feature_agent_framework' of https://github.com/microsof…
crickman Apr 3, 2024
143394b
Merge branch 'main' into feature_agent_framework
crickman Apr 3, 2024
8908968
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman Apr 3, 2024
a562a7e
Merged from main
crickman Apr 3, 2024
6277f59
Fix merge
crickman Apr 3, 2024
c0a62d0
Merge branch 'feature_agent_framework' of https://github.com/microsof…
crickman Apr 3, 2024
ffeeeff
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman Apr 3, 2024
1aa05cd
Fix merge
crickman Apr 3, 2024
e9736ec
Namespace
crickman Apr 3, 2024
4466048
Coverage
crickman Apr 3, 2024
5a021a8
Update from PR comments
crickman Apr 3, 2024
8dfcf5d
PR Comments
crickman Apr 3, 2024
c1dae3f
Resolve merge
crickman Apr 3, 2024
60fe17f
Typo
crickman Apr 3, 2024
dd50899
Cleanup
crickman Apr 3, 2024
c22176f
Merge branch 'main' into feature_agent_framework
crickman Apr 3, 2024
10823e2
Heck ya
crickman Apr 4, 2024
104ebbd
Fix
crickman Apr 4, 2024
5587125
Termination Strategies
crickman Apr 4, 2024
07c9774
Ack
crickman Apr 4, 2024
9a2b4e2
Strategies
crickman Apr 4, 2024
c17fcb4
Merge branch 'main' into feature_agent_framework
crickman Apr 4, 2024
c58191c
CancellationToken default
crickman Apr 4, 2024
7ac3051
Merge branch 'feature_agent_framework' of https://github.com/microsof…
crickman Apr 4, 2024
16b438b
Merge branch 'main' into feature_agent_framework
crickman Apr 4, 2024
92b9da7
Merge branch 'main' into feature_agent_framework
crickman Apr 4, 2024
0878281
Merge branch 'main' into feature_agent_framework
crickman Apr 4, 2024
734656e
Type/concept rename
crickman Apr 4, 2024
769d658
Merge branch 'feature_agent_framework' of https://github.com/microsof…
crickman Apr 4, 2024
70871f9
Latest and greatest
crickman Apr 4, 2024
b9706e4
Nexus scrub
crickman Apr 4, 2024
5436fed
Abstraction rename
crickman Apr 4, 2024
c2020fd
One more (Abstractions folder name)
crickman Apr 4, 2024
de2dad0
Remove connector dependency
crickman Apr 4, 2024
e2860cc
Re-add connector reference downstream
crickman Apr 4, 2024
adf0bee
Review
crickman Apr 4, 2024
af41586
Comment
crickman Apr 4, 2024
73079ed
Comments
crickman Apr 4, 2024
6b7a0b7
Support 'init'
crickman Apr 4, 2024
df620ef
Resolve merge
crickman Apr 4, 2024
a463b36
AgentGroupChat
crickman Apr 4, 2024
2e60f01
Clean
crickman Apr 4, 2024
e46cf2d
Comment
crickman Apr 4, 2024
503dd98
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman Apr 4, 2024
4a0dd62
Nuget description
crickman Apr 4, 2024
9a2c957
Nuget
crickman Apr 4, 2024
0482a96
Assembly naming
crickman Apr 4, 2024
90e642a
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman Apr 4, 2024
69ec8c6
Build
crickman Apr 4, 2024
6d446c7
Build
crickman Apr 4, 2024
d5be2ca
Comments
crickman Apr 4, 2024
75226d2
Merge branch 'main' into feature_agent_framework
crickman Apr 5, 2024
9478524
Comments Checkpoint
crickman Apr 7, 2024
6fe407e
Dead code
crickman Apr 7, 2024
1143f5a
More comments + typo
crickman Apr 7, 2024
5d37582
More PR updates
crickman Apr 7, 2024
9479b49
Don't copy
crickman Apr 7, 2024
f8d758c
Blank line
crickman Apr 7, 2024
b7f35f7
Merge from feature
crickman Apr 7, 2024
b711530
More
crickman Apr 7, 2024
14929f0
Namespace
crickman Apr 7, 2024
e6c6991
public => private: perfect
crickman Apr 7, 2024
0e8b981
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman Apr 7, 2024
b06b7e2
Remove namespace
crickman Apr 7, 2024
b6566ff
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman Apr 7, 2024
8291e0f
init KernelArguments
crickman Apr 7, 2024
d8f4c2e
Signatures
crickman Apr 7, 2024
510751f
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman Apr 7, 2024
822f494
Test fix
crickman Apr 7, 2024
b3da6a6
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman Apr 7, 2024
46f7060
Build
crickman Apr 7, 2024
23395cf
Fix mock
crickman Apr 7, 2024
546e5f0
Merge branch 'main' into feature_agent_framework
crickman Apr 8, 2024
83613aa
Sans templatization
crickman Apr 8, 2024
e7f2294
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman Apr 8, 2024
bbe584b
Namespace
crickman Apr 8, 2024
09677a2
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman Apr 8, 2024
6a13d00
Merge branch 'main' into feature_agent_framework
crickman Apr 8, 2024
7f98506
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman Apr 8, 2024
2585798
Rename local function for agent example
crickman Apr 9, 2024
0ad4b0b
Remove `AddUserMessage`
crickman Apr 9, 2024
919b8f8
Test fix
crickman Apr 9, 2024
1fc19eb
Merge branch 'main' into feature_agent_framework
crickman Apr 9, 2024
031c28a
Merge branch 'feature_agent_framework' of https://github.com/microsof…
crickman Apr 9, 2024
865b725
Update project/package reference
crickman Apr 9, 2024
5e47fb5
Remove constructors
crickman Apr 9, 2024
5ef126b
Spelling
crickman Apr 9, 2024
d47271b
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman Apr 9, 2024
6556a25
Use real AgentChat in examples
crickman Apr 9, 2024
28a3428
Namespace
crickman Apr 9, 2024
3f87008
Namespace
crickman Apr 9, 2024
8c8da67
Channel comment clarification
crickman Apr 9, 2024
a8ee4cf
Merge branch 'main' into feature_agent_framework
crickman Apr 9, 2024
811b100
Agent examples build directive clean-up
crickman Apr 10, 2024
4595945
Merge branch 'feature_agent_framework' of https://github.com/microsof…
crickman Apr 10, 2024
270590e
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman Apr 10, 2024
b45dc56
Resolve merge
crickman Apr 10, 2024
4c3c2ae
Namespace / Merge fix
crickman Apr 10, 2024
0bd61fd
Last merge fix
crickman Apr 10, 2024
f7cf4e1
Merge branch 'main' into feature_agent_chat
crickman Apr 10, 2024
948cea7
Merge branch 'main' into feature_agent_chat
crickman Apr 11, 2024
6ef5dbc
Merge branch 'main' into feature_agent_chat
crickman Apr 11, 2024
45abc89
First update from PR comments.
crickman Apr 11, 2024
88f59e3
Consolidate AgentBoundTerminationStrategy contract
crickman Apr 11, 2024
59d13e4
Typos and namespaces
crickman Apr 11, 2024
639a4de
SequentialSelectionStrategy.Reset()
crickman Apr 11, 2024
4d3418d
Blank line
crickman Apr 11, 2024
40d22bd
Removed null defaults for execution settings / strategies
crickman Apr 11, 2024
2e8eb1c
Typos
crickman Apr 11, 2024
31778cc
Namespace
crickman Apr 11, 2024
6d7baa0
Merge branch 'main' into feature_agent_chat
crickman Apr 11, 2024
4c4729d
Throw on no selection-strategy
crickman Apr 11, 2024
0dd303c
Selection failure contract
crickman Apr 11, 2024
9ab4130
Reset termination / iscomplete option
crickman Apr 11, 2024
cb843b9
Clean
crickman Apr 11, 2024
616366d
Clean-up
crickman Apr 11, 2024
28e37f1
Improvement
crickman Apr 11, 2024
7b73c4c
dotnet version for UT
crickman Apr 11, 2024
758bfd3
Merge branch 'main' into feature_agent_chat
crickman Apr 12, 2024
6158c97
ConfigureAwait
crickman Apr 12, 2024
5c9ae72
Merge branch 'feature_agent_chat' of https://github.com/microsoft/sem…
crickman Apr 12, 2024
3952a0c
Merge from main
crickman Apr 15, 2024
cc7291d
Fix merge
crickman Apr 15, 2024
7f6d04e
Clean-up
crickman Apr 15, 2024
11db2b6
Namespace
crickman Apr 15, 2024
bdceeb5
Update example
crickman Apr 15, 2024
f79a086
Lil' luv
crickman Apr 15, 2024
2a75117
Onward
crickman Apr 15, 2024
10d6578
Merge branch 'main' into feature_agent_chat
crickman Apr 16, 2024
af9a6b3
Merge branch 'main' into feature_agent_chat
crickman Apr 16, 2024
01ec7d6
Merge branch 'main' into feature_agent_chat
crickman Apr 16, 2024
cfd2337
Comments
crickman Apr 16, 2024
eeb5317
Merge branch 'feature_agent_chat' of https://github.com/microsoft/sem…
crickman Apr 16, 2024
d5c3ff6
SelectionStrategy default
crickman Apr 16, 2024
0f4418e
Iterating on max-turns
crickman Apr 16, 2024
971b7e6
Namespace
crickman Apr 16, 2024
7bfc7b8
Checkpoint
crickman Apr 16, 2024
fde6614
Merge from parent
crickman Apr 16, 2024
70eaf2a
Comments
crickman Apr 16, 2024
39fd77c
Typos
crickman Apr 16, 2024
646d09f
Fix name
crickman Apr 16, 2024
f85ff03
Backport fix
crickman Apr 16, 2024
5dcdfa9
Tune
crickman Apr 16, 2024
ce3987a
Merge branch 'feature_agent_chat' into feature_chat_strategy
crickman Apr 16, 2024
5bfbe5c
Test update
crickman Apr 16, 2024
c56c7f8
Another test
crickman Apr 16, 2024
65d9784
Comment fix
crickman Apr 16, 2024
6c67b8b
Spelling
crickman Apr 17, 2024
acf0eea
Spot fix
crickman Apr 17, 2024
22ea261
Another test
crickman Apr 17, 2024
efc8ae8
Almost done with tests.
crickman Apr 17, 2024
8f913fe
Reconcile
crickman Apr 17, 2024
c5d60bf
Remove dead test
crickman Apr 17, 2024
a6adc16
Merge from main
crickman Apr 17, 2024
b8bd338
Merge branch 'main' into feature_chat_strategy
crickman Apr 18, 2024
b0ec0de
Convention
crickman Apr 18, 2024
451d5f1
Merge branch 'feature_chat_strategy' of https://github.com/microsoft/…
crickman Apr 18, 2024
7ea3ef8
Merge branch 'main' into feature_chat_strategy
crickman Apr 22, 2024
cc3b85e
Merge branch 'main' into feature_chat_strategy
crickman Apr 22, 2024
9ee36c9
Minor
crickman Apr 22, 2024
82298b1
Merge branch 'main' into feature_chat_strategy
crickman Apr 23, 2024
a4136ea
Merge from main
crickman Apr 24, 2024
4d1e049
Comment fix
crickman Apr 24, 2024
7d66c3f
Clean
crickman Apr 24, 2024
5f1d111
Even more simple
crickman Apr 24, 2024
f1db3f9
Even more simple
crickman Apr 24, 2024
0b7d555
Merge branch 'main' into feature_chat_strategy
crickman Apr 24, 2024
8d6eb50
Sample Alignment
crickman Apr 24, 2024
dd0bddf
Merge branch 'main' into feature_chat_strategy
crickman Apr 25, 2024
e8a718f
Project clean-up
crickman Apr 25, 2024
489ff8d
ykw
crickman Apr 25, 2024
6b160e9
Merge branch 'main' into feature_chat_strategy
crickman Apr 25, 2024
184eded
Merge branch 'main' into feature_chat_strategy
crickman Apr 25, 2024
25f8365
NoWarn
crickman Apr 25, 2024
0bdcfce
Merge branch 'feature_chat_strategy' of https://github.com/microsoft/…
crickman Apr 25, 2024
74c1de5
Move result translator
crickman Apr 25, 2024
25848da
Updated
crickman Apr 25, 2024
e1703c5
this.
crickman Apr 25, 2024
0c49422
Result processing
crickman Apr 25, 2024
1d73574
Updated
crickman Apr 25, 2024
6c3abfb
Remove debugging
crickman Apr 25, 2024
1dd0532
Blank line
crickman Apr 25, 2024
bd22c2e
Update Kernel
crickman Apr 25, 2024
689c280
Sample utility comment
crickman Apr 25, 2024
d7f6545
Final
crickman Apr 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions dotnet/samples/Concepts/AgentSyntax/AgentSyntax.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<IsTestProject>true</IsTestProject>
<IsPackable>false</IsPackable>
<!-- Suppress: "Declare types in namespaces", "Require ConfigureAwait", "Experimental" -->
<NoWarn>CS8618,IDE0009,CA1051,CA1050,CA1707,CA2007,VSTHRD111,CS1591,RCS1110,CA5394,SKEXP0001,SKEXP0010,SKEXP0110</NoWarn>
<NoWarn>IDE0009,VSTHRD111,CS0612,CS1591,CS8618,CA1050,CA1051,CA1707,CA2007,CA5394,RCS1110,SKEXP0001,SKEXP0010,SKEXP0110</NoWarn>
<OutputType>Library</OutputType>
</PropertyGroup>
<ItemGroup>
Expand Down Expand Up @@ -48,8 +48,4 @@
</EmbeddedResource>
<None Remove="Resources\*" />
</ItemGroup>
<ItemGroup>
<Folder Include="MixedAgents\" />
<Folder Include="OpenAIAssistant\" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion dotnet/samples/Concepts/AgentSyntax/BaseTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public abstract class BaseTest
TestConfiguration.OpenAI.ChatModelId :
TestConfiguration.AzureOpenAI.ChatDeploymentName;

protected Kernel CreateEmptyKernel() => Kernel.CreateBuilder().Build();
protected Kernel CreateEmptyKernel() => new();

protected Kernel CreateKernelWithChatCompletion()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class Step3_Chat(ITestOutputHelper output) : BaseTest(output)
private const string ReviewerInstructions =
"""
You are an art director who has opinions about copywriting born of a love for David Ogilvy.
The goal is to determine is the given copy is acceptable to print.
The goal is to determine if the given copy is acceptable to print.
If so, state that it is approved.
If not, provide insight on how to refine suggested copy without example.
""";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Copyright (c) Microsoft. All rights reserved.
using System;
using System.Threading.Tasks;
using Examples;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.Chat;
using Microsoft.SemanticKernel.ChatCompletion;
using Xunit;
using Xunit.Abstractions;

namespace GettingStarted;

/// <summary>
/// Demonstrate usage of <see cref="KernelFunctionTerminationStrategy"/> and <see cref="KernelFunctionSelectionStrategy"/>
/// to manage <see cref="AgentGroupChat"/> execution.
/// </summary>
public class Step4_KernelFunctionStrategies(ITestOutputHelper output) : BaseTest(output)
{
private const string ReviewerName = "ArtDirector";
private const string ReviewerInstructions =
"""
You are an art director who has opinions about copywriting born of a love for David Ogilvy.
The goal is to determine if the given copy is acceptable to print.
If so, state that it is approved.
If not, provide insight on how to refine suggested copy without examples.
""";

private const string CopyWriterName = "Writer";
private const string CopyWriterInstructions =
"""
You are a copywriter with ten years of experience and are known for brevity and a dry humor.
You're laser focused on the goal at hand. Don't waste time with chit chat.
The goal is to refine and decide on the single best copy as an expert in the field.
Consider suggestions when refining an idea.
""";

[Fact]
public async Task RunAsync()
{
// Define the agents
ChatCompletionAgent agentReviewer =
new()
{
Instructions = ReviewerInstructions,
Name = ReviewerName,
Kernel = this.CreateKernelWithChatCompletion(),
};

ChatCompletionAgent agentWriter =
new()
{
Instructions = CopyWriterInstructions,
Name = CopyWriterName,
Kernel = this.CreateKernelWithChatCompletion(),
};

KernelFunction terminationFunction =
KernelFunctionFactory.CreateFromPrompt(
"""
Determine if the copy has been approved. If so, respond with a single word: yes

History:
{{$history}}
""");

KernelFunction selectionFunction =
KernelFunctionFactory.CreateFromPrompt(
"""
You are in a role playing game.
Carefully read the conversation history and carry on the conversation by specifying only the name of player to take the next turn.

The available names are:
{{$agents}}

History:
{{$history}}
""");

// Create a chat for agent interaction.
AgentGroupChat chat =
new(agentWriter, agentReviewer)
{
ExecutionSettings =
new()
{
// Here KernelFunctionTerminationStrategy will terminate
// when the art-director has given their approval.
TerminationStrategy =
new KernelFunctionTerminationStrategy(terminationFunction, CreateKernelWithChatCompletion())
{
// Only the art-director may approve.
Agents = [agentReviewer],
// Customer result parser to determine if the response is "yes"
ResultParser = (result) => result.GetValue<string>()?.Contains("yes", StringComparison.OrdinalIgnoreCase) ?? false,
// The prompt variable name for the history argument.
HistoryVariableName = "history",
// Limit total number of turns
MaximumIterations = 10,
},
// Here a KernelFunctionSelectionStrategy selects agents based on a prompt function.
SelectionStrategy =
new KernelFunctionSelectionStrategy(selectionFunction, CreateKernelWithChatCompletion())
{
// Returns the entire result value as a string.
ResultParser = (result) => result.GetValue<string>() ?? string.Empty,
// The prompt variable name for the agents argument.
AgentsVariableName = "agents",
// The prompt variable name for the history argument.
HistoryVariableName = "history",
},
}
};

// Invoke chat and display messages.
string input = "concept: maps made out of egg cartons.";
chat.AddChatMessage(new ChatMessageContent(AuthorRole.User, input));
this.WriteLine($"# {AuthorRole.User}: '{input}'");

await foreach (var content in chat.InvokeAsync())
{
this.WriteLine($"# {content.Role} - {content.AuthorName ?? "*"}: '{content.Content}'");
}

this.WriteLine($"# IS COMPLETE: {chat.IsComplete}");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Examples;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.Chat;
using Microsoft.SemanticKernel.ChatCompletion;
using Resources;
using Xunit;
using Xunit.Abstractions;

namespace GettingStarted;

/// <summary>
/// Demonstrate parsing JSON response.
/// </summary>
public class Step5_JsonResult(ITestOutputHelper output) : BaseTest(output)
{
private const string TutorName = "Tutor";
private const string TutorInstructions =
"""
Think step-by-step and rate the user input on creativity and expressivness from 1-100.

Respond in JSON format with the following JSON schema:

{
"score": "integer (1-100)",
"notes": "the reason for your score"
}
""";

[Fact]
public async Task RunAsync()
{
// Define the agents
ChatCompletionAgent agent =
new()
{
Instructions = TutorInstructions,
Name = TutorName,
Kernel = this.CreateKernelWithChatCompletion(),
};

// Create a chat for agent interaction.
AgentGroupChat chat =
new()
{
ExecutionSettings =
new()
{
// Here a TerminationStrategy subclass is used that will terminate when
// the response includes a score that is greater than or equal to 70.
TerminationStrategy = new ThresholdTerminationStrategy()
}
};

// Respond to user input
await InvokeAgentAsync("The sunset is very colorful.");
await InvokeAgentAsync("The sunset is setting over the mountains.");
await InvokeAgentAsync("The sunset is setting over the mountains and filled the sky with a deep red flame, setting the clouds ablaze.");

// Local function to invoke agent and display the conversation messages.
async Task InvokeAgentAsync(string input)
{
chat.AddChatMessage(new ChatMessageContent(AuthorRole.User, input));

this.WriteLine($"# {AuthorRole.User}: '{input}'");

await foreach (var content in chat.InvokeAsync(agent))
{
this.WriteLine($"# {content.Role} - {content.AuthorName ?? "*"}: '{content.Content}'");
this.WriteLine($"# IS COMPLETE: {chat.IsComplete}");
}
}
}

private record struct InputScore(int score, string notes);

private sealed class ThresholdTerminationStrategy : TerminationStrategy
{
protected override Task<bool> ShouldAgentTerminateAsync(Agent agent, IReadOnlyList<ChatMessageContent> history, CancellationToken cancellationToken)
{
string lastMessageContent = history[history.Count - 1].Content ?? string.Empty;

InputScore? result = JsonResultTranslator.Translate<InputScore>(lastMessageContent);

return Task.FromResult((result?.score ?? 0) >= 70);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Text.Json;
using Microsoft.SemanticKernel;

namespace Resources;
/// <summary>
/// Supports parsing json from a text block that may contain literals delimiters:
/// <list type="table">
/// <item>
/// <code>
/// [json]
/// </code>
/// </item>
/// <item>
/// <code>
/// ```
/// [json]
/// ```
/// </code>
/// </item>
/// <item>
/// <code>
/// ```json
/// [json]
/// ```
/// </code>
/// </item>
/// </list>
/// </summary>
/// <remarks>
/// Encountering json with this form of delimiters is not uncommon for agent scenarios.
/// </remarks>
public static class JsonResultTranslator
{
private const string LiteralDelimiter = "```";
private const string JsonPrefix = "json";

/// <summary>
/// Utility method for extracting a JSON result from an agent response.
/// </summary>
/// <param name="result">A text result</param>
/// <typeparam name="TResult">The target type of the <see cref="FunctionResult"/>.</typeparam>
/// <returns>The JSON translated to the requested type.</returns>
public static TResult? Translate<TResult>(string result)
{
string rawJson = ExtractJson(result);

return JsonSerializer.Deserialize<TResult>(rawJson);
}

private static string ExtractJson(string result)
{
// Search for initial literal delimiter: ```
int startIndex = result.IndexOf(LiteralDelimiter, System.StringComparison.Ordinal);
if (startIndex < 0)
{
// No initial delimiter, return entire expression.
return result;
}

startIndex += LiteralDelimiter.Length;

// Accommodate "json" prefix, if present.
if (JsonPrefix.Equals(result.Substring(startIndex, JsonPrefix.Length), System.StringComparison.OrdinalIgnoreCase))
{
startIndex += JsonPrefix.Length;
}

// Locate final literal delimiter
int endIndex = result.IndexOf(LiteralDelimiter, startIndex, System.StringComparison.OrdinalIgnoreCase);
if (endIndex < 0)
{
endIndex = result.Length;
}

// Extract JSON
return result.Substring(startIndex, endIndex - startIndex);
}
}
2 changes: 1 addition & 1 deletion dotnet/src/Agents/Abstractions/KernelAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ public abstract class KernelAgent : Agent
/// <remarks>
/// Defaults to empty Kernel, but may be overridden.
/// </remarks>
public Kernel Kernel { get; init; } = Kernel.CreateBuilder().Build();
public Kernel Kernel { get; init; } = new Kernel();
}
1 change: 1 addition & 0 deletions dotnet/src/Agents/Core/Agents.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

<ItemGroup>
<Compile Include="$(RepoRoot)/dotnet/src/InternalUtilities/src/Diagnostics/*" Link="%(RecursiveDir)Utilities/%(Filename)%(Extension)" />
<Compile Include="$(RepoRoot)/dotnet/src/InternalUtilities/src/System/TypeConverterFactory.cs" Link="%(RecursiveDir)Utilities/%(Filename)%(Extension)" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading