Added jina block

This commit is contained in:
Waleed Latif
2025-01-30 17:46:59 -08:00
parent c7ee96df35
commit 49a9dcaa06
8 changed files with 206 additions and 6 deletions

View File

@@ -3,7 +3,7 @@ import { CrewAIIcon } from '@/components/icons'
import { VisionResponse } from '@/tools/crewai/vision'
export const CrewAIVisionBlock: BlockConfig<VisionResponse> = {
type: 'crewaivision',
type: 'crewai_vision',
toolbar: {
title: 'CrewAI Vision Tool',
description: 'Analyze images using vision models',

View File

@@ -3,7 +3,7 @@ import { FirecrawlIcon } from '@/components/icons'
import { ScrapeResponse } from '@/tools/firecrawl/scrape'
export const FirecrawlScrapeBlock: BlockConfig<ScrapeResponse> = {
type: 'firecrawlscrape',
type: 'firecrawl_scrape',
toolbar: {
title: 'Firecrawl Scraper',
description: 'Extract clean content from any webpage',

View File

@@ -32,6 +32,7 @@ export const FunctionBlock: BlockConfig<CodeExecutionOutput> = {
title: 'Code',
type: 'code',
layout: 'full',
placeholder: 'Enter your code here...'
}
],
},

74
blocks/blocks/jina.ts Normal file
View File

@@ -0,0 +1,74 @@
import { JinaAIIcon } from '@/components/icons'
import { BlockConfig } from '../types'
import { ReadUrlResponse } from '@/tools/jina/reader'
export const JinaBlock: BlockConfig<ReadUrlResponse> = {
type: 'jina_reader',
toolbar: {
title: 'Jina Reader',
description: 'Convert any URL to LLM-friendly text',
bgColor: '#ffffff',
icon: JinaAIIcon,
category: 'advanced',
},
tools: {
access: ['jina.readurl']
},
workflow: {
inputs: {
url: { type: 'string', required: true },
useReaderLMv2: { type: 'boolean', required: false },
removeImages: { type: 'boolean', required: false },
gatherLinks: { type: 'boolean', required: false },
jsonResponse: { type: 'boolean', required: false }
},
outputs: {
response: {
type: {
content: 'string'
}
}
},
subBlocks: [
{
id: 'url',
title: 'URL',
type: 'short-input',
layout: 'full',
placeholder: 'Enter URL to read',
},
{
id: 'useReaderLMv2',
title: 'Use ReaderLM v2',
type: 'switch',
layout: 'half',
},
{
id: 'removeImages',
title: 'Remove Images',
type: 'switch',
layout: 'half',
},
{
id: 'gatherLinks',
title: 'Gather Links',
type: 'switch',
layout: 'half',
},
{
id: 'jsonResponse',
title: 'JSON Response',
type: 'switch',
layout: 'half',
},
{
id: 'apiKey',
title: 'API Key',
type: 'short-input',
layout: 'full',
placeholder: 'Enter API Key (optional)',
password: true
}
],
},
}

View File

@@ -6,17 +6,26 @@ import { ApiBlock } from './blocks/api'
import { FunctionBlock } from './blocks/function'
import { CrewAIVisionBlock } from './blocks/crewai'
import { FirecrawlScrapeBlock } from './blocks/firecrawl'
import { JinaBlock } from './blocks/jina'
// Export blocks for ease of use
export { AgentBlock, ApiBlock, FunctionBlock, CrewAIVisionBlock, FirecrawlScrapeBlock }
export {
AgentBlock,
ApiBlock,
FunctionBlock,
CrewAIVisionBlock,
FirecrawlScrapeBlock,
JinaBlock
}
// Registry of all block configurations
const blocks: Record<string, BlockConfig> = {
agent: AgentBlock,
api: ApiBlock,
function: FunctionBlock,
crewaivision: CrewAIVisionBlock,
firecrawlscrape: FirecrawlScrapeBlock
crewai_vision: CrewAIVisionBlock,
firecrawl_scrape: FirecrawlScrapeBlock,
jina_reader: JinaBlock
}
// Build a reverse mapping of tools to block types

View File

@@ -910,3 +910,32 @@ export const FirecrawlIcon = (props: SVGProps<SVGSVGElement>) => (
<circle cx="12" cy="12" r="3" />
</svg>
)
export function JinaAIIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg
{...props}
width="94"
height="40"
viewBox="0 0 94 40"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="m6.12,39.92c3.38,0 6.12,-2.74 6.12,-6.12s-2.74,-6.12 -6.12,-6.12s-6.12,2.74 -6.12,6.12s2.74,6.12 6.12,6.12z"
fill="#EB6161"
/>
<path
clipRule="evenodd"
d="m25.4,14.52c0.8,0 1.44,0.64 1.44,1.44l-0.08,11.72c0,6.68 -5.36,12.12 -12.04,12.24l-0.2,0l0,-12.2l0.04,0l0.04,-11.72c0,-0.8 0.64,-1.44 1.44,-1.44l9.36,0l0,-0.04zm18.8,0c0.8,0 1.44,0.64 1.44,1.44l0,16.4c0,0.8 -0.64,1.44 -1.44,1.44l-9.36,0c-0.8,0 -1.44,-0.64 -1.44,-1.44l0,-16.4c0,-0.8 0.64,-1.44 1.44,-1.44l9.36,0zm14.72,-0.04l0.2,0c6,0.08 10.88,4.92 11.04,10.92l0,6.92c0,0.8 -0.64,1.44 -1.44,1.44l-15.12,0c-0.8,0 -1.44,-0.64 -1.44,-1.44l0,-16.4c0,-0.8 0.64,-1.44 1.44,-1.44l5.32,0zm24.76,19.12c-5.04,-0.32 -9.08,-4.52 -9.08,-9.64c0,-5.32 4.32,-9.64 9.64,-9.64c5.12,0 9.32,4 9.64,9.08l0,8.76c0,0.8 -0.64,1.44 -1.44,1.44l-8.76,0z"
fillRule="evenodd"
fill="#009191"
/>
<path
d="m39.499,12.24c3.38,0 6.12,-2.74 6.12,-6.12s-2.74,-6.12 -6.12,-6.12s-6.12,2.74 -6.12,6.12s2.74,6.12 6.12,6.12z"
fill="#FBCB67"
/>
</g>
</svg>
)
}

