From c3081a3dd00ba0a4a6c7a7e145795eeedf0dccf9 Mon Sep 17 00:00:00 2001 From: aboutphilippe Date: Fri, 28 Mar 2025 11:25:26 +0530 Subject: [PATCH] cleanup packages --- agent-reactflow/apps/backend/package.json | 2 +- .../apps/backend/src/agents/flow.ts | 21 +- .../apps/backend/src/functions/mockFlow.ts | 2 - .../frontend/components/agent-builder.tsx | 22 +++ .../apps/frontend/lib/temporal-integration.ts | 180 ------------------ .../apps/frontend/lib/workflowData.tsx | 2 +- agent-reactflow/apps/frontend/package.json | 36 +--- 7 files changed, 34 insertions(+), 231 deletions(-) delete mode 100644 agent-reactflow/apps/frontend/lib/temporal-integration.ts diff --git a/agent-reactflow/apps/backend/package.json b/agent-reactflow/apps/backend/package.json index ff8b5b5..84e19ea 100644 --- a/agent-reactflow/apps/backend/package.json +++ b/agent-reactflow/apps/backend/package.json @@ -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", diff --git a/agent-reactflow/apps/backend/src/agents/flow.ts b/agent-reactflow/apps/backend/src/agents/flow.ts index 7f59f08..c22c49d 100644 --- a/agent-reactflow/apps/backend/src/agents/flow.ts +++ b/agent-reactflow/apps/backend/src/agents/flow.ts @@ -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 = { @@ -52,14 +55,14 @@ export async function agentFlow({flowJson}: AgentFlowInput): Promise({}).mockFlow(); } - const {flowMap} = await step({}).dslInterpreter({ + const {flowMap} = await step({}).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}`); @@ -86,20 +89,15 @@ export async function agentFlow({flowJson}: AgentFlowInput): Promise { - // 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({}).sendAgentEvent({ eventName: 'flowEvent', eventInput: { - name: nextEvent.targetNodeId, + name: nextFlowEvent.eventName, input: childOutput.response, }, agentId: agentInfo().workflowId, @@ -108,7 +106,7 @@ export async function agentFlow({flowJson}: AgentFlowInput): Promise endReceived); log.info("end condition met"); diff --git a/agent-reactflow/apps/backend/src/functions/mockFlow.ts b/agent-reactflow/apps/backend/src/functions/mockFlow.ts index f33fcc0..39c07ef 100644 --- a/agent-reactflow/apps/backend/src/functions/mockFlow.ts +++ b/agent-reactflow/apps/backend/src/functions/mockFlow.ts @@ -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 => { try { diff --git a/agent-reactflow/apps/frontend/components/agent-builder.tsx b/agent-reactflow/apps/frontend/components/agent-builder.tsx index d440f77..a259d16 100644 --- a/agent-reactflow/apps/frontend/components/agent-builder.tsx +++ b/agent-reactflow/apps/frontend/components/agent-builder.tsx @@ -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(null) @@ -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>({}) // Apply layout when nodes or edges change const applyLayout = useCallback(async () => { @@ -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) => { diff --git a/agent-reactflow/apps/frontend/lib/temporal-integration.ts b/agent-reactflow/apps/frontend/lib/temporal-integration.ts deleted file mode 100644 index b4d469c..0000000 --- a/agent-reactflow/apps/frontend/lib/temporal-integration.ts +++ /dev/null @@ -1,180 +0,0 @@ -"use client" - -// This file would contain the actual integration with Temporal -// Below is a simplified mock implementation - -export interface WorkflowNode { - id: string - type: string - data: any -} - -export interface WorkflowEdge { - id: string - source: string - target: string - sourceHandle?: string -} - -export interface WorkflowDefinition { - nodes: WorkflowNode[] - edges: WorkflowEdge[] -} - -// Convert React Flow JSON to Temporal workflow definition -export function convertToTemporalWorkflow(flowData: WorkflowDefinition) { - // This would transform the React Flow JSON into a format that can be used by Temporal - - const workflowSteps = flowData.nodes.map((node) => { - return { - id: node.id, - type: node.type, - config: node.data, - next: flowData.edges - .filter((edge) => edge.source === node.id) - .map((edge) => ({ - target: edge.target, - condition: edge.sourceHandle ? edge.sourceHandle : "default", - })), - } - }) - - return { - workflowId: `workflow-${Date.now()}`, - steps: workflowSteps, - entryPoint: flowData.nodes.find((node) => node.type === "input")?.id, - } -} - -// Execute a workflow using Temporal -export async function executeWorkflow(workflowDefinition: any, input: any) { - console.log("Executing workflow with Temporal", workflowDefinition, input) - - // In a real implementation, this would call the Temporal API - // For now, we'll just simulate a response - - return new Promise((resolve) => { - setTimeout(() => { - resolve({ - workflowId: workflowDefinition.workflowId, - status: "COMPLETED", - result: { - output: "Workflow execution completed successfully", - steps: workflowDefinition.steps.map((step: any) => ({ - id: step.id, - status: "COMPLETED", - output: `Step ${step.id} completed`, - })), - }, - }) - }, 2000) - }) -} - -// Create a workflow template for specific use cases -export function createWorkflowTemplate(useCase: "blablacar" | "traderepublic") { - if (useCase === "blablacar") { - return { - nodes: [ - { - id: "input", - type: "input", - position: { x: 250, y: 25 }, - data: { label: "Input" }, - }, - { - id: "id-verification", - type: "verification", - position: { x: 250, y: 125 }, - data: { - label: "ID Verification", - idType: "driving_license", - }, - }, - { - id: "country-check", - type: "split", - position: { x: 250, y: 225 }, - data: { label: "Country Check" }, - }, - { - id: "age-check", - type: "split", - position: { x: 125, y: 325 }, - data: { label: "Age Check" }, - }, - { - id: "approve", - type: "output", - position: { x: 50, y: 425 }, - data: { label: "Approve" }, - }, - { - id: "human-review", - type: "manualReview", - position: { x: 200, y: 425 }, - data: { label: "Human Review" }, - }, - ], - edges: [ - { id: "e1-2", source: "input", target: "id-verification" }, - { id: "e2-3", source: "id-verification", target: "country-check" }, - { id: "e3-4", source: "country-check", target: "age-check", sourceHandle: "a" }, - { id: "e4-5", source: "age-check", target: "approve", sourceHandle: "a" }, - { id: "e4-6", source: "age-check", target: "human-review", sourceHandle: "b" }, - ], - } - } else { - return { - nodes: [ - { - id: "input", - type: "input", - position: { x: 250, y: 25 }, - data: { label: "Input" }, - }, - { - id: "id-verification", - type: "verification", - position: { x: 250, y: 125 }, - data: { - label: "ID Verification", - idType: "passport", - }, - }, - { - id: "country-check", - type: "split", - position: { x: 250, y: 225 }, - data: { label: "Country Check" }, - }, - { - id: "deny", - type: "output", - position: { x: 375, y: 325 }, - data: { label: "Deny" }, - }, - { - id: "age-check", - type: "split", - position: { x: 125, y: 325 }, - data: { label: "Age Check" }, - }, - { - id: "human-review", - type: "manualReview", - position: { x: 125, y: 425 }, - data: { label: "Human Review" }, - }, - ], - edges: [ - { id: "e1-2", source: "input", target: "id-verification" }, - { id: "e2-3", source: "id-verification", target: "country-check" }, - { id: "e3-4", source: "country-check", target: "deny", sourceHandle: "b" }, - { id: "e3-5", source: "country-check", target: "age-check", sourceHandle: "a" }, - { id: "e5-6", source: "age-check", target: "human-review", sourceHandle: "a" }, - ], - } - } -} - diff --git a/agent-reactflow/apps/frontend/lib/workflowData.tsx b/agent-reactflow/apps/frontend/lib/workflowData.tsx index 5749e75..6c5f555 100644 --- a/agent-reactflow/apps/frontend/lib/workflowData.tsx +++ b/agent-reactflow/apps/frontend/lib/workflowData.tsx @@ -18,7 +18,7 @@ export const workflowData: Node[] = [ }, { id: "endFlow", - type: "default", + type: "workflow", position: { x: 0, y: 0 }, data: { label: "End", diff --git a/agent-reactflow/apps/frontend/package.json b/agent-reactflow/apps/frontend/package.json index 9a02339..6c43a26 100644 --- a/agent-reactflow/apps/frontend/package.json +++ b/agent-reactflow/apps/frontend/package.json @@ -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": {