Skip to content

.Net: Ai context behavior merge and renames #12198

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
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion dotnet/samples/Concepts/Agents/ChatCompletion_Rag.cs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ namespace Agents;
/// <remarks>
/// This example shows how to use the <see cref="TextSearchStore{TKey}"/> class which is designed
/// to simplify the process of storing and searching text documents by having a built in schema.
/// If you want to control the schema yourself, you can use an implementation of <see cref="IVectorStoreRecordCollection{TKey, TRecord}"/>
/// If you want to control the schema yourself, you can use an implementation of <see cref="VectorStoreCollection{TKey, TRecord}"/>
/// with the <see cref="VectorStoreTextSearch{TRecord}"/> class instead.
/// </remarks>
public class ChatCompletion_Rag(ITestOutputHelper output) : BaseTest(output)
12 changes: 6 additions & 6 deletions dotnet/src/Agents/Abstractions/AgentThread.cs
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ public abstract class AgentThread
/// Gets or sets the container for <see cref="AIContextBehavior"/> objects that manages their lifecycle and interactions.
/// </summary>
[Experimental("SKEXP0110")]
public virtual AIContextBehaviorsManager AIContextBehaviors { get; init; } = new AIContextBehaviorsManager();
public virtual AggregateAIContextBehavior AIContextBehaviors { get; init; } = new AggregateAIContextBehavior();

/// <summary>
/// Called when the current conversion is temporarily suspended and any state should be saved.
@@ -45,7 +45,7 @@ public abstract class AgentThread
[Experimental("SKEXP0110")]
public virtual Task OnSuspendAsync(CancellationToken cancellationToken = default)
{
return this.AIContextBehaviors.OnSuspendAsync(this.Id, cancellationToken);
return this.AIContextBehaviors.SuspendingAsync(this.Id, cancellationToken);
}

/// <summary>
@@ -70,7 +70,7 @@ public virtual Task OnResumeAsync(CancellationToken cancellationToken = default)
throw new InvalidOperationException("This thread cannot be resumed, since it has not been created.");
}

return this.AIContextBehaviors.OnResumeAsync(this.Id, cancellationToken);
return this.AIContextBehaviors.ResumingAsync(this.Id, cancellationToken);
}

/// <summary>
@@ -94,7 +94,7 @@ protected internal virtual async Task CreateAsync(CancellationToken cancellation
this.Id = await this.CreateInternalAsync(cancellationToken: cancellationToken).ConfigureAwait(false);

#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
await this.AIContextBehaviors.OnThreadCreatedAsync(this.Id, cancellationToken).ConfigureAwait(false);
await this.AIContextBehaviors.ThreadCreatedAsync(this.Id, cancellationToken).ConfigureAwait(false);
#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
}

@@ -117,7 +117,7 @@ public virtual async Task DeleteAsync(CancellationToken cancellationToken = defa
}

#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
await this.AIContextBehaviors.OnThreadDeleteAsync(this.Id, cancellationToken).ConfigureAwait(false);
await this.AIContextBehaviors.ThreadDeletingAsync(this.Id, cancellationToken).ConfigureAwait(false);
#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.

await this.DeleteInternalAsync(cancellationToken).ConfigureAwait(false);
@@ -148,7 +148,7 @@ internal virtual async Task OnNewMessageAsync(ChatMessageContent newMessage, Can
}

#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
await this.AIContextBehaviors.OnNewMessageAsync(this.Id, newMessage, cancellationToken).ConfigureAwait(false);
await this.AIContextBehaviors.MessageAddingAsync(this.Id, newMessage, cancellationToken).ConfigureAwait(false);
#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.

await this.OnNewMessageInternalAsync(newMessage, cancellationToken).ConfigureAwait(false);
4 changes: 2 additions & 2 deletions dotnet/src/Agents/AzureAI/AzureAIAgent.cs
Original file line number Diff line number Diff line change
@@ -189,7 +189,7 @@ public async IAsyncEnumerable<AgentResponseItem<ChatMessageContent>> InvokeAsync

// Get the context contributions from the AIContextBehaviors.
#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
var behaviorsContext = await azureAIAgentThread.AIContextBehaviors.OnModelInvokeAsync(messages, cancellationToken).ConfigureAwait(false);
var behaviorsContext = await azureAIAgentThread.AIContextBehaviors.ModelInvokingAsync(messages, cancellationToken).ConfigureAwait(false);
kernel.Plugins.AddFromAIContextPart(behaviorsContext, "Tools");
#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.

@@ -319,7 +319,7 @@ public async IAsyncEnumerable<AgentResponseItem<StreamingChatMessageContent>> In

