mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
.NET: [BREAKING] Support Checkpoint Serialization (#735)
* feat: Support Checkpoint Serialization * Implements serialization roundtripping for checkpoints. * Adds support for JSON serialization * Adds FileSystem-based checkpoint persistence * fix: Executor State does not deserialize correctly The StateManager was not properly handling delay-deserialized values. * Fix PortableValue handling in StateManager (this makes it delegate to PortableValue the uwnrapping) * Fix UnitTest to actually test checkpoint serialization * Additional review comment fixes --------- Co-authored-by: Chris <66376200+crickman@users.noreply.github.com>
This commit is contained in:
@@ -2,7 +2,9 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Agents.Workflows.Checkpointing;
|
||||
using Microsoft.Shared.Diagnostics;
|
||||
|
||||
using MessageHandlerF =
|
||||
@@ -17,24 +19,29 @@ namespace Microsoft.Agents.Workflows.Execution;
|
||||
internal class MessageRouter
|
||||
{
|
||||
private readonly Dictionary<Type, MessageHandlerF> _typedHandlers;
|
||||
private readonly Dictionary<TypeId, Type> _runtimeTypeMap;
|
||||
private readonly bool _hasCatchall;
|
||||
|
||||
internal MessageRouter(Dictionary<Type, MessageHandlerF> handlers)
|
||||
{
|
||||
this._typedHandlers = Throw.IfNull(handlers);
|
||||
this._hasCatchall = this._typedHandlers.ContainsKey(typeof(object));
|
||||
Throw.IfNull(handlers);
|
||||
|
||||
this.IncomingTypes = [.. this._typedHandlers.Keys];
|
||||
this._typedHandlers = handlers;
|
||||
this._runtimeTypeMap = handlers.Keys.ToDictionary(t => new TypeId(t), t => t);
|
||||
|
||||
this._hasCatchall = handlers.ContainsKey(typeof(object));
|
||||
|
||||
this.IncomingTypes = [.. handlers.Keys];
|
||||
}
|
||||
|
||||
public HashSet<Type> IncomingTypes { get; }
|
||||
|
||||
public bool CanHandle(object message) => this.CanHandle(Throw.IfNull(message).GetType());
|
||||
public bool CanHandle(object message) => this.CanHandle(new TypeId(Throw.IfNull(message).GetType()));
|
||||
public bool CanHandle(Type candidateType) => this.CanHandle(new TypeId(Throw.IfNull(candidateType)));
|
||||
|
||||
public bool CanHandle(Type candidateType)
|
||||
public bool CanHandle(TypeId candidateType)
|
||||
{
|
||||
// For now we only support routing to handlers registered on the exact type (no base type delegation).
|
||||
return this._hasCatchall || this._typedHandlers.ContainsKey(candidateType);
|
||||
return this._hasCatchall || this._runtimeTypeMap.ContainsKey(candidateType);
|
||||
}
|
||||
|
||||
public async ValueTask<CallResult?> RouteMessageAsync(object message, IWorkflowContext context, bool requireRoute = false)
|
||||
@@ -43,6 +50,13 @@ internal class MessageRouter
|
||||
|
||||
CallResult? result = null;
|
||||
|
||||
if (message is PortableValue portableValue &&
|
||||
this._runtimeTypeMap.TryGetValue(portableValue.TypeId, out Type? runtimeType))
|
||||
{
|
||||
// If we found a runtime type, we can use it
|
||||
message = portableValue.AsType(runtimeType) ?? message;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (this._typedHandlers.TryGetValue(message.GetType(), out MessageHandlerF? handler))
|
||||
|
||||
Reference in New Issue
Block a user