77 lines
3.5 KiB
C#
77 lines
3.5 KiB
C#
using MAF1.Decisions;
|
|
using Microsoft.Agents.AI;
|
|
using Microsoft.Agents.AI.Workflows;
|
|
using MAF1.Agents.FileCity;
|
|
|
|
namespace MAF1.Workflows;
|
|
|
|
/// <summary>
|
|
/// 用 Microsoft.Agents.AI.Workflows 拼「抽城市 → 查天气」两张对照图。
|
|
/// 建议对照 BuildNodeCondition / BuildEdgeCondition:前者 if 在 CityGate 里,后者 if 在边上。
|
|
/// RequestPort 是官方的「向外要一次人工输入」端口,对应网页的 needsDecision。
|
|
/// </summary>
|
|
public static class CityWeatherWorkflow
|
|
{
|
|
/// <summary>
|
|
/// 节点内判断:FileCity → CityGate。有城市则 Gate 直接催 Weather;没有则发 DecisionRequest。
|
|
/// </summary>
|
|
public static Workflow BuildNodeCondition(AIAgent fileCityAgent, AIAgent weatherAgent, int decisionTimeoutSeconds)
|
|
{
|
|
(ExecutorBinding fileCity, ExecutorBinding weather) = BindAgents(fileCityAgent, weatherAgent);
|
|
CityGateExecutor gate = new(decisionTimeoutSeconds);
|
|
RequestPort cityDecision = RequestPort.Create<DecisionRequest, DecisionAnswer>("CityDecision");
|
|
ApplyCityDecisionExecutor apply = new();
|
|
ToWeatherPromptExecutor toWeather = new();
|
|
|
|
return new WorkflowBuilder(fileCity)
|
|
.AddEdge(fileCity, gate)
|
|
.AddEdge(gate, weather)
|
|
.AddEdge(gate, cityDecision)
|
|
.AddEdge(cityDecision, apply)
|
|
.AddEdge<CityExtraction>(apply, toWeather, extraction => extraction is { HasValidCities: true })
|
|
.AddEdge(toWeather, weather)
|
|
.WithOutputFrom(apply, weather)
|
|
.WithName("CityWeather-Node")
|
|
.Build();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 边条件:Parse 之后两条边,condition 看 HasValidCities。没有城市走 Ask → RequestPort,而不是直接结束。
|
|
/// </summary>
|
|
public static Workflow BuildEdgeCondition(AIAgent fileCityAgent, AIAgent weatherAgent, int decisionTimeoutSeconds)
|
|
{
|
|
(ExecutorBinding fileCity, ExecutorBinding weather) = BindAgents(fileCityAgent, weatherAgent);
|
|
CityParseExecutor parse = new();
|
|
ToWeatherPromptExecutor toWeather = new();
|
|
AskCityDecisionExecutor ask = new(decisionTimeoutSeconds);
|
|
RequestPort cityDecision = RequestPort.Create<DecisionRequest, DecisionAnswer>("CityDecision");
|
|
ApplyCityDecisionExecutor apply = new();
|
|
|
|
return new WorkflowBuilder(fileCity)
|
|
.AddEdge(fileCity, parse)
|
|
.AddEdge<CityExtraction>(parse, toWeather, extraction => extraction is { HasValidCities: true })
|
|
.AddEdge<CityExtraction>(parse, ask, extraction => extraction is not { HasValidCities: true })
|
|
.AddEdge(ask, cityDecision)
|
|
.AddEdge(cityDecision, apply)
|
|
.AddEdge<CityExtraction>(apply, toWeather, extraction => extraction is { HasValidCities: true })
|
|
.AddEdge(toWeather, weather)
|
|
.WithOutputFrom(apply, weather)
|
|
.WithName("CityWeather-Edge")
|
|
.Build();
|
|
}
|
|
|
|
/// <summary>把 AIAgent 嵌进 Workflow。ForwardIncomingMessages=false 避免把上游闲聊原样转给下游。</summary>
|
|
private static (ExecutorBinding FileCity, ExecutorBinding Weather) BindAgents(AIAgent fileCityAgent, AIAgent weatherAgent)
|
|
{
|
|
AIAgentHostOptions agentOptions = new()
|
|
{
|
|
ForwardIncomingMessages = false,
|
|
ReassignOtherAgentsAsUsers = true,
|
|
EmitAgentUpdateEvents = true,
|
|
EmitAgentResponseEvents = true,
|
|
};
|
|
|
|
return (fileCityAgent.BindAsExecutor(agentOptions), weatherAgent.BindAsExecutor(agentOptions));
|
|
}
|
|
}
|