这是indexloc提供的服务,不要输入任何密码
Skip to content

Implement importing of agent flows from community hub #3867

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/dev-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ concurrency:

on:
push:
branches: ['3872-feat-direct-output-to-chat-from-agent-flows'] # put your current branch to create a build. Core team only.
branches: ['3866-feat-import-agent-flows-from-community-hub'] # put your current branch to create a build. Core team only.
paths-ignore:
- '**.md'
- 'cloud-deployments/*'
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/models/agentFlows.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const AgentFlows = {
body: JSON.stringify({ name, config, uuid }),
})
.then((res) => {
if (!res.ok) throw new Error(response.error || "Failed to save flow");
if (!res.ok) throw new Error(res.error || "Failed to save flow");
return res;
})
.then((res) => res.json())
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/pages/Admin/AgentBuilder/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,9 @@ export default function AgentBuilder() {
await loadAvailableFlows();
} catch (error) {
console.error("Save error details:", error);
showToast("Failed to save agent flow", "error", { clear: true });
showToast(`Failed to save agent flow. ${error.message}`, "error", {
clear: true,
});
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const DEFAULT_USER_ITEMS = {
agentSkills: { items: [] },
systemPrompts: { items: [] },
slashCommands: { items: [] },
agentFlows: { items: [] },
},
teamItems: [],
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import CommunityHubImportItemSteps from "..";
import CTAButton from "@/components/lib/CTAButton";
import { Link } from "react-router-dom";
import paths from "@/utils/paths";

export default function Completed({ settings, setSettings, setStep }) {
return (
Expand All @@ -15,6 +17,14 @@ export default function Completed({ settings, setSettings, setStep }) {
imported successfully! It is now available in your AnythingLLM
instance.
</p>
{settings.item.itemType === "agent-flow" && (
<Link
to={paths.settings.agentSkills()}
className="text-theme-text-primary hover:text-blue-500 hover:underline"
>
View "{settings.item.name}" in Agent Skills
</Link>
)}
<p>
Any changes you make to this {settings.item.itemType} will not be
reflected in the community hub. You can now modify as needed.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import CTAButton from "@/components/lib/CTAButton";
import CommunityHubImportItemSteps from "../..";
import showToast from "@/utils/toast";
import paths from "@/utils/paths";
import { CircleNotch } from "@phosphor-icons/react";
import { useState } from "react";
import AgentFlows from "@/models/agentFlows";
import { safeJsonParse } from "@/utils/request";

export default function AgentFlow({ item, setStep }) {
const flowInfo = safeJsonParse(item.flow, { steps: [] });
const [loading, setLoading] = useState(false);

async function importAgentFlow() {
try {
setLoading(true);
const { success, error, flow } = await AgentFlows.saveFlow(
item.name,
flowInfo
);
if (!success) throw new Error(error);
if (!!flow?.uuid) await AgentFlows.toggleFlow(flow.uuid, true); // Enable the flow automatically after import

showToast(`Agent flow imported successfully!`, "success");
setStep(CommunityHubImportItemSteps.completed.key);
} catch (e) {
console.error(e);
showToast(`Failed to import agent flow. ${e.message}`, "error");
} finally {
setLoading(false);
}
}

return (
<div className="flex flex-col mt-4 gap-y-4">
<div className="flex flex-col gap-y-1">
<h2 className="text-base text-theme-text-primary font-semibold">
Import Agent Flow &quot;{item.name}&quot;
</h2>
{item.creatorUsername && (
<p className="text-white/60 light:text-theme-text-secondary text-xs font-mono">
Created by{" "}
<a
href={paths.communityHub.profile(item.creatorUsername)}
target="_blank"
className="hover:text-blue-500 hover:underline"
rel="noreferrer"
>
@{item.creatorUsername}
</a>
</p>
)}
</div>
<div className="flex flex-col gap-y-[25px] text-white/80 light:text-theme-text-secondary text-sm">
<p>
Agent flows allow you to create reusable sequences of actions that can
be triggered by your agent.
</p>
<div className="flex flex-col gap-y-2">
<p className="font-semibold">Flow Details:</p>
<p>Description: {item.description}</p>
<p className="font-semibold">Steps ({flowInfo.steps.length}):</p>
<ul className="list-disc pl-6">
{flowInfo.steps.map((step, index) => (
<li key={index}>{step.type}</li>
))}
</ul>
</div>
</div>
<CTAButton
disabled={loading}
className="text-dark-text w-full mt-[18px] h-[34px] hover:bg-accent"
onClick={importAgentFlow}
>
{loading ? <CircleNotch size={16} className="animate-spin" /> : null}
{loading ? "Importing..." : "Import agent flow"}
</CTAButton>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import SystemPrompt from "./SystemPrompt";
import SlashCommand from "./SlashCommand";
import UnknownItem from "./Unknown";
import AgentSkill from "./AgentSkill";
import AgentFlow from "./AgentFlow";

const HubItemComponent = {
"agent-skill": AgentSkill,
"system-prompt": SystemPrompt,
"slash-command": SlashCommand,
"agent-flow": AgentFlow,
unknown: UnknownItem,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import CommunityHubImportItemSteps from "..";
import CTAButton from "@/components/lib/CTAButton";
import { useEffect, useState } from "react";
import HubItemComponent from "./HubItem";
import PreLoader from "@/components/Preloader";

function useGetCommunityHubItem({ importId, updateSettings }) {
const [item, setItem] = useState(null);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Link } from "react-router-dom";
import paths from "@/utils/paths";
import { VisibilityIcon } from "./generic";

export default function AgentFlowHubCard({ item }) {
const flow = JSON.parse(item.flow);
return (
<Link
to={paths.communityHub.importItem(item.importId)}
className="bg-black/70 light:bg-slate-100 rounded-lg p-3 hover:bg-black/60 light:hover:bg-slate-200 transition-all duration-200 cursor-pointer group border border-transparent hover:border-slate-400 flex flex-col h-full"
>
<div className="flex gap-x-2 items-center">
<p className="text-white text-sm font-medium">{item.name}</p>
<VisibilityIcon visibility={item.visibility} />
</div>
<div className="flex flex-col gap-2 flex-1">
<p className="text-white/60 text-xs mt-1">{item.description}</p>
<label className="text-white/60 text-xs font-semibold mt-4">
Steps ({flow.steps.length}):
</label>
<p className="text-white/60 text-xs bg-zinc-900 light:bg-slate-200 px-2 py-1 rounded-md font-mono border border-slate-800 light:border-slate-300">
<ul className="list-disc pl-4">
{flow.steps.map((step, index) => (
<li key={index}>{step.type}</li>
))}
</ul>
</p>
</div>
<div className="flex justify-end mt-2">
<Link
to={paths.communityHub.importItem(item.importId)}
className="text-primary-button hover:text-primary-button/80 text-sm font-medium px-3 py-1.5 rounded-md bg-black/30 light:bg-slate-200 group-hover:bg-black/50 light:group-hover:bg-slate-300 transition-all"
>
Import →
</Link>
</div>
</Link>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import GenericHubCard from "./generic";
import SystemPromptHubCard from "./systemPrompt";
import SlashCommandHubCard from "./slashCommand";
import AgentSkillHubCard from "./agentSkill";
import AgentFlowHubCard from "./agentFlow";

export default function HubItemCard({ type, item }) {
switch (type) {
Expand All @@ -11,6 +12,8 @@ export default function HubItemCard({ type, item }) {
return <SlashCommandHubCard item={item} />;
case "agentSkills":
return <AgentSkillHubCard item={item} />;
case "agentFlows":
return <AgentFlowHubCard item={item} />;
default:
return <GenericHubCard item={item} />;
}
Expand Down
10 changes: 8 additions & 2 deletions frontend/src/pages/GeneralSettings/CommunityHub/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Convert a type to a readable string for the community hub.
* @param {("agentSkills" | "agentSkill" | "systemPrompts" | "systemPrompt" | "slashCommands" | "slashCommand")} type
* @param {("agentSkills" | "agentSkill" | "systemPrompts" | "systemPrompt" | "slashCommands" | "slashCommand" | "agentFlows" | "agentFlow")} type
* @returns {string}
*/
export function readableType(type) {
Expand All @@ -14,12 +14,15 @@ export function readableType(type) {
case "slashCommand":
case "slashCommands":
return "Slash Commands";
case "agentFlows":
case "agentFlow":
return "Agent Flows";
}
}

/**
* Convert a type to a path for the community hub.
* @param {("agentSkill" | "agentSkills" | "systemPrompt" | "systemPrompts" | "slashCommand" | "slashCommands")} type
* @param {("agentSkill" | "agentSkills" | "systemPrompt" | "systemPrompts" | "slashCommand" | "slashCommands" | "agentFlow" | "agentFlows")} type
* @returns {string}
*/
export function typeToPath(type) {
Expand All @@ -33,5 +36,8 @@ export function typeToPath(type) {
case "slashCommand":
case "slashCommands":
return "slash-commands";
case "agentFlow":
case "agentFlows":
return "agent-flows";
}
}
10 changes: 4 additions & 6 deletions server/endpoints/agentFlows.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,10 @@ function agentFlowEndpoints(app) {
}

const flow = AgentFlows.saveFlow(name, config, uuid);
if (!flow) {
return response.status(500).json({
success: false,
error: "Failed to save flow",
});
}
if (!flow || !flow.success)
return response
.status(200)
.json({ flow: null, error: flow.error || "Failed to save flow" });

if (!uuid) {
await Telemetry.sendTelemetry("agent_flow_created", {
Expand Down
12 changes: 0 additions & 12 deletions server/utils/agentFlows/executor.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
const { FLOW_TYPES } = require("./flowTypes");
const executeApiCall = require("./executors/api-call");
const executeWebsite = require("./executors/website");
const executeFile = require("./executors/file");
const executeCode = require("./executors/code");
const executeLLMInstruction = require("./executors/llm-instruction");
const executeWebScraping = require("./executors/web-scraping");
const { Telemetry } = require("../../models/telemetry");
Expand Down Expand Up @@ -161,15 +158,6 @@ class FlowExecutor {
case FLOW_TYPES.API_CALL.type:
result = await executeApiCall(config, context);
break;
case FLOW_TYPES.WEBSITE.type:
result = await executeWebsite(config, context);
break;
case FLOW_TYPES.FILE.type:
result = await executeFile(config, context);
break;
case FLOW_TYPES.CODE.type:
result = await executeCode(config, context);
break;
case FLOW_TYPES.LLM_INSTRUCTION.type:
result = await executeLLMInstruction(config, context);
break;
Expand Down
12 changes: 0 additions & 12 deletions server/utils/agentFlows/executors/code.js

This file was deleted.

12 changes: 0 additions & 12 deletions server/utils/agentFlows/executors/file.js

This file was deleted.

12 changes: 0 additions & 12 deletions server/utils/agentFlows/executors/website.js

This file was deleted.

Loading