From d31d19f64b6d85f6bcd9f281775e6284c82a900a Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Wed, 29 Jan 2025 11:43:23 -0800 Subject: [PATCH] Added CrewAI vision block, not functional --- blocks/blocks/crewai.ts | 58 +++++++++++++++++++++++++++++++ blocks/index.ts | 6 ++-- components/icons.tsx | 16 ++++++++- tools/crewai/vision.ts | 75 +++++++++++++++++++++++++++++++++++++++++ tools/index.ts | 5 ++- 5 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 blocks/blocks/crewai.ts create mode 100644 tools/crewai/vision.ts diff --git a/blocks/blocks/crewai.ts b/blocks/blocks/crewai.ts new file mode 100644 index 0000000000..d13ff13641 --- /dev/null +++ b/blocks/blocks/crewai.ts @@ -0,0 +1,58 @@ +import { BlockConfig } from '../types' +import { CrewAIIcon } from '@/components/icons' + +export const CrewAIVisionBlock: BlockConfig = { + type: 'crewaivision', + toolbar: { + title: 'CrewAI Vision', + description: 'Analyze images with CrewAI Vision API', + bgColor: '#FF2F5E', + icon: CrewAIIcon, + category: 'advanced' + }, + tools: { + access: ['crewai.vision'] + }, + workflow: { + inputs: { + apiKey: { type: 'string', required: true }, + imageUrl: { type: 'string', required: false }, + base64Image: { type: 'string', required: false }, + model: { type: 'string', required: false } + }, + outputs: { + response: 'any' + }, + subBlocks: [ + { + id: 'apiKey', + title: 'API Key', + type: 'short-input', + layout: 'full', + placeholder: 'Enter your CrewAI API key', + password: true + }, + { + id: 'imageUrl', + title: 'Image URL', + type: 'short-input', + layout: 'full', + placeholder: 'Enter image URL' + }, + { + id: 'base64Image', + title: 'Base64 Image', + type: 'code', + layout: 'full', + placeholder: 'Paste base64-encoded data' + }, + { + id: 'model', + title: 'Vision Model', + type: 'dropdown', + layout: 'half', + options: ['vision-latest', 'vision-beta'] + } + ] + } +} \ No newline at end of file diff --git a/blocks/index.ts b/blocks/index.ts index 4bb63d299b..8ecf4fef82 100644 --- a/blocks/index.ts +++ b/blocks/index.ts @@ -4,15 +4,17 @@ import { BlockConfig } from './types' import { AgentBlock } from './blocks/agent' import { ApiBlock } from './blocks/api' import { FunctionBlock } from './blocks/function' +import { CrewAIVisionBlock } from './blocks/crewai' // Export blocks for ease of use -export { AgentBlock, ApiBlock, FunctionBlock } +export { AgentBlock, ApiBlock, FunctionBlock, CrewAIVisionBlock } // Registry of all block configurations const blocks: Record = { agent: AgentBlock, api: ApiBlock, - function: FunctionBlock + function: FunctionBlock, + crewaivision: CrewAIVisionBlock } // Build a reverse mapping of tools to block types diff --git a/components/icons.tsx b/components/icons.tsx index 65086886fa..8458d99ed7 100644 --- a/components/icons.tsx +++ b/components/icons.tsx @@ -344,7 +344,7 @@ export function SectionIcon(props: SVGProps) { xmlns="http://www.w3.org/2000/svg" > ) { ) } + +export function CrewAIIcon(props: SVGProps) { + return ( + + + + ) +} diff --git a/tools/crewai/vision.ts b/tools/crewai/vision.ts new file mode 100644 index 0000000000..e16444a8e4 --- /dev/null +++ b/tools/crewai/vision.ts @@ -0,0 +1,75 @@ +import { ToolConfig, ToolResponse } from '../types' + +interface CrewAIVisionParams { + apiKey: string + imageUrl?: string + base64Image?: string + model?: string +} + +interface CrewAIVisionResponse extends ToolResponse { + tokens?: number + model?: string +} + +export const visionTool: ToolConfig = { + id: 'crewai.vision', + name: 'CrewAI Vision', + description: 'Analyze images using CrewAI\'s Vision model', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + description: 'Your CrewAI API key' + }, + imageUrl: { + type: 'string', + required: false, + description: 'Publicly accessible image URL' + }, + base64Image: { + type: 'string', + required: false, + description: 'Base64-encoded image data' + }, + model: { + type: 'string', + required: false, + default: 'vision-latest', + description: 'Model to use for image analysis' + } + }, + + request: { + url: 'https://api.crewai.com/v1/vision/analyze', + method: 'POST', + headers: (params) => ({ + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${params.apiKey}` + }), + body: (params) => { + return { + model: params.model, + imageUrl: params.imageUrl, + base64: params.base64Image + } + } + }, + + transformResponse: async (response: Response) => { + const data = await response.json() + return { + output: data.result, + tokens: data.usage?.total_tokens, + model: data.model + } + }, + + transformError: (error) => { + const message = error.error?.message || error.message + const code = error.error?.type || error.code + return `${message} (${code})` + } +} \ No newline at end of file diff --git a/tools/index.ts b/tools/index.ts index 944c3ad5f8..69f77a68d4 100644 --- a/tools/index.ts +++ b/tools/index.ts @@ -9,6 +9,7 @@ import { requestTool as httpRequest } from './http/request' import { contactsTool as hubspotContacts } from './hubspot/contacts' import { opportunitiesTool as salesforceOpportunities } from './salesforce/opportunities' import { functionExecuteTool as functionExecute } from './function/execute' +import { visionTool as crewAIVision } from './crewai/vision' // Registry of all available tools export const tools: Record = { @@ -25,7 +26,9 @@ export const tools: Record = { 'hubspot.contacts': hubspotContacts, 'salesforce.opportunities': salesforceOpportunities, // Function Tools - 'function.execute': functionExecute + 'function.execute': functionExecute, + // CrewAI Tools + 'crewai.vision': crewAIVision } // Get a tool by its ID