Skip to content

Commit

Permalink
update swarm edge styles, connect user to swarm, initial agent
Browse files Browse the repository at this point in the history
  • Loading branch information
lazToum committed Jan 16, 2025
1 parent df623ef commit b62ca68
Show file tree
Hide file tree
Showing 15 changed files with 318 additions and 254 deletions.
2 changes: 1 addition & 1 deletion src/waldiez/containers/edges/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const WaldiezEdgeCommon = (props: WaldiezEdgeProps) => {
return <WaldiezEdgeSwarmView {...props} swarmType="nested" />;
}
const isSwarmSource = () =>
sourceAgent.data.agentType !== "swarm" && targetAgent?.data.agentType === "swarm_container";
sourceAgent.data.agentType !== "swarm" && targetAgent?.data.agentType === "swarm";
if (isSwarmSource()) {
return <WaldiezEdgeSwarmView {...props} swarmType="source" />;
}
Expand Down
33 changes: 11 additions & 22 deletions src/waldiez/containers/edges/swarm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BaseEdge, EdgeLabelRenderer, Position, getSmoothStepPath } from "@xyflow/react";
import { BaseEdge, EdgeLabelRenderer, getSmoothStepPath } from "@xyflow/react";

import { FaTrashAlt } from "react-icons/fa";
import { FaGear } from "react-icons/fa6";
Expand All @@ -7,6 +7,7 @@ import { GiShakingHands } from "react-icons/gi";
import { MdMessage } from "react-icons/md";

import { WaldiezEdgeProps } from "@waldiez/containers/edges/types";
import { getEdgeTranslations } from "@waldiez/containers/edges/utils";
import { useWaldiez } from "@waldiez/store";
import { AGENT_COLORS } from "@waldiez/theme";

