Skip to content

Commit

Permalink
remove connectors
Browse files Browse the repository at this point in the history
  • Loading branch information
toyamarinyon committed Oct 25, 2024
1 parent fccd2cc commit b9c1044
Show file tree
Hide file tree
Showing 4 changed files with 247 additions and 2 deletions.
6 changes: 5 additions & 1 deletion app/(playground)/p/[agentId]/beta-proto/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { useGraph } from "./graph/context";
import type { Graph } from "./graph/types";
import { Header } from "./header";
import {
type ReactFlowEdge,
type ReactFlowNode,
edgeTypes,
nodeTypes,
Expand All @@ -45,6 +46,7 @@ import {
useGraphToReactFlowEffect,
useKeyUpHandler,
useNodeEventHandler,
useReacrFlowEdgeEventHandler,
useReactFlowNodeEventHandler,
} from "./react-flow-adapter/graph";
import { setSelectTool } from "./tool/actions";
Expand All @@ -62,9 +64,10 @@ function EditorInner() {
const { handleConnect } = useConnectionHandler();
const { handleKeyUp } = useKeyUpHandler();
const { handleNodesChange } = useReactFlowNodeEventHandler();
const { handleEdgesChange } = useReacrFlowEdgeEventHandler();
return (
<div className="w-full h-screen">
<ReactFlow<ReactFlowNode>
<ReactFlow<ReactFlowNode, ReactFlowEdge>
nodes={graphState.graph.xyFlow.nodes}
edges={graphState.graph.xyFlow.edges}
nodeTypes={nodeTypes}
Expand All @@ -76,6 +79,7 @@ function EditorInner() {
colorMode="dark"
onConnect={handleConnect}
onNodesChange={handleNodesChange}
onEdgesChange={handleEdgesChange}
onPaneClick={(event) => {
event.preventDefault();
if (toolState.activeTool.type === "addGiselleNode") {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { setConnectors } from "../../../connector/actions";
import type { ConnectorId } from "../../../connector/types";
import { giselleNodeArchetypes } from "../../../giselle-node/blueprints";
import { giselleNodeCategories } from "../../../giselle-node/types";
import type { CompositeAction } from "../../context";
import { type Source, removeSource } from "./remove-source";

type RemoveConnectorInput = {
connectorId: ConnectorId;
};

export function removeConnector({
input,
}: { input: RemoveConnectorInput }): CompositeAction {
return (dispatch, getState) => {
const removeConnector = getState().graph.connectors.find(
(connector) => connector.id === input.connectorId,
);
if (removeConnector === undefined) {
throw new Error(`Connector not found: ${input.connectorId}`);
}
switch (removeConnector.targetNodeCategory) {
case giselleNodeCategories.action: {
switch (removeConnector.sourceNodeCategory) {
case giselleNodeCategories.action: {
// Execute this process when a connector
// from an action node like TextGenerator
// or WebSearch to another action node is removed.
// There is a Prompt node connected to the target
// action node that instructed the connection,
// hence remove it.
const relevantInstructionConnector =
getState().graph.connectors.find(
(connector) =>
connector.target === removeConnector.target &&
connector.sourceNodeCategory ===
giselleNodeCategories.instruction,
);
if (relevantInstructionConnector === undefined) {
throw new Error(
`Instruction connector not found: ${removeConnector.target}`,
);
}
let source: Source | undefined;
if (
removeConnector.sourceNodeArcheType ===
giselleNodeArchetypes.textGenerator
) {
const removeArtifact = getState().graph.artifacts.find(
(artifact) =>
artifact.generatorNode.id === removeConnector.source,
);
if (removeArtifact !== undefined) {
source = {
object: "artifact.reference",
id: removeArtifact.id,
};
}
} else if (
removeConnector.sourceNodeArcheType ===
giselleNodeArchetypes.webSearch
) {
const webSearch = getState().graph.webSearches.find(
(webSearch) =>
webSearch.generatorNode.id === removeConnector.source,
);
if (webSearch !== undefined) {
source = webSearch;
}
}
if (source === undefined) {
throw new Error(`Source not found: ${removeConnector.source}`);
}

dispatch(
removeSource({
input: {
nodeId: relevantInstructionConnector.source,
source,
},
}),
);
break;
}
case giselleNodeCategories.instruction:
dispatch(
setConnectors({
input: {
connectors: getState().graph.connectors.filter(
(connector) => connector.id !== removeConnector.id,
),
},
}),
);
break;
}
break;
}
default:
throw new Error("Unexpected target node category detected");
}
if (removeConnector.targetNodeCategory === giselleNodeCategories.action) {
if (removeConnector.sourceNodeCategory === giselleNodeCategories.action) {
}
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import type { ArtifactReference } from "../../../artifact/types";
import { setConnectors } from "../../../connector/actions";
import type { GiselleNode, GiselleNodeId } from "../../../giselle-node/types";
import type { TextContentReference } from "../../../text-content/types";
import type { WebSearch } from "../../../web-search/types";
import { removeParameterFromNode, updateNodeProperty } from "../../actions";
import type { CompositeAction } from "../../context";

export type Source = ArtifactReference | TextContentReference | WebSearch;
type RemoveSourceInput = {
source: Source;
nodeId: GiselleNodeId;
};

export function removeSource({
input,
}: { input: RemoveSourceInput }): CompositeAction {
return (dispatch, getState) => {
const node = getState().graph.nodes.find(
(node) => node.id === input.nodeId,
);
if (node === undefined) {
throw new Error(`Node not found: ${input.nodeId}`);
}

// Remove the source from the sourceNode property
const currentSources = node.properties.sources ?? [];
if (!Array.isArray(currentSources)) {
throw new Error(`${node.id}'s sources property is not an array`);
}
dispatch(
updateNodeProperty({
node: {
id: input.nodeId,
property: {
key: "sources",
value: currentSources.filter(
(currentSource) =>
typeof currentSource === "object" &&
currentSource !== null &&
typeof currentSource.id === "string" &&
currentSource.id !== input.source.id,
),
},
},
}),
);

// Remove the source from the targetNode parameter
let sourceCreatorNodeId: GiselleNodeId | undefined;
if (input.source.object === "artifact.reference") {
sourceCreatorNodeId = getState().graph.artifacts.find(
(artifact) => artifact.id === input.source.id,
)?.generatorNode?.id;
} else if (input.source.object === "webSearch") {
sourceCreatorNodeId = getState().graph.webSearches.find(
(webSearch) => webSearch.id === input.source.id,
)?.generatorNode?.id;
}
if (sourceCreatorNodeId === undefined) {
throw new Error(`Source creator node not found: ${input.source.id}`);
}
const relevantConnectors = getState().graph.connectors.filter(
(connector) => connector.source === input.nodeId,
);
for (const relevantConnector of relevantConnectors) {
const sourceConnector = getState().graph.connectors.find(
(connector) =>
connector.source === sourceCreatorNodeId &&
connector.target === relevantConnector.target,
);
if (sourceConnector === undefined) {
throw new Error(
`Source connector not found: ${sourceCreatorNodeId} -> ${relevantConnector.target}`,
);
}
dispatch(
removeParameterFromNode({
node: {
id: relevantConnector.target,
},
parameter: {
key: sourceConnector.targetHandle,
},
}),
);
dispatch(
setConnectors({
input: {
connectors: getState().graph.connectors.filter(
(connector) => connector.id !== sourceConnector.id,
),
},
}),
);
}
};
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import {
type Connection,
type EdgeChange,
type NodeChange,
type OnNodeDrag,
type OnSelectionChangeFunc,
applyEdgeChanges,
applyNodeChanges,
useOnSelectionChange,
useReactFlow,
} from "@xyflow/react";
import { type KeyboardEventHandler, useCallback, useEffect } from "react";
import type { ConnectorId } from "../connector/types";
import {
type GiselleNodeId,
assertGiselleNodeId,
Expand All @@ -22,7 +25,8 @@ import {
} from "../graph/actions";
import { useGraph } from "../graph/context";
import type { Graph } from "../graph/types";
import { setXyFlowNodes } from "../graph/v2/xy-flow";
import { removeConnector } from "../graph/v2/composition/remove-connector";
import { setXyFlowEdges, setXyFlowNodes } from "../graph/v2/xy-flow";
import {
type ReactFlowEdge,
type ReactFlowNode,
Expand Down Expand Up @@ -84,6 +88,8 @@ export const useReactFlowNodeEventHandler = () => {
],
}),
);
} else if (change.type === "remove") {
console.log(`remove node ${change.id}`);
}
});
},
Expand All @@ -92,6 +98,36 @@ export const useReactFlowNodeEventHandler = () => {
return { handleNodesChange };
};

export function useReacrFlowEdgeEventHandler() {
const { state, dispatch } = useGraph();

const handleEdgesChange = useCallback(
(changes: EdgeChange<ReactFlowEdge>[]) => {
dispatch(
setXyFlowEdges({
input: {
xyFlowEdges: applyEdgeChanges(changes, state.graph.xyFlow.edges),
},
}),
);
changes.map((change) => {
if (change.type === "remove") {
dispatch(
removeConnector({
input: {
connectorId: change.id as ConnectorId,
},
}),
);
}
});
},
[dispatch, state.graph.xyFlow.edges],
);

return { handleEdgesChange };
}

export const useGraphToReactFlowEffect = () => {
const { state, dispatch } = useGraph();
const reactFlowInstance = useReactFlow();
Expand Down

0 comments on commit b9c1044

Please sign in to comment.