Skip to content
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 agent-reactflow/apps/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"restack-up": "node restack_up.mjs"
},
"dependencies": {
"@restackio/ai": "^0.0.115",
"@restackio/ai": "^0.0.119",
"@temporalio/workflow": "1.11.6",
"dotenv": "^16.4.5",
"node-fetch": "^3.3.2",
Expand Down
21 changes: 9 additions & 12 deletions agent-reactflow/apps/backend/src/agents/flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ import {
AgentError,
agentInfo,
sleep

} from "@restackio/ai/agent";
import { nextEvent, getFlow } from "@restackio/ai/flow";
import { Workflow } from "@temporalio/workflow";
import * as flowFunctions from "@restackio/ai/flow";
import * as functions from "../functions";

export type EndEvent = {
Expand Down Expand Up @@ -52,14 +55,14 @@ export async function agentFlow({flowJson}: AgentFlowInput): Promise<AgentFlowOu
flowJson = await step<typeof functions>({}).mockFlow();
}

const {flowMap} = await step<typeof functions>({}).dslInterpreter({
const {flowMap} = await step<typeof flowFunctions>({}).dslInterpreter({
reactflowJson: flowJson,
});

onEvent(flowEvent, async ({ name, input }: FlowEvent) => {
log.info(`Received event: ${name}`);
log.info(`Received event data: ${input}`);
const flow = flowMap.find((flow) => flow.eventName === name);
const flow = getFlow({flowMap, name})

if (!flow) {
throw new AgentError(`No workflow found for event: ${name}`);
Expand All @@ -86,20 +89,15 @@ export async function agentFlow({flowJson}: AgentFlowInput): Promise<AgentFlowOu
response: childOutput.response,
});

// Evaluate the output against edge conditions
const nextEvent = flow.edgeConditions.find((condition) => {
// Access the correct property within childOutput
const outputCondition = childOutput.response.response;
return outputCondition === condition.condition;
});
const nextFlowEvent = nextEvent({flow, childOutput});

if (nextEvent) {
if (nextFlowEvent) {

await sleep(1000);
step<typeof functions>({}).sendAgentEvent({
eventName: 'flowEvent',
eventInput: {
name: nextEvent.targetNodeId,
name: nextFlowEvent.eventName,
input: childOutput.response,
},
agentId: agentInfo().workflowId,
Expand All @@ -108,7 +106,7 @@ export async function agentFlow({flowJson}: AgentFlowInput): Promise<AgentFlowOu
}
return {
...childOutput,
nextEvent: nextEvent?.targetNodeId,
nextEvent: nextFlowEvent?.eventName,
}

});
Expand All @@ -118,7 +116,6 @@ export async function agentFlow({flowJson}: AgentFlowInput): Promise<AgentFlowOu
endReceived = true;
});

// We use the `condition` function to wait for the event goodbyeReceived to return `True`.
await condition(() => endReceived);

log.info("end condition met");
Expand Down
2 changes: 0 additions & 2 deletions agent-reactflow/apps/backend/src/functions/mockFlow.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { FunctionFailure } from "@restackio/ai/function";
import { ReactFlowJsonObject } from "reactflow";
import { endFlow, idVerification, manualVerification } from "../workflows";
import z from "zod";
import { zodResponseFormat } from "openai/helpers/zod.mjs";

export const mockFlow = async (): Promise<ReactFlowJsonObject> => {
try {
Expand Down
22 changes: 22 additions & 0 deletions agent-reactflow/apps/frontend/components/agent-builder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { nodes as initialNodes, edges as initialEdges } from "../lib/agent-init"
import AgentTestPanel from "./agent-test"
import { createNode, getLayoutedElements } from "./flow/autoLayout"
import WorkflowEditPanel from "./workflow-edit"
import { validateNodeIds, getWorkflowTypes } from "@restackio/react/hook"

export default function WorkflowBuilder() {
const reactFlowWrapper = useRef<HTMLDivElement>(null)
Expand All @@ -40,6 +41,7 @@ export default function WorkflowBuilder() {
const [agentVersion, setAgentVersion] = useState("v1.2")
const [isLayouting, setIsLayouting] = useState(false)
const [viewMode, setViewMode] = useState<'flow' | 'json'>('flow')
const [workflowTypes, setWorkflowTypes] = useState<Record<string, string>>({})

// Apply layout when nodes or edges change
const applyLayout = useCallback(async () => {
Expand Down Expand Up @@ -80,6 +82,26 @@ export default function WorkflowBuilder() {
return () => clearTimeout(timer)
}, [nodes.length, edges.length, applyLayout])

useEffect(() => {
const fetchAndValidateWorkflowTypes = async () => {
try {
const types = await getWorkflowTypes()
setWorkflowTypes(types)
const validationError = validateNodeIds(nodes, types)
if (validationError) {
console.error(validationError)
}
} catch (error) {
console.error("Error fetching or validating workflow types:", error)
}
}

// Only fetch and validate if nodes have changed
if (nodes.length > 0) {
fetchAndValidateWorkflowTypes()
}
}, [nodes])

const onConnect = useCallback((params: Connection | Edge) => setEdges((eds) => addEdge(params, eds)), [setEdges])

const onDragOver = useCallback((event: React.DragEvent<HTMLDivElement>) => {
Expand Down
180 changes: 0 additions & 180 deletions agent-reactflow/apps/frontend/lib/temporal-integration.ts

This file was deleted.

2 changes: 1 addition & 1 deletion agent-reactflow/apps/frontend/lib/workflowData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const workflowData: Node[] = [
},
{
id: "endFlow",
type: "default",
type: "workflow",
position: { x: 0, y: 0 },
data: {
label: "End",
Expand Down
36 changes: 1 addition & 35 deletions agent-reactflow/apps/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,59 +13,25 @@
"dependencies": {
"@ai-sdk/openai": "^1.3.3",
"@ai-sdk/react": "^1.2.2",
"@dagrejs/dagre": "^1.1.4",
"@hookform/resolvers": "^3.9.1",
"@radix-ui/react-accordion": "^1.2.2",
"@radix-ui/react-alert-dialog": "^1.1.4",
"@radix-ui/react-aspect-ratio": "^1.1.1",
"@radix-ui/react-avatar": "^1.1.2",
"@radix-ui/react-checkbox": "^1.1.3",
"@radix-ui/react-collapsible": "^1.1.2",
"@radix-ui/react-context-menu": "^2.2.4",
"@radix-ui/react-dialog": "^1.1.4",
"@radix-ui/react-dropdown-menu": "^2.1.4",
"@radix-ui/react-hover-card": "^1.1.4",
"@radix-ui/react-label": "^2.1.1",
"@radix-ui/react-menubar": "^1.1.4",
"@radix-ui/react-navigation-menu": "^1.2.3",
"@radix-ui/react-popover": "^1.1.4",
"@radix-ui/react-progress": "^1.1.1",
"@radix-ui/react-radio-group": "^1.2.2",
"@radix-ui/react-scroll-area": "^1.2.2",
"@radix-ui/react-select": "^2.1.4",
"@radix-ui/react-separator": "^1.1.1",
"@radix-ui/react-slider": "^1.2.2",
"@radix-ui/react-slot": "^1.1.1",
"@radix-ui/react-switch": "^1.1.2",
"@radix-ui/react-tabs": "^1.1.2",
"@radix-ui/react-toast": "^1.2.4",
"@radix-ui/react-toggle": "^1.1.1",
"@radix-ui/react-toggle-group": "^1.1.1",
"@radix-ui/react-tooltip": "^1.1.6",
"@restackio/ai": "^0.0.115",
"@restackio/react": "^0.10.3",
"@xyflow/react": "^12.4.4",
"ai": "^4.2.5",
"autoprefixer": "^10.4.20",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "1.0.4",
"date-fns": "4.1.0",
"elkjs": "^0.10.0",
"embla-carousel-react": "8.5.1",
"input-otp": "1.4.1",
"lucide-react": "^0.454.0",
"next": "^15.2.1",
"next-themes": "^0.4.4",
"react": "^19.0.0",
"react-day-picker": "8.10.1",
"react-dom": "^19.0.0",
"react-hook-form": "^7.54.1",
"react-resizable-panels": "^2.1.7",
"recharts": "2.15.0",
"sonner": "^1.7.1",
"tailwind-merge": "^2.5.5",
"tailwindcss-animate": "^1.0.7",
"vaul": "^0.9.6",
"zod": "^3.24.2"
},
"devDependencies": {
Expand Down