Expand Down Expand Up @@ -118,7 +119,7 @@ export const WaldiezEdgeSwarmView = (
if (label === "") {
return null;
}
const trimmedTo20 = label.length > 15 ? `${label.slice(0, 15)}...` : label;
const trimmedTo20 = label.length > 20 ? `${label.slice(0, 20)}...` : label;
return (
<div
style={{
Expand All @@ -138,26 +139,14 @@ export const WaldiezEdgeSwarmView = (
);
};
const className = swarmType === "source" ? "agent-edge-box" : "clickable agent-edge-swarm-box";
const translations = {
edgeStart: `translate(-50%, 0%) translate(${sourceX}px,${sourceY}px)`,
edgeEnd: `translate(-50%, 0%) translate(${targetX}px,${targetY}px)`,
};
if (sourcePosition === Position.Right && targetPosition === Position.Left) {
translations.edgeStart = `translate(0%, 0%) translate(${sourceX}px,${sourceY - 35}px)`;
translations.edgeEnd = `translate(-100%, -100%) translate(${targetX}px,${targetY}px)`;
}
if (sourcePosition === Position.Left && targetPosition === Position.Right) {
translations.edgeStart = `translate(-100%, 0%) translate(${sourceX}px,${sourceY}px)`;
translations.edgeEnd = `translate(0, 0) translate(${targetX}px,${targetY}px)`;
}
if (sourcePosition === Position.Top && targetPosition === Position.Bottom) {
translations.edgeStart = `translate(-100%, 0%) translate(${sourceX}px,${sourceY - 30}px)`;
translations.edgeEnd = `translate(-100%, 0%) translate(${targetX}px,${targetY}px)`;
}
if (sourcePosition === Position.Bottom && targetPosition === Position.Top) {
translations.edgeStart = `translate(0%, 0%) translate(${sourceX}px,${sourceY}px)`;
translations.edgeEnd = `translate(0%, 0%) translate(${targetX}px,${targetY - 30}px)`;
}
const translations = getEdgeTranslations(
sourceX,
sourceY,
targetX,
targetY,
sourcePosition,
targetPosition,
);
return (
<>
<BaseEdge path={edgePath} markerEnd={markerEnd} style={style} />
Expand Down
67 changes: 67 additions & 0 deletions src/waldiez/containers/edges/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Position } from "@xyflow/react";

// eslint-disable-next-line complexity
export const getEdgeTranslations = (
sourceX: number,
sourceY: number,
targetX: number,
targetY: number,
sourcePosition: Position,
targetPosition: Position,
) => {
const translations = {
edgeStart: `translate(-50%, 0%) translate(${sourceX}px,${sourceY}px)`,
edgeEnd: `translate(-50%, 0%) translate(${targetX}px,${targetY}px)`,
};
if (sourcePosition === Position.Right && targetPosition === Position.Left) {
translations.edgeStart = `translate(0%, 0%) translate(${sourceX - 10}px,${sourceY - 35}px)`;
translations.edgeEnd = `translate(-100%, -100%) translate(${targetX}px,${targetY}px)`;
return translations;
}
if (sourcePosition === Position.Right && targetPosition === Position.Top) {
translations.edgeStart = `translate(0%, 0%) translate(${sourceX - 10}px,${sourceY}px)`;
translations.edgeEnd = `translate(-100%, 0%) translate(${targetX}px,${targetY}px)`;
return translations;
}
if (sourcePosition === Position.Right && targetPosition === Position.Right) {
translations.edgeStart = `translate(0%, 0%) translate(${sourceX - 10}px,${sourceY}px)`;
translations.edgeEnd = `translate(0, 0) translate(${targetX}px,${targetY}px)`;
return translations;
}
if (sourcePosition === Position.Left && targetPosition === Position.Right) {
translations.edgeStart = `translate(-100%, 0%) translate(${sourceX + 10}px,${sourceY}px)`;
translations.edgeEnd = `translate(0, 0) translate(${targetX}px,${targetY}px)`;
return translations;
}
if (sourcePosition === Position.Left && targetPosition === Position.Bottom) {
translations.edgeStart = `translate(-100%, 0%) translate(${sourceX + 10}px,${sourceY - 30}px)`;
translations.edgeEnd = `translate(0, 0) translate(${targetX}px,${targetY}px)`;
return translations;
}
if (sourcePosition === Position.Left && targetPosition === Position.Left) {
translations.edgeStart = `translate(-100%, 0%) translate(${sourceX + 10}px,${sourceY}px)`;
translations.edgeEnd = `translate(-100%, 0%) translate(${targetX}px,${targetY}px)`;
return translations;
}
if (sourcePosition === Position.Top && targetPosition === Position.Bottom) {
translations.edgeStart = `translate(-100%, 0%) translate(${sourceX}px,${sourceY - 30}px)`;
translations.edgeEnd = `translate(-100%, 0%) translate(${targetX}px,${targetY}px)`;
return translations;
}
if (sourcePosition === Position.Top && targetPosition === Position.Right) {
translations.edgeStart = `translate(-100%, 0%) translate(${sourceX}px,${sourceY - 30}px)`;
translations.edgeEnd = `translate(0, 0) translate(${targetX}px,${targetY}px)`;
return translations;
}
if (sourcePosition === Position.Bottom && targetPosition === Position.Left) {
translations.edgeStart = `translate(0%, 0%) translate(${sourceX}px,${sourceY}px)`;
translations.edgeEnd = `translate(-100%, 0%) translate(${targetX}px,${targetY - 30}px)`;
return translations;
}
if (sourcePosition === Position.Bottom && targetPosition === Position.Top) {
translations.edgeStart = `translate(0%, 0%) translate(${sourceX}px,${sourceY}px)`;
translations.edgeEnd = `translate(0%, 0%) translate(${targetX}px,${targetY - 30}px)`;
return translations;
}
return translations;
};
178 changes: 81 additions & 97 deletions src/waldiez/containers/nodes/agent/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const WaldiezNodeAgentView = (props: WaldiezNodeAgentProps) => {
/>
);
}
const handleClassNameBase = agentType === "swarm" ? "swarm-" : data.parentId ? "hidden" : "";
return (
<div className={className} data-testid={`agent-node-${id}-view`}>
{!data.parentId && (
Expand All @@ -57,103 +58,86 @@ export const WaldiezNodeAgentView = (props: WaldiezNodeAgentProps) => {
<WaldiezNodeAgentFooter id={id} data={data} isModalOpen={isModalOpen} />
</div>
)}
{agentType === "swarm" ? (
<>
<Handle
className="swarm-handle top target"
type="target"
isConnectableStart
position={Position.Top}
onConnect={onEdgeConnection}
data-testid={`agent-handle-${id}-top-target`}
id={`agent-handle-${id}-top-target`}
/>
<Handle
className="swarm-handle top source"
type="source"
isConnectableStart
position={Position.Top}
onConnect={onEdgeConnection}
data-testid={`agent-handle-${id}-top-source`}
id={`agent-handle-${id}-top-source`}
/>
<Handle
className="swarm-handle bottom target"
type="target"
isConnectableStart
position={Position.Bottom}
onConnect={onEdgeConnection}
data-testid={`agent-handle-${id}-bottom-target`}
id={`agent-handle-${id}-bottom-target`}
/>
<Handle
className="swarm-handle bottom source"
type="source"
isConnectableStart
position={Position.Bottom}
onConnect={onEdgeConnection}
data-testid={`agent-handle-${id}-bottom-source`}
id={`agent-handle-${id}-bottom-source`}
/>
<Handle
className="swarm-handle left target"
type="target"
isConnectableStart
position={Position.Left}
onConnect={onEdgeConnection}
data-testid={`agent-handle-${id}-left-target`}
id={`agent-handle-${id}-left-target`}
/>
<Handle
className="swarm-handle left source"
type="source"
isConnectableStart
position={Position.Left}
onConnect={onEdgeConnection}
data-testid={`agent-handle-${id}-left-source`}
id={`agent-handle-${id}-left-target`}
/>
<Handle
className="swarm-handle right target"
type="target"
isConnectableStart
position={Position.Right}
onConnect={onEdgeConnection}
data-testid={`agent-handle-${id}-right-target`}
id={`agent-handle-${id}-right-target`}
/>
<Handle
className="swarm-handle right source"
type="source"
isConnectableStart
position={Position.Right}
onConnect={onEdgeConnection}
data-testid={`agent-handle-${id}-right-source`}
id={`agent-handle-${id}-right-source`}
/>
</>
) : (
<>
<Handle
className={data.parentId ? "hidden" : ""}
type="target"
isConnectableEnd
position={Position.Left}
onConnect={onEdgeConnection}
data-testid={`agent-handle-${id}-left"}`}
id={`agent-handle-${id}-left`}
/>
<Handle
className={data.parentId ? "hidden" : ""}
type="source"
isConnectableStart
position={Position.Right}
onConnect={onEdgeConnection}
data-testid={`agent-handle-${id}-right`}
id={`agent-handle-${id}-source`}
/>
</>
)}
<Handle
className={`${handleClassNameBase}handle top target`}
type="target"
isConnectableEnd
position={Position.Top}
onConnect={onEdgeConnection}
data-testid={`agent-handle-top-target-${id}`}
id={`agent-handle-top-target-${id}`}
style={{ left: "75%" }}
/>
<Handle
className={`${handleClassNameBase}handle top source`}
type="source"
isConnectableStart
position={Position.Top}
onConnect={onEdgeConnection}
data-testid={`agent-handle-top-source-${id}`}
id={`agent-handle-top-source-${id}`}
style={{ left: "25%" }}
/>
<Handle
className={`${handleClassNameBase}handle bottom target`}
type="target"
isConnectableEnd
position={Position.Bottom}
onConnect={onEdgeConnection}
data-testid={`agent-handle-bottom-target-${id}`}
id={`agent-handle-bottom-target-${id}`}
style={{ left: "25%" }}
/>
<Handle
className={`${handleClassNameBase}handle bottom source`}
type="source"
isConnectableStart
position={Position.Bottom}
onConnect={onEdgeConnection}
data-testid={`agent-handle-bottom-source${id}`}
id={`agent-handle-bottom-source${id}`}
style={{ left: "75%" }}
/>
<Handle
className={`${handleClassNameBase}handle left target`}
type="target"
// isConnectableEnd
position={Position.Left}
onConnect={onEdgeConnection}
data-testid={`agent-handle-left-target-${id}`}
id={`agent-handle-left-target-${id}`}
style={{ top: "25%" }}
/>
<Handle
className={`${handleClassNameBase}handle left source`}
type="source"
isConnectableStart
position={Position.Left}
onConnect={onEdgeConnection}
data-testid={`agent-handle-left-source-${id}`}
id={`agent-handle-left-source-${id}`}
style={{ top: "75%" }}
/>
<Handle
className={`${handleClassNameBase}handle right target`}
type="target"
isConnectableEnd
position={Position.Right}
onConnect={onEdgeConnection}
data-testid={`agent-handle-right-target-${id}`}
id={`agent-handle-right-target-${id}`}
style={{ top: "75%" }}
/>
<Handle
className={`${handleClassNameBase}handle right source`}
type="source"
isConnectableStart
position={Position.Right}
onConnect={onEdgeConnection}
data-testid={`agent-handle-right-source-${id}`}
id={`agent-handle-right-source-${id}`}
style={{ top: "25%" }}
/>
<button
title="Open Node Modal"
type="button"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const WaldiezNodeSwarmContainerModal = (props: WaldiezSwarmContainerModal
const getSwarmEdges = useWaldiez(s => s.getSwarmEdges);
const getNonSwarmAgents = useWaldiez(s => s.getNonSwarmAgents);
const updateAgentData = useWaldiez(s => s.updateAgentData);
const updateSwarmInitialAgent = useWaldiez(s => s.updateSwarmInitialAgent);
const onFlowChanged = useWaldiez(s => s.onFlowChanged);
const onSave = () => {
updateAgentData(id, agentData);
Expand Down Expand Up @@ -61,7 +62,10 @@ export const WaldiezNodeSwarmContainerModal = (props: WaldiezSwarmContainerModal
};
const onInitialAgentChange = (option: SingleValue<{ label: string; value: any }>) => {
const newData = { ...agentData, initialAgent: option?.value.id };
setAgentData(newData);
if (option?.value.id) {
updateSwarmInitialAgent(option.value.id);
}
// setAgentData(newData);
const dirty = !isEqual(data, newData);
setIsDirty(dirty);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const useEditFlowModal = (props: EditFlowModalProps) => {
});
const [selectedNewEdge, setSelectedNewEdge] = useState<WaldiezEdge | null>(null);
const getFlowEdges = useWaldiez(s => s.getFlowEdges);
const { used: sortedEdges, remaining: remainingEdges } = getFlowEdges();
const { used: sortedEdges, remaining: remainingEdges } = getFlowEdges(true);
const onFlowChanged = useWaldiez(s => s.onFlowChanged);
// tmp state (to save onSubmit, discard onCancel)
const [sortedEdgesState, setSortedEdgesState] = useState<WaldiezEdge[]>(sortedEdges);
Expand Down Expand Up @@ -56,7 +56,7 @@ export const useEditFlowModal = (props: EditFlowModalProps) => {
const reset = () => {
const { name, description, requirements, tags, isAsync } = getFlowInfo();
setFlowData({ name, description, requirements, tags, isAsync });
const { used, remaining } = getFlowEdges();
const { used, remaining } = getFlowEdges(true);
setSortedEdgesState(used);
setRemainingEdgeState(remaining);
setIsDirty(false);
Expand Down
2 changes: 2 additions & 0 deletions src/waldiez/models/Stores/IAgentStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export interface IWaldiezAgentStore {
addGroupMember: (groupId: string, memberId: string) => void;
removeGroupMember: (groupId: string, memberId: string) => void;
getSwarmAgents: () => WaldiezNodeAgentSwarm[];
setSwarmInitialAgent: (agentId: string) => void;
updateSwarmInitialAgent: (agentId: string) => void;
getNonSwarmAgents: (
swarmContainerId: string,
swarmAgents: WaldiezNodeAgent[],
Expand Down
2 changes: 1 addition & 1 deletion src/waldiez/models/Stores/IFlowStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export interface IWaldiezFlowStore {
onFlowChanged: () => WaldiezFlow;
onViewportChange: (viewport: { x: number; y: number; zoom: number }, nodeType: WaldiezNodeType) => void;
saveFlow: () => void;
getFlowEdges: () => { used: WaldiezEdge[]; remaining: WaldiezEdge[] };
getFlowEdges: (skipSwarm: boolean) => { used: WaldiezEdge[]; remaining: WaldiezEdge[] };
importFlow: (items: ThingsToImport, flowData: ImportedFlow, typeShown: WaldiezNodeType) => void;
exportFlow: (hideSecrets: boolean, skipLinks: boolean) => WaldiezFlow;
updateFlowOrder: (data: { id: string; order: number }[]) => void;
Expand Down
Loading

0 comments on commit b62ca68

Please sign in to comment.