View File

@@ -11,6 +11,7 @@ import { opportunitiesTool as salesforceOpportunities } from './salesforce/oppor
import { functionExecuteTool as functionExecute } from './function/execute'
import { visionTool as crewAIVision } from './crewai/vision'
import { scrapeTool } from './firecrawl/scrape'
import { readUrlTool } from './jina/reader'
// Registry of all available tools
export const tools: Record<string, ToolConfig> = {
// AI Models
@@ -30,7 +31,9 @@ export const tools: Record<string, ToolConfig> = {
// CrewAI Tools
'crewai.vision': crewAIVision,
// Firecrawl Tools
'firecrawl.scrape': scrapeTool
'firecrawl.scrape': scrapeTool,
// Jina Tools
'jina.readurl': readUrlTool
}
// Get a tool by its ID

84
tools/jina/reader.ts Normal file
View File

@@ -0,0 +1,84 @@
import { ToolConfig, ToolResponse } from '../types'
export interface ReadUrlParams {
url: string
useReaderLMv2?: boolean
removeImages?: boolean
gatherLinks?: boolean
jsonResponse?: boolean
apiKey?: string
}
export interface ReadUrlResponse extends ToolResponse {
output: {
content: string
}
}
export const readUrlTool: ToolConfig<ReadUrlParams, ReadUrlResponse> = {
id: 'jina.readurl',
name: 'Jina Reader',
description: 'Convert any URL to LLM-friendly text using Jina AI Reader',
version: '1.0.0',
params: {
url: {
type: 'string',
required: true,
description: 'The URL to read and convert to markdown'
},
useReaderLMv2: {
type: 'boolean',
description: 'Whether to use ReaderLM-v2 for better quality'
},
removeImages: {
type: 'boolean',
description: 'Whether to remove all images from the response'
},
gatherLinks: {
type: 'boolean',
description: 'Whether to gather all links at the end'
},
jsonResponse: {
type: 'boolean',
description: 'Whether to return response in JSON format'
},
apiKey: {
type: 'string',
description: 'Your Jina AI API key'
}
},
request: {
url: (params: ReadUrlParams) => {
const baseUrl = `https://r.jina.ai/https://${params.url.replace(/^https?:\/\//, '')}`
const queryParams = new URLSearchParams()
if (params.useReaderLMv2) queryParams.append('use_readerlm_v2', 'true')
if (params.removeImages) queryParams.append('remove_images', 'true')
if (params.gatherLinks) queryParams.append('gather_links', 'true')
if (params.jsonResponse) queryParams.append('json_response', 'true')
return `${baseUrl}${queryParams.toString() ? '?' + queryParams.toString() : ''}`
},
method: 'GET',
headers: (params: ReadUrlParams) => ({
'Content-Type': 'application/json',
'Authorization': `Bearer ${params.apiKey}`
})
},
transformResponse: async (response: Response) => {
const content = await response.text()
return {
success: response.ok,
output: {
content
}
}
},
transformError: (error) => {
return error instanceof Error ? error.message : 'Failed to read URL'
}
}