feat(executor): trigger pinned_output overrides triggerItems on manual runs
This commit is contained in:
@@ -99,7 +99,7 @@ public sealed class Executor
|
||||
|
||||
try
|
||||
{
|
||||
await RunAsync(eid, workflowId, graph, triggerNodeId, triggerItems, answerChannelId, logger, ct);
|
||||
await RunAsync(eid, workflowId, graph, triggerNodeId, triggerKind, triggerItems, answerChannelId, logger, ct);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -113,11 +113,21 @@ public sealed class Executor
|
||||
|
||||
private async Task RunAsync(
|
||||
string executionId, string workflowId, WorkflowGraph graph,
|
||||
string triggerNodeId, IReadOnlyList<Item> triggerItems,
|
||||
string triggerNodeId, string triggerKind, IReadOnlyList<Item> triggerItems,
|
||||
Guid? answerChannelId, ILogger logger, CancellationToken ct)
|
||||
{
|
||||
var triggerNode = graph.Nodes.FirstOrDefault(n => n.Id == triggerNodeId)
|
||||
?? throw new InvalidOperationException($"Trigger node {triggerNodeId} not found in graph.");
|
||||
|
||||
// Manual runs honor the trigger's pinned_output — replaces the
|
||||
// endpoint-passed triggerItems entirely. Live runs (webhook, NATS, etc.)
|
||||
// ignore the pin so a stale value never corrupts real traffic.
|
||||
if (triggerKind == "manual" && triggerNode.PinnedOutputJson is { } pinJson)
|
||||
{
|
||||
using var pinDoc = JsonDocument.Parse(pinJson);
|
||||
triggerItems = WrapPin(pinDoc.RootElement);
|
||||
}
|
||||
|
||||
var triggerStart = DateTimeOffset.UtcNow;
|
||||
_neRepo.Create(executionId, triggerNodeId,
|
||||
inputsJson: "[]",
|
||||
|
||||
@@ -416,4 +416,62 @@ public class ExecutorTests
|
||||
Assert.Single(items);
|
||||
Assert.Equal("42", items[0].Json.GetRawText());
|
||||
}
|
||||
|
||||
// --- trigger pinned_output on manual runs ------------------------------
|
||||
|
||||
[Fact]
|
||||
public async Task Trigger_pinned_output_overrides_trigger_items_on_manual_run()
|
||||
{
|
||||
var rec = new Recorder { Id = "sink.trig_pin_manual" };
|
||||
var (er, nr, exec, _) = Build(new TestTrigger(), rec);
|
||||
|
||||
var graph = new WorkflowGraph
|
||||
{
|
||||
Nodes = new[]
|
||||
{
|
||||
new WorkflowNode("t", "test.trigger", null, "{}",
|
||||
PinnedOutputJson: """{"pinned":true}"""),
|
||||
new WorkflowNode("s", "sink.trig_pin_manual", null, "{}"),
|
||||
},
|
||||
Edges = new[] { new WorkflowEdge("t", 0, "s", 0) },
|
||||
};
|
||||
|
||||
var passedIn = new Core.Item(JsonSerializer.SerializeToElement(new { pinned = false }));
|
||||
var eid = await exec.StartExecutionAsync("wf", graph, "t", "manual",
|
||||
new[] { passedIn }, null, null, CancellationToken.None);
|
||||
|
||||
Assert.Equal("completed", er.Get(eid)!.Status);
|
||||
var sinkRow = nr.ListByExecution(eid).Single(r => r.NodeId == "s");
|
||||
using var inputs = JsonDocument.Parse(sinkRow.InputsJson);
|
||||
var port0Item0Json = inputs.RootElement[0][0].GetProperty("json");
|
||||
Assert.True(port0Item0Json.GetProperty("pinned").GetBoolean());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Trigger_pinned_output_is_ignored_on_non_manual_run()
|
||||
{
|
||||
var rec = new Recorder { Id = "sink.trig_pin_webhook" };
|
||||
var (er, nr, exec, _) = Build(new TestTrigger(), rec);
|
||||
|
||||
var graph = new WorkflowGraph
|
||||
{
|
||||
Nodes = new[]
|
||||
{
|
||||
new WorkflowNode("t", "test.trigger", null, "{}",
|
||||
PinnedOutputJson: """{"pinned":true}"""),
|
||||
new WorkflowNode("s", "sink.trig_pin_webhook", null, "{}"),
|
||||
},
|
||||
Edges = new[] { new WorkflowEdge("t", 0, "s", 0) },
|
||||
};
|
||||
|
||||
var passedIn = new Core.Item(JsonSerializer.SerializeToElement(new { pinned = false }));
|
||||
var eid = await exec.StartExecutionAsync("wf", graph, "t", "http.webhook",
|
||||
new[] { passedIn }, null, null, CancellationToken.None);
|
||||
|
||||
Assert.Equal("completed", er.Get(eid)!.Status);
|
||||
var sinkRow = nr.ListByExecution(eid).Single(r => r.NodeId == "s");
|
||||
using var inputs = JsonDocument.Parse(sinkRow.InputsJson);
|
||||
var port0Item0Json = inputs.RootElement[0][0].GetProperty("json");
|
||||
Assert.False(port0Item0Json.GetProperty("pinned").GetBoolean());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user