// Get the context contributions from the AIContextBehaviors.
#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
var behaviorsContext = await azureAIAgentThread.AIContextBehaviors.OnModelInvokeAsync(messages, cancellationToken).ConfigureAwait(false);
var behaviorsContext = await azureAIAgentThread.AIContextBehaviors.ModelInvokingAsync(messages, cancellationToken).ConfigureAwait(false);
kernel.Plugins.AddFromAIContextPart(behaviorsContext, "Tools");
#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.

4 changes: 2 additions & 2 deletions dotnet/src/Agents/Bedrock/BedrockAgent.cs
Original file line number Diff line number Diff line change
@@ -122,7 +122,7 @@ public override async IAsyncEnumerable<AgentResponseItem<ChatMessageContent>> In

// Get the context contributions from the AIContextBehaviors.
#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
var behaviorsContext = await bedrockThread.AIContextBehaviors.OnModelInvokeAsync(messages, cancellationToken).ConfigureAwait(false);
var behaviorsContext = await bedrockThread.AIContextBehaviors.ModelInvokingAsync(messages, cancellationToken).ConfigureAwait(false);
#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.

// Ensure that the last message provided is a user message
@@ -358,7 +358,7 @@ public override async IAsyncEnumerable<AgentResponseItem<StreamingChatMessageCon

// Get the context contributions from the AIContextBehaviors.
#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
var behaviorsContext = await bedrockThread.AIContextBehaviors.OnModelInvokeAsync(messages, cancellationToken).ConfigureAwait(false);
var behaviorsContext = await bedrockThread.AIContextBehaviors.ModelInvokingAsync(messages, cancellationToken).ConfigureAwait(false);
#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.

// Ensure that the last message provided is a user message
4 changes: 2 additions & 2 deletions dotnet/src/Agents/Core/ChatCompletionAgent.cs
Original file line number Diff line number Diff line change
@@ -78,7 +78,7 @@ public override async IAsyncEnumerable<AgentResponseItem<ChatMessageContent>> In

// Get the context contributions from the AIContextBehaviors.
#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
var behaviorsContext = await chatHistoryAgentThread.AIContextBehaviors.OnModelInvokeAsync(messages, cancellationToken).ConfigureAwait(false);
var behaviorsContext = await chatHistoryAgentThread.AIContextBehaviors.ModelInvokingAsync(messages, cancellationToken).ConfigureAwait(false);
kernel.Plugins.AddFromAIContextPart(behaviorsContext, "Tools");
#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.

@@ -171,7 +171,7 @@ public override async IAsyncEnumerable<AgentResponseItem<StreamingChatMessageCon

// Get the context contributions from the AIContextBehaviors.
#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
var behaviorsContext = await chatHistoryAgentThread.AIContextBehaviors.OnModelInvokeAsync(messages, cancellationToken).ConfigureAwait(false);
var behaviorsContext = await chatHistoryAgentThread.AIContextBehaviors.ModelInvokingAsync(messages, cancellationToken).ConfigureAwait(false);
kernel.Plugins.AddFromAIContextPart(behaviorsContext, "Tools");
#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.

4 changes: 2 additions & 2 deletions dotnet/src/Agents/OpenAI/OpenAIAssistantAgent.cs
Original file line number Diff line number Diff line change
@@ -415,7 +415,7 @@ public async IAsyncEnumerable<AgentResponseItem<ChatMessageContent>> InvokeAsync

// Get the context contributions from the AIContextBehaviors.
#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
var behaviorsContext = await openAIAssistantAgentThread.AIContextBehaviors.OnModelInvokeAsync(messages, cancellationToken).ConfigureAwait(false);
var behaviorsContext = await openAIAssistantAgentThread.AIContextBehaviors.ModelInvokingAsync(messages, cancellationToken).ConfigureAwait(false);
kernel.Plugins.AddFromAIContextPart(behaviorsContext, "Tools");
#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.

@@ -560,7 +560,7 @@ public async IAsyncEnumerable<AgentResponseItem<StreamingChatMessageContent>> In

// Get the context contributions from the AIContextBehaviors.
#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
var behaviorsContext = await openAIAssistantAgentThread.AIContextBehaviors.OnModelInvokeAsync(messages, cancellationToken).ConfigureAwait(false);
var behaviorsContext = await openAIAssistantAgentThread.AIContextBehaviors.ModelInvokingAsync(messages, cancellationToken).ConfigureAwait(false);
kernel.Plugins.AddFromAIContextPart(behaviorsContext, "Tools");
#pragma warning restore SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.

