.NET: [BREAKING] Change SerializeSession to be Async (#3879)

* Change SerializeSession to be Async

* Update Changelog
This commit is contained in:
westey
2026-02-12 11:56:42 +00:00
committed by GitHub
Unverified
parent 1b10b051fd
commit 6a88c7b1a1
43 changed files with 72 additions and 69 deletions
@@ -31,14 +31,14 @@ namespace SampleApp
protected override ValueTask<AgentSession> CreateSessionCoreAsync(CancellationToken cancellationToken = default)
=> new(new CustomAgentSession());
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
{
if (session is not CustomAgentSession typedSession)
{
throw new ArgumentException($"The provided session is not of type {nameof(CustomAgentSession)}.", nameof(session));
}
return typedSession.Serialize(jsonSerializerOptions);
return new(typedSession.Serialize(jsonSerializerOptions));
}
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
@@ -55,7 +55,7 @@ await Task.Delay(TimeSpan.FromSeconds(2));
Console.WriteLine(await agent.RunAsync("What do you already know about my upcoming trip?", session));
Console.WriteLine("\n>> Serialize and deserialize the session to demonstrate persisted state\n");
JsonElement serializedSession = agent.SerializeSession(session);
JsonElement serializedSession = await agent.SerializeSessionAsync(session);
AgentSession restoredSession = await agent.DeserializeSessionAsync(serializedSession);
Console.WriteLine(await agent.RunAsync("Can you recap the personal details you remember?", restoredSession));
@@ -47,7 +47,7 @@ Console.WriteLine(await agent.RunAsync("My name is Ruaidhrí", session));
Console.WriteLine(await agent.RunAsync("I am 20 years old", session));
// We can serialize the session. The serialized state will include the state of the memory component.
JsonElement sesionElement = agent.SerializeSession(session);
JsonElement sesionElement = await agent.SerializeSessionAsync(session);
Console.WriteLine("\n>> Use deserialized session with previously created memories\n");
@@ -25,7 +25,7 @@ AgentSession session = await agent.CreateSessionAsync();
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate.", session));
// Serialize the session state to a JsonElement, so it can be stored for later use.
JsonElement serializedSession = agent.SerializeSession(session);
JsonElement serializedSession = await agent.SerializeSessionAsync(session);
// Save the serialized session to a temporary file (for demonstration purposes).
string tempFilePath = Path.GetTempFileName();
@@ -49,7 +49,7 @@ Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate.", session
// Serialize the session state, so it can be stored for later use.
// Since the chat history is stored in the vector store, the serialized session
// only contains the guid that the messages are stored under in the vector store.
JsonElement serializedSession = agent.SerializeSession(session);
JsonElement serializedSession = await agent.SerializeSessionAsync(session);
Console.WriteLine("\n--- Serialized session ---\n");
Console.WriteLine(JsonSerializer.Serialize(serializedSession, new JsonSerializerOptions { WriteIndented = true }));
@@ -40,7 +40,7 @@ AgentResponse response = await agent.RunAsync("Write a very long novel about a t
// Poll for background responses until complete.
while (response.ContinuationToken is not null)
{
PersistAgentState(agent, session, response.ContinuationToken);
await PersistAgentState(agent, session, response.ContinuationToken);
await Task.Delay(TimeSpan.FromSeconds(10));
@@ -52,9 +52,9 @@ while (response.ContinuationToken is not null)
Console.WriteLine(response.Text);
void PersistAgentState(AIAgent agent, AgentSession? session, ResponseContinuationToken? continuationToken)
async Task PersistAgentState(AIAgent agent, AgentSession? session, ResponseContinuationToken? continuationToken)
{
stateStore["session"] = agent.SerializeSession(session!);
stateStore["session"] = await agent.SerializeSessionAsync(session!);
stateStore["continuationToken"] = JsonSerializer.SerializeToElement(continuationToken, AgentAbstractionsJsonUtilities.DefaultOptions.GetTypeInfo(typeof(ResponseContinuationToken)));
}
@@ -65,7 +65,7 @@ Console.WriteLine(await agent.RunAsync("I need to make a dentist appointment for
Console.WriteLine(await agent.RunAsync("I've taken Sally to soccer practice.", session) + "\n");
// We can serialize the session, and it will contain both the chat history and the data that each AI context provider serialized.
JsonElement serializedSession = agent.SerializeSession(session);
JsonElement serializedSession = await agent.SerializeSessionAsync(session);
// Let's print it to console to show the contents.
Console.WriteLine(JsonSerializer.Serialize(serializedSession, options: new JsonSerializerOptions() { WriteIndented = true, IndentSize = 2 }) + "\n");
// The serialized session can be stored long term in a persistent store, but in this case we will just deserialize again and continue the conversation.
@@ -25,7 +25,7 @@ AgentSession session = await agent.CreateSessionAsync();
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate.", session));
// Serialize the session state to a JsonElement, so it can be stored for later use.
JsonElement serializedSession = agent.SerializeSession(session);
JsonElement serializedSession = await agent.SerializeSessionAsync(session);
// Save the serialized session to a temporary file (for demonstration purposes).
string tempFilePath = Path.GetTempFileName();
@@ -80,7 +80,7 @@ internal sealed class AFAgentApplication : AgentApplication
}
// Serialize and save the updated conversation history back to turn state.
JsonElement sessionElementEnd = this._agent.SerializeSession(agentSession, JsonUtilities.DefaultOptions);
JsonElement sessionElementEnd = await this._agent.SerializeSessionAsync(agentSession, JsonUtilities.DefaultOptions, cancellationToken);
turnState.SetValue("conversation.chatHistory", sessionElementEnd);
// End the streaming response
@@ -66,7 +66,7 @@ public sealed class A2AAgent : AIAgent
=> new(new A2AAgentSession() { ContextId = contextId });
/// <inheritdoc/>
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
{
_ = Throw.IfNull(session);
@@ -75,7 +75,7 @@ public sealed class A2AAgent : AIAgent
throw new InvalidOperationException("The provided session is not compatible with the agent. Only sessions created by the agent can be serialized.");
}
return typedSession.Serialize(jsonSerializerOptions);
return new(typedSession.Serialize(jsonSerializerOptions));
}
/// <inheritdoc/>
@@ -157,7 +157,8 @@ public abstract class AIAgent
/// </summary>
/// <param name="session">The <see cref="AgentSession"/> to serialize.</param>
/// <param name="jsonSerializerOptions">Optional settings to customize the serialization process.</param>
/// <returns>A <see cref="JsonElement"/> containing the serialized session state.</returns>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
/// <returns>A value task that represents the asynchronous operation. The task result contains a <see cref="JsonElement"/> with the serialized session state.</returns>
/// <exception cref="ArgumentNullException"><paramref name="session"/> is <see langword="null"/>.</exception>
/// <exception cref="InvalidOperationException">The type of <paramref name="session"/> is not supported by this agent.</exception>
/// <remarks>
@@ -165,19 +166,20 @@ public abstract class AIAgent
/// allowing conversations to resume across application restarts or be migrated between
/// different agent instances. Use <see cref="DeserializeSessionAsync"/> to restore the session.
/// </remarks>
public JsonElement SerializeSession(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
=> this.SerializeSessionCore(session, jsonSerializerOptions);
public ValueTask<JsonElement> SerializeSessionAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> this.SerializeSessionCoreAsync(session, jsonSerializerOptions, cancellationToken);
/// <summary>
/// Core implementation of session serialization logic.
/// </summary>
/// <param name="session">The <see cref="AgentSession"/> to serialize.</param>
/// <param name="jsonSerializerOptions">Optional settings to customize the serialization process.</param>
/// <returns>A <see cref="JsonElement"/> containing the serialized session state.</returns>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests. The default is <see cref="CancellationToken.None"/>.</param>
/// <returns>A value task that represents the asynchronous operation. The task result contains a <see cref="JsonElement"/> with the serialized session state.</returns>
/// <remarks>
/// This is the primary session serialization method that implementations must override.
/// </remarks>
protected abstract JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null);
protected abstract ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default);
/// <summary>
/// Deserializes an agent session from its JSON serialized representation.
@@ -36,7 +36,7 @@ namespace Microsoft.Agents.AI;
/// <para>
/// To support conversations that may need to survive application restarts or separate service requests, an <see cref="AgentSession"/> can be serialized
/// and deserialized, so that it can be saved in a persistent store.
/// The <see cref="AIAgent"/> provides the <see cref="AIAgent.SerializeSession(AgentSession, JsonSerializerOptions?)"/> method to serialize the session to a
/// The <see cref="AIAgent"/> provides the <see cref="AIAgent.SerializeSessionAsync(AgentSession, JsonSerializerOptions?, System.Threading.CancellationToken)"/> method to serialize the session to a
/// <see cref="JsonElement"/> and the <see cref="AIAgent.DeserializeSessionAsync(JsonElement, JsonSerializerOptions?, System.Threading.CancellationToken)"/> method
/// can be used to deserialize the session.
/// </para>
@@ -77,8 +77,8 @@ public abstract class DelegatingAIAgent : AIAgent
protected override ValueTask<AgentSession> CreateSessionCoreAsync(CancellationToken cancellationToken = default) => this.InnerAgent.CreateSessionAsync(cancellationToken);
/// <inheritdoc />
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
=> this.InnerAgent.SerializeSession(session, jsonSerializerOptions);
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> this.InnerAgent.SerializeSessionAsync(session, jsonSerializerOptions, cancellationToken);
/// <inheritdoc />
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
@@ -54,7 +54,7 @@ public class CopilotStudioAgent : AIAgent
=> new(new CopilotStudioAgentSession() { ConversationId = conversationId });
/// <inheritdoc/>
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
{
Throw.IfNull(session);
@@ -63,7 +63,7 @@ public class CopilotStudioAgent : AIAgent
throw new InvalidOperationException("The provided session is not compatible with the agent. Only sessions created by the agent can be serialized.");
}
return typedSession.Serialize(jsonSerializerOptions);
return new(typedSession.Serialize(jsonSerializerOptions));
}
/// <inheritdoc/>
@@ -11,6 +11,7 @@
- Moved AgentSession.Serialize to AIAgent.SerializeSession ([#3650](https://github.com/microsoft/agent-framework/pull/3650))
- Renamed serializedSession parameter to serializedState on DeserializeSessionAsync for consistency ([#3681](https://github.com/microsoft/agent-framework/pull/3681))
- Introduce Core method pattern for Session management methods on AIAgent ([#3699](https://github.com/microsoft/agent-framework/pull/3699))
- Changed AIAgent.SerializeSession to AIAgent.SerializeSessionAsync ([#3879](https://github.com/microsoft/agent-framework/pull/3879))
## v1.0.0-preview.251204.1
@@ -45,8 +45,9 @@ public sealed class DurableAIAgent : AIAgent
/// </summary>
/// <param name="session">The session to serialize.</param>
/// <param name="jsonSerializerOptions">Optional JSON serializer options.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>A <see cref="JsonElement"/> containing the serialized session state.</returns>
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
{
if (session is null)
{
@@ -58,7 +59,7 @@ public sealed class DurableAIAgent : AIAgent
throw new InvalidOperationException("The provided session is not compatible with the agent. Only sessions created by the agent can be serialized.");
}
return durableSession.Serialize(jsonSerializerOptions);
return new(durableSession.Serialize(jsonSerializerOptions));
}
/// <summary>
@@ -11,7 +11,7 @@ internal class DurableAIAgentProxy(string name, IDurableAgentClient agentClient)
public override string? Name { get; } = name;
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
{
if (session is null)
{
@@ -23,7 +23,7 @@ internal class DurableAIAgentProxy(string name, IDurableAgentClient agentClient)
throw new InvalidOperationException("The provided session is not compatible with the agent. Only sessions created by the agent can be serialized.");
}
return durableSession.Serialize(jsonSerializerOptions);
return new(durableSession.Serialize(jsonSerializerOptions));
}
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(
@@ -98,7 +98,7 @@ public sealed class GitHubCopilotAgent : AIAgent, IAsyncDisposable
=> new(new GitHubCopilotAgentSession() { SessionId = sessionId });
/// <inheritdoc/>
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
{
_ = Throw.IfNull(session);
@@ -107,7 +107,7 @@ public sealed class GitHubCopilotAgent : AIAgent, IAsyncDisposable
throw new InvalidOperationException("The provided session is not compatible with the agent. Only sessions created by the agent can be serialized.");
}
return typedSession.Serialize(jsonSerializerOptions);
return new(typedSession.Serialize(jsonSerializerOptions));
}
/// <inheritdoc/>
@@ -30,11 +30,10 @@ public sealed class InMemoryAgentSessionStore : AgentSessionStore
private readonly ConcurrentDictionary<string, JsonElement> _threads = new();
/// <inheritdoc/>
public override ValueTask SaveSessionAsync(AIAgent agent, string conversationId, AgentSession session, CancellationToken cancellationToken = default)
public override async ValueTask SaveSessionAsync(AIAgent agent, string conversationId, AgentSession session, CancellationToken cancellationToken = default)
{
var key = GetKey(conversationId, agent.Id);
this._threads[key] = agent.SerializeSession(session);
return default;
this._threads[key] = await agent.SerializeSessionAsync(session, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <inheritdoc/>
@@ -30,9 +30,9 @@ internal class PurviewAgent : AIAgent, IDisposable
}
/// <inheritdoc/>
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
{
return this._innerAgent.SerializeSession(session, jsonSerializerOptions);
return this._innerAgent.SerializeSessionAsync(session, jsonSerializerOptions, cancellationToken);
}
/// <inheritdoc/>
@@ -101,7 +101,7 @@ internal sealed class AIAgentHostExecutor : ChatProtocolExecutor
protected internal override async ValueTask OnCheckpointingAsync(IWorkflowContext context, CancellationToken cancellationToken = default)
{
JsonElement? sessionState = this._session is not null ? this._agent.SerializeSession(this._session) : null;
JsonElement? sessionState = this._session is not null ? await this._agent.SerializeSessionAsync(this._session, cancellationToken: cancellationToken).ConfigureAwait(false) : null;
AIAgentHostState state = new(sessionState, this._currentTurnEmitEvents);
Task coreStateTask = context.QueueStateUpdateAsync(AIAgentHostStateKey, state, cancellationToken: cancellationToken).AsTask();
Task userInputRequestsTask = this._userInputHandler?.OnCheckpointingAsync(UserInputRequestStateKey, context, cancellationToken).AsTask() ?? Task.CompletedTask;
@@ -68,7 +68,7 @@ internal sealed class WorkflowHostAgent : AIAgent
protected override ValueTask<AgentSession> CreateSessionCoreAsync(CancellationToken cancellationToken = default)
=> new(new WorkflowSession(this._workflow, this.GenerateNewId(), this._executionEnvironment, this._checkpointManager, this._includeExceptionDetails, this._includeWorkflowOutputsInResponse));
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
{
_ = Throw.IfNull(session);
@@ -77,7 +77,7 @@ internal sealed class WorkflowHostAgent : AIAgent
throw new InvalidOperationException("The provided session is not compatible with the agent. Only sessions created by the agent can be serialized.");
}
return workflowSession.Serialize(jsonSerializerOptions);
return new(workflowSession.Serialize(jsonSerializerOptions));
}
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
@@ -385,7 +385,7 @@ public sealed partial class ChatClientAgent : AIAgent
}
/// <inheritdoc/>
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
{
_ = Throw.IfNull(session);
@@ -394,7 +394,7 @@ public sealed partial class ChatClientAgent : AIAgent
throw new InvalidOperationException("The provided session is not compatible with the agent. Only sessions created by the agent can be serialized.");
}
return typedSession.Serialize(jsonSerializerOptions);
return new(typedSession.Serialize(jsonSerializerOptions));
}
/// <inheritdoc/>
@@ -251,7 +251,7 @@ public sealed class AGUIAgentTests
var chatClient = new AGUIChatClient(httpClient, "http://localhost/agent", null, AGUIJsonSerializerContext.Default.Options);
AIAgent agent = chatClient.AsAIAgent(instructions: null, name: "agent1", description: "Test agent", tools: []);
AgentSession originalSession = await agent.CreateSessionAsync();
JsonElement serialized = agent.SerializeSession(originalSession);
JsonElement serialized = await agent.SerializeSessionAsync(originalSession);
// Act
AgentSession deserialized = await agent.DeserializeSessionAsync(serialized);
@@ -576,7 +576,7 @@ public class AIAgentTests
protected override ValueTask<AgentSession> CreateSessionCoreAsync(CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
@@ -617,7 +617,7 @@ public class AIAgentTests
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
protected override Task<AgentResponse> RunCoreAsync(
@@ -211,7 +211,7 @@ public sealed class AgentRunContextTests
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
protected override Task<AgentResponse> RunCoreAsync(
@@ -71,7 +71,7 @@ public sealed class AggregatorPromptAgentFactoryTests
throw new NotImplementedException();
}
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
}
@@ -286,7 +286,7 @@ internal sealed class FakeChatClientAgent : AIAgent
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default) =>
new(new FakeInMemoryAgentSession(serializedState, jsonSerializerOptions));
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
protected override async Task<AgentResponse> RunCoreAsync(
@@ -353,14 +353,14 @@ internal sealed class FakeMultiMessageAgent : AIAgent
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default) =>
new(new FakeInMemoryAgentSession(serializedState, jsonSerializerOptions));
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
{
if (session is not FakeInMemoryAgentSession fakeSession)
{
throw new InvalidOperationException("The provided session is not compatible with the agent. Only sessions created by the agent can be serialized.");
}
return fakeSession.Serialize(jsonSerializerOptions);
return new(fakeSession.Serialize(jsonSerializerOptions));
}
protected override async Task<AgentResponse> RunCoreAsync(
@@ -340,14 +340,14 @@ internal sealed class FakeForwardedPropsAgent : AIAgent
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default) =>
new(new FakeInMemoryAgentSession(serializedState, jsonSerializerOptions));
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
{
if (session is not FakeInMemoryAgentSession fakeSession)
{
throw new InvalidOperationException("The provided session is not compatible with the agent. Only sessions created by the agent can be serialized.");
}
return fakeSession.Serialize(jsonSerializerOptions);
return new(fakeSession.Serialize(jsonSerializerOptions));
}
private sealed class FakeInMemoryAgentSession : InMemoryAgentSession
@@ -423,14 +423,14 @@ internal sealed class FakeStateAgent : AIAgent
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default) =>
new(new FakeInMemoryAgentSession(serializedState, jsonSerializerOptions));
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
{
if (session is not FakeInMemoryAgentSession fakeSession)
{
throw new InvalidOperationException("The provided session is not compatible with the agent. Only sessions created by the agent can be serialized.");
}
return fakeSession.Serialize(jsonSerializerOptions);
return new(fakeSession.Serialize(jsonSerializerOptions));
}
private sealed class FakeInMemoryAgentSession : InMemoryAgentSession
@@ -431,14 +431,14 @@ public sealed class AGUIEndpointRouteBuilderExtensionsTests
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default) =>
new(new TestInMemoryAgentSession(serializedState, jsonSerializerOptions));
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
{
if (session is not TestInMemoryAgentSession testSession)
{
throw new InvalidOperationException("The provided session is not compatible with the agent. Only sessions created by the agent can be serialized.");
}
return testSession.Serialize(jsonSerializerOptions);
return new(testSession.Serialize(jsonSerializerOptions));
}
protected override Task<AgentResponse> RunCoreAsync(IEnumerable<ChatMessage> messages, AgentSession? session = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default)
@@ -534,14 +534,14 @@ public sealed class AGUIEndpointRouteBuilderExtensionsTests
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default) =>
new(new TestInMemoryAgentSession(serializedState, jsonSerializerOptions));
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
{
if (session is not TestInMemoryAgentSession testSession)
{
throw new InvalidOperationException("The provided session is not compatible with the agent. Only sessions created by the agent can be serialized.");
}
return testSession.Serialize(jsonSerializerOptions);
return new(testSession.Serialize(jsonSerializerOptions));
}
protected override Task<AgentResponse> RunCoreAsync(IEnumerable<ChatMessage> messages, AgentSession? session = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default)
@@ -13,7 +13,7 @@ internal sealed class TestAgent(string name, string description) : AIAgent
protected override ValueTask<AgentSession> CreateSessionCoreAsync(CancellationToken cancellationToken = default) => new(new DummyAgentSession());
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(
@@ -385,7 +385,7 @@ public class AgentExtensionsTests
protected override ValueTask<AgentSession> CreateSessionCoreAsync(CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
@@ -24,7 +24,7 @@ internal sealed class TestAIAgent : AIAgent
public override string? Description => this.DescriptionFunc?.Invoke() ?? base.Description;
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default) =>
@@ -141,7 +141,7 @@ public class AgentWorkflowBuilderTests
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> new(new DoubleEchoAgentSession());
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> default;
protected override Task<AgentResponse> RunCoreAsync(
@@ -149,7 +149,7 @@ public class InProcessExecutionTests
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(System.Text.Json.JsonElement serializedState,
System.Text.Json.JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default) => new(new SimpleTestAgentSession());
protected override System.Text.Json.JsonElement SerializeSessionCore(AgentSession session, System.Text.Json.JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<System.Text.Json.JsonElement> SerializeSessionCoreAsync(AgentSession session, System.Text.Json.JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> default;
protected override Task<AgentResponse> RunCoreAsync(
@@ -30,7 +30,7 @@ public class RepresentationTests
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
protected override Task<AgentResponse> RunCoreAsync(IEnumerable<ChatMessage> messages, AgentSession? session = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default) =>
@@ -19,7 +19,7 @@ internal sealed class RoleCheckAgent(bool allowOtherAssistantRoles, string? id =
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> new(new RoleCheckAgentSession());
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> default;
protected override ValueTask<AgentSession> CreateSessionCoreAsync(CancellationToken cancellationToken = default) => new(new RoleCheckAgentSession());
@@ -66,7 +66,7 @@ internal sealed class HelloAgent(string id = nameof(HelloAgent)) : AIAgent
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> new(new HelloAgentSession());
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> default;
protected override async Task<AgentResponse> RunCoreAsync(IEnumerable<ChatMessage> messages, AgentSession? session = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default)
@@ -21,14 +21,14 @@ internal class TestEchoAgent(string? id = null, string? name = null, string? pre
return serializedState.Deserialize<EchoAgentSession>(jsonSerializerOptions) ?? await this.CreateSessionAsync(cancellationToken);
}
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
{
if (session is not EchoAgentSession typedSession)
{
throw new InvalidOperationException("The provided session is not compatible with the agent. Only sessions created by the agent can be serialized.");
}
return typedSession.Serialize(jsonSerializerOptions);
return new(typedSession.Serialize(jsonSerializerOptions));
}
protected override ValueTask<AgentSession> CreateSessionCoreAsync(CancellationToken cancellationToken = default) =>
@@ -51,7 +51,7 @@ public class TestReplayAgent(List<ChatMessage>? messages = null, string? id = nu
protected override ValueTask<AgentSession> DeserializeSessionCoreAsync(JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> new(new ReplayAgentSession());
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> default;
public static TestReplayAgent FromStrings(params string[] messages) =>
@@ -45,7 +45,7 @@ internal sealed class TestRequestAgent(TestAgentRequestType requestType, int unp
_ => throw new NotSupportedException(),
});
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> default;
protected override Task<AgentResponse> RunCoreAsync(IEnumerable<ChatMessage> messages, AgentSession? session = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default)
@@ -51,7 +51,7 @@ public class WorkflowHostSmokeTests
return new(new Session());
}
protected override JsonElement SerializeSessionCore(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null)
protected override ValueTask<JsonElement> SerializeSessionCoreAsync(AgentSession session, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default)
=> default;
protected override async Task<AgentResponse> RunCoreAsync(IEnumerable<ChatMessage> messages, AgentSession? session = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default)