File size: 1,947 Bytes
05c5ed5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
"use client";
import { appStore } from "@/app/store";
import { Edge } from "@xyflow/react";
import { createUINode } from "lib/ai/workflow/create-ui-node";
import {
  LLMNodeData,
  NodeKind,
  UINode,
} from "lib/ai/workflow/workflow.interface";
import { generateUniqueKey, generateUUID } from "lib/utils";

/**
 * Creates a new workflow node and connects it to an existing source node.
 * This function handles:
 * - Generating unique node names and IDs
 * - Positioning the new node relative to the source
 * - Creating the connecting edge between nodes
 * - Setting appropriate default configurations
 *
 * @param params - Configuration for creating the new node
 * @returns Object containing the new node and optional connecting edge
 */
export function createAppendNode({
  sourceNode,
  kind,
  edge,
  allNodes,
  allEdges,
}: {
  sourceNode: UINode;
  kind: NodeKind;
  edge?: Partial<Edge>;
  allNodes: UINode[];
  allEdges: Edge[];
}): { node: UINode; edge?: Edge } {
  const connectors = allEdges
    .filter((edge) => edge.source === sourceNode.id)
    .map((v) => v.target);

  const connectedNodes = allNodes.filter((node) =>
    connectors.includes(node.id),
  );

  const maxY = Math.max(
    ...connectedNodes.map(
      (node) => node.position.y + (node.measured?.height ?? 0),
    ),
  );

  const names = allNodes.map((node) => node.data.name as string);
  const name = generateUniqueKey(kind.toUpperCase(), names);

  const node = createUINode(kind, {
    name,
    position: {
      x: sourceNode.position.x + 300 * 1.2,
      y: !connectedNodes.length ? sourceNode.position.y : maxY + 80,
    },
  });

  if (kind === NodeKind.LLM) {
    (node.data as LLMNodeData).model = appStore.getState().chatModel! ?? {};
  }
  if (kind === NodeKind.Note) {
    return {
      node,
    };
  }

  return {
    node,
    edge: {
      id: generateUUID(),
      source: sourceNode.id,
      target: node.id,
      ...edge,
    },
  };
}