Skip to content

Commit

Permalink
Merge pull request #43 from route06inc/final-node-for-each-flow
Browse files Browse the repository at this point in the history
Add Viewer mode and isFinal flag to prepare for flow execution
  • Loading branch information
shige authored Oct 24, 2024
2 parents 12a39cd + aec2bb0 commit 167c708
Show file tree
Hide file tree
Showing 21 changed files with 573 additions and 240 deletions.
240 changes: 13 additions & 227 deletions app/(playground)/p/[agentId]/beta-proto/component.tsx
Original file line number Diff line number Diff line change
@@ -1,228 +1,21 @@
"use client";

import { GiselleLogo } from "@/components/giselle-logo";
import {
Background,
BackgroundVariant,
Panel,
ReactFlow,
ReactFlowProvider,
useReactFlow,
} from "@xyflow/react";
import Link from "next/link";
import { useState } from "react";
import bg from "./bg.png";
import "@xyflow/react/dist/style.css";
import { GradientPathDefinitions } from "./connector/gradient-definitions";
import {
MousePositionProvider,
useMousePosition,
} from "./contexts/mouse-position";
import { Editor } from "./editor";
import { FeatureFlagProvider } from "./feature-flags/provider";
import type { FeatureFlags } from "./feature-flags/types";
import {
giselleNodeArchetypes,
promptBlueprint,
textGeneratorParameterNames,
webSearchBlueprint,
} from "./giselle-node/blueprints";
import {
GiselleNode,
GiselleNodeInformationPanel,
} from "./giselle-node/components";
import { type GiselleNodeId, panelTabs } from "./giselle-node/types";
import {
addNodesAndConnect,
selectNode,
selectNodeAndSetPanelTab,
} from "./graph/actions";
import { useGraph } from "./graph/context";
import { GraphProvider } from "./graph/provider";
import type { Graph } from "./graph/types";
import {
type ReactFlowNode,
edgeTypes,
nodeTypes,
} from "./react-flow-adapter/giselle-node";
import {
useConnectionHandler,
useGraphToReactFlowEffect,
useKeyUpHandler,
useNodeEventHandler,
} from "./react-flow-adapter/graph";
import { setSelectTool } from "./tool/actions";
import { Toolbar } from "./tool/components";
import { useTool } from "./tool/context";
import { ToolProvider } from "./tool/provider";
import { type Graph, playgroundModes } from "./graph/types";
import type { AgentId } from "./types";
import { Viewer } from "./viewer";

