Modified block implementation so block output format relies on tool outputs

This commit is contained in:
Waleed Latif
2025-01-30 16:35:08 -08:00
parent f686b407a6
commit 985db94d68
20 changed files with 78 additions and 65 deletions

View File

@@ -1,5 +1,6 @@
import { AgentIcon } from '@/components/icons'
import { BlockConfig } from '../types'
import { ChatResponse } from '@/tools/openai/chat'
// Map of models to their tools
const MODEL_TOOLS = {
@@ -11,9 +12,9 @@ const MODEL_TOOLS = {
'claude-3-5-sonnet-20241022': 'anthropic.chat',
'gemini-pro': 'google.chat',
'grok-2-latest': 'xai.chat'
} as const
} as const
export const AgentBlock: BlockConfig = {
export const AgentBlock: BlockConfig<ChatResponse> = {
type: 'agent',
toolbar: {
title: 'Agent',
@@ -53,20 +54,10 @@ export const AgentBlock: BlockConfig = {
outputs: {
response: {
type: {
text: 'string',
content: 'string',
model: 'string',
tokens: 'number'
},
dependsOn: {
subBlockId: 'responseFormat',
condition: {
whenEmpty: {
response: { type: 'string' }
},
whenFilled: {
response: { type: 'json' }
}
}
tokens: 'any',
reasoning_tokens: 'any'
}
}
},

View File

@@ -1,7 +1,8 @@
import { ApiIcon } from '@/components/icons'
import { BlockConfig } from '../types'
import { RequestResponse } from '@/tools/http/request'
export const ApiBlock: BlockConfig = {
export const ApiBlock: BlockConfig<RequestResponse> = {
type: 'api',
toolbar: {
title: 'API',
@@ -23,7 +24,7 @@ export const ApiBlock: BlockConfig = {
outputs: {
response: {
type: {
body: 'any',
data: 'any',
status: 'number',
headers: 'json'
}

View File

@@ -1,7 +1,8 @@
import { BlockConfig } from '../types'
import { CrewAIIcon } from '@/components/icons'
import { VisionResponse } from '@/tools/crewai/vision'
export const CrewAIVisionBlock: BlockConfig = {
export const CrewAIVisionBlock: BlockConfig<VisionResponse> = {
type: 'crewaivision',
toolbar: {
title: 'CrewAI Vision Tool',
@@ -23,9 +24,9 @@ export const CrewAIVisionBlock: BlockConfig = {
outputs: {
response: {
type: {
text: 'string',
model: 'string',
tokens: 'number'
content: 'string',
model: 'any',
tokens: 'any'
}
}
},
@@ -55,7 +56,7 @@ export const CrewAIVisionBlock: BlockConfig = {
layout: 'full',
placeholder: 'Enter your API key',
password: true
},
},
{
id: 'prompt',
title: 'Custom Prompt',

View File

@@ -1,7 +1,8 @@
import { BlockConfig } from '../types'
import { FirecrawlIcon } from '@/components/icons'
import { ScrapeResponse } from '@/tools/firecrawl/scrape'
export const FirecrawlScrapeBlock: BlockConfig = {
export const FirecrawlScrapeBlock: BlockConfig<ScrapeResponse> = {
type: 'firecrawlscrape',
toolbar: {
title: 'Firecrawl Scraper',
@@ -20,10 +21,10 @@ export const FirecrawlScrapeBlock: BlockConfig = {
scrapeOptions: { type: 'json', required: false }
},
outputs: {
response: {
response: {
type: {
markdown: 'string',
html: 'string',
html: 'any',
metadata: 'json'
}
}
@@ -43,7 +44,7 @@ export const FirecrawlScrapeBlock: BlockConfig = {
type: 'short-input',
layout: 'full',
placeholder: 'Enter the webpage URL to scrape'
},
},
{
id: 'onlyMainContent',
title: 'Only Main Content',

View File

@@ -1,7 +1,8 @@
import { CodeIcon } from '@/components/icons'
import { BlockConfig } from '../types'
export const FunctionBlock: BlockConfig = {
import { CodeExecutionOutput } from '@/tools/function/execute'
export const FunctionBlock: BlockConfig<CodeExecutionOutput> = {
type: 'function',
toolbar: {
title: 'Function',
@@ -11,10 +12,7 @@ export const FunctionBlock: BlockConfig = {
category: 'advanced',
},
tools: {
access: ['function.execute'],
config: {
tool: () => 'function.execute'
}
access: ['function.execute']
},
workflow: {
inputs: {
@@ -23,7 +21,7 @@ export const FunctionBlock: BlockConfig = {
outputs: {
response: {
type: {
value: 'any',
result: 'any',
stdout: 'string'
}
}
@@ -34,8 +32,7 @@ export const FunctionBlock: BlockConfig = {
title: 'Code',
type: 'code',
layout: 'full',
placeholder: 'Enter your code here...'
}
]
}
],
},
}

View File

@@ -1,5 +1,7 @@
import type { SVGProps } from 'react'
import type { JSX } from 'react'
import { ToolResponse } from '@/tools/types'
import { ExtractToolOutput, ToolOutputToValueType } from './utils'
export type BlockIcon = (props: SVGProps<SVGSVGElement>) => JSX.Element
export type BlockCategory = 'basic' | 'advanced'
@@ -45,7 +47,7 @@ export interface SubBlockConfig {
password?: boolean
}
export interface BlockConfig {
export interface BlockConfig<T extends ToolResponse = ToolResponse> {
type: string
toolbar: {
title: string
@@ -63,6 +65,10 @@ export interface BlockConfig {
workflow: {
subBlocks: SubBlockConfig[]
inputs: Record<string, ParamConfig>
outputs: Record<string, OutputConfig>
outputs: {
response: {
type: ToolOutputToValueType<ExtractToolOutput<T>>
}
}
}
}

View File

@@ -1,11 +1,27 @@
import { BlockState, SubBlockState } from '@/stores/workflow/types'
import { BlockOutput, OutputConfig } from '@/blocks/types'
import { BlockOutput, OutputConfig, PrimitiveValueType } from '@/blocks/types'
import { ToolResponse } from '@/tools/types'
interface CodeLine {
id: string
content: string
}
// Tool output type utilities
export type ExtractToolOutput<T> = T extends ToolResponse
? T['output']
: never
export type ToolOutputToValueType<T> = T extends Record<string, any>
? {
[K in keyof T]: T[K] extends string ? 'string'
: T[K] extends number ? 'number'
: T[K] extends boolean ? 'boolean'
: T[K] extends object ? 'json'
: 'any'
}
: never
function isEmptyValue(value: SubBlockState['value']): boolean {
if (value === null || value === undefined) return true
if (typeof value === 'string') return value.trim() === ''

View File

@@ -5,7 +5,7 @@ import { Executor } from '@/executor'
export interface WorkflowExecutionResult {
success: boolean
data?: Record<string, any>
output?: Record<string, any>
error?: string
}
@@ -32,10 +32,10 @@ export async function executeWorkflow(
// 3. Return result
if (result.success) {
console.log('Workflow executed successfully:', result.data)
console.log('Workflow executed successfully:', result.output)
return {
success: true,
data: result.data
output: result.output
}
} else {
console.error('Workflow execution failed:', result.error)

View File

@@ -1,6 +1,6 @@
import { ToolConfig, ToolResponse } from '../types'
interface ChatParams {
export interface ChatParams {
apiKey: string
systemPrompt: string
context?: string
@@ -11,7 +11,7 @@ interface ChatParams {
stream?: boolean
}
interface ChatResponse extends ToolResponse {
export interface ChatResponse extends ToolResponse {
output: {
content: string
model: string

View File

@@ -1,13 +1,13 @@
import { ToolConfig, ToolResponse } from '../types'
interface VisionParams {
export interface VisionParams {
apiKey: string
imageUrl: string
model?: string
prompt?: string
}
interface VisionResponse extends ToolResponse {
export interface VisionResponse extends ToolResponse {
output: {
content: string
model?: string

View File

@@ -5,7 +5,7 @@ interface Message {
content: string
}
interface ChatParams {
export interface ChatParams {
apiKey: string
systemPrompt?: string
context?: string
@@ -14,7 +14,7 @@ interface ChatParams {
responseFormat?: string
}
interface ChatResponse extends ToolResponse {
export interface ChatResponse extends ToolResponse {
output: {
content: string
model: string

View File

@@ -5,7 +5,7 @@ interface Message {
content: string
}
interface ChatParams {
export interface ChatParams {
apiKey: string
systemPrompt?: string
context?: string
@@ -13,7 +13,7 @@ interface ChatParams {
temperature?: number
}
interface ChatResponse extends ToolResponse {
export interface ChatResponse extends ToolResponse {
output: {
content: string
model: string

View File

@@ -1,6 +1,6 @@
import { ToolConfig, ToolResponse } from '../types'
interface ScrapeParams {
export interface ScrapeParams {
apiKey: string
url: string
scrapeOptions?: {
@@ -9,7 +9,7 @@ interface ScrapeParams {
}
}
interface ScrapeResponse extends ToolResponse {
export interface ScrapeResponse extends ToolResponse {
output: {
markdown: string
html?: string

View File

@@ -1,11 +1,11 @@
import { ToolConfig, ToolResponse } from '../types'
interface CodeExecutionInput {
export interface CodeExecutionInput {
code: Array<{content: string, id: string}> | string
input?: Record<string, any>
}
interface CodeExecutionOutput extends ToolResponse {
export interface CodeExecutionOutput extends ToolResponse {
output: {
result: any
stdout: string

View File

@@ -1,6 +1,6 @@
import { ToolConfig, ToolResponse } from '../types'
interface ChatParams {
export interface ChatParams {
apiKey: string
systemPrompt: string
context?: string
@@ -11,7 +11,7 @@ interface ChatParams {
topK?: number
}
interface ChatResponse extends ToolResponse {
export interface ChatResponse extends ToolResponse {
output: {
content: string
model: string

View File

@@ -1,6 +1,6 @@
import { ToolConfig, HttpMethod, ToolResponse } from '../types'
interface RequestParams {
export interface RequestParams {
url: string
method?: HttpMethod
headers?: Record<string, string>
@@ -12,7 +12,7 @@ interface RequestParams {
validateStatus?: (status: number) => boolean
}
interface RequestResponse extends ToolResponse {
export interface RequestResponse extends ToolResponse {
output: {
data: any
status: number

View File

@@ -1,6 +1,6 @@
import { ToolConfig, ToolResponse } from '../types'
interface ContactsParams {
export interface ContactsParams {
apiKey: string
action: 'create' | 'update' | 'search' | 'delete'
id?: string
@@ -15,7 +15,7 @@ interface ContactsParams {
data: Record<string, any>
}
interface ContactsResponse extends ToolResponse {
export interface ContactsResponse extends ToolResponse {
output: {
contacts: any[]
totalResults?: number

View File

@@ -14,7 +14,7 @@ interface ChatParams {
stream?: boolean
}
interface ChatResponse extends ToolResponse {
export interface ChatResponse extends ToolResponse {
output: {
content: string
model: string

View File

@@ -1,6 +1,6 @@
import { ToolConfig, ToolResponse } from '../types'
interface OpportunityParams {
export interface OpportunityParams {
apiKey: string
action: 'create' | 'update' | 'search' | 'delete'
id?: string
@@ -16,7 +16,7 @@ interface OpportunityParams {
data: Record<string, any>
}
interface OpportunityResponse extends ToolResponse {
export interface OpportunityResponse extends ToolResponse {
output: {
records: any[]
totalResults?: number

View File

@@ -1,6 +1,6 @@
import { ToolConfig, ToolResponse } from '../types'
interface ChatParams {
export interface ChatParams {
apiKey: string
systemPrompt: string
context?: string
@@ -12,7 +12,7 @@ interface ChatParams {
presencePenalty?: number
}
interface ChatResponse extends ToolResponse {
export interface ChatResponse extends ToolResponse {
output: {
content: string
model: string