mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
.NET: Rename ChatMessageStore to ChatHistoryProvider (#3375)
* Rename ChatMessageStore to ChatHistoryProvider * Fix merge issue * Fixed PR comments * Fix tests after property rename * Add unit tests and fix merge issues * Fix encoding
This commit is contained in:
+8
-8
@@ -45,18 +45,18 @@ namespace SampleApp
|
||||
}
|
||||
|
||||
// Get existing messages from the store
|
||||
var invokingContext = new ChatMessageStore.InvokingContext(messages);
|
||||
var storeMessages = await typedThread.MessageStore.InvokingAsync(invokingContext, cancellationToken);
|
||||
var invokingContext = new ChatHistoryProvider.InvokingContext(messages);
|
||||
var storeMessages = await typedThread.ChatHistoryProvider.InvokingAsync(invokingContext, cancellationToken);
|
||||
|
||||
// Clone the input messages and turn them into response messages with upper case text.
|
||||
List<ChatMessage> responseMessages = CloneAndToUpperCase(messages, this.Name).ToList();
|
||||
|
||||
// Notify the thread of the input and output messages.
|
||||
var invokedContext = new ChatMessageStore.InvokedContext(messages, storeMessages)
|
||||
var invokedContext = new ChatHistoryProvider.InvokedContext(messages, storeMessages)
|
||||
{
|
||||
ResponseMessages = responseMessages
|
||||
};
|
||||
await typedThread.MessageStore.InvokedAsync(invokedContext, cancellationToken);
|
||||
await typedThread.ChatHistoryProvider.InvokedAsync(invokedContext, cancellationToken);
|
||||
|
||||
return new AgentResponse
|
||||
{
|
||||
@@ -77,18 +77,18 @@ namespace SampleApp
|
||||
}
|
||||
|
||||
// Get existing messages from the store
|
||||
var invokingContext = new ChatMessageStore.InvokingContext(messages);
|
||||
var storeMessages = await typedThread.MessageStore.InvokingAsync(invokingContext, cancellationToken);
|
||||
var invokingContext = new ChatHistoryProvider.InvokingContext(messages);
|
||||
var storeMessages = await typedThread.ChatHistoryProvider.InvokingAsync(invokingContext, cancellationToken);
|
||||
|
||||
// Clone the input messages and turn them into response messages with upper case text.
|
||||
List<ChatMessage> responseMessages = CloneAndToUpperCase(messages, this.Name).ToList();
|
||||
|
||||
// Notify the thread of the input and output messages.
|
||||
var invokedContext = new ChatMessageStore.InvokedContext(messages, storeMessages)
|
||||
var invokedContext = new ChatHistoryProvider.InvokedContext(messages, storeMessages)
|
||||
{
|
||||
ResponseMessages = responseMessages
|
||||
};
|
||||
await typedThread.MessageStore.InvokedAsync(invokedContext, cancellationToken);
|
||||
await typedThread.ChatHistoryProvider.InvokedAsync(invokedContext, cancellationToken);
|
||||
|
||||
foreach (var message in responseMessages)
|
||||
{
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ AIAgent agent = azureOpenAIClient
|
||||
// Since we are using ChatCompletion which stores chat history locally, we can also add a message removal policy
|
||||
// that removes messages produced by the TextSearchProvider before they are added to the chat history, so that
|
||||
// we don't bloat chat history with all the search result messages.
|
||||
ChatMessageStoreFactory = (ctx, ct) => new ValueTask<ChatMessageStore>(new InMemoryChatMessageStore(ctx.SerializedState, ctx.JsonSerializerOptions)
|
||||
ChatHistoryProviderFactory = (ctx, ct) => new ValueTask<ChatHistoryProvider>(new InMemoryChatHistoryProvider(ctx.SerializedState, ctx.JsonSerializerOptions)
|
||||
.WithAIContextProviderMessageRemoval()),
|
||||
});
|
||||
|
||||
|
||||
+15
-15
@@ -31,17 +31,17 @@ AIAgent agent = new AzureOpenAIClient(
|
||||
{
|
||||
ChatOptions = new() { Instructions = "You are good at telling jokes." },
|
||||
Name = "Joker",
|
||||
ChatMessageStoreFactory = (ctx, ct) => new ValueTask<ChatMessageStore>(
|
||||
// Create a new chat message store for this agent that stores the messages in a vector store.
|
||||
// Each thread must get its own copy of the VectorChatMessageStore, since the store
|
||||
// also contains the id that the thread is stored under.
|
||||
new VectorChatMessageStore(vectorStore, ctx.SerializedState, ctx.JsonSerializerOptions))
|
||||
ChatHistoryProviderFactory = (ctx, ct) => new ValueTask<ChatHistoryProvider>(
|
||||
// Create a new ChatHistoryProvider for this agent that stores chat history in a vector store.
|
||||
// Each thread must get its own copy of the VectorChatHistoryProvider, since the provider
|
||||
// also contains the id that the chat history is stored under.
|
||||
new VectorChatHistoryProvider(vectorStore, ctx.SerializedState, ctx.JsonSerializerOptions))
|
||||
});
|
||||
|
||||
// Start a new thread for the agent conversation.
|
||||
AgentThread thread = await agent.GetNewThreadAsync();
|
||||
|
||||
// Run the agent with the thread that stores conversation history in the vector store.
|
||||
// Run the agent with the thread that stores chat history in the vector store.
|
||||
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate.", thread));
|
||||
|
||||
// Serialize the thread state, so it can be stored for later use.
|
||||
@@ -58,30 +58,30 @@ Console.WriteLine(JsonSerializer.Serialize(serializedThread, new JsonSerializerO
|
||||
// Deserialize the thread state after loading from storage.
|
||||
AgentThread resumedThread = await agent.DeserializeThreadAsync(serializedThread);
|
||||
|
||||
// Run the agent with the thread that stores conversation history in the vector store a second time.
|
||||
// Run the agent with the thread that stores chat history in the vector store a second time.
|
||||
Console.WriteLine(await agent.RunAsync("Now tell the same joke in the voice of a pirate, and add some emojis to the joke.", resumedThread));
|
||||
|
||||
// We can access the VectorChatMessageStore via the thread's GetService method if we need to read the key under which threads are stored.
|
||||
var messageStore = resumedThread.GetService<VectorChatMessageStore>()!;
|
||||
Console.WriteLine($"\nThread is stored in vector store under key: {messageStore.ThreadDbKey}");
|
||||
// We can access the VectorChatHistoryProvider via the thread's GetService method if we need to read the key under which chat history is stored.
|
||||
var chatHistoryProvider = resumedThread.GetService<VectorChatHistoryProvider>()!;
|
||||
Console.WriteLine($"\nThread is stored in vector store under key: {chatHistoryProvider.ThreadDbKey}");
|
||||
|
||||
namespace SampleApp
|
||||
{
|
||||
/// <summary>
|
||||
/// A sample implementation of <see cref="ChatMessageStore"/> that stores chat messages in a vector store.
|
||||
/// A sample implementation of <see cref="ChatHistoryProvider"/> that stores chat history in a vector store.
|
||||
/// </summary>
|
||||
internal sealed class VectorChatMessageStore : ChatMessageStore
|
||||
internal sealed class VectorChatHistoryProvider : ChatHistoryProvider
|
||||
{
|
||||
private readonly VectorStore _vectorStore;
|
||||
|
||||
public VectorChatMessageStore(VectorStore vectorStore, JsonElement serializedStoreState, JsonSerializerOptions? jsonSerializerOptions = null)
|
||||
public VectorChatHistoryProvider(VectorStore vectorStore, JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null)
|
||||
{
|
||||
this._vectorStore = vectorStore ?? throw new ArgumentNullException(nameof(vectorStore));
|
||||
|
||||
if (serializedStoreState.ValueKind is JsonValueKind.String)
|
||||
if (serializedState.ValueKind is JsonValueKind.String)
|
||||
{
|
||||
// Here we can deserialize the thread id so that we can access the same messages as before the suspension.
|
||||
this.ThreadDbKey = serializedStoreState.Deserialize<string>();
|
||||
this.ThreadDbKey = serializedState.Deserialize<string>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ AIAgent agent = new AzureOpenAIClient(
|
||||
{
|
||||
ChatOptions = new() { Instructions = "You are good at telling jokes." },
|
||||
Name = "Joker",
|
||||
ChatMessageStoreFactory = (ctx, ct) => new ValueTask<ChatMessageStore>(new InMemoryChatMessageStore(new MessageCountingChatReducer(2), ctx.SerializedState, ctx.JsonSerializerOptions))
|
||||
ChatHistoryProviderFactory = (ctx, ct) => new ValueTask<ChatHistoryProvider>(new InMemoryChatHistoryProvider(new MessageCountingChatReducer(2), ctx.SerializedState, ctx.JsonSerializerOptions))
|
||||
});
|
||||
|
||||
AgentThread thread = await agent.GetNewThreadAsync();
|
||||
|
||||
@@ -45,7 +45,7 @@ AIAgent agent = new AzureOpenAIClient(
|
||||
You manage a TODO list for the user. When the user has completed one of the tasks it can be removed from the TODO list. Only provide the list of TODO items if asked.
|
||||
You remind users of upcoming calendar events when the user interacts with you.
|
||||
""" },
|
||||
ChatMessageStoreFactory = (ctx, ct) => new ValueTask<ChatMessageStore>(new InMemoryChatMessageStore()
|
||||
ChatHistoryProviderFactory = (ctx, ct) => new ValueTask<ChatHistoryProvider>(new InMemoryChatHistoryProvider()
|
||||
// Use WithAIContextProviderMessageRemoval, so that we don't store the messages from the AI context provider in the chat history.
|
||||
// You may want to store these messages, depending on their content and your requirements.
|
||||
.WithAIContextProviderMessageRemoval()),
|
||||
|
||||
Reference in New Issue
Block a user