function Inner() {
const [previewMode, setPreviewMode] = useState(false);
const { state: toolState, dispatch: toolDispatch } = useTool();
const { dispatch: graphDispatch } = useGraph();
const reactFlowInstance = useReactFlow();
const mousePosition = useMousePosition();
useGraphToReactFlowEffect();
const { handleConnect } = useConnectionHandler();
const { handleNodeDragStop } = useNodeEventHandler();
const { handleKeyUp } = useKeyUpHandler();
return (
<div className="w-full h-screen">
<div className="absolute z-10 left-[20px] right-[20px] top-[20px] h-[36px] flex justify-between">
<div className="flex gap-[8px] items-center">
<Link href="/">
<GiselleLogo className="fill-white w-[70px] h-auto mt-[6px]" />
</Link>
<div className="font-rosart text-[18px] text-black--30">
Playground
</div>
{/**
<div className="flex items-center gap-[10px] group">
<label className="w-[30px] h-[18px] border border-black-70 rounded-full relative bg-black-80 cursor-pointer group has-[:checked]:bg-black-70 ">
<div className="absolute bg-black-100 rounded-full w-[16px] h-[16px] group-has-[:checked]:translate-x-[12px] transition-all" />
<input type="checkbox" name="previewMode" className="hidden" />
</label>
<div className="relative font-avenir h-[18px] text-[12px]">
<div className="h-[18px] flex items-center absolute top-0 text-black--30 opacity-100 group-has-[:checked]:opacity-0 transition-opacity duration-400">
Edit
</div>
<div className="h-[18px] flex items-center absolute text-black--30 opacity-0 group-has-[:checked]:opacity-100 transition-opacity duration-400">
Preview
</div>
</div>
</div>
*/}
</div>
</div>
<ReactFlow<ReactFlowNode>
defaultNodes={[]}
defaultEdges={[]}
nodeTypes={nodeTypes}
edgeTypes={edgeTypes}
panOnScroll
onKeyUp={handleKeyUp}
selectionOnDrag
panOnDrag={false}
colorMode="dark"
onConnect={handleConnect}
onNodeDragStop={handleNodeDragStop}
onNodeClick={(_, node) => {
graphDispatch(
selectNodeAndSetPanelTab({
selectNode: {
id: node.id as GiselleNodeId,
panelTab: panelTabs.property,
},
}),
);
}}
onPaneClick={(event) => {
event.preventDefault();
graphDispatch(
selectNode({
selectedNodeIds: [],
}),
);
if (toolState.activeTool.type === "addGiselleNode") {
const position = reactFlowInstance.flowToScreenPosition({
x: event.clientX,
y: event.clientY,
});
if (
toolState.activeTool.giselleNodeBlueprint.archetype ===
giselleNodeArchetypes.textGenerator
) {
graphDispatch(
addNodesAndConnect({
sourceNode: {
node: promptBlueprint,
position: {
x: position.x - 300,
y: position.y + 100,
},
},
targetNode: {
node: toolState.activeTool.giselleNodeBlueprint,
position,
},
connector: {
targetParameterName:
textGeneratorParameterNames.instruction,
},
}),
);
}
if (
toolState.activeTool.giselleNodeBlueprint.archetype ===
giselleNodeArchetypes.webSearch
) {
graphDispatch(
addNodesAndConnect({
sourceNode: {
node: promptBlueprint,
position: {
x: position.x - 300,
y: position.y + 100,
},
},
targetNode: {
node: toolState.activeTool.giselleNodeBlueprint,
position,
},
connector: {
targetParameterName:
textGeneratorParameterNames.instruction,
},
}),
);
}
toolDispatch(setSelectTool);
}
}}
deleteKeyCode={null}
>
<Background
className="!bg-black-100"
lineWidth={0}
variant={BackgroundVariant.Lines}
style={{
backgroundImage: `url(${bg.src})`,
backgroundPositionX: "center",
backgroundPositionY: "center",
backgroundSize: "cover",
}}
/>
{toolState.activeTool.type === "addGiselleNode" && (
<div
className="absolute"
style={{
left: `${mousePosition.x - 0}px`,
top: `${mousePosition.y - 0}px`,
}}
>
<GiselleNode {...toolState.activeTool.giselleNodeBlueprint} />
</div>
)}

<Panel position={"bottom-center"}>
<Toolbar />
</Panel>
<Panel position="top-right" className="!top-0 !bottom-0 !right-0 !m-0">
<GiselleNodeInformationPanel />
</Panel>
{/**<Panel position="top-left" className="!top-0 !bottom-0 !left-0 !m-0">
<div className="absolute bg-black-100 w-[380px] rounded-[16px] overflow-hidden shadow-[0px_0px_8px_0px_hsla(0,_0%,_100%,_0.2)] top-[80px] bottom-[20px] left-[20px]">
<div className="absolute z-0 rounded-[16px] inset-0 border mask-fill bg-gradient-to-br bg-origin-border bg-clip-boarder border-transparent from-[hsla(233,4%,37%,1)] to-[hsla(233,62%,22%,1)]" />
<div className="flex gap-[10px] flex-col h-full">
<div className="relative z-10 pt-[16px] px-[24px] flex justify-between h-[40px]">
hello
</div>
</div>
</div>
</Panel>**/}
</ReactFlow>
</div>
);
const { state } = useGraph();
if (state.graph.mode === playgroundModes.edit) {
return <Editor />;
}
return <Viewer />;
}

