mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
cleanup
This commit is contained in:
@@ -35,6 +35,8 @@
|
||||
<Project Path="samples/AzureFunctions/07_AgentAsMcpTool/07_AgentAsMcpTool.csproj" />
|
||||
<Project Path="samples/AzureFunctions/08_ReliableStreaming/08_ReliableStreaming.csproj" />
|
||||
<Project Path="samples/AzureFunctions/09_Workflow/09_Workflow.csproj" />
|
||||
<Project Path="samples/AzureFunctions/10_WorkflowConcurrent/10_WorkflowConcurrent.csproj" />
|
||||
<Project Path="samples/AzureFunctions/11_WorkflowWithDifferentTypes/11_WorkflowWithDifferentTypes.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Samples/GettingStarted/">
|
||||
<File Path="samples/GettingStarted/README.md" />
|
||||
|
||||
@@ -26,7 +26,7 @@ AzureOpenAIClient client = !string.IsNullOrEmpty(azureOpenAiKey)
|
||||
// Set up an AI agent following the standard Microsoft Agent Framework pattern.
|
||||
const string JokerName = "Joker";
|
||||
const string JokerInstructions = "You are good at telling jokes.";
|
||||
const string AnalysisInstructions = """
|
||||
const string FeedbackAnalysisInstructions = """
|
||||
You are a Customer Feedback Analyzer. Your task is to analyze customer survey responses and categorize them accurately.
|
||||
|
||||
INPUT: You will receive customer feedback text that may include a rating and comments.
|
||||
@@ -44,31 +44,44 @@ CATEGORIZATION RULES:
|
||||
- "Support Incident Status": Follow-ups on existing tickets, status inquiries about previous issues
|
||||
|
||||
RESPONSE FORMAT: Return only the category name exactly as shown above, with no additional text or explanation.
|
||||
|
||||
Examples:
|
||||
- "The app crashes when I try to export" → Bug Report
|
||||
- "Love the new design! Great work" → General Feedback
|
||||
- "Why was I charged twice this month?" → Billing Question
|
||||
- "What's the status of ticket #12345?" → Support Incident Status
|
||||
""";
|
||||
AIAgent agent = client.GetChatClient(deploymentName).CreateAIAgent(JokerInstructions, JokerName);
|
||||
AIAgent surveyFeedbackAgent = client.GetChatClient(deploymentName).CreateAIAgent(AnalysisInstructions, "FeedbackAnalysisBot");
|
||||
|
||||
AIAgent agent = client.GetChatClient(deploymentName).CreateAIAgent(JokerInstructions, JokerName);
|
||||
|
||||
// 3 Executors usd by the workflow.
|
||||
// 1. Class based executor to parse survey response.
|
||||
SurveyResponseParserExecutor surveyResponseParserExecutor = new();
|
||||
ResponseRouterExecutor responseRouterExecutor = new();
|
||||
|
||||
// 2. AI Agent to analyze feedback and categorize it.
|
||||
AIAgent surveyFeedbackAgent = client.GetChatClient(deploymentName).CreateAIAgent(FeedbackAnalysisInstructions, "FeedbackAnalyzerAgent");
|
||||
|
||||
// 3. Function delegate executor to route response based on category.
|
||||
Func<string, string> responseHandlingExecutorFunc = input => input switch
|
||||
{
|
||||
var s when s.Contains("billing", StringComparison.OrdinalIgnoreCase)
|
||||
=> "Will notify Billing Team",
|
||||
|
||||
var s when s.Contains("Bug Report", StringComparison.OrdinalIgnoreCase)
|
||||
=> "Will notify Technical Support Team",
|
||||
|
||||
_ => "Will notify General Support Team"
|
||||
};
|
||||
var responseRouterExecutor = responseHandlingExecutorFunc.BindAsExecutor("ResponseRouterExecutor");
|
||||
|
||||
WorkflowBuilder builder = new(surveyResponseParserExecutor);
|
||||
builder.AddEdge(surveyResponseParserExecutor, surveyFeedbackAgent);
|
||||
builder.AddEdge(surveyFeedbackAgent, responseRouterExecutor).WithOutputFrom(responseRouterExecutor);
|
||||
|
||||
var workflow = builder.WithName("HandleSurveyResponse").Build();
|
||||
|
||||
// Configure the function app to host AI agents and workflows in a unified way.
|
||||
// This will automatically generate HTTP API endpoints for agents and workflows.
|
||||
var functionBuilder = FunctionsApplication.CreateBuilder(args);
|
||||
functionBuilder.ConfigureFunctionsWebApplication().ConfigureDurableOptions(options =>
|
||||
{
|
||||
// Configure workflows
|
||||
options.Workflows.AddWorkflow(workflow);
|
||||
});
|
||||
functionBuilder.Build().Run();
|
||||
FunctionsApplication.CreateBuilder(args)
|
||||
.ConfigureFunctionsWebApplication()
|
||||
//.ConfigureDurableAgents(options => options.AddAIAgent(agent))
|
||||
.ConfigureDurableOptions(options =>
|
||||
{
|
||||
// Configure workflows
|
||||
options.Workflows.AddWorkflow(workflow);
|
||||
|
||||
// Optional - Configure AI agents
|
||||
// options.Agents.AddAIAgent(agent);
|
||||
})
|
||||
.Build().Run();
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using Microsoft.Agents.AI.Workflows;
|
||||
|
||||
namespace SingleAgent;
|
||||
|
||||
/// <summary>
|
||||
/// Routes survey responses to appropriate teams based on rating and category.
|
||||
/// </summary>
|
||||
public sealed class ResponseRouterExecutor() : Executor<string, string>("ResponseRouterExecutor")
|
||||
{
|
||||
public override ValueTask<string> HandleAsync(string message, IWorkflowContext context, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (message.Contains("billing", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return ValueTask.FromResult("Routed to Billing Team");
|
||||
}
|
||||
else if (message.Contains("technical", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return ValueTask.FromResult("Routed to Technical Support Team");
|
||||
}
|
||||
else
|
||||
{
|
||||
return ValueTask.FromResult("Routed to General Support Team");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,12 +23,12 @@ internal sealed partial class SurveyResponseParserExecutor() : Executor<string,
|
||||
|
||||
public override ValueTask<string> HandleAsync(string message, IWorkflowContext context, CancellationToken cancellationToken = default)
|
||||
{
|
||||
SurveyResponse response = this.ParseSurveyResponse(message);
|
||||
SurveyResponse response = ParseSurveyResponse(message);
|
||||
string jsonResult = JsonSerializer.Serialize(response, s_jsonOptions);
|
||||
return ValueTask.FromResult(jsonResult);
|
||||
}
|
||||
|
||||
private SurveyResponse ParseSurveyResponse(string message)
|
||||
private static SurveyResponse ParseSurveyResponse(string message)
|
||||
{
|
||||
// Parse the message to extract rating and comment
|
||||
int? rating = null;
|
||||
|
||||
@@ -6,3 +6,9 @@ POST {{authority}}/api/workflows/HandleSurveyResponse/run
|
||||
Content-Type: text/plain
|
||||
|
||||
Rating: 10. Why was I charged $99 when my plan should be $49? I need a refund for the overcharge
|
||||
|
||||
|
||||
POST {{authority}}/api/workflows/HandleSurveyResponse/run
|
||||
Content-Type: text/plain
|
||||
|
||||
Rating: 10. Why was I charged $99 when my plan should be $49? I need a refund for the overcharge
|
||||
@@ -171,9 +171,19 @@ public sealed class DurableAgentsOptions
|
||||
/// Determines whether an agent is configured as workflow-only (no HTTP triggers).
|
||||
/// </summary>
|
||||
/// <param name="agentName">The name of the agent.</param>
|
||||
/// <returns>True if the agent is workflow-only; otherwise, false.</returns>
|
||||
/// <returns><see langword="true"/> if the agent is workflow-only; otherwise, <see langword="false"/>.</returns>
|
||||
internal bool IsWorkflowOnly(string agentName)
|
||||
{
|
||||
return this._workflowOnlyAgents.Contains(agentName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether an agent with the specified name is already registered.
|
||||
/// </summary>
|
||||
/// <param name="agentName">The name of the agent.</param>
|
||||
/// <returns><see langword="true"/> if an agent with the name is registered; otherwise, <see langword="false"/>.</returns>
|
||||
internal bool ContainsAgent(string agentName)
|
||||
{
|
||||
return this._agentFactories.ContainsKey(agentName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using Microsoft.Agents.AI.Workflows;
|
||||
using Microsoft.Agents.AI.Workflows.Checkpointing;
|
||||
|
||||
namespace Microsoft.Agents.AI.DurableTask;
|
||||
|
||||
@@ -25,13 +26,10 @@ public sealed class DurableWorkflowOptions
|
||||
/// <summary>
|
||||
/// Gets the collection of workflows available in the current context, keyed by their unique names.
|
||||
/// </summary>
|
||||
/// <remarks>The returned dictionary is read-only and reflects the current set of registered workflows.
|
||||
/// Changes to the underlying workflow collection are immediately visible through this property. Accessing a
|
||||
/// workflow by name that does not exist will result in a KeyNotFoundException.</remarks>
|
||||
public IReadOnlyDictionary<string, Workflow> Workflows => this._workflows;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the executor registry.
|
||||
/// Gets the executor registry for direct executor lookup.
|
||||
/// </summary>
|
||||
internal ExecutorRegistry Executors { get; }
|
||||
|
||||
@@ -41,8 +39,10 @@ public sealed class DurableWorkflowOptions
|
||||
/// <param name="workflow">The workflow instance to add. Cannot be null.</param>
|
||||
/// <remarks>
|
||||
/// When a workflow is added, any AI agent executors in the workflow will be automatically
|
||||
/// registered with the DurableAgentsOptions if it was provided during construction.
|
||||
/// registered with the <see cref="DurableAgentsOptions"/> if it was provided during construction.
|
||||
/// </remarks>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="workflow"/> is null.</exception>
|
||||
/// <exception cref="ArgumentException">Thrown when the workflow does not have a valid name.</exception>
|
||||
public void AddWorkflow(Workflow workflow)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(workflow);
|
||||
@@ -54,48 +54,33 @@ public sealed class DurableWorkflowOptions
|
||||
|
||||
this._workflows[workflow.Name] = workflow;
|
||||
|
||||
// Register executors in the registry for direct lookup
|
||||
RegisterExecutors(workflow, this.Executors);
|
||||
|
||||
// Register any agentic executors with DurableAgentsOptions if available through parent
|
||||
DurableAgentsOptions? agentOptions = this.TryGetAgentOptions();
|
||||
DurableAgentsOptions? agentOptions = this._parentOptions?.Agents;
|
||||
if (agentOptions is not null)
|
||||
{
|
||||
RegisterAgenticExecutors(workflow, agentOptions);
|
||||
}
|
||||
}
|
||||
|
||||
private DurableAgentsOptions? TryGetAgentOptions()
|
||||
private static void RegisterExecutors(Workflow workflow, ExecutorRegistry registry)
|
||||
{
|
||||
return this._parentOptions?.Agents;
|
||||
foreach (KeyValuePair<string, ExecutorInfo> executor in workflow.ReflectExecutors())
|
||||
{
|
||||
int underscoreIndex = executor.Key.IndexOf('_');
|
||||
string executorName = underscoreIndex > 0 ? executor.Key[..underscoreIndex] : executor.Key;
|
||||
registry.Register(executorName, executor.Key, workflow);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RegisterAgenticExecutors(Workflow workflow, DurableAgentsOptions agentOptions)
|
||||
{
|
||||
// Use the public EnumerateAgentExecutors method to get all AIAgent instances
|
||||
foreach (AIAgent agent in workflow.EnumerateAgentExecutors())
|
||||
{
|
||||
try
|
||||
if (agent.Name is not null && !agentOptions.ContainsAgent(agent.Name))
|
||||
{
|
||||
// Register the agent as workflow-only (no HTTP trigger)
|
||||
agentOptions.AddAIAgent(agent, workflowOnly: true);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
// Agent with this name is already registered, skip it
|
||||
// This is expected behavior when multiple workflows use the same agent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void RegisterExecutors(Workflow workflow, ExecutorRegistry registry)
|
||||
{
|
||||
// Register all executors from the workflow in the registry
|
||||
foreach (KeyValuePair<string, Workflows.Checkpointing.ExecutorInfo> executor in workflow.ReflectExecutors())
|
||||
{
|
||||
// Extract the executor name (without GUID suffix)
|
||||
string executorName = executor.Key.Split('_')[0];
|
||||
registry.Register(executorName, executor.Key, workflow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,52 +7,40 @@ namespace Microsoft.Agents.AI.DurableTask;
|
||||
/// <summary>
|
||||
/// Provides a registry for storing and retrieving executor bindings independently from workflows.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This registry allows executors to be looked up by name without needing to search through all workflows,
|
||||
/// which is useful for activity function execution where only the executor name is known.
|
||||
/// </remarks>
|
||||
internal sealed class ExecutorRegistry
|
||||
{
|
||||
private readonly Dictionary<string, ExecutorRegistration> _executors = new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of registered executors.
|
||||
/// </summary>
|
||||
public int Count => this._executors.Count;
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get an executor registration by name.
|
||||
/// </summary>
|
||||
/// <param name="executorName">The executor name to look up.</param>
|
||||
/// <param name="registration">When this method returns, contains the registration if found; otherwise, null.</param>
|
||||
/// <returns><see langword="true"/> if the executor was found; otherwise, <see langword="false"/>.</returns>
|
||||
public bool TryGetExecutor(string executorName, out ExecutorRegistration? registration)
|
||||
{
|
||||
return this._executors.TryGetValue(executorName, out registration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers an executor binding from a workflow.
|
||||
/// </summary>
|
||||
/// <param name="executorName">The executor name (without GUID suffix).</param>
|
||||
/// <param name="executorId">The full executor ID (may include GUID suffix).</param>
|
||||
/// <param name="workflow">The workflow containing the executor.</param>
|
||||
/// <remarks>
|
||||
/// If an executor with the same name is already registered, it will be skipped.
|
||||
/// This is expected behavior when the same executor is used across multiple workflows.
|
||||
/// </remarks>
|
||||
internal void Register(string executorName, string executorId, Workflow workflow)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrEmpty(executorName);
|
||||
ArgumentException.ThrowIfNullOrEmpty(executorId);
|
||||
ArgumentNullException.ThrowIfNull(workflow);
|
||||
|
||||
// Only register if not already present (first registration wins)
|
||||
if (!this._executors.ContainsKey(executorName))
|
||||
{
|
||||
this._executors[executorName] = new ExecutorRegistration(executorId, workflow);
|
||||
}
|
||||
this._executors.TryAdd(executorName, new ExecutorRegistration(executorId, workflow));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get an executor registration by name.
|
||||
/// </summary>
|
||||
/// <param name="executorName">The executor name to look up.</param>
|
||||
/// <param name="registration">When this method returns, contains the registration if found; otherwise, null.</param>
|
||||
/// <returns><c>true</c> if the executor was found; otherwise, <c>false</c>.</returns>
|
||||
public bool TryGetExecutor(string executorName, out ExecutorRegistration? registration)
|
||||
{
|
||||
return this._executors.TryGetValue(executorName, out registration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of registered executors.
|
||||
/// </summary>
|
||||
public int Count => this._executors.Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -44,7 +44,6 @@ internal sealed class BuiltInFunctionExecutor : IFunctionExecutor
|
||||
string? encodedEntityRequest = null;
|
||||
DurableTaskClient? durableTaskClient = null;
|
||||
ToolInvocationContext? mcpToolInvocationContext = null;
|
||||
//string? encodedTaskOrchestrationContext = null;
|
||||
|
||||
foreach (var binding in values)
|
||||
{
|
||||
@@ -62,9 +61,6 @@ internal sealed class BuiltInFunctionExecutor : IFunctionExecutor
|
||||
case ToolInvocationContext toolContext:
|
||||
mcpToolInvocationContext = toolContext;
|
||||
break;
|
||||
//case string orchestrationContext:
|
||||
// encodedTaskOrchestrationContext = orchestrationContext;
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +80,7 @@ internal sealed class BuiltInFunctionExecutor : IFunctionExecutor
|
||||
|
||||
context.GetInvocationResult().Value = await BuiltInFunctions.RunAgentHttpAsync(
|
||||
httpRequestData,
|
||||
durableTaskClient!,
|
||||
durableTaskClient,
|
||||
context);
|
||||
return;
|
||||
}
|
||||
@@ -97,7 +93,7 @@ internal sealed class BuiltInFunctionExecutor : IFunctionExecutor
|
||||
}
|
||||
|
||||
context.GetInvocationResult().Value = await BuiltInFunctions.InvokeAgentAsync(
|
||||
durableTaskClient!,
|
||||
durableTaskClient,
|
||||
encodedEntityRequest,
|
||||
context);
|
||||
return;
|
||||
@@ -111,7 +107,7 @@ internal sealed class BuiltInFunctionExecutor : IFunctionExecutor
|
||||
}
|
||||
|
||||
context.GetInvocationResult().Value =
|
||||
await BuiltInFunctions.RunMcpToolAsync(mcpToolInvocationContext, durableTaskClient!, context);
|
||||
await BuiltInFunctions.RunMcpToolAsync(mcpToolInvocationContext, durableTaskClient, context);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -124,7 +120,7 @@ internal sealed class BuiltInFunctionExecutor : IFunctionExecutor
|
||||
|
||||
context.GetInvocationResult().Value = await BuiltInFunctions.RunWorkflowOrechstrtationHttpTriggerAsync(
|
||||
httpRequestData,
|
||||
durableTaskClient!,
|
||||
durableTaskClient,
|
||||
context);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,9 @@ internal static class BuiltInFunctions
|
||||
[ActivityTrigger] string input,
|
||||
FunctionContext functionContext)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(input);
|
||||
ArgumentNullException.ThrowIfNull(functionContext);
|
||||
|
||||
string activityFunctionName = functionContext.FunctionDefinition.Name;
|
||||
|
||||
DurableWorkflowRunner runner = functionContext.InstanceServices.GetRequiredService<DurableWorkflowRunner>();
|
||||
|
||||
@@ -5,18 +5,18 @@ using System.Text.Json.Serialization;
|
||||
namespace Microsoft.Agents.AI.Hosting.AzureFunctions;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a request to run a workflow in the Duable system.
|
||||
/// Represents a request to run a durable workflow.
|
||||
/// </summary>
|
||||
public sealed class DuableWorkflowRunRequest
|
||||
internal sealed class DuableWorkflowRunRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the workflow.
|
||||
/// Gets or sets the name of the workflow to execute.
|
||||
/// </summary>
|
||||
[JsonPropertyName("workflowName")]
|
||||
public string WorkflowName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the input string to be processed or analyzed.
|
||||
/// Gets or sets the input for the workflow.
|
||||
/// </summary>
|
||||
[JsonPropertyName("input")]
|
||||
public string Input { get; set; } = string.Empty;
|
||||
|
||||
@@ -98,6 +98,9 @@ public static class DurableOptionsExtensions
|
||||
|
||||
private static void ConfigureWorkflowOrchestration(FunctionsApplicationBuilder builder)
|
||||
{
|
||||
// Registering a single orchestration function to handle all workflow runs.
|
||||
// This is due to a gap in durable extension today and can be replace with dynamic orchestration registration in future, per workflow.
|
||||
|
||||
builder.ConfigureDurableWorker().AddTasks(tasks =>
|
||||
tasks.AddOrchestratorFunc<DuableWorkflowRunRequest, List<string>>(
|
||||
"WorkflowRunnerOrchestration",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Agents.AI.DurableTask;
|
||||
using Microsoft.Agents.AI.Workflows;
|
||||
@@ -113,7 +114,7 @@ internal sealed class DurableWorkflowRunner
|
||||
{
|
||||
WorkflowExecutorInfo executorInfo = level.Executors[0];
|
||||
string input = GetExecutorInput(executorInfo.ExecutorId, initialInput, results, plan);
|
||||
results[executorInfo.ExecutorId] = await this.ExecuteExecutorAsync(context, workflow, executorInfo, input, logger).ConfigureAwait(true);
|
||||
results[executorInfo.ExecutorId] = await this.ExecuteExecutorAsync(context, executorInfo, input, logger).ConfigureAwait(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -121,7 +122,7 @@ internal sealed class DurableWorkflowRunner
|
||||
foreach (WorkflowExecutorInfo executorInfo in level.Executors)
|
||||
{
|
||||
string input = GetExecutorInput(executorInfo.ExecutorId, initialInput, results, plan);
|
||||
tasks.Add(this.ExecuteExecutorWithIdAsync(context, workflow, executorInfo, input, logger));
|
||||
tasks.Add(this.ExecuteExecutorWithIdAsync(context, executorInfo, input, logger));
|
||||
}
|
||||
|
||||
foreach ((string id, string result) in await Task.WhenAll(tasks).ConfigureAwait(true))
|
||||
@@ -136,18 +137,16 @@ internal sealed class DurableWorkflowRunner
|
||||
|
||||
private async Task<(string Id, string Result)> ExecuteExecutorWithIdAsync(
|
||||
TaskOrchestrationContext context,
|
||||
Workflow workflow,
|
||||
WorkflowExecutorInfo executorInfo,
|
||||
string input,
|
||||
ILogger logger)
|
||||
{
|
||||
string result = await this.ExecuteExecutorAsync(context, workflow, executorInfo, input, logger).ConfigureAwait(true);
|
||||
string result = await this.ExecuteExecutorAsync(context, executorInfo, input, logger).ConfigureAwait(true);
|
||||
return (executorInfo.ExecutorId, result);
|
||||
}
|
||||
|
||||
private async Task<string> ExecuteExecutorAsync(
|
||||
TaskOrchestrationContext context,
|
||||
Workflow workflow,
|
||||
WorkflowExecutorInfo executorInfo,
|
||||
string input,
|
||||
ILogger logger)
|
||||
@@ -158,10 +157,10 @@ internal sealed class DurableWorkflowRunner
|
||||
return await context.CallActivityAsync<string>(triggerName, input).ConfigureAwait(true);
|
||||
}
|
||||
|
||||
return await this.ExecuteAgentAsync(context, executorInfo, input, logger).ConfigureAwait(true);
|
||||
return await ExecuteAgentAsync(context, executorInfo, input, logger).ConfigureAwait(true);
|
||||
}
|
||||
|
||||
private async Task<string> ExecuteAgentAsync(
|
||||
private static async Task<string> ExecuteAgentAsync(
|
||||
TaskOrchestrationContext context,
|
||||
WorkflowExecutorInfo executorInfo,
|
||||
string input,
|
||||
@@ -259,15 +258,15 @@ internal sealed class DurableWorkflowRunner
|
||||
return underscoreIndex > 0 ? executorId[..underscoreIndex] : executorId;
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("AOT", "IL3050", Justification = "Serializing known types.")]
|
||||
[System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Serializing known types.")]
|
||||
[UnconditionalSuppressMessage("AOT", "IL3050", Justification = "Serializing known types.")]
|
||||
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Serializing known types.")]
|
||||
private static string SerializeToJson(List<string> values)
|
||||
{
|
||||
return JsonSerializer.Serialize(values);
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("AOT", "IL3050", Justification = "Serializing workflow types registered at startup.")]
|
||||
[System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Serializing workflow types registered at startup.")]
|
||||
[UnconditionalSuppressMessage("AOT", "IL3050", Justification = "Serializing workflow types registered at startup.")]
|
||||
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Serializing workflow types registered at startup.")]
|
||||
private static string SerializeResult(object? result)
|
||||
{
|
||||
if (result is null)
|
||||
@@ -289,8 +288,8 @@ internal sealed class DurableWorkflowRunner
|
||||
return JsonSerializer.Serialize(result, resultType);
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("AOT", "IL3050", Justification = "Deserializing workflow types registered at startup.")]
|
||||
[System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Deserializing workflow types registered at startup.")]
|
||||
[UnconditionalSuppressMessage("AOT", "IL3050", Justification = "Deserializing workflow types registered at startup.")]
|
||||
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Deserializing workflow types registered at startup.")]
|
||||
private static object DeserializeInput(string input, Type targetType)
|
||||
{
|
||||
if (targetType == typeof(string))
|
||||
|
||||
Reference in New Issue
Block a user