Skip to content

Commit a5b8995

Browse files
Merge pull request #128 from restackio/reactflowFixes
Agent with React Flow cleanup packages
2 parents 5325fea + c3081a3 commit a5b8995

File tree

7 files changed

+34
-231
lines changed

7 files changed

+34
-231
lines changed

agent-reactflow/apps/backend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"restack-up": "node restack_up.mjs"
1515
},
1616
"dependencies": {
17-
"@restackio/ai": "^0.0.115",
17+
"@restackio/ai": "^0.0.119",
1818
"@temporalio/workflow": "1.11.6",
1919
"dotenv": "^16.4.5",
2020
"node-fetch": "^3.3.2",

agent-reactflow/apps/backend/src/agents/flow.ts

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ import {
99
AgentError,
1010
agentInfo,
1111
sleep
12+
1213
} from "@restackio/ai/agent";
14+
import { nextEvent, getFlow } from "@restackio/ai/flow";
1315
import { Workflow } from "@temporalio/workflow";
16+
import * as flowFunctions from "@restackio/ai/flow";
1417
import * as functions from "../functions";
1518

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

55-
const {flowMap} = await step<typeof functions>({}).dslInterpreter({
58+
const {flowMap} = await step<typeof flowFunctions>({}).dslInterpreter({
5659
reactflowJson: flowJson,
5760
});
5861

5962
onEvent(flowEvent, async ({ name, input }: FlowEvent) => {
6063
log.info(`Received event: ${name}`);
6164
log.info(`Received event data: ${input}`);
62-
const flow = flowMap.find((flow) => flow.eventName === name);
65+
const flow = getFlow({flowMap, name})
6366

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

89-
// Evaluate the output against edge conditions
90-
const nextEvent = flow.edgeConditions.find((condition) => {
91-
// Access the correct property within childOutput
92-
const outputCondition = childOutput.response.response;
93-
return outputCondition === condition.condition;
94-
});
92+
const nextFlowEvent = nextEvent({flow, childOutput});
9593

96-
if (nextEvent) {
94+
if (nextFlowEvent) {
9795

9896
await sleep(1000);
9997
step<typeof functions>({}).sendAgentEvent({
10098
eventName: 'flowEvent',
10199
eventInput: {
102-
name: nextEvent.targetNodeId,
100+
name: nextFlowEvent.eventName,
103101
input: childOutput.response,
104102
},
105103
agentId: agentInfo().workflowId,
@@ -108,7 +106,7 @@ export async function agentFlow({flowJson}: AgentFlowInput): Promise<AgentFlowOu
108106
}
109107
return {
110108
...childOutput,
111-
nextEvent: nextEvent?.targetNodeId,
109+
nextEvent: nextFlowEvent?.eventName,
112110
}
113111

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

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

124121
log.info("end condition met");

agent-reactflow/apps/backend/src/functions/mockFlow.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { FunctionFailure } from "@restackio/ai/function";
22
import { ReactFlowJsonObject } from "reactflow";
33
import { endFlow, idVerification, manualVerification } from "../workflows";
4-
import z from "zod";
5-
import { zodResponseFormat } from "openai/helpers/zod.mjs";
64

75
export const mockFlow = async (): Promise<ReactFlowJsonObject> => {
86
try {

agent-reactflow/apps/frontend/components/agent-builder.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { nodes as initialNodes, edges as initialEdges } from "../lib/agent-init"
2626
import AgentTestPanel from "./agent-test"
2727
import { createNode, getLayoutedElements } from "./flow/autoLayout"
2828
import WorkflowEditPanel from "./workflow-edit"
29+
import { validateNodeIds, getWorkflowTypes } from "@restackio/react/hook"
2930

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

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

85+
useEffect(() => {
86+
const fetchAndValidateWorkflowTypes = async () => {
87+
try {
88+
const types = await getWorkflowTypes()
89+
setWorkflowTypes(types)
90+
const validationError = validateNodeIds(nodes, types)
91+
if (validationError) {
92+
console.error(validationError)
93+
}
94+
} catch (error) {
95+
console.error("Error fetching or validating workflow types:", error)
96+
}
97+
}
98+
99+
// Only fetch and validate if nodes have changed
100+
if (nodes.length > 0) {
101+
fetchAndValidateWorkflowTypes()
102+
}
103+
}, [nodes])
104+
83105
const onConnect = useCallback((params: Connection | Edge) => setEdges((eds) => addEdge(params, eds)), [setEdges])
84106

85107
const onDragOver = useCallback((event: React.DragEvent<HTMLDivElement>) => {

agent-reactflow/apps/frontend/lib/temporal-integration.ts

Lines changed: 0 additions & 180 deletions
This file was deleted.

agent-reactflow/apps/frontend/lib/workflowData.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export const workflowData: Node[] = [
1818
},
1919
{
2020
id: "endFlow",
21-
type: "default",
21+
type: "workflow",
2222
position: { x: 0, y: 0 },
2323
data: {
2424
label: "End",

agent-reactflow/apps/frontend/package.json

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,59 +13,25 @@
1313
"dependencies": {
1414
"@ai-sdk/openai": "^1.3.3",
1515
"@ai-sdk/react": "^1.2.2",
16-
"@dagrejs/dagre": "^1.1.4",
17-
"@hookform/resolvers": "^3.9.1",
18-
"@radix-ui/react-accordion": "^1.2.2",
19-
"@radix-ui/react-alert-dialog": "^1.1.4",
20-
"@radix-ui/react-aspect-ratio": "^1.1.1",
21-
"@radix-ui/react-avatar": "^1.1.2",
22-
"@radix-ui/react-checkbox": "^1.1.3",
23-
"@radix-ui/react-collapsible": "^1.1.2",
24-
"@radix-ui/react-context-menu": "^2.2.4",
25-
"@radix-ui/react-dialog": "^1.1.4",
2616
"@radix-ui/react-dropdown-menu": "^2.1.4",
27-
"@radix-ui/react-hover-card": "^1.1.4",
2817
"@radix-ui/react-label": "^2.1.1",
29-
"@radix-ui/react-menubar": "^1.1.4",
30-
"@radix-ui/react-navigation-menu": "^1.2.3",
31-
"@radix-ui/react-popover": "^1.1.4",
32-
"@radix-ui/react-progress": "^1.1.1",
33-
"@radix-ui/react-radio-group": "^1.2.2",
3418
"@radix-ui/react-scroll-area": "^1.2.2",
35-
"@radix-ui/react-select": "^2.1.4",
3619
"@radix-ui/react-separator": "^1.1.1",
37-
"@radix-ui/react-slider": "^1.2.2",
3820
"@radix-ui/react-slot": "^1.1.1",
39-
"@radix-ui/react-switch": "^1.1.2",
40-
"@radix-ui/react-tabs": "^1.1.2",
41-
"@radix-ui/react-toast": "^1.2.4",
42-
"@radix-ui/react-toggle": "^1.1.1",
43-
"@radix-ui/react-toggle-group": "^1.1.1",
44-
"@radix-ui/react-tooltip": "^1.1.6",
4521
"@restackio/ai": "^0.0.115",
22+
"@restackio/react": "^0.10.3",
4623
"@xyflow/react": "^12.4.4",
4724
"ai": "^4.2.5",
48-
"autoprefixer": "^10.4.20",
4925
"class-variance-authority": "^0.7.1",
5026
"clsx": "^2.1.1",
51-
"cmdk": "1.0.4",
52-
"date-fns": "4.1.0",
5327
"elkjs": "^0.10.0",
54-
"embla-carousel-react": "8.5.1",
55-
"input-otp": "1.4.1",
5628
"lucide-react": "^0.454.0",
5729
"next": "^15.2.1",
5830
"next-themes": "^0.4.4",
5931
"react": "^19.0.0",
60-
"react-day-picker": "8.10.1",
6132
"react-dom": "^19.0.0",
62-
"react-hook-form": "^7.54.1",
63-
"react-resizable-panels": "^2.1.7",
64-
"recharts": "2.15.0",
65-
"sonner": "^1.7.1",
6633
"tailwind-merge": "^2.5.5",
6734
"tailwindcss-animate": "^1.0.7",
68-
"vaul": "^0.9.6",
6935
"zod": "^3.24.2"
7036
},
7137
"devDependencies": {

0 commit comments

Comments
 (0)