interface PlaygroundProps {
Expand All @@ -232,17 +25,10 @@ interface PlaygroundProps {
}
export function Playground(props: PlaygroundProps) {
return (
<ReactFlowProvider>
<FeatureFlagProvider {...props.featureFlags}>
<MousePositionProvider>
<ToolProvider>
<GraphProvider agentId={props.agentId} defaultGraph={props.graph}>
<GradientPathDefinitions />
<Inner />
</GraphProvider>
</ToolProvider>
</MousePositionProvider>
</FeatureFlagProvider>
</ReactFlowProvider>
<FeatureFlagProvider {...props.featureFlags}>
<GraphProvider agentId={props.agentId} defaultGraph={props.graph}>
<Inner />
</GraphProvider>
</FeatureFlagProvider>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { FC, SVGProps } from "react";

export const SparklesIcon: FC<SVGProps<SVGSVGElement>> = (props) => (
<svg
width="18"
height="18"
viewBox="0 0 18 18"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<title>Sparkles Icon</title>
<g clipPath="url(#clip0_6588_4373)">
<g filter="url(#filter0_d_6588_4373)">
<path d="M14.7272 7.77291C8.63104 8.24793 8.24769 8.63129 7.77266 14.7275C7.29764 8.63129 6.91428 8.24793 0.818115 7.77291C6.91428 7.29788 7.29764 6.91453 7.77266 0.818359C8.24769 6.91453 8.63104 7.29788 14.7272 7.77291Z" />
</g>
<g filter="url(#filter1_d_6588_4373)">
<path d="M17.1818 14.7273C13.9541 14.9507 13.7513 15.131 13.4999 18C13.2486 15.131 13.0458 14.9507 9.81812 14.7273C13.0458 14.5039 13.2486 14.3236 13.4999 11.4546C13.7513 14.3236 13.9541 14.5039 17.1818 14.7273Z" />
</g>
</g>
<defs>
<clipPath id="clip0_6588_4373">
<rect width="18" height="18" />
</clipPath>
</defs>
</svg>
);
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { FC, SVGProps } from "react";

export const WillisIcon: FC<SVGProps<SVGSVGElement>> = (props) => (
export const WilliIcon: FC<SVGProps<SVGSVGElement>> = (props) => (
<svg
width="16"
height="16"
Expand Down
56 changes: 56 additions & 0 deletions app/(playground)/p/[agentId]/beta-proto/components/mode-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type { ReactNode } from "react";
import { useGraph } from "../graph/context";
import type { PlaygroundMode } from "../graph/types";
import { updateMode } from "../graph/v2/mode";

function SelectionIndicator() {
return (
<svg
width="70"
height="32"
viewBox="0 0 70 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<title>Selection Indicator</title>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M67.1402 12.1274C66.9421 12.4761 66.7105 12.8341 66.4438 13.2011C65.1133 15.0319 62.9944 16.9585 60.173 18.8432C54.5383 22.6072 46.3748 26.0225 37.0232 28.1281C36.7764 28.1837 36.53 28.238 36.2841 28.2912C35.9438 28.2992 35.602 28.3053 35.259 28.3094C25.7364 28.4229 17.1525 26.9771 10.9859 24.6019C7.89837 23.4127 5.49151 22.019 3.87301 20.5357C3.55344 20.2428 3.26861 19.9504 3.01705 19.6591C3.23284 19.2627 3.49226 18.8542 3.79778 18.4338C5.12826 16.603 7.2472 14.6764 10.0685 12.7917C15.7032 9.02772 23.8668 5.6124 33.2183 3.50685C33.5357 3.4354 33.8522 3.36595 34.1678 3.29849C34.3585 3.29497 34.5495 3.29207 34.741 3.28979C44.2635 3.17628 52.8475 4.62209 59.0141 6.9973C62.1016 8.18652 64.5085 9.58017 66.127 11.0635C66.5151 11.4192 66.852 11.7741 67.1402 12.1274ZM68.0138 13.4742C64.5805 18.7398 55.682 24.1517 44.2965 27.7203C50.1314 27.0137 55.3006 25.7153 59.3667 24.0252C62.4034 22.763 64.7514 21.3127 66.3077 19.7915C67.8608 18.2733 68.5276 16.7899 68.4989 15.4003C68.4859 14.7721 68.33 14.1281 68.0138 13.4742ZM36.4479 29.7878C55.2361 29.3192 70.1557 22.9646 69.9988 15.3824C69.9741 14.1916 69.579 13.0398 68.8575 11.9442C69.4501 10.6239 69.6744 9.3254 69.482 8.08082C68.3259 0.599797 52.5477 -2.14952 34.0078 1.80124C15.0058 2.17748 -0.157012 8.57345 0.00122734 16.2168C0.0276145 17.4913 0.478388 18.7211 1.29942 19.8851C0.770428 21.1384 0.576644 22.3707 0.75953 23.5541C1.92009 31.0639 17.8155 33.8055 36.4479 29.7878ZM28.3757 29.6186C16.4759 28.8081 6.69877 25.564 2.38267 21.1723C2.17159 21.9076 2.12519 22.5923 2.2229 23.2246C2.43309 24.5848 3.33787 25.8811 5.12281 27.0079C6.91063 28.1365 9.46253 29.0115 12.6571 29.5417C17.0099 30.2641 22.4122 30.3228 28.3757 29.6186ZM2.10372 18.3548C1.70844 17.6219 1.51565 16.9006 1.50112 16.1989C1.47235 14.8093 2.13917 13.3259 3.69231 11.8077C5.24861 10.2865 7.5966 8.8362 10.6333 7.57399C14.8317 5.82891 20.2063 4.50135 26.2755 3.81179C14.5914 7.42214 5.47462 12.9776 2.10372 18.3548ZM41.9658 2.00462C47.8897 1.31276 53.256 1.37486 57.5845 2.09323C60.779 2.62339 63.3309 3.49837 65.1188 4.62703C66.9037 5.75386 67.8085 7.05015 68.0187 8.41031C68.1236 9.0894 68.0623 9.82899 67.8093 10.6269C63.6361 6.17621 53.8903 2.86638 41.9658 2.00462Z"
fill="#BAC6D0"
/>
</svg>
);
}

interface ModeButtonProps {
children: ReactNode;
mode: PlaygroundMode;
selected?: boolean;
}
export function ModeButton(props: ModeButtonProps) {
const { state, dispatch } = useGraph();

return (
<button
type="button"
className="px-[16px] uppercase font-bold text-[14px] relative"
onClick={() => {
dispatch(
updateMode({
input: {
mode: props.mode,
},
}),
);
}}
>
{props.children}
{state.graph.mode === props.mode && (
<div className="absolute left-0 -top-[6px]">
<SelectionIndicator />
</div>
)}
</button>
);
}
Loading

0 comments on commit 167c708

Please sign in to comment.