10 changes: 5 additions & 5 deletions dotnet/src/Agents/UnitTests/Core/AgentThreadTests.cs
Original file line number Diff line number Diff line change
@@ -189,7 +189,7 @@ public async Task OnSuspendShouldCallOnSuspendOnRegisteredPartsAsync()
await thread.OnSuspendAsync();

// Assert.
mockPart.Verify(x => x.OnSuspendAsync("test-thread-id", It.IsAny<CancellationToken>()), Times.Once);
mockPart.Verify(x => x.SuspendingAsync("test-thread-id", It.IsAny<CancellationToken>()), Times.Once);
}

/// <summary>
@@ -209,7 +209,7 @@ public async Task OnResumeShouldCallOnResumeOnRegisteredPartsAsync()
await thread.OnResumeAsync();

// Assert.
mockPart.Verify(x => x.OnResumeAsync("test-thread-id", It.IsAny<CancellationToken>()), Times.Once);
mockPart.Verify(x => x.ResumingAsync("test-thread-id", It.IsAny<CancellationToken>()), Times.Once);
}

/// <summary>
@@ -228,7 +228,7 @@ public async Task CreateShouldCallOnThreadCreatedOnRegisteredPartsAsync()
await thread.CreateAsync();

// Assert.
mockPart.Verify(x => x.OnThreadCreatedAsync("test-thread-id", It.IsAny<CancellationToken>()), Times.Once);
mockPart.Verify(x => x.ThreadCreatedAsync("test-thread-id", It.IsAny<CancellationToken>()), Times.Once);
}

/// <summary>
@@ -248,7 +248,7 @@ public async Task DeleteShouldCallOnThreadDeleteOnRegisteredPartsAsync()
await thread.DeleteAsync();

// Assert.
mockPart.Verify(x => x.OnThreadDeleteAsync("test-thread-id", It.IsAny<CancellationToken>()), Times.Once);
mockPart.Verify(x => x.ThreadDeletingAsync("test-thread-id", It.IsAny<CancellationToken>()), Times.Once);
}

/// <summary>
@@ -270,7 +270,7 @@ public async Task OnNewMessageShouldCallOnNewMessageOnRegisteredPartsAsync()
await thread.OnNewMessageAsync(message);

// Assert.
mockPart.Verify(x => x.OnNewMessageAsync("test-thread-id", It.Is<ChatMessage>(x => x.Text == "Test Message." && x.Role == ChatRole.User), It.IsAny<CancellationToken>()), Times.Once);
mockPart.Verify(x => x.MessageAddingAsync("test-thread-id", It.Is<ChatMessage>(x => x.Text == "Test Message." && x.Role == ChatRole.User), It.IsAny<CancellationToken>()), Times.Once);
}

