mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-08 22:48:14 -05:00
Added Firecrawl web scrape tool/block and switch toggle sub-block
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
import { Switch as UISwitch } from '@/components/ui/switch'
|
||||
import { useSubBlockValue } from '../hooks/use-sub-block-value'
|
||||
|
||||
interface SwitchProps {
|
||||
blockId: string
|
||||
subBlockId: string
|
||||
}
|
||||
|
||||
export function Switch({ blockId, subBlockId }: SwitchProps) {
|
||||
const [value, setValue] = useSubBlockValue(blockId, subBlockId)
|
||||
|
||||
return (
|
||||
<UISwitch
|
||||
checked={Boolean(value)}
|
||||
onCheckedChange={(checked) => setValue(checked)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import { Dropdown } from './components/dropdown'
|
||||
import { SliderInput } from './components/slider-input'
|
||||
import { Table } from './components/table'
|
||||
import { Code } from './components/code'
|
||||
import { Switch } from './components/switch'
|
||||
|
||||
interface SubBlockProps {
|
||||
blockId: string
|
||||
@@ -70,6 +71,13 @@ export function SubBlock({ blockId, config, isConnecting }: SubBlockProps) {
|
||||
)
|
||||
case 'code':
|
||||
return <Code blockId={blockId} subBlockId={config.id} />
|
||||
case 'switch':
|
||||
return (
|
||||
<div className="flex items-center justify-between">
|
||||
<Label className="text-sm font-medium">{config.title}</Label>
|
||||
<Switch blockId={blockId} subBlockId={config.id} />
|
||||
</div>
|
||||
)
|
||||
default:
|
||||
return null
|
||||
}
|
||||
@@ -77,7 +85,7 @@ export function SubBlock({ blockId, config, isConnecting }: SubBlockProps) {
|
||||
|
||||
return (
|
||||
<div className="space-y-1" onMouseDown={handleMouseDown}>
|
||||
<Label>{config.title}</Label>
|
||||
{config.type !== 'switch' && <Label>{config.title}</Label>}
|
||||
{renderInput()}
|
||||
</div>
|
||||
)
|
||||
|
||||
66
app/w/page.tsx
Normal file
66
app/w/page.tsx
Normal file
@@ -0,0 +1,66 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { WorkflowBlock } from "./components/workflow-block/workflow-block"
|
||||
import { BlockConfig, BlockCategory, BlockIcon } from "@/blocks/types"
|
||||
import { LayoutDashboard } from "lucide-react"
|
||||
|
||||
const WorkflowIcon: BlockIcon = (props) => <LayoutDashboard {...props} />
|
||||
|
||||
interface WorkflowBlockState {
|
||||
id: string
|
||||
type: string
|
||||
position: { x: number; y: number }
|
||||
config: BlockConfig
|
||||
name: string
|
||||
}
|
||||
|
||||
export default function Page() {
|
||||
const [workflows, setWorkflows] = useState<WorkflowBlockState[]>([])
|
||||
|
||||
const createNewWorkflow = () => {
|
||||
const newWorkflow: WorkflowBlockState = {
|
||||
id: `workflow-${workflows.length + 1}`,
|
||||
type: "default",
|
||||
position: { x: 0, y: 0 },
|
||||
config: {
|
||||
type: "default",
|
||||
toolbar: {
|
||||
title: "New Workflow",
|
||||
description: "Empty workflow",
|
||||
bgColor: "#808080",
|
||||
icon: WorkflowIcon,
|
||||
category: "basic" as BlockCategory
|
||||
},
|
||||
tools: {
|
||||
access: []
|
||||
},
|
||||
workflow: {
|
||||
subBlocks: [],
|
||||
inputs: {},
|
||||
outputs: {}
|
||||
}
|
||||
},
|
||||
name: `New Workflow ${workflows.length + 1}`
|
||||
}
|
||||
setWorkflows([...workflows, newWorkflow])
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button onClick={createNewWorkflow}>New Workflow</button>
|
||||
<div>
|
||||
{workflows.map((workflow) => (
|
||||
<WorkflowBlock
|
||||
key={workflow.id}
|
||||
id={workflow.id}
|
||||
type={workflow.type}
|
||||
position={workflow.position}
|
||||
config={workflow.config}
|
||||
name={workflow.name}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
49
blocks/blocks/firecrawl.ts
Normal file
49
blocks/blocks/firecrawl.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { BlockConfig } from '../types'
|
||||
import { FirecrawlIcon } from '@/components/icons'
|
||||
|
||||
export const FirecrawlScrapeBlock: BlockConfig = {
|
||||
type: 'firecrawlscrape',
|
||||
toolbar: {
|
||||
title: 'Firecrawl Scraper',
|
||||
description: 'Extract clean content from any webpage',
|
||||
bgColor: '#FF6B6B',
|
||||
icon: FirecrawlIcon,
|
||||
category: 'advanced'
|
||||
},
|
||||
tools: {
|
||||
access: ['firecrawl.scrape']
|
||||
},
|
||||
workflow: {
|
||||
inputs: {
|
||||
apiKey: { type: 'string', required: true },
|
||||
url: { type: 'string', required: true },
|
||||
scrapeOptions: { type: 'json', required: false }
|
||||
},
|
||||
outputs: {
|
||||
response: 'any'
|
||||
},
|
||||
subBlocks: [
|
||||
{
|
||||
id: 'apiKey',
|
||||
title: 'API Key',
|
||||
type: 'short-input',
|
||||
layout: 'full',
|
||||
placeholder: 'Enter your Firecrawl API key',
|
||||
password: true
|
||||
},
|
||||
{
|
||||
id: 'url',
|
||||
title: 'Website URL',
|
||||
type: 'short-input',
|
||||
layout: 'full',
|
||||
placeholder: 'Enter the webpage URL to scrape'
|
||||
},
|
||||
{
|
||||
id: 'onlyMainContent',
|
||||
title: 'Only Main Content',
|
||||
type: 'switch',
|
||||
layout: 'half'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -5,16 +5,18 @@ import { AgentBlock } from './blocks/agent'
|
||||
import { ApiBlock } from './blocks/api'
|
||||
import { FunctionBlock } from './blocks/function'
|
||||
import { CrewAIVisionBlock } from './blocks/crewai'
|
||||
import { FirecrawlScrapeBlock } from './blocks/firecrawl'
|
||||
|
||||
// Export blocks for ease of use
|
||||
export { AgentBlock, ApiBlock, FunctionBlock, CrewAIVisionBlock }
|
||||
export { AgentBlock, ApiBlock, FunctionBlock, CrewAIVisionBlock, FirecrawlScrapeBlock }
|
||||
|
||||
// Registry of all block configurations
|
||||
const blocks: Record<string, BlockConfig> = {
|
||||
agent: AgentBlock,
|
||||
api: ApiBlock,
|
||||
function: FunctionBlock,
|
||||
crewaivision: CrewAIVisionBlock
|
||||
crewaivision: CrewAIVisionBlock,
|
||||
firecrawlscrape: FirecrawlScrapeBlock
|
||||
}
|
||||
|
||||
// Build a reverse mapping of tools to block types
|
||||
|
||||
@@ -6,7 +6,7 @@ export type BlockCategory = 'basic' | 'advanced'
|
||||
export type OutputType = 'string' | 'number' | 'json' | 'boolean' | 'any'
|
||||
export type ParamType = 'string' | 'number' | 'boolean' | 'json'
|
||||
|
||||
export type SubBlockType = 'short-input' | 'long-input' | 'dropdown' | 'slider' | 'table' | 'code'
|
||||
export type SubBlockType = 'short-input' | 'long-input' | 'dropdown' | 'slider' | 'table' | 'code' | 'switch'
|
||||
export type SubBlockLayout = 'full' | 'half'
|
||||
|
||||
export type OutputConfig = OutputType | {
|
||||
|
||||
@@ -344,7 +344,7 @@ export function SectionIcon(props: SVGProps<SVGSVGElement>) {
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M4.88889 22.2222V7.77778M4.88889 22.2222C4.31752 22.2222 3.75898 22.3917 3.28391 22.7091C2.80883 23.0265 2.43856 23.4777 2.2199 24.0056C2.00125 24.5335 1.94404 25.1143 2.05551 25.6747C2.16698 26.2351 2.44212 26.7498 2.84614 27.1539C3.25016 27.5579 3.76491 27.833 4.3253 27.9445C4.88569 28.056 5.46654 27.9987 5.99442 27.7801C6.5223 27.5614 6.97348 27.1912 7.29091 26.7161C7.60835 26.241 7.77778 25.6825 7.77778 25.1111M4.88889 22.2222C5.65507 22.2222 6.38987 22.5266 6.93164 23.0684C7.47341 23.6101 7.77778 24.3449 7.77778 25.1111M4.88889 7.77778C5.65507 7.77778 6.38987 7.47341 6.93164 6.93164C7.47341 6.38987 7.77778 5.65507 7.77778 4.88889M4.88889 7.77778C4.31752 7.77778 3.75898 7.60835 3.28391 7.29091C2.80883 6.97348 2.43856 6.5223 2.2199 5.99442C2.00125 5.46654 1.94404 4.88569 2.05551 4.3253C2.16698 3.76491 2.44212 3.25016 2.84614 2.84614C3.25016 2.44212 3.76491 2.16698 4.3253 2.05551C4.88569 1.94404 5.46654 2.00125 5.99442 2.2199C6.5223 2.43856 6.97348 2.80883 7.29091 3.28391C7.60835 3.75898 7.77778 4.31752 7.77778 4.88889M7.77778 25.1111H22.2222M7.77778 4.88889H22.2222M22.2222 4.88889C22.2222 5.65507 22.5266 6.38987 23.0684 6.93164C23.6101 7.47341 24.3449 7.77778 25.1111 7.77778M22.2222 4.88889C22.2222 4.31752 22.3917 3.75898 22.7091 3.28391C23.0265 2.80883 23.4777 2.43856 24.0056 2.2199C24.5335 2.00125 25.1143 1.94404 25.6747 2.05551C26.2351 2.16698 26.7498 2.44212 27.1539 2.84614C27.5579 3.25016 27.833 3.76491 27.9445 4.3253C28.056 4.88569 27.9987 5.46654 27.7801 5.99442C27.5614 6.5223 27.1912 6.97348 26.7161 7.29091C26.241 7.60835 25.6825 7.77778 25.1111 7.77778M25.1111 7.77778V22.2222M25.1111 22.2222C24.3449 22.2222 23.6101 22.5266 23.0684 23.0684C22.5266 23.6101 22.2222 24.3449 22.2222 25.1111M25.1111 22.2222C25.6825 22.2222 26.241 22.3917 26.7161 22.7091C27.1912 23.0265 27.5614 23.4777 27.7801 24.0056C27.9987 24.5335 28 25.1143 27.9445 25.6747C27.833 26.2351 27.5579 26.7498 27.1539 27.1539C26.7498 27.5579 26.2351 27.833 25.6747 27.9445C25.1143 28.056 24.5335 27.9987 24.0056 27.7801C23.4777 27.5614 23.0265 27.1912 22.7091 26.7161C22.3917 26.241 22.2222 25.6825 22.2222 25.1111"
|
||||
d="M4.88889 22.2222V7.77778M4.88889 22.2222C4.31752 22.2222 3.75898 22.3917 3.28391 22.7091C2.80883 23.0265 2.43856 23.4777 2.2199 24.0056C2.00125 24.5335 1.94404 25.1143 2.05551 25.6747C2.16698 26.2351 2.44212 26.7498 2.84614 27.1539C3.25016 27.5579 3.76491 27.833 4.3253 27.9445C4.88569 28.056 5.46654 27.9987 5.99442 27.7801C6.5223 27.5614 6.97348 27.1912 7.29091 26.7161C7.60835 26.241 7.77778 25.6825 7.77778 25.1111M4.88889 22.2222C5.65507 22.2222 6.38987 22.5266 6.93164 23.0684C7.47341 23.6101 7.77778 24.3449 7.77778 25.1111M4.88889 7.77778C5.65507 7.77778 6.38987 7.47341 6.93164 6.93164C7.47341 6.38987 7.77778 5.65507 7.77778 4.88889M4.88889 7.77778C4.31752 7.77778 3.75898 7.60835 3.28391 7.29091C2.80883 6.97348 2.43856 6.5223 2.2199 5.99442C2.00125 5.46654 1.94404 4.88569 2.05551 4.3253C2.16698 3.76491 2.44212 3.25016 2.84614 2.84614C3.25016 2.44212 3.76491 2.16698 4.3253 2.05551C4.88569 1.94404 5.46654 2.00125 5.99442 2.2199C6.5223 2.43856 6.97348 2.80883 7.29091 3.28391C7.60835 3.75898 7.77778 4.31752 7.77778 4.88889M7.77778 25.1111H22.2222M7.77778 4.88889H22.2222M22.2222 4.88889C22.2222 5.65507 22.5266 6.38987 23.0684 6.93164C23.6101 7.47341 24.3449 7.77778 25.1111 7.77778M22.2222 4.88889C22.2222 4.31752 22.3917 3.75898 22.7091 3.28391C23.0265 2.80883 23.4777 2.43856 24.0056 2.2199C24.5335 2.00125 25.1143 1.94404 25.6747 2.05551C26.2351 2.16698 26.7498 2.44212 27.1539 2.84614C27.5579 3.25016 27.833 3.76491 27.9445 4.3253C28 4.88569 27.9987 5.46654 27.7801 5.99442C27.5614 6.5223 27.1912 6.97348 26.7161 7.29091C26.241 7.60835 25.6825 7.77778 25.1111 7.77778M25.1111 7.77778V22.2222M25.1111 22.2222C24.3449 22.2222 23.6101 22.5266 23.0684 23.0684C22.5266 23.6101 22.2222 24.3449 22.2222 25.1111M25.1111 22.2222C25.6825 22.2222 26.241 22.3917 26.7161 22.7091C27.1912 23.0265 27.5614 23.4777 27.7801 24.0056C27.9987 24.5335 28 25.1143 27.9445 25.6747C27.833 26.2351 27.5579 26.7498 27.1539 27.1539C26.7498 27.5579 26.2351 27.833 25.6747 27.9445C25.1143 28.056 24.5335 27.9987 24.0056 27.7801C23.4777 27.5614 23.0265 27.1912 22.7091 26.7161C22.3917 26.241 22.2222 25.6825 22.2222 25.1111"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="round"
|
||||
@@ -892,3 +892,21 @@ export function SalesforceIcon(props: SVGProps<SVGSVGElement>) {
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export const FirecrawlIcon = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
{...props}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5" />
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
</svg>
|
||||
)
|
||||
|
||||
26
components/ui/switch.tsx
Normal file
26
components/ui/switch.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import * as React from "react"
|
||||
import * as SwitchPrimitives from "@radix-ui/react-switch"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const Switch = React.forwardRef<
|
||||
React.ElementRef<typeof SwitchPrimitives.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<SwitchPrimitives.Root
|
||||
className={cn(
|
||||
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-blue-500 data-[state=unchecked]:bg-gray-200",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
ref={ref}
|
||||
>
|
||||
<SwitchPrimitives.Thumb
|
||||
className={cn(
|
||||
"pointer-events-none block h-5 w-5 rounded-full bg-white shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
|
||||
)}
|
||||
/>
|
||||
</SwitchPrimitives.Root>
|
||||
))
|
||||
Switch.displayName = SwitchPrimitives.Root.displayName
|
||||
|
||||
export { Switch }
|
||||
30
package-lock.json
generated
30
package-lock.json
generated
@@ -15,6 +15,7 @@
|
||||
"@radix-ui/react-select": "^2.1.4",
|
||||
"@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-tooltip": "^1.1.6",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
@@ -2568,6 +2569,35 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-switch": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.1.2.tgz",
|
||||
"integrity": "sha512-zGukiWHjEdBCRyXvKR6iXAQG6qXm2esuAD6kDOi9Cn+1X6ev3ASo4+CsYaD6Fov9r/AQFekqnD/7+V0Cs6/98g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.1",
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-context": "1.1.1",
|
||||
"@radix-ui/react-primitive": "2.0.1",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0",
|
||||
"@radix-ui/react-use-previous": "1.1.0",
|
||||
"@radix-ui/react-use-size": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-tabs": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.2.tgz",
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
"@radix-ui/react-select": "^2.1.4",
|
||||
"@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-tooltip": "^1.1.6",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
|
||||
91
tools/firecrawl/scrape.ts
Normal file
91
tools/firecrawl/scrape.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { ToolConfig, ToolResponse } from '../types'
|
||||
|
||||
interface ScrapeParams {
|
||||
apiKey: string
|
||||
url: string
|
||||
scrapeOptions?: {
|
||||
onlyMainContent?: boolean
|
||||
formats?: string[]
|
||||
}
|
||||
}
|
||||
|
||||
interface ScrapeResponse extends ToolResponse {
|
||||
success: boolean
|
||||
data: {
|
||||
markdown: string
|
||||
html?: string
|
||||
metadata: {
|
||||
title: string
|
||||
description: string
|
||||
language: string
|
||||
keywords: string
|
||||
robots: string
|
||||
ogTitle: string
|
||||
ogDescription: string
|
||||
ogUrl: string
|
||||
ogImage: string
|
||||
ogLocaleAlternate: string[]
|
||||
ogSiteName: string
|
||||
sourceURL: string
|
||||
statusCode: number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const scrapeTool: ToolConfig<ScrapeParams, ScrapeResponse> = {
|
||||
id: 'firecrawl.scrape',
|
||||
name: 'Firecrawl Website Scraper',
|
||||
description: 'Extract clean content from any webpage in markdown format',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
description: 'Firecrawl API key'
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
description: 'The URL to scrape content from'
|
||||
},
|
||||
scrapeOptions: {
|
||||
type: 'json',
|
||||
required: false,
|
||||
description: 'Options for content scraping'
|
||||
}
|
||||
},
|
||||
|
||||
request: {
|
||||
method: 'POST',
|
||||
url: 'https://api.firecrawl.dev/v1/scrape',
|
||||
headers: (params) => ({
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${params.apiKey}`
|
||||
}),
|
||||
body: (params) => ({
|
||||
url: params.url,
|
||||
formats: params.scrapeOptions?.formats || ["markdown"]
|
||||
})
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!data.success) {
|
||||
throw new Error(data.error?.message || 'Unknown error occurred')
|
||||
}
|
||||
|
||||
return {
|
||||
success: data.success,
|
||||
data: data.data,
|
||||
output: data.data.markdown
|
||||
}
|
||||
},
|
||||
|
||||
transformError: (error) => {
|
||||
const message = error.error?.message || error.message
|
||||
const code = error.error?.type || error.code
|
||||
return `${message} (${code})`
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ToolConfig } from './types'
|
||||
import { chatTool as openaiChat } from './openai/chat'
|
||||
import { ToolConfig } from './types'
|
||||
import { chatTool as openAIChat } from './openai/chat'
|
||||
import { chatTool as anthropicChat } from './anthropic/chat'
|
||||
import { chatTool as googleChat } from './google/chat'
|
||||
import { chatTool as xaiChat } from './xai/chat'
|
||||
@@ -8,13 +8,13 @@ import { reasonerTool as deepseekReasoner } from './deepseek/reasoner'
|
||||
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 { functionExecuteTool as functionExecute } from './function/execute'
|
||||
import { visionTool as crewAIVision } from './crewai/vision'
|
||||
|
||||
import { scrapeTool } from './firecrawl/scrape'
|
||||
// Registry of all available tools
|
||||
export const tools: Record<string, ToolConfig> = {
|
||||
// AI Models
|
||||
'openai.chat': openaiChat,
|
||||
'openai.chat': openAIChat,
|
||||
'anthropic.chat': anthropicChat,
|
||||
'google.chat': googleChat,
|
||||
'xai.chat': xaiChat,
|
||||
@@ -28,7 +28,9 @@ export const tools: Record<string, ToolConfig> = {
|
||||
// Function Tools
|
||||
'function.execute': functionExecute,
|
||||
// CrewAI Tools
|
||||
'crewai.vision': crewAIVision
|
||||
'crewai.vision': crewAIVision,
|
||||
// Firecrawl Tools
|
||||
'firecrawl.scrape': scrapeTool
|
||||
}
|
||||
|
||||
// Get a tool by its ID
|
||||
@@ -65,8 +67,7 @@ export async function executeTool(
|
||||
throw new Error(tool.transformError(error))
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return tool.transformResponse(data)
|
||||
return tool.transformResponse(response)
|
||||
} catch (error) {
|
||||
throw new Error(tool.transformError(error))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user