@fieldwangai/agentflow 0.1.64 → 0.1.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2122,7 +2122,9 @@ function workspaceExtractNamedOutputValue(content, slotName) {
2122
2122
  }
2123
2123
 
2124
2124
  function workspaceApplyAgentOutputSlots(instance, content) {
2125
- const structured = workspaceStructuredAgentOutput(content);
2125
+ const structured = content && typeof content === "object" && !Array.isArray(content)
2126
+ ? content
2127
+ : workspaceStructuredAgentOutput(content);
2126
2128
  const text = String(structured.result || "").trim();
2127
2129
  let changed = false;
2128
2130
  const next = {
@@ -2419,20 +2421,26 @@ function workspaceRunPlan(graph, runNodeId) {
2419
2421
  const edges = Array.isArray(graph?.edges) ? graph.edges : [];
2420
2422
  const target = String(runNodeId || "").trim();
2421
2423
  if (!target || !instances[target]) throw new Error("Missing workspace run node");
2422
- const upstream = new Map();
2423
- const downstream = new Map();
2424
+ const incoming = new Map();
2425
+ const controlDownstream = new Map();
2426
+ const validEdges = [];
2424
2427
  for (const edge of edges) {
2425
2428
  const source = String(edge?.source || "");
2426
2429
  const dest = String(edge?.target || "");
2427
2430
  if (!source || !dest || !instances[source] || !instances[dest]) continue;
2428
- if (!upstream.has(dest)) upstream.set(dest, []);
2429
- upstream.get(dest).push(source);
2430
- if (!downstream.has(source)) downstream.set(source, []);
2431
- downstream.get(source).push(dest);
2431
+ validEdges.push(edge);
2432
+ if (!incoming.has(dest)) incoming.set(dest, []);
2433
+ incoming.get(dest).push(edge);
2434
+ if (workspaceIsControlEdge(graph, edge)) {
2435
+ if (!controlDownstream.has(source)) controlDownstream.set(source, []);
2436
+ controlDownstream.get(source).push(dest);
2437
+ }
2432
2438
  }
2433
2439
  const needed = new Set();
2434
2440
  const pauseNodeIds = new Set();
2435
- const visit = (id) => {
2441
+ // Downstream execution is selected only by control edges. Data/context edges
2442
+ // are used later to pull in upstream dependencies for selected nodes.
2443
+ const addNeeded = (id) => {
2436
2444
  if (!id || needed.has(id)) return;
2437
2445
  const defId = String(instances[id]?.definitionId || "");
2438
2446
  if (id !== target && defId === "workspace_run") {
@@ -2440,23 +2448,41 @@ function workspaceRunPlan(graph, runNodeId) {
2440
2448
  return;
2441
2449
  }
2442
2450
  needed.add(id);
2443
- for (const next of downstream.get(id) || []) visit(next);
2444
2451
  };
2445
- visit(target);
2452
+ const visitControlDownstream = (id) => {
2453
+ for (const next of controlDownstream.get(id) || []) {
2454
+ const before = needed.size;
2455
+ addNeeded(next);
2456
+ if (needed.size !== before) visitControlDownstream(next);
2457
+ }
2458
+ };
2459
+ visitControlDownstream(target);
2446
2460
  needed.delete(target);
2447
- const indegree = new Map(Array.from(needed).map((id) => [id, 0]));
2448
- for (const id of needed) {
2449
- for (const prev of upstream.get(id) || []) {
2450
- if (needed.has(prev)) indegree.set(id, (indegree.get(id) || 0) + 1);
2461
+ const dependencyQueue = Array.from(needed);
2462
+ for (let i = 0; i < dependencyQueue.length; i++) {
2463
+ const id = dependencyQueue[i];
2464
+ for (const edge of incoming.get(id) || []) {
2465
+ const source = String(edge?.source || "");
2466
+ if (!source || source === target || needed.has(source)) continue;
2467
+ addNeeded(source);
2468
+ if (needed.has(source)) dependencyQueue.push(source);
2451
2469
  }
2452
2470
  }
2471
+ const indegree = new Map(Array.from(needed).map((id) => [id, 0]));
2472
+ const dependents = new Map(Array.from(needed).map((id) => [id, []]));
2473
+ for (const edge of validEdges) {
2474
+ const source = String(edge?.source || "");
2475
+ const dest = String(edge?.target || "");
2476
+ if (!needed.has(source) || !needed.has(dest)) continue;
2477
+ indegree.set(dest, (indegree.get(dest) || 0) + 1);
2478
+ dependents.get(source)?.push(dest);
2479
+ }
2453
2480
  const ready = Array.from(needed).filter((id) => (indegree.get(id) || 0) === 0);
2454
2481
  const ordered = [];
2455
2482
  while (ready.length) {
2456
2483
  const id = ready.shift();
2457
2484
  ordered.push(id);
2458
- for (const next of downstream.get(id) || []) {
2459
- if (!needed.has(next)) continue;
2485
+ for (const next of dependents.get(id) || []) {
2460
2486
  const n = (indegree.get(next) || 0) - 1;
2461
2487
  indegree.set(next, n);
2462
2488
  if (n === 0) ready.push(next);
@@ -2468,6 +2494,23 @@ function workspaceRunPlan(graph, runNodeId) {
2468
2494
  return { order: ordered, pauseNodeIds: Array.from(pauseNodeIds) };
2469
2495
  }
2470
2496
 
2497
+ function workspaceIsControlInputSlot(slot) {
2498
+ const name = String(slot?.name || "");
2499
+ const type = String(slot?.type || "");
2500
+ return type === "node" || name === "prev" || name === "next";
2501
+ }
2502
+
2503
+ function workspaceIsControlOutputSlot(slot) {
2504
+ const name = String(slot?.name || "");
2505
+ const type = String(slot?.type || "");
2506
+ return type === "node" || name === "prev" || name === "next";
2507
+ }
2508
+
2509
+ function workspaceIsControlEdge(graph, edge) {
2510
+ return workspaceIsControlOutputSlot(workspaceSourceSlotForEdge(graph, edge)) ||
2511
+ workspaceIsControlInputSlot(workspaceTargetSlotForEdge(graph, edge));
2512
+ }
2513
+
2471
2514
  function workspaceUpstreamText(graph, nodeId, outputs) {
2472
2515
  const edges = Array.isArray(graph?.edges) ? graph.edges : [];
2473
2516
  const incoming = edges
@@ -3372,7 +3415,7 @@ async function runWorkspaceGraph(root, scopedRoot, payload, userCtx = {}, opts =
3372
3415
  const normalizedAgentOutput = workspacePublishAgentOutputFiles(workspaceStructuredAgentOutput(content), runPackage);
3373
3416
  const resultContent = normalizedAgentOutput.result || content;
3374
3417
  outputs.set(nodeId, resultContent);
3375
- const slotUpdate = workspaceApplyAgentOutputSlots(instance, content);
3418
+ const slotUpdate = workspaceApplyAgentOutputSlots(instance, normalizedAgentOutput);
3376
3419
  if (slotUpdate.changed) graph.instances[nodeId] = slotUpdate.instance;
3377
3420
  const updatedDisplays = workspaceUpdateDirectDisplays(graph, nodeId, resultContent, outputs);
3378
3421
  if (slotUpdate.changed || updatedDisplays.length) emit({ type: "graph", nodeId, displayNodeIds: updatedDisplays, graph });