private sealed class TestAgentThread : AgentThread
1 change: 0 additions & 1 deletion dotnet/src/IntegrationTests/Agents/AzureAIAgentTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Linq;
using System.Threading.Tasks;
using Azure.AI.Agents.Persistent;
Original file line number Diff line number Diff line change
@@ -26,8 +26,8 @@ public virtual async Task StatePartReceivesMessagesFromAgentAsync()
{
// Arrange
var mockStatePart = new Mock<AIContextBehavior>() { CallBase = true };
mockStatePart.Setup(x => x.OnNewMessageAsync(It.IsAny<string>(), It.IsAny<ChatMessage>(), It.IsAny<CancellationToken>()));
mockStatePart.Setup(x => x.OnModelInvokeAsync(It.IsAny<ICollection<ChatMessage>>(), It.IsAny<CancellationToken>())).ReturnsAsync(new AIContextPart());
mockStatePart.Setup(x => x.MessageAddingAsync(It.IsAny<string>(), It.IsAny<ChatMessage>(), It.IsAny<CancellationToken>()));
mockStatePart.Setup(x => x.ModelInvokingAsync(It.IsAny<ICollection<ChatMessage>>(), It.IsAny<CancellationToken>())).ReturnsAsync(new AIContextPart());

var agent = this.Fixture.Agent;

@@ -44,8 +44,8 @@ public virtual async Task StatePartReceivesMessagesFromAgentAsync()

// Assert
Assert.Contains("Paris", result.Message.Content);
mockStatePart.Verify(x => x.OnNewMessageAsync(It.IsAny<string>(), It.Is<ChatMessage>(cm => cm.Text == inputMessage), It.IsAny<CancellationToken>()), Times.Once);
mockStatePart.Verify(x => x.OnNewMessageAsync(It.IsAny<string>(), It.Is<ChatMessage>(cm => cm.Text == result.Message.Content), It.IsAny<CancellationToken>()), Times.Once);
mockStatePart.Verify(x => x.MessageAddingAsync(It.IsAny<string>(), It.Is<ChatMessage>(cm => cm.Text == inputMessage), It.IsAny<CancellationToken>()), Times.Once);
mockStatePart.Verify(x => x.MessageAddingAsync(It.IsAny<string>(), It.Is<ChatMessage>(cm => cm.Text == result.Message.Content), It.IsAny<CancellationToken>()), Times.Once);
}
finally
{
@@ -59,8 +59,8 @@ public virtual async Task StatePartReceivesMessagesFromAgentWhenStreamingAsync()
{
// Arrange
var mockStatePart = new Mock<AIContextBehavior>() { CallBase = true };
mockStatePart.Setup(x => x.OnNewMessageAsync(It.IsAny<string>(), It.IsAny<ChatMessage>(), It.IsAny<CancellationToken>()));
mockStatePart.Setup(x => x.OnModelInvokeAsync(It.IsAny<ICollection<ChatMessage>>(), It.IsAny<CancellationToken>())).ReturnsAsync(new AIContextPart());
mockStatePart.Setup(x => x.MessageAddingAsync(It.IsAny<string>(), It.IsAny<ChatMessage>(), It.IsAny<CancellationToken>()));
mockStatePart.Setup(x => x.ModelInvokingAsync(It.IsAny<ICollection<ChatMessage>>(), It.IsAny<CancellationToken>())).ReturnsAsync(new AIContextPart());

var agent = this.Fixture.Agent;

@@ -78,8 +78,8 @@ public virtual async Task StatePartReceivesMessagesFromAgentWhenStreamingAsync()
// Assert
var responseMessage = string.Concat(results.Select(x => x.Message.Content));
Assert.Contains("Paris", responseMessage);
mockStatePart.Verify(x => x.OnNewMessageAsync(It.IsAny<string>(), It.Is<ChatMessage>(cm => cm.Text == inputMessage), It.IsAny<CancellationToken>()), Times.Once);
mockStatePart.Verify(x => x.OnNewMessageAsync(It.IsAny<string>(), It.Is<ChatMessage>(cm => cm.Text == responseMessage), It.IsAny<CancellationToken>()), Times.Once);
mockStatePart.Verify(x => x.MessageAddingAsync(It.IsAny<string>(), It.Is<ChatMessage>(cm => cm.Text == inputMessage), It.IsAny<CancellationToken>()), Times.Once);
mockStatePart.Verify(x => x.MessageAddingAsync(It.IsAny<string>(), It.Is<ChatMessage>(cm => cm.Text == responseMessage), It.IsAny<CancellationToken>()), Times.Once);
}
finally
{
@@ -93,7 +93,7 @@ public virtual async Task StatePartPreInvokeStateIsUsedByAgentAsync()
{
// Arrange
var mockStatePart = new Mock<AIContextBehavior>() { CallBase = true };
mockStatePart.Setup(x => x.OnModelInvokeAsync(It.IsAny<ICollection<ChatMessage>>(), It.IsAny<CancellationToken>())).ReturnsAsync(new AIContextPart { Instructions = "User name is Caoimhe" });
mockStatePart.Setup(x => x.ModelInvokingAsync(It.IsAny<ICollection<ChatMessage>>(), It.IsAny<CancellationToken>())).ReturnsAsync(new AIContextPart { Instructions = "User name is Caoimhe" });

var agent = this.Fixture.Agent;

@@ -123,7 +123,7 @@ public virtual async Task StatePartPreInvokeStateIsUsedByAgentWhenStreamingAsync
{
// Arrange
var mockStatePart = new Mock<AIContextBehavior>() { CallBase = true };
mockStatePart.Setup(x => x.OnModelInvokeAsync(It.IsAny<ICollection<ChatMessage>>(), It.IsAny<CancellationToken>())).ReturnsAsync(new AIContextPart { Instructions = "User name is Caoimhe" });
mockStatePart.Setup(x => x.ModelInvokingAsync(It.IsAny<ICollection<ChatMessage>>(), It.IsAny<CancellationToken>())).ReturnsAsync(new AIContextPart { Instructions = "User name is Caoimhe" });

var agent = this.Fixture.Agent;

Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Threading.Tasks;
using Azure;
using Azure.AI.Agents.Persistent;
@@ -31,7 +30,7 @@ public class AzureAIAgentFixture : AgentFixture
private AzureAIAgentThread? _serviceFailingAgentThread;
private AzureAIAgentThread? _createdServiceFailingAgentThread;

public AAIP.AgentsClient AgentsClient => this._agentsClient!;
public PersistentAgentsClient AgentsClient => this._agentsClient!;

public override Agent Agent => this._agent!;

Loading
Oops, something went wrong.
Loading
Oops, something went wrong.