* wip agent builder * refactor structure for agent builder * improve ui for add block menu and sidebar * lint * node ui improvement * handle deleting variable in all nodes * add headers and body to apiCall node * lint * Agent flow builder backend (#3078) * wip agent builder backend * save/load agent tasks * lint * refactor agent task to use uuids instead of names * placeholder for run task * update frontend sidebar + seperate backend to agent-tasks utils * lint * add deleting of agent tasks * create AgentTasks class + wip load agent tasks into aibitat * lint * inject + call agent tasks * wip call agent tasks * add llm instruction + fix api calling blocks * add ui + backend for editing/toggling agent tasks * lint * add back middlewares * disable run task + add navigate to home on logo click * implement normalizePath to prevent path traversal * wip make api calling more consistent * lint * rename all references from task to flow * patch load flow bug when on editing page * remove unneeded files/comments * lint * fix delete endpoint + rename load flows * add move block to ui + fix api-call backend + add telemetry * lint * add web scraping block * only allow admin for agent builder --------- Co-authored-by: timothycarambat <rambat1010@gmail.com> * Move AgentFlowManager flows to static simplify UI states Handle LLM prompt flow when provided non-string * delete/edit menu for agent flow panel + update flow icon * lint * fix open builder button hidden bug * add tooltips to move up/down block buttons * add tooltip to delete block * truncate block description to fit on blocklist component * light mode agent builder sidebar * light mode api call block * fix light mode styles for agent builder blocks * agent flow fetch in UI * sync delete flow * agent flow ui/ux improvements * remove unused AgentSidebar component * comment out /run * UI changes and updates for flow builder * format flow panel info * update link handling * ui tweaks to header menu * remove unused import * update doc links update block icons * bump readme * Patch code block header oddity resolves #3117 * bump dev image --------- Co-authored-by: Timothy Carambat <rambat1010@gmail.com>
125 lines
4.6 KiB
JavaScript
125 lines
4.6 KiB
JavaScript
import React, { useState, useEffect, useRef } from "react";
|
|
import AgentFlows from "@/models/agentFlows";
|
|
import showToast from "@/utils/toast";
|
|
import { FlowArrow, Gear } from "@phosphor-icons/react";
|
|
import { useNavigate } from "react-router-dom";
|
|
import paths from "@/utils/paths";
|
|
|
|
function ManageFlowMenu({ flow, onDelete }) {
|
|
const [open, setOpen] = useState(false);
|
|
const menuRef = useRef(null);
|
|
const navigate = useNavigate();
|
|
|
|
async function deleteFlow() {
|
|
if (
|
|
!window.confirm(
|
|
"Are you sure you want to delete this flow? This action cannot be undone."
|
|
)
|
|
)
|
|
return;
|
|
const { success, error } = await AgentFlows.deleteFlow(flow.uuid);
|
|
if (success) {
|
|
showToast("Flow deleted successfully.", "success");
|
|
onDelete(flow.uuid);
|
|
} else {
|
|
showToast(error || "Failed to delete flow.", "error");
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
const handleClickOutside = (event) => {
|
|
if (menuRef.current && !menuRef.current.contains(event.target)) {
|
|
setOpen(false);
|
|
}
|
|
};
|
|
|
|
document.addEventListener("mousedown", handleClickOutside);
|
|
return () => {
|
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<div className="relative" ref={menuRef}>
|
|
<button
|
|
type="button"
|
|
onClick={() => setOpen(!open)}
|
|
className="p-1.5 rounded-lg text-white hover:bg-theme-action-menu-item-hover transition-colors duration-300"
|
|
>
|
|
<Gear className="h-5 w-5" weight="bold" />
|
|
</button>
|
|
{open && (
|
|
<div className="absolute w-[100px] -top-1 left-7 mt-1 border-[1.5px] border-white/40 rounded-lg bg-theme-action-menu-bg flex flex-col shadow-[0_4px_14px_rgba(0,0,0,0.25)] text-white z-99 md:z-10">
|
|
<button
|
|
type="button"
|
|
onClick={() => navigate(paths.agents.editAgent(flow.uuid))}
|
|
className="border-none flex items-center rounded-lg gap-x-2 hover:bg-theme-action-menu-item-hover py-1.5 px-2 transition-colors duration-200 w-full text-left"
|
|
>
|
|
<span className="text-sm">Edit Flow</span>
|
|
</button>
|
|
<button
|
|
type="button"
|
|
onClick={deleteFlow}
|
|
className="border-none flex items-center rounded-lg gap-x-2 hover:bg-theme-action-menu-item-hover py-1.5 px-2 transition-colors duration-200 w-full text-left"
|
|
>
|
|
<span className="text-sm">Delete Flow</span>
|
|
</button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default function FlowPanel({ flow, toggleFlow, onDelete }) {
|
|
const [isActive, setIsActive] = useState(flow.active);
|
|
|
|
useEffect(() => {
|
|
setIsActive(flow.active);
|
|
}, [flow.uuid, flow.active]);
|
|
|
|
const handleToggle = async () => {
|
|
try {
|
|
const { success, error } = await AgentFlows.toggleFlow(
|
|
flow.uuid,
|
|
!isActive
|
|
);
|
|
if (!success) throw new Error(error);
|
|
setIsActive(!isActive);
|
|
toggleFlow(flow.uuid);
|
|
showToast("Flow status updated successfully", "success", { clear: true });
|
|
} catch (error) {
|
|
console.error("Failed to toggle flow:", error);
|
|
showToast("Failed to toggle flow", "error", { clear: true });
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<div className="p-2">
|
|
<div className="flex flex-col gap-y-[18px] max-w-[500px]">
|
|
<div className="flex items-center gap-x-2">
|
|
<FlowArrow size={24} weight="bold" className="text-white" />
|
|
<label htmlFor="name" className="text-white text-md font-bold">
|
|
{flow.name}
|
|
</label>
|
|
<label className="border-none relative inline-flex items-center ml-auto cursor-pointer">
|
|
<input
|
|
type="checkbox"
|
|
className="peer sr-only"
|
|
checked={isActive}
|
|
onChange={handleToggle}
|
|
/>
|
|
<div className="peer-disabled:opacity-50 pointer-events-none peer h-6 w-11 rounded-full bg-[#CFCFD0] after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:shadow-xl after:border-none after:bg-white after:box-shadow-md after:transition-all after:content-[''] peer-checked:bg-[#32D583] peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-transparent"></div>
|
|
<span className="ml-3 text-sm font-medium"></span>
|
|
</label>
|
|
<ManageFlowMenu flow={flow} onDelete={onDelete} />
|
|
</div>
|
|
<p className="whitespace-pre-wrap text-white text-opacity-60 text-xs font-medium py-1.5">
|
|
{flow.description || "No description provided"}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|