2026-08-26 18:06:02 +08:00
|
|
|
using System.Text.Json;
|
|
|
|
|
|
|
|
|
|
namespace MAF1.Agents;
|
|
|
|
|
|
2026-08-28 11:51:48 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 一次 Agent 执行的统一结果。网页编排器和进程外插件都用这套字段,方便画布把输出接到下一节点。
|
|
|
|
|
/// Message 是给日志看的原文;Outputs 才是下游节点真正读取的端口数据。
|
|
|
|
|
/// </summary>
|
2026-08-26 18:06:02 +08:00
|
|
|
public sealed class AgentStepResult
|
|
|
|
|
{
|
|
|
|
|
public string Message { get; init; } = "";
|
|
|
|
|
public Dictionary<string, object?> Inputs { get; init; } = new(StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
public Dictionary<string, object?> Outputs { get; init; } = new(StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-28 11:51:48 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 从图 JSON / 插件 stdin 读入参。值可能是 string、数组,也可能是 System.Text.Json 反序列化后的 JsonElement。
|
|
|
|
|
/// </summary>
|
2026-08-28 10:43:57 +08:00
|
|
|
public static class AgentInputs
|
2026-08-26 18:06:02 +08:00
|
|
|
{
|
2026-08-28 11:51:48 +08:00
|
|
|
/// <summary>按端口名读一个字符串;没有该键则返回 null。</summary>
|
2026-08-26 18:06:02 +08:00
|
|
|
public static string? ReadString(IReadOnlyDictionary<string, object?> inputs, string key)
|
|
|
|
|
{
|
|
|
|
|
if (!inputs.TryGetValue(key, out object? value) || value is null)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (value is JsonElement el)
|
|
|
|
|
{
|
|
|
|
|
return el.ValueKind == JsonValueKind.String ? el.GetString() : el.ToString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return value.ToString();
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-28 11:51:48 +08:00
|
|
|
/// <summary>读城市列表:支持 JSON 数组、["a","b"] 风格,或用顿号/逗号分隔的一串文字。</summary>
|
2026-08-26 18:06:02 +08:00
|
|
|
public static List<string> ReadStringList(IReadOnlyDictionary<string, object?> inputs, string key)
|
|
|
|
|
{
|
|
|
|
|
if (!inputs.TryGetValue(key, out object? value) || value is null)
|
|
|
|
|
{
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (value is JsonElement el)
|
|
|
|
|
{
|
|
|
|
|
if (el.ValueKind == JsonValueKind.Array)
|
|
|
|
|
{
|
|
|
|
|
return el.EnumerateArray()
|
|
|
|
|
.Select(item => item.ValueKind == JsonValueKind.String ? item.GetString() : item.ToString())
|
|
|
|
|
.Where(s => !string.IsNullOrWhiteSpace(s))
|
|
|
|
|
.Select(s => s!.Trim())
|
|
|
|
|
.ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (el.ValueKind == JsonValueKind.String)
|
|
|
|
|
{
|
|
|
|
|
return Split(el.GetString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (value is IEnumerable<string> typed)
|
|
|
|
|
{
|
|
|
|
|
return typed.Where(v => !string.IsNullOrWhiteSpace(v)).Select(v => v.Trim()).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (value is IEnumerable<object> objects)
|
|
|
|
|
{
|
|
|
|
|
return objects.Select(o => o?.ToString())
|
|
|
|
|
.Where(s => !string.IsNullOrWhiteSpace(s))
|
|
|
|
|
.Select(s => s!.Trim())
|
|
|
|
|
.ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Split(value.ToString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static List<string> Split(string? text)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(text))
|
|
|
|
|
{
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return text.Split(['、', ',', ';', '\n'], StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
|
|
|
|
.ToList();
|
|
|
|
|
}
|
|
|
|
|
}
|