Moved tools property out of workflows in block definitions, updated serializer & tests accordingly

This commit is contained in:
Waleed Latif
2025-01-19 01:29:48 -08:00
parent 9b59d68209
commit 2f3fa0c059
8 changed files with 125 additions and 80 deletions
+48 -19
View File
@@ -4,42 +4,71 @@ import { SerializedWorkflow } from '../types';
import { BlockState } from '@/stores/workflow/types';
import { OutputType } from '@/blocks/types';
// Mock icons
jest.mock('@/components/icons', () => ({
AgentIcon: () => 'AgentIcon',
ApiIcon: () => 'ApiIcon',
CodeIcon: () => 'CodeIcon',
}));
// Mock blocks
jest.mock('@/blocks', () => ({
getBlock: (type: string) => {
if (type === 'http') {
if (type === 'api') {
return {
type,
toolbar: {
title: 'API',
description: 'Use any API',
bgColor: '#2F55FF',
icon: () => null,
category: 'basic',
},
tools: {
access: ['http.request']
},
workflow: {
tools: {
access: ['http.request'],
config: {
tool: () => 'http.request'
}
},
outputType: 'json',
inputs: {
url: 'string',
method: 'string'
},
outputType: 'json'
subBlocks: []
}
};
}
// Default agent block config
return {
type,
toolbar: {
title: 'Agent',
description: 'Use any LLM',
bgColor: '#7F2FFF',
icon: () => null,
category: 'basic',
},
tools: {
access: ['openai.chat'],
config: {
tool: () => 'openai.chat'
}
},
workflow: {
tools: {
access: ['openai.chat'],
config: {
tool: () => 'openai.chat'
}
},
outputType: 'string',
inputs: {
prompt: 'string'
},
outputType: 'string'
subBlocks: []
}
};
},
getBlockTypeForTool: (toolId: string) => {
const toolToType: Record<string, string> = {
'openai.chat': 'agent',
'http.request': 'api',
'function': 'function'
};
return toolToType[toolId];
}
}));
@@ -79,7 +108,7 @@ describe('Serializer', () => {
},
'http-1': {
id: 'http-1',
type: 'http',
type: 'api',
name: 'API Call',
position: { x: 400, y: 100 },
subBlocks: {
@@ -165,7 +194,7 @@ describe('Serializer', () => {
const blocks: Record<string, BlockState> = {
'input-1': {
id: 'input-1',
type: 'http',
type: 'api',
name: 'Data Input',
position: { x: 100, y: 100 },
subBlocks: {
@@ -203,7 +232,7 @@ describe('Serializer', () => {
},
'output-1': {
id: 'output-1',
type: 'http',
type: 'api',
name: 'Data Output',
position: { x: 500, y: 100 },
subBlocks: {
@@ -321,7 +350,7 @@ describe('Serializer', () => {
const { blocks } = serializer.deserializeWorkflow(workflow);
const block = blocks['agent-1'];
expect(block.type).toBe('openai.chat');
expect(block.type).toBe('agent');
expect(block.subBlocks.model.value).toBe('gpt-4o');
expect(block.subBlocks.systemPrompt.value).toBe('You are helpful');
expect(block.outputType).toBe('string');
+18 -15
View File
@@ -1,7 +1,7 @@
import { BlockState, SubBlockState } from '@/stores/workflow/types';
import { Edge } from 'reactflow';
import { SerializedBlock, SerializedConnection, SerializedWorkflow } from './types';
import { getBlock } from '@/blocks';
import { getBlock, getBlockTypeForTool } from '@/blocks';
import { OutputType, SubBlockType } from '@/blocks/types';
export class Serializer {
@@ -25,7 +25,7 @@ export class Serializer {
}
// Get the tool ID from the block's configuration
const tools = blockConfig.workflow.tools;
const tools = blockConfig.tools;
if (!tools?.access || tools.access.length === 0) {
throw new Error(`No tools specified for block type: ${block.type}`);
}
@@ -83,15 +83,28 @@ export class Serializer {
}
private deserializeBlock(serialized: SerializedBlock): BlockState {
const toolId = serialized.config.tool;
const blockType = getBlockTypeForTool(toolId);
if (!blockType) {
throw new Error(`Could not determine block type for tool: ${toolId}`);
}
const blockConfig = getBlock(blockType);
if (!blockConfig) {
throw new Error(`Block configuration not found for type: ${blockType}`);
}
return {
id: serialized.id,
type: serialized.config.tool,
name: `${serialized.config.tool} Block`,
type: blockType,
name: `${blockType} Block`,
position: serialized.position,
subBlocks: Object.entries(serialized.config.params).reduce((acc, [key, value]) => {
const subBlock = blockConfig.workflow.subBlocks?.find(sb => sb.id === key);
acc[key] = {
id: key,
type: this.inferSubBlockType(value),
type: subBlock?.type || 'short-input',
value: value
};
return acc;
@@ -99,14 +112,4 @@ export class Serializer {
outputType: serialized.config.interface.outputs.output as OutputType
};
}
private inferSubBlockType(value: any): SubBlockType {
if (Array.isArray(value) && Array.isArray(value[0])) {
return 'table';
}
if (typeof value === 'string' && value.length > 100) {
return 'long-input';
}
return 'short-input';
}
}