feat(executor): parse pinned_input/pinned_output on WorkflowNode + WrapPin helper

This commit is contained in:
Claude
2026-08-30 14:11:03 +00:00
parent 55cf372442
commit 8a68b13a70
4 changed files with 149 additions and 2 deletions

View File

@@ -6,7 +6,10 @@ using VolcanicCore.Persistence.Repositories;
namespace VolcanicCore.Api.Engine;
public sealed record WorkflowNode(string Id, string TypeId, string? ConnectionId, string ConfigJson);
public sealed record WorkflowNode(
string Id, string TypeId, string? ConnectionId, string ConfigJson,
string? PinnedInputJson = null,
string? PinnedOutputJson = null);
public sealed record WorkflowEdge(string FromNode, int FromPort, string ToNode, int ToPort);
public sealed record WorkflowGraph
{
@@ -31,7 +34,9 @@ public sealed record WorkflowGraph
: n.TryGetProperty("connectionId", out var c2) ? c2.GetString() : null;
var cfg = n.TryGetProperty("config_json", out var g1) ? g1.GetRawText()
: n.TryGetProperty("config", out var g2) ? g2.GetRawText() : "{}";
nodes.Add(new WorkflowNode(id, typeId!, connId, cfg));
var pinIn = ReadPin(n, "pinned_input");
var pinOut = ReadPin(n, "pinned_output");
nodes.Add(new WorkflowNode(id, typeId!, connId, cfg, pinIn, pinOut));
}
var edges = new List<WorkflowEdge>();
if (root.TryGetProperty("edges", out var edgesEl))
@@ -47,6 +52,13 @@ public sealed record WorkflowGraph
}
return new WorkflowGraph { Nodes = nodes, Edges = edges };
}
private static string? ReadPin(JsonElement node, string name)
{
if (!node.TryGetProperty(name, out var v)) return null;
if (v.ValueKind == JsonValueKind.Null) return null;
return v.GetRawText();
}
}
public sealed class Executor
@@ -407,6 +419,22 @@ public sealed class Executor
}
}
// Wraps a pinned JSON value into a port-shape Item[] on port 0.
// - Array → one item per element (each item's Json = the element)
// - Anything else (object, scalar, null) → single item wrapping the value
// `internal` so unit tests can reach it without going through a full run.
internal static IReadOnlyList<Item> WrapPin(JsonElement pin)
{
if (pin.ValueKind == JsonValueKind.Array)
{
var arr = new List<Item>(pin.GetArrayLength());
foreach (var el in pin.EnumerateArray())
arr.Add(new Item(el.Clone()));
return arr;
}
return new[] { new Item(pin.Clone()) };
}
private static string SerializeInputs(IReadOnlyList<IReadOnlyList<Item>> ports)
=> JsonSerializer.Serialize(ports.Select(port => port.Select(i => new
{

View File

@@ -11,6 +11,10 @@
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="VolcanicCore.Tests" />
</ItemGroup>
<ItemGroup>
<Content Update="wwwroot\**\*" CopyToOutputDirectory="Never" CopyToPublishDirectory="PreserveNewest" />
</ItemGroup>