-
Notifications
You must be signed in to change notification settings - Fork 4.5k
.Net - Introducing AgentGroupChat (Step #2) #5725
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
205 commits
Select commit
Hold shift + click to select a range
ed2bd33
Agent framework
crickman 33f1c0e
Project structure
crickman ca4c1a6
Readme cleanup
crickman d58e416
Build
crickman 74d8deb
Tests and examples
crickman de71d83
Test coverage
crickman 5236c28
Update tests
crickman 308d4b8
Spelling
crickman 905e438
Namespace
crickman d86380d
Coverage
crickman 4273aae
PlugIn Example
crickman 2a1aba2
Merge branch 'main' into feature_agent_framework
crickman bd98124
Test comments & clean-up
crickman 070f82d
Merge branch 'feature_agent_framework' of https://github.com/microsof…
crickman ca53ecd
MVP
crickman fbdf862
Format Fix
crickman 72b720e
Remove System.Linq.Async
crickman 425af3c
Build GD
crickman 000f079
Rollback
crickman e7d365a
Merge branch 'main' into feature_agent_framework
crickman 6a4fb99
Build plz
crickman 4e880e3
Format
crickman 1e01292
Project form
crickman 264cc82
Extra instructions
crickman f3c54c4
ChatCompletionAgent UT
crickman 0e44caf
Coverage
crickman 7225767
Coverage
crickman 22fc872
TODO - Render Filters
crickman 6416ea6
Experiment def
crickman 7dbe37a
Bootstrap AgentChat
crickman ba16b05
Fix experiments
crickman 2ac41f0
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman 8ba1c91
Introducing AgentChat
crickman 42e0bcd
Comment
crickman 56bc185
Tuning
crickman 2cc1686
Merge branch 'main' into feature_agent_framework
crickman aa7231c
Spelling
crickman 01c7d85
Merge branch 'feature_agent_framework' of https://github.com/microsof…
crickman 8f99aa6
TODO Comments
crickman 9048a69
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman cd5ed82
Example
crickman 7977d0a
Spelling
crickman b931c48
More tests
crickman f334ccc
Merge branch 'main' into feature_agent_framework
crickman f57d1ca
Refine
crickman 75fc135
Merge branch 'main' into feature_agent_framework
crickman ac090fd
Merge branch 'main' into feature_agent_framework
crickman dec0de2
Checkpoint
crickman 0984733
Less experiment ids
crickman f8a8365
Identity
crickman 4f436a3
Merge from main
crickman 0438231
Update test
crickman 737cd2f
Test checkpoint
crickman acc0d2a
Encoder fix
crickman 180d37d
Encoder2
crickman 713d20c
Test cleanup
crickman 7fe0af3
Needs unit test
crickman afde6b3
Yeah
crickman ab1383c
BroadcastQueue Failure Propagation
crickman fdedc20
Merge branch 'main' into feature_agent_framework
crickman 7144324
Update from PR Comments
crickman cc5c211
Merge branch 'feature_agent_framework' of https://github.com/microsof…
crickman 143394b
Merge branch 'main' into feature_agent_framework
crickman 8908968
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman a562a7e
Merged from main
crickman 6277f59
Fix merge
crickman c0a62d0
Merge branch 'feature_agent_framework' of https://github.com/microsof…
crickman ffeeeff
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman 1aa05cd
Fix merge
crickman e9736ec
Namespace
crickman 4466048
Coverage
crickman 5a021a8
Update from PR comments
crickman 8dfcf5d
PR Comments
crickman c1dae3f
Resolve merge
crickman 60fe17f
Typo
crickman dd50899
Cleanup
crickman c22176f
Merge branch 'main' into feature_agent_framework
crickman 10823e2
Heck ya
crickman 104ebbd
Fix
crickman 5587125
Termination Strategies
crickman 07c9774
Ack
crickman 9a2b4e2
Strategies
crickman c17fcb4
Merge branch 'main' into feature_agent_framework
crickman c58191c
CancellationToken default
crickman 7ac3051
Merge branch 'feature_agent_framework' of https://github.com/microsof…
crickman 16b438b
Merge branch 'main' into feature_agent_framework
crickman 92b9da7
Merge branch 'main' into feature_agent_framework
crickman 0878281
Merge branch 'main' into feature_agent_framework
crickman 734656e
Type/concept rename
crickman 769d658
Merge branch 'feature_agent_framework' of https://github.com/microsof…
crickman 70871f9
Latest and greatest
crickman b9706e4
Nexus scrub
crickman 5436fed
Abstraction rename
crickman c2020fd
One more (Abstractions folder name)
crickman de2dad0
Remove connector dependency
crickman e2860cc
Re-add connector reference downstream
crickman adf0bee
Review
crickman af41586
Comment
crickman 73079ed
Comments
crickman 6b7a0b7
Support 'init'
crickman df620ef
Resolve merge
crickman a463b36
AgentGroupChat
crickman 2e60f01
Clean
crickman e46cf2d
Comment
crickman 503dd98
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman 4a0dd62
Nuget description
crickman 9a2c957
Nuget
crickman 0482a96
Assembly naming
crickman 90e642a
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman 69ec8c6
Build
crickman 6d446c7
Build
crickman d5be2ca
Comments
crickman 75226d2
Merge branch 'main' into feature_agent_framework
crickman 9478524
Comments Checkpoint
crickman 6fe407e
Dead code
crickman 1143f5a
More comments + typo
crickman 5d37582
More PR updates
crickman 9479b49
Don't copy
crickman f8d758c
Blank line
crickman b7f35f7
Merge from feature
crickman b711530
More
crickman 14929f0
Namespace
crickman e6c6991
public => private: perfect
crickman 0e8b981
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman b06b7e2
Remove namespace
crickman b6566ff
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman 8291e0f
init KernelArguments
crickman d8f4c2e
Signatures
crickman 510751f
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman 822f494
Test fix
crickman b3da6a6
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman 46f7060
Build
crickman 23395cf
Fix mock
crickman 546e5f0
Merge branch 'main' into feature_agent_framework
crickman 83613aa
Sans templatization
crickman e7f2294
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman bbe584b
Namespace
crickman 09677a2
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman 6a13d00
Merge branch 'main' into feature_agent_framework
crickman 7f98506
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman 2585798
Rename local function for agent example
crickman 0ad4b0b
Remove `AddUserMessage`
crickman 919b8f8
Test fix
crickman 1fc19eb
Merge branch 'main' into feature_agent_framework
crickman 031c28a
Merge branch 'feature_agent_framework' of https://github.com/microsof…
crickman 865b725
Update project/package reference
crickman 5e47fb5
Remove constructors
crickman 5ef126b
Spelling
crickman d47271b
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman 6556a25
Use real AgentChat in examples
crickman 28a3428
Namespace
crickman 3f87008
Namespace
crickman 8c8da67
Channel comment clarification
crickman a8ee4cf
Merge branch 'main' into feature_agent_framework
crickman 811b100
Agent examples build directive clean-up
crickman 4595945
Merge branch 'feature_agent_framework' of https://github.com/microsof…
crickman 270590e
Merge branch 'feature_agent_framework' into feature_agent_chat
crickman b45dc56
Resolve merge
crickman 4c3c2ae
Namespace / Merge fix
crickman 0bd61fd
Last merge fix
crickman f7cf4e1
Merge branch 'main' into feature_agent_chat
crickman 948cea7
Merge branch 'main' into feature_agent_chat
crickman 6ef5dbc
Merge branch 'main' into feature_agent_chat
crickman 45abc89
First update from PR comments.
crickman 88f59e3
Consolidate AgentBoundTerminationStrategy contract
crickman 59d13e4
Typos and namespaces
crickman 639a4de
SequentialSelectionStrategy.Reset()
crickman 4d3418d
Blank line
crickman 40d22bd
Removed null defaults for execution settings / strategies
crickman 2e8eb1c
Typos
crickman 31778cc
Namespace
crickman 6d7baa0
Merge branch 'main' into feature_agent_chat
crickman 4c4729d
Throw on no selection-strategy
crickman 0dd303c
Selection failure contract
crickman 9ab4130
Reset termination / iscomplete option
crickman cb843b9
Clean
crickman 616366d
Clean-up
crickman 28e37f1
Improvement
crickman 7b73c4c
dotnet version for UT
crickman 758bfd3
Merge branch 'main' into feature_agent_chat
crickman 6158c97
ConfigureAwait
crickman 5c9ae72
Merge branch 'feature_agent_chat' of https://github.com/microsoft/sem…
crickman 3952a0c
Merge from main
crickman cc7291d
Fix merge
crickman 7f6d04e
Clean-up
crickman 11db2b6
Namespace
crickman bdceeb5
Update example
crickman f79a086
Lil' luv
crickman 2a75117
Onward
crickman 10d6578
Merge branch 'main' into feature_agent_chat
crickman af9a6b3
Merge branch 'main' into feature_agent_chat
crickman 01ec7d6
Merge branch 'main' into feature_agent_chat
crickman cfd2337
Comments
crickman eeb5317
Merge branch 'feature_agent_chat' of https://github.com/microsoft/sem…
crickman d5c3ff6
SelectionStrategy default
crickman 0f4418e
Iterating on max-turns
crickman 971b7e6
Namespace
crickman f85ff03
Backport fix
crickman 1e261fb
Merge branch 'main' into feature_agent_chat
crickman 5664b84
Test rename
crickman 218b97f
Comment
crickman 683cb15
set => init
crickman 8c393b5
Merge branch 'main' into feature_agent_chat
crickman ef71f35
Comment
crickman 081cb77
Merge branch 'feature_agent_chat' of https://github.com/microsoft/sem…
crickman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| // Copyright (c) Microsoft. All rights reserved. | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
| using Microsoft.SemanticKernel; | ||
| using Microsoft.SemanticKernel.Agents; | ||
| using Microsoft.SemanticKernel.Agents.Chat; | ||
| using Microsoft.SemanticKernel.ChatCompletion; | ||
| using Xunit; | ||
| using Xunit.Abstractions; | ||
|
|
||
| namespace Examples; | ||
|
|
||
| /// <summary> | ||
| /// Demonstrate creation of <see cref="AgentChat"/> with <see cref="AgentGroupChatSettings"/> | ||
| /// that inform how chat proceeds with regards to: Agent selection, chat continuation, and maximum | ||
| /// number of agent interactions. | ||
| /// </summary> | ||
| public class Example03_Chat(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 is 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. | ||
| """; | ||
|
|
||
| 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(), | ||
| }; | ||
|
|
||
| // Create a chat for agent interaction. | ||
| AgentGroupChat chat = | ||
| new(agentWriter, agentReviewer) | ||
| { | ||
| ExecutionSettings = | ||
| new() | ||
| { | ||
| // Here a TerminationStrategy subclass is used that will terminate when | ||
| // an assistant message contains the term "approve". | ||
| TerminationStrategy = | ||
| new ApprovalTerminationStrategy() | ||
| { | ||
| // Only the art-director may approve. | ||
| Agents = [agentReviewer], | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| // 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}"); | ||
| } | ||
|
|
||
| private sealed class ApprovalTerminationStrategy : TerminationStrategy | ||
| { | ||
| // Terminate when the final message contains the term "approve" | ||
| protected override Task<bool> ShouldAgentTerminateAsync(Agent agent, IReadOnlyList<ChatMessageContent> history, CancellationToken cancellationToken) | ||
| => Task.FromResult(history[history.Count - 1].Content?.Contains("approve", StringComparison.OrdinalIgnoreCase) ?? false); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,148 @@ | ||
| // Copyright (c) Microsoft. All rights reserved. | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Runtime.CompilerServices; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
| using Microsoft.SemanticKernel.Agents.Chat; | ||
| using Microsoft.SemanticKernel.ChatCompletion; | ||
|
|
||
| namespace Microsoft.SemanticKernel.Agents; | ||
|
|
||
| /// <summary> | ||
| /// A an <see cref="AgentChat"/> that supports multi-turn interactions. | ||
| /// </summary> | ||
| public sealed class AgentGroupChat : AgentChat | ||
| { | ||
| private readonly HashSet<string> _agentIds; // Efficient existence test | ||
| private readonly List<Agent> _agents; // Maintain order | ||
|
|
||
| /// <summary> | ||
| /// Indicates if completion criteria has been met. If set, no further | ||
| /// agent interactions will occur. Clear to enable more agent interactions. | ||
| /// </summary> | ||
| public bool IsComplete { get; set; } | ||
crickman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| /// <summary> | ||
| /// Settings for defining chat behavior. | ||
| /// </summary> | ||
| public AgentGroupChatSettings ExecutionSettings { get; set; } = new AgentGroupChatSettings(); | ||
|
|
||
| /// <summary> | ||
| /// The agents participating in the chat. | ||
| /// </summary> | ||
| public IReadOnlyList<Agent> Agents => this._agents.AsReadOnly(); | ||
|
|
||
| /// <summary> | ||
| /// Add a <see cref="Agent"/> to the chat. | ||
| /// </summary> | ||
| /// <param name="agent">The <see cref="KernelAgent"/> to add.</param> | ||
| public void AddAgent(Agent agent) | ||
| { | ||
| if (this._agentIds.Add(agent.Id)) | ||
crickman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| this._agents.Add(agent); | ||
| } | ||
markwallace-microsoft marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| /// <summary> | ||
| /// Process a series of interactions between the <see cref="AgentGroupChat.Agents"/> that have joined this <see cref="AgentGroupChat"/>. | ||
| /// The interactions will proceed according to the <see cref="SelectionStrategy"/> and the <see cref="TerminationStrategy"/> | ||
| /// defined via <see cref="AgentGroupChat.ExecutionSettings"/>. | ||
| /// In the absence of an <see cref="AgentGroupChatSettings.SelectionStrategy"/>, this method will not invoke any agents. | ||
| /// Any agent may be explicitly selected by calling <see cref="AgentGroupChat.InvokeAsync(Agent, bool, CancellationToken)"/>. | ||
| /// </summary> | ||
| /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param> | ||
| /// <returns>Asynchronous enumeration of messages.</returns> | ||
| public async IAsyncEnumerable<ChatMessageContent> InvokeAsync([EnumeratorCancellation] CancellationToken cancellationToken = default) | ||
| { | ||
| if (this.IsComplete) | ||
| { | ||
| // Throw exception if chat is completed and automatic-reset is not enabled. | ||
| if (!this.ExecutionSettings.TerminationStrategy.AutomaticReset) | ||
| { | ||
| throw new KernelException("Agent Failure - Chat has completed."); | ||
| } | ||
|
|
||
| this.IsComplete = false; | ||
| } | ||
|
|
||
| for (int index = 0; index < this.ExecutionSettings.TerminationStrategy.MaximumIterations; index++) | ||
| { | ||
| // Identify next agent using strategy | ||
| Agent agent = await this.ExecutionSettings.SelectionStrategy.NextAsync(this.Agents, this.History, cancellationToken).ConfigureAwait(false); | ||
|
|
||
| // Invoke agent and process messages along with termination | ||
| await foreach (var message in base.InvokeAgentAsync(agent, cancellationToken).ConfigureAwait(false)) | ||
| { | ||
| if (message.Role == AuthorRole.Assistant) | ||
| { | ||
| var task = this.ExecutionSettings.TerminationStrategy.ShouldTerminateAsync(agent, this.History, cancellationToken); | ||
| this.IsComplete = await task.ConfigureAwait(false); | ||
| } | ||
|
|
||
| yield return message; | ||
| } | ||
|
|
||
| if (this.IsComplete) | ||
| { | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Process a single interaction between a given <see cref="Agent"/> an a <see cref="AgentGroupChat"/>. | ||
| /// </summary> | ||
| /// <param name="agent">The agent actively interacting with the chat.</param> | ||
| /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param> | ||
| /// <returns>Asynchronous enumeration of messages.</returns> | ||
| /// <remark> | ||
| /// Specified agent joins the chat. | ||
| /// </remark>> | ||
| public IAsyncEnumerable<ChatMessageContent> InvokeAsync( | ||
| Agent agent, | ||
| CancellationToken cancellationToken = default) => | ||
| this.InvokeAsync(agent, isJoining: true, cancellationToken); | ||
|
|
||
| /// <summary> | ||
| /// Process a single interaction between a given <see cref="KernelAgent"/> an a <see cref="AgentGroupChat"/> irregardless of | ||
| /// the <see cref="SelectionStrategy"/> defined via <see cref="AgentGroupChat.ExecutionSettings"/>. Likewise, this does | ||
| /// not regard <see cref="TerminationStrategy.MaximumIterations"/> as it only takes a single turn for the specified agent. | ||
| /// </summary> | ||
| /// <param name="agent">The agent actively interacting with the chat.</param> | ||
| /// <param name="isJoining">Optional flag to control if agent is joining the chat.</param> | ||
| /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param> | ||
| /// <returns>Asynchronous enumeration of messages.</returns> | ||
| public async IAsyncEnumerable<ChatMessageContent> InvokeAsync( | ||
| Agent agent, | ||
| bool isJoining, | ||
| [EnumeratorCancellation] CancellationToken cancellationToken = default) | ||
| { | ||
| if (isJoining) | ||
| { | ||
| this.AddAgent(agent); | ||
| } | ||
|
|
||
| await foreach (var message in base.InvokeAgentAsync(agent, cancellationToken).ConfigureAwait(false)) | ||
| { | ||
| if (message.Role == AuthorRole.Assistant) | ||
| { | ||
| var task = this.ExecutionSettings.TerminationStrategy.ShouldTerminateAsync(agent, this.History, cancellationToken); | ||
| this.IsComplete = await task.ConfigureAwait(false); | ||
| } | ||
|
|
||
| yield return message; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="AgentGroupChat"/> class. | ||
| /// </summary> | ||
| /// <param name="agents">The agents initially participating in the chat.</param> | ||
| public AgentGroupChat(params Agent[] agents) | ||
| { | ||
| this._agents = new(agents); | ||
| this._agentIds = new(this._agents.Select(a => a.Id)); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.