You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: agent-framework/tutorials/agents/function-tools-approvals.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -66,7 +66,7 @@ Since you now have a function that requires approval, the agent might respond wi
66
66
You can check the response content for any `FunctionApprovalRequestContent` instances, which indicates that the agent requires user approval for a function.
67
67
68
68
```csharp
69
-
AgentThreadthread=agent.GetNewThread();
69
+
AgentThreadthread=awaitagent.GetNewThreadAsync();
70
70
AgentResponseresponse=awaitagent.RunAsync("What is the weather like in Amsterdam?", thread);
Copy file name to clipboardExpand all lines: agent-framework/tutorials/agents/memory.md
+9-6Lines changed: 9 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -146,6 +146,8 @@ To use the custom `AIContextProvider`, you need to provide an `AIContextProvider
146
146
147
147
When creating a `ChatClientAgent` it is possible to provide a `ChatClientAgentOptions` object that allows providing the `AIContextProviderFactory` in addition to all other agent options.
148
148
149
+
The factory is an async function that receives a context object and a cancellation token.
150
+
149
151
```csharp
150
152
usingSystem;
151
153
usingAzure.AI.OpenAI;
@@ -161,19 +163,20 @@ ChatClient chatClient = new AzureOpenAIClient(
When creating a new thread, the `AIContextProvider` will be created by `GetNewThread`
174
+
When creating a new thread, the `AIContextProvider` will be created by `GetNewThreadAsync`
172
175
and attached to the thread. Once memories are extracted it is therefore possible to access the memory component via the thread's `GetService` method and inspect the memories.
173
176
174
177
```csharp
175
178
// Create a new thread for the conversation.
176
-
AgentThreadthread=agent.GetNewThread();
179
+
AgentThreadthread=awaitagent.GetNewThreadAsync();
177
180
178
181
Console.WriteLine(awaitagent.RunAsync("Hello, what is the square root of 9?", thread));
179
182
Console.WriteLine(awaitagent.RunAsync("My name is Ruaidhrí", thread));
Copy file name to clipboardExpand all lines: agent-framework/tutorials/agents/multi-turn-conversation.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -27,10 +27,10 @@ For prerequisites and creating the agent, see the [Create and run a simple agent
27
27
Agents are stateless and do not maintain any state internally between calls.
28
28
To have a multi-turn conversation with an agent, you need to create an object to hold the conversation state and pass this object to the agent when running it.
29
29
30
-
To create the conversation state object, call the `GetNewThread` method on the agent instance.
30
+
To create the conversation state object, call the `GetNewThreadAsync` method on the agent instance.
31
31
32
32
```csharp
33
-
AgentThreadthread=agent.GetNewThread();
33
+
AgentThreadthread=awaitagent.GetNewThreadAsync();
34
34
```
35
35
36
36
You can then pass this thread object to the `RunAsync` and `RunStreamingAsync` methods on the agent instance, along with the user input.
@@ -52,8 +52,8 @@ These threads can then be used to maintain separate conversation states for each
52
52
The conversations will be fully independent of each other, since the agent does not maintain any state internally.
Copy file name to clipboardExpand all lines: agent-framework/tutorials/agents/third-party-chat-history-storage.md
+81-41Lines changed: 81 additions & 41 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -47,32 +47,32 @@ To create a custom `ChatMessageStore`, you need to implement the abstract `ChatM
47
47
48
48
The most important methods to implement are:
49
49
50
-
-`AddMessagesAsync` - called to add new messages to the store.
51
-
-`GetMessagesAsync` - called to retrieve the messages from the store.
50
+
-`InvokingAsync` - called at the start of agent invocation to retrieve messages from the store that should be provided as context.
51
+
-`InvokedAsync` - called at the end of agent invocation to add new messages to the store.
52
52
53
-
`GetMessagesAsync` should return the messages in ascending chronological order. All messages returned by it will be used by the `ChatClientAgent` when making calls to the underlying <xref:Microsoft.Extensions.AI.IChatClient>. It's therefore important that this method considers the limits of the underlying model, and only returns as many messages as can be handled by the model.
53
+
`InvokingAsync` should return the messages in ascending chronological order (oldest first). All messages returned by it will be used by the `ChatClientAgent` when making calls to the underlying <xref:Microsoft.Extensions.AI.IChatClient>. It's therefore important that this method considers the limits of the underlying model, and only returns as many messages as can be handled by the model.
54
54
55
-
Any chat history reduction logic, such as summarization or trimming, should be done before returning messages from `GetMessagesAsync`.
55
+
Any chat history reduction logic, such as summarization or trimming, should be done before returning messages from `InvokingAsync`.
56
56
57
57
### Serialization
58
58
59
59
`ChatMessageStore` instances are created and attached to an `AgentThread` when the thread is created, and when a thread is resumed from a serialized state.
60
60
61
61
While the actual messages making up the chat history are stored externally, the `ChatMessageStore` instance might need to store keys or other state to identify the chat history in the external store.
62
62
63
-
To allow persisting threads, you need to implement the `SerializeStateAsync` method of the `ChatMessageStore` class. You also need to provide a constructor that takes a <xref:System.Text.Json.JsonElement> parameter, which can be used to deserialize the state when resuming a thread.
63
+
To allow persisting threads, you need to implement the `Serialize` method of the `ChatMessageStore` class. This method should return a `JsonElement` containing the state needed to restore the store later. When deserializing, the agent framework will pass this serialized state to the ChatMessageStoreFactory, allowing you to use it to recreate the store.
64
64
65
65
### Sample ChatMessageStore implementation
66
66
67
67
The following sample implementation stores chat messages in a vector store.
68
68
69
-
`AddMessagesAsync` upserts messages into the vector store, using a unique key for each message.
69
+
`InvokedAsync` upserts messages into the vector store, using a unique key for each message. It stores both the request messages and response messages from the invocation context.
70
70
71
-
`GetMessagesAsync` retrieves the messages for the current thread from the vector store, orders them by timestamp, and returns them in ascending order.
71
+
`InvokingAsync` retrieves the messages for the current thread from the vector store, orders them by timestamp, and returns them in ascending chronological order (oldest first).
72
72
73
-
When the first message is received, the store generates a unique key for the thread, which is then used to identify the chat history in the vector store for subsequent calls.
73
+
When the first invocation occurs, the store generates a unique key for the thread, which is then used to identify the chat history in the vector store for subsequent calls.
74
74
75
-
The unique key is stored in the `ThreadDbKey` property, which is serialized and deserialized using the `SerializeStateAsync` method and the constructor that takes a `JsonElement`.
75
+
The unique key is stored in the `ThreadDbKey` property, which is serialized using the `Serialize` method and deserialized via the constructor that takes a `JsonElement`.
76
76
This key will therefore be persisted as part of the `AgentThread` state, allowing the thread to be resumed later and continue using the same chat history.
77
77
78
78
```csharp
@@ -105,31 +105,22 @@ internal sealed class VectorChatMessageStore : ChatMessageStore
@@ -169,28 +191,46 @@ To use the custom `ChatMessageStore`, you need to provide a `ChatMessageStoreFac
169
191
170
192
When creating a `ChatClientAgent` it is possible to provide a `ChatClientAgentOptions` object that allows providing the `ChatMessageStoreFactory` in addition to all other agent options.
171
193
194
+
The factory is an async function that receives a context object and a cancellation token, and returns a `ValueTask<ChatMessageStore>`.
0 commit comments