Added router block; fixed hidden rendering on workflow block

This commit is contained in:
Emir Karabeg
2025-02-05 12:44:02 -08:00
parent 4f3fa9000a
commit 707b7fd8bc
5 changed files with 127 additions and 5 deletions

View File

@@ -17,10 +17,6 @@ interface SubBlockProps {
} }
export function SubBlock({ blockId, config, isConnecting }: SubBlockProps) { export function SubBlock({ blockId, config, isConnecting }: SubBlockProps) {
if (config.hidden) {
return null
}
const handleMouseDown = (e: React.MouseEvent) => { const handleMouseDown = (e: React.MouseEvent) => {
e.stopPropagation() e.stopPropagation()
} }

View File

@@ -89,11 +89,14 @@ export function WorkflowBlock({ id, type, config, name, selected }: WorkflowBloc
}, [workflow.subBlocks, id, updateNodeInternals]) }, [workflow.subBlocks, id, updateNodeInternals])
function groupSubBlocks(subBlocks: SubBlockConfig[]) { function groupSubBlocks(subBlocks: SubBlockConfig[]) {
// Filter out hidden subblocks
const visibleSubBlocks = subBlocks.filter(block => !block.hidden)
const rows: SubBlockConfig[][] = [] const rows: SubBlockConfig[][] = []
let currentRow: SubBlockConfig[] = [] let currentRow: SubBlockConfig[] = []
let currentRowWidth = 0 let currentRowWidth = 0
subBlocks.forEach((block) => { visibleSubBlocks.forEach((block) => {
const blockWidth = block.layout === 'half' ? 0.5 : 1 const blockWidth = block.layout === 'half' ? 0.5 : 1
if (currentRowWidth + blockWidth > 1) { if (currentRowWidth + blockWidth > 1) {
rows.push([...currentRow]) rows.push([...currentRow])

104
blocks/blocks/router.ts Normal file
View File

@@ -0,0 +1,104 @@
import { ConnectIcon } from '@/components/icons'
import { CodeExecutionOutput } from '@/tools/function/execute'
import { BlockConfig } from '../types'
import { MODEL_TOOLS, ModelType } from '../consts'
const routerPrompt = (
prompt: string
) => `You are an intelligent routing agent responsible for directing workflow requests to the most appropriate block. Your task is to analyze the input and determine the single most suitable destination based on the request.
Key Instructions:
1. You MUST choose exactly ONE destination from the IDs of the blocks in the workflow. The destination must be a valid block id.
2. Analysis Framework:
- Carefully evaluate the intent and requirements of the request
- Consider the primary action needed
- Match the core functionality with the most appropriate destination
Routing Request: ${prompt}
Response Format:
Return ONLY the destination id as a single word, lowercase, no punctuation or explanation.
Example: "2acd9007-27e8-4510-a487-73d3b825e7c1"`
export const RouterBlock: BlockConfig<CodeExecutionOutput> = {
type: 'router',
toolbar: {
title: 'Router',
description: 'Add a router',
bgColor: '#28C43F',
icon: ConnectIcon,
category: 'blocks',
},
tools: {
access: [
'openai_chat',
'anthropic_chat',
'google_chat',
'xai_chat',
'deepseek_chat',
'deepseek_reasoner',
],
config: {
tool: (params: Record<string, any>) => {
const model = params.model || 'gpt-4o'
if (!model) {
throw new Error('No model selected')
}
const tool = MODEL_TOOLS[model as ModelType]
if (!tool) {
throw new Error(`Invalid model selected: ${model}`)
}
return tool
},
},
},
workflow: {
inputs: {
code: { type: 'string', required: true },
},
outputs: {
response: {
type: {
result: 'any',
stdout: 'string',
},
},
},
subBlocks: [
{
id: 'prompt',
title: 'Prompt',
type: 'long-input',
layout: 'full',
placeholder: 'Route to the correct block based on the input...',
},
{
id: 'model',
title: 'Model',
type: 'dropdown',
layout: 'full',
options: Object.keys(MODEL_TOOLS),
},
{
id: 'apiKey',
title: 'API Key',
type: 'short-input',
layout: 'full',
placeholder: 'Enter your API key',
password: true,
connectionDroppable: false,
},
{
id: 'systemPrompt',
title: 'System Prompt',
type: 'code',
layout: 'full',
hidden: true,
value: (params: Record<string, any>) => {
return routerPrompt(params.prompt || '')
},
},
],
},
}

View File

@@ -7,6 +7,7 @@ import { FirecrawlScrapeBlock } from './blocks/firecrawl'
import { FunctionBlock } from './blocks/function' import { FunctionBlock } from './blocks/function'
import { GitHubBlock } from './blocks/github' import { GitHubBlock } from './blocks/github'
import { JinaBlock } from './blocks/jina' import { JinaBlock } from './blocks/jina'
import { RouterBlock } from './blocks/router'
import { SerperBlock } from './blocks/serper' import { SerperBlock } from './blocks/serper'
import { SlackMessageBlock } from './blocks/slack' import { SlackMessageBlock } from './blocks/slack'
import { TavilyExtractBlock, TavilySearchBlock } from './blocks/tavily' import { TavilyExtractBlock, TavilySearchBlock } from './blocks/tavily'
@@ -28,6 +29,7 @@ export {
SerperBlock, SerperBlock,
TavilySearchBlock, TavilySearchBlock,
TavilyExtractBlock, TavilyExtractBlock,
RouterBlock,
} }
// Registry of all block configurations // Registry of all block configurations
@@ -45,6 +47,7 @@ const blocks: Record<string, BlockConfig> = {
serper_search: SerperBlock, serper_search: SerperBlock,
tavily_search: TavilySearchBlock, tavily_search: TavilySearchBlock,
tavily_extract: TavilyExtractBlock, tavily_extract: TavilyExtractBlock,
router: RouterBlock,
} }
// Build a reverse mapping of tools to block types // Build a reverse mapping of tools to block types

View File

@@ -1109,3 +1109,19 @@ export const TavilyIcon = (props: SVGProps<SVGSVGElement>) => (
/> />
</svg> </svg>
) )
export const ConnectIcon = (props: SVGProps<SVGSVGElement>) => (
<svg
{...props}
width="24"
height="24"
viewBox="-2 -2 28 28"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M24 16C24 17.4667 23.4778 18.7222 22.4333 19.7667C21.3889 20.8111 20.1333 21.3333 18.6667 21.3333H7.76667C7.47778 22.1111 6.99467 22.7498 6.31733 23.2493C5.64 23.7489 4.86756 23.9991 4 24C2.88889 24 1.94444 23.6111 1.16667 22.8333C0.388889 22.0556 0 21.1111 0 20C0 18.8889 0.388889 17.9444 1.16667 17.1667C1.94444 16.3889 2.88889 16 4 16C4.86667 16 5.63911 16.2498 6.31733 16.7493C6.99556 17.2489 7.47867 17.888 7.76667 18.6667H18.6667C19.4 18.6667 20.028 18.4053 20.5507 17.8827C21.0733 17.36 21.3342 16.7324 21.3333 16C21.3324 15.2676 21.0716 14.6396 20.5507 14.116C20.0298 13.5924 19.4018 13.3316 18.6667 13.3333L5.33333 13.3333C3.86667 13.3333 2.61111 12.8111 1.56667 11.7667C0.522222 10.7222 0 9.46667 0 8C0 6.53334 0.522222 5.27778 1.56667 4.23334C2.61111 3.18889 3.86667 2.66667 5.33333 2.66667H16.2333C16.5222 1.88889 17.0058 1.24978 17.684 0.749337C18.3622 0.248893 19.1342 -0.000885312 20 3.57628e-06C21.1111 3.57628e-06 22.0556 0.388892 22.8333 1.16667C23.6111 1.94445 24 2.88889 24 4C24 5.11111 23.6111 6.05556 22.8333 6.83334C22.0556 7.61111 21.1111 8 20 8C19.1333 8 18.3556 7.74978 17.6667 7.24934C16.9778 6.74889 16.5 6.11022 16.2333 5.33334H5.33333C4.6 5.33334 3.97244 5.59422 3.45067 6.116C2.92889 6.63778 2.66756 7.26578 2.66667 8C2.66578 8.73422 2.92711 9.36178 3.45067 9.88267C3.97422 10.4036 4.60178 10.6649 5.33333 10.6667L18.6667 10.6667C20.1333 10.6667 21.3889 11.1889 22.4333 12.2333C23.4778 13.2778 24 14.5333 24 16ZM5.33333 20C5.33333 19.6222 5.20533 19.3053 4.94933 19.0493C4.69333 18.7933 4.37689 18.6658 4 18.6667C3.62311 18.6676 3.30667 18.7956 3.05067 19.0507C2.79467 19.3058 2.66667 19.6222 2.66667 20C2.66667 20.3778 2.79467 20.6942 3.05067 20.9493C3.30667 21.2044 3.62311 21.3324 4 21.3333C4.37689 21.3342 4.69378 21.2062 4.95067 20.9493C5.20756 20.6924 5.33511 20.376 5.33333 20ZM21.3333 4C21.3333 3.62223 21.2053 3.30534 20.9493 3.04934C20.6933 2.79334 20.3769 2.66578 20 2.66667C19.6231 2.66756 19.3067 2.79556 19.0507 3.05067C18.7947 3.30578 18.6667 3.62223 18.6667 4C18.6667 4.37778 18.7947 4.69422 19.0507 4.94934C19.3067 5.20445 19.6231 5.33245 20 5.33334C20.3769 5.33423 20.6938 5.20622 20.9507 4.94934C21.2076 4.69245 21.3351 4.376 21.3333 4Z"
fill="currentColor"
/>